Don't know if to celebrate yet - IMU adventures

TL;DR: See Update 3 at bottom.

I don’t know if I can celebrate just quite yet in my IMU adventures. I feel productive after creating an IMU interface:

  • startIMU_NDOF_Mode.py # starts IMU in full Fusion mode using gyros, accels, and mags
  • startIMU_IMUPLUS_Mode.py # starts IMU in Fusion mode using gyros and accels only
  • safeReadIMU.py # Initializes software interface object without changing hardware and performs reads
  • resetIMU.py # Resets heading, pitch, roll values without changing hardware mode
     

Evaluating the results:

  • the last three docking rotations, which are commands “turn_degrees(180.0)”, actually logged values close to 180 (look at the “rotation:” values), and
  • the last heading value of 355.4 does seem to correspond to what I see at the moment - Carl is sitting on the dock pointed somewhat CCW of 0 ( the line in floor boards is roughly 0)
2020-05-08 19:59|[logIMU.py.main]** resetIMU.py executed **
2020-05-08 22:35|[imulog.py.logMotionStop]heading:     2.2  rotation:     2.2 motion:     2.8 sec errors: 335
2020-05-09 04:46|[imulog.py.logMotionStop]heading:   181.0  rotation:   178.8 motion:     2.4 sec errors: 362
2020-05-09 04:47|[imulog.py.logMotionStop]heading:     1.4  rotation:   180.2 motion:     2.3 sec errors: 362
2020-05-09 04:47|[imulog.py.logMotionStop]heading:   356.9  rotation:    -4.6 motion:     2.8 sec errors: 362
2020-05-09 04:47|[imulog.py.logMotionStop]heading:   356.9  rotation:     0.1 motion:     0.3 sec errors: 362
2020-05-09 04:47|[imulog.py.logMotionStop]heading:   357.2  rotation:     0.2 motion:     0.4 sec errors: 362
2020-05-09 04:47|[imulog.py.logMotionStop]heading:   357.2  rotation:     0.0 motion:     0.1 sec errors: 362
2020-05-09 06:11|[imulog.py.logMotionStop]heading:   357.8  rotation:     0.6 motion:     2.9 sec errors: 369
2020-05-09 09:13|[imulog.py.logMotionStop]heading:   178.1  rotation:   180.2 motion:     2.5 sec errors: 386
2020-05-09 09:13|[imulog.py.logMotionStop]heading:   358.8  rotation:   180.3 motion:     2.4 sec errors: 386
2020-05-09 09:14|[imulog.py.logMotionStop]heading:   355.1  rotation:    -3.6 motion:     2.7 sec errors: 386
2020-05-09 09:14|[imulog.py.logMotionStop]heading:   355.2  rotation:     0.1 motion:     0.3 sec errors: 386
2020-05-09 09:14|[imulog.py.logMotionStop]heading:   355.4  rotation:     0.2 motion:     0.4 sec errors: 386
2020-05-09 09:14|[imulog.py.logMotionStop]heading:   355.4  rotation:     0.0 motion:     0.1 sec errors: 386

I am working on a calIbrate IMU program, which means Carl doesn’t get to run very long before I fiddle with him. Therefore, rigorous testing is still waiting.

The IMUPLUS mode (Fusion with Gyros and Accellerometers only, no mags) results do look more promising (+/- 2 deg from encoder values), than prior results in the full NDOF mode (Fusion with Gyros, Accels, and Mags), which was giving +/- 10 degrees over time.

I’ll just have to celebrate how fun it feels when each program has no syntax errors, and runs as expected.

(For reference - the matching wheel.log:)

