Introduction: A Way to Use a Inertial Measurement Unit ?
The context:
I am building for the fun a robot that I want to move autonomously inside a house.
It is a long work and I am doing step by step.
I already published 2 instructables on that topic:
My robot is driven by to 2 DC motors with the help of my home made wheel encoder.
I am currently improving the moving control and have spent some time with gyroscope, accelerometer and IMU. I would pleased to share this experience.
You want to know more about localization ? Here is an article on how to combine artificial intelligence and ultrasounds to localize the robot
Step 1: Why to Use a Inertial Measurement Unit ?
So why did I use an IMU ?
The first reason was that if wheel encoder is precise enough to control straight move, even after tunning I was not able to get a precision for rotation less than +- 5 degres and that is not enough.
So I tried 2 different sensors. Firstly I use a magnetometer (LSM303D). The principle was simple: before rotation get the north orientation, compute the target and adjust the move till the target is reached. It was a little better than with the encoder but with too dispersion. After that I tried to use a gyroscope (L3GD20). The principle was just to integrate the rotation speed provided by the sensor to compute the rotation. And it worked fine. I was able to control rotation at +- 1 degre.
Nevertheless I was curious to try some IMU. I choose a BNO055 component. I spent some time to understand and test this IMU. At the end I decided to select this sensor for the folowing reasons
- I can control rotation as well as with the L3GD20
- I can detect slight rotation when moving straight
- I need to get north orientation for the robot localization and the compass calibration of the BNO055 is very simple
Step 2: How to Use BNO055 for 2D Localization ?
BNO055 IMU is a Bosch 9 axis intelligent sensor that could provide absolute orientation.
The datasheet provides a complete documentation. It is a high tech component is it a rather complex product and I spent some hours to learn how it works and try different ways of using it.
I think it could be useful to share this experience.
Firstly I used the Adafruit library that provides a good tool to calibrate and discover the sensor.
At the end and after a lot of tests I decided to
- use Adafruit library for saving calibration only
- use 3 of all the possible modes of BNO055 (NDOF, IMU, Compss)
- dedicate a Arduino Nano to compute localization based on BNO055 mesurments
Attachments
Step 3: Hardware Point of Vue
BNO055 is a I2C component. So it needs power supply, SDA and SCL to communicate.
Just take care to Vdd voltage according to the product you bought. The Bosch chip works in the range: 2.4V to 3.6V and you can find 3.3v and 5v component.
There are no difficulties for connecting the Nano and the BNO055.
- The BNO055 is powered by the Nano
- SDA & SCL are connected with 2 x 2k pull-up resistors.
- 3 LED connected to the Nano for diagnosis (with resistors)
- 2 connectors used to define the mode after boot
- 1 connector toward the BNO (Gnd, Vdd, Sda,Scl,Int)
- 1 connector toward the Robot/Mega (+9V, Gnd, sda,Scl, Pin11, Pin12)
A little bit of soldering and that's it !
Step 4: How Does It Work ?
From communication point of vue:
- The Nano is the I2C bus master
- The Robot/Mega and the BNO055 are I2C slaves
- The Nano permanently read the BNO055 registers
- The Robot/Mega rises a numeric signal to request the word from the Nano
From calculation point of vue:
The Nano combined with the BNO055 delivers
- The compass heading (used for localization)
- A relative heading (used to control rotations)
- The absolute heading and position (used to control moves)
From functional point of vue:
The Nano:
- manages the BNO055 calibration
- manages the BNO055 parameters and commands
The subsystem Nano & BNO055:
- compute for each robot wheels the absolute heading and localization (with a scale factor)
- compute the relative heading during rotation of the robot
Step 5: The Architecture and Software
The main software is running on an Arduino Nano.
- Architecture is based on I2C communication.
- I chosen to dedicate a Nano due to the fact that the Atmega that runs the robot was rather already loaded and this architecture make it easiest to reuse elsewhere.
- The Nano reads the BNO055 registers, compute and store heading and localization in its own registers.
- The Arduino Atmega that runs the robot code, sends wheels encoders information to the Nano and read the headings and localization inside the Nano registers.
There subsytem (Nano) code is available here on GitHub
The Adafruit calibration tool if here on GitHub (calibration will be stored on eeproom)
Step 6: What Did I Learnt ?
Regarding I2C
Firstly I tried to have 2 masters (Arduino) and 1 slave (sensor) on the same bus but at the end it is possible and easiest to set only the Nano as master and use GPIO connection between the 2 Arduinos to "request the token".
Regarding BNO055 for 2D orientation
I can concentrate on 3 different running modes: NDOF (combine gyroscope, accelerometer and Compas) when the robot is idle, IMU (combine gyroscope, accelerometer) when the robot is moving and Compass during the localization phase. Switching between these modes is easy and fast.
To reduce code size and keep the possibility tu use BNO055 interrupt to detect collision, I prefer not to use Adafruit library and do it on my own.