2020-05-08 22:35|[wheellog.py.logMotionStop]travel:   213.9 rotation:     0.6 motion:     2.8 sec
2020-05-09 04:46|[wheellog.py.logMotionStop]travel:     0.3 rotation:   179.3 motion:     2.4 sec
2020-05-09 04:47|[wheellog.py.logMotionStop]travel:     0.3 rotation:   178.7 motion:     2.3 sec
2020-05-09 04:47|[wheellog.py.logMotionStop]travel:  -211.7 rotation:    -1.7 motion:     2.7 sec
2020-05-09 04:47|[wheellog.py.logMotionStop]travel:    -5.0 rotation:    -0.6 motion:     0.3 sec
2020-05-09 04:47|[wheellog.py.logMotionStop]travel:   -10.3 rotation:     0.3 motion:     0.5 sec
2020-05-09 04:47|[wheellog.py.logMotionStop]travel:     0.0 rotation:     0.0 motion:     0.1 sec
2020-05-09 06:11|[wheellog.py.logMotionStop]travel:   214.7 rotation:     0.8 motion:     2.9 sec
2020-05-09 09:13|[wheellog.py.logMotionStop]travel:     0.3 rotation:   179.3 motion:     2.4 sec
2020-05-09 09:13|[wheellog.py.logMotionStop]travel:     0.3 rotation:   178.7 motion:     2.3 sec
2020-05-09 09:14|[wheellog.py.logMotionStop]travel:  -211.1 rotation:    -1.1 motion:     2.7 sec
2020-05-09 09:14|[wheellog.py.logMotionStop]travel:    -4.5 rotation:     0.0 motion:     0.3 sec
2020-05-09 09:14|[wheellog.py.logMotionStop]travel:    -9.5 rotation:     0.0 motion:     0.4 sec
2020-05-09 09:14|[wheellog.py.logMotionStop]travel:     0.0 rotation:     0.0 motion:     0.1 sec

Update: Undocked Heading: 356.1 degrees looks close:

2020-05-09 12:01|[imulog.py.logMotionStop]heading:   356.1  rotation:     0.8 motion:     2.8 sec errors: 398

Update 2: Undocked Heading per IMU: 354.0 Actual Looks Like 360:

 
 
Update 3: Docked Heading per IMU: 355.8 Actual Looks like 360 to me:


Started off dock IMU reading 359.4, actual looked like +1 degree to me,
then backed onto dock, IMU reading 355.8, Actual looks like 360 to me.
This is IMUPLUS mode reset 12 hours ago, so roughly 4 degrees drift.

2020-05-10 14:52|[imulog.py.logMotionStop]heading:   359.4  
2020-05-10 21:04|[imulog.py.logMotionStop]heading:   177.8  rotation:   178.4 motion:     2.5 sec errors: 553
2020-05-10 21:05|[imulog.py.logMotionStop]heading:   355.7  rotation:   177.7 motion:     2.4 sec errors: 553
2020-05-10 21:05|[imulog.py.logMotionStop]heading:   355.8  rotation:     0.1 motion:     0.1 sec errors: 553
2020-05-10 21:05|[imulog.py.logMotionStop]heading:   355.7  rotation:    -0.1 motion:     2.7 sec errors: 553
2020-05-10 21:05|[imulog.py.logMotionStop]heading:   355.7  rotation:     0.0 motion:     0.3 sec errors: 553
2020-05-10 21:05|[imulog.py.logMotionStop]heading:   355.8  rotation:     0.1 motion:     0.3 sec errors: 553

I saw a posting on the Bosch sensor forum that drift during non-motion is a problem when not using the earth magnetic as a reference. Can’t win with this - need magnetic, but magnetic is not reliable reference. I’m starting to believe the wheel encoders are more reliable with slightly better accuracy.

For comparison, note the corresponding two +180 degree turns recorded by the wheel encoders -0.1 degrees and -0.7 degrees, versus -1.6 degrees and -2.3 degrees from the IMU!

2020-05-10 21:04|[wheellog.py.logMotionStop]travel:     0.3 rotation:   179.9 motion:     2.4 sec
2020-05-10 21:05|[wheellog.py.logMotionStop]travel:     0.8 rotation:   179.3 motion:     2.3 sec
1 Like

IMU will be my next project once I will try to get a good result with OpenCV and face recognition. I promised my kids that Phil could recognized them one day or another.
I will be back to see your progress and do some reverse engineering.

1 Like

I’ve been working through Adrian Rosebrock’s “Practical Python and OpenCV” book and course which had a chapter on “face recognition” but to do “person recognition” directly on the Pi; he has moved on to “deep learning” for that. His free tutorial is here

He does point to a OpenCV face/person recognition package on github that seems very easy to program.

I’ll be interested to learn how you make out with “person reco” on the RPi; Like how far away can your kids be and still be reco’d as a “a face” vs how far to be reco’d as “this particular family member”. (Also what the frame rate, (or time for single photo, and processor temperature you end up at.)

My camera is pointed roughly horizontal, so for a face to be in the view the person has to be across the room. I’m thinking to build a “socked and unsocked ankle detector” since my wife always wears socks in the house, and I am always barefoot.

Rock on!

Update 3, above, is the last update I’ll make on this thread.

Here is a pointer to my IMU library:

BNO055 Inertial Measurement Unit For GoPiGo3

Dexter Industries provides a very nice compass robot example for the GoPiGo3 which uses the BNO055 chip in the NDOF mode (Fusion using Gyros, Accels, and Mags).

After exploring the three DI interface modules:

  • BNO055.py # Hardware Interface Class BNO055()
  • inertial_measurement_unit.py # IMU abstraction class InertialMeasurementUnit()
  • easy_inertial_measurement_unit.py # multi-process/thread safe EasyIMUSensor() class with wrappers for most needed IMU functions

 
The InertialMeasurmentUnit() and EasyIMUSensor() classes perform HW initialization in NDOF mode and offer calibration and value read methods.

From my investigations of IMU heading values:

  • NDOF Mode: typ. +/- 2 deg, max +/- 10, drift 5-6 degrees per hour
  • IMUPLUS Mode: typ. +/- 1 deg, max +/- 2, drift 3-6 degrees per day

What I needed beyond the DI provided modules:

  • Initialization of HW in IMUPLUS mode (Fusion using only Gyros and Accels, no mags)
  • Safe “reset and remap axes” method to set heading to 0
  • Tracking of soft I2C exceptions
  • Software Only Interface Object initialization to allow HW access/control without setting mode
  • Multi-process safe program to read values from IMU without knowing current mode
  • verbose options for greater visibility into IMU operations

My interface modules:

  • myBNO55.py # Hardware Interface Class BNO055() with verbose and “no init” options
  • my_inertial_measurement_unit.py # IMU abstraction class InertialMeasurementUnit() with verbose option, “init=False” option, mode option
  • my_safe_inertial_measurement_unit.py # multi-process/thread SafeIMUSensor() class with wrappers for most needed IMU functions

Example programs:

  • startIMU_IMUPLUS_MODE.py # Full HW and SW initialization in IMUPLUS mode
  • startIMU_NDOF_MODE.py # Full HW and SW initialization in NDOF mode
  • resetIMU.py # Reset HW and remap axes without changing mode
  • calIMU.py # Perform mode respective calibration (IMUPLUS does not require calibration)
  • safeReadIMU.py # Initialize software object without affecting HW and perform periodic all value retrievals
  • imulog.py # Watches GoPiGo3 wheel encoders for motion start/stop, logs datetime, IMU heading, delta heading, time in motion, and software error count when motion ends
  • noInitTest.py # Test of SafeIMUSensor() Software only initialization

Usage:

  1. ./startIMU_IMUPLUS_Mode.py
  2. ./resetIMU.py when bot is in reference direction (on dock and aligned with floor boards)
  3. ./safeReadIMU.py anytime I want to check what the IMU thinks is the current heading.

I followed 3/4 tutorials from Adrian Rosebrock web site but the result is not satisfying me yet. First, I don’t know if you have ever tried but OpenCV installation is a very long process (2/3 hours). Second, RPI is not able to utilize the best detection method which requires to have a GPU, so accuracy can not be the best. Right now, I have everything up and running but even if RPI is able to recognize me against my daughter, it is not able to recognize her from her classmates!. :thinking:
Maybe the issue is that I have still to resize the images datasets in a proper way. I still I have to do further investigations. I will give you an estimation about frame rate and real time detection in a couple of days, if my work and sons will give me a breath. More I go deep, more I think that I have to find a job in this area. :slight_smile:

I don’t recall the time, but I remember there were two options 1) fast non-optimal 2) recommended: involved compiling a bunch of stuff. I have been working with the easy install non-optimal.

OpenCV Install

Performed 7 Aug 2019:

From https://www.pyimagesearch.com/2018/09/19/pip-install-opencv/

sudo apt-get update && sudo apt-get upgrade

sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-100
sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
sudo apt-get install libatlas-base-dev
sudo apt-get install libjasper-dev


wget https://bootstrap.pypa.io/get-pip.py
sudo python3 get-pip.py


**** OPTION A: INSTALL OpenCV to RPi system (not virtual environments)

sudo pip install opencv-contrib-python



=== get opencv/data/  (did not install from package - package owner admitted issue ===
(browse to https://opencv.org/releases, find OpenCV - 3.4.4, click Sources to dnld zip) or
cd ~/Carl/Examples/OpenCV/
wget https://github.com/opencv/opencv/archive/3.4.4.zip
unzip *.zip

data is in ~/Carl/Examples/OpenCV/opencv-3.4.4/data

** Continuing from "Practical Python and OpenCV"

pip install numpy
pip install scipy
sudo pip install mahotas
pip install scikit-learn
sudo pip install -U scikit-image
sudo pip install imutils