Sensor Fusion¶
Sensor fusion software is a complete 9-axis fusion solution, which combines the measurements from 3-axis gyroscope, 3-axis geomagnetic sensor and a 3-axis accelerometer to provide a robust absolute orientation vector. The algorithm fuses the sensor raw data from three sensors in an intelligent way to improve each sensor’s output.
This includes algorithms for offset calibration of each sensor, monitoring of the calibration status and Kalman filter fusion to provide distortion-free and refined orientation vectors.
There are 5 outputs of sensor fusion:
Quaternion
Linear Acceleration
Rotation
Gravity
Robust Heading
The sensor_fusion.h header file interfaces with the sensor fusion algorithm running on MetaMotion boards. When using the sensor fusion algorithm, it is important that you do not simultaneously use the Accelerometer, Gyro, and Magnetometer modules; the algorithm configures those sensors internally based on the selected fusion mode.
The Sensor fusion algorithm we use is from BOSCH and is hardcoded at 100Hz.
To activate the sensor fusion algorithm, first set the fusion mode and data ranges, then subscribe to and enable the desired output data, and finally, call mbl_mw_sensor_fusion_start.
Mode¶
The sensor fusion algorithm has 4 fusion modes, listed in the below table:
Mode |
Description |
---|---|
NDoF |
Calculates absolute orientation from accelerometer, gyro, and magnetometer |
IMUPlus |
Calculates relative orientation in space from accelerometer and gyro data |
Compass |
Determines geographic direction from the Earth’s magnetic field |
M4G |
Similar to IMUPlus except rotation is detected with the magnetometer |
The sensor fusion algorithm provides raw acceleration, rotation, and magnetic field values along with quaternion values and Euler angles.
Furthermore, the source of acceleration can be separated into gravity and linear acceleration and both values are also provided. Keep in mind that each sensor fusion mode has different sets of available data and produces it at different rates.
Mode |
Acc |
Gyro |
Mag |
---|---|---|---|
NDoF |
100Hz |
100Hz |
25Hz |
IMUPlus |
100Hz |
100Hz |
N/A |
Compass |
25Hz |
N/A |
25Hz |
M4G |
50Hz |
N/A |
50Hz |
The mode is set with mbl_mw_sensor_fusion_set_mode and written to the board by calling mbl_mw_sensor_fusion_write_config. Before writing the configuration, you can also set the acceleration and rotation ranges of the accelerometer and gyroscope respectively.
libmetawear.mbl_mw_sensor_fusion_set_mode(board, SensorFusionMode.NDOF)
libmetawear.mbl_mw_sensor_fusion_set_acc_range(board, SensorFusionAccRange._4G)
libmetawear.mbl_mw_sensor_fusion_set_gyro_range(board, SensorFusionGyroRange._2000DPS)
libmetawear.mbl_mw_sensor_fusion_write_config(board)
NDOF¶
This is a fusion mode with 9 degrees of freedom where the fused absolute orientation data is calculated from accelerometer, gyroscope and the magnetometer.
The advantages of combining all three sensors are a fast calculation, resulting in high output data rate, and high robustness from magnetic field distortions.
IMUPlus¶
In the IMU mode the relative orientation of the device in space is calculated from the accelerometer and gyroscope data. The calculation is fast (i.e. high output data rate).
Compass¶
The COMPASS mode is intended to measure the magnetic earth field and calculate the geographic direction.
The measurement accuracy depends on the stability of the surrounding magnetic field (magnets can interfere with the magnetometer and provide false readings since the earth magnetic field is usually much smaller than the magnetic fields that occur around and inside electronic devices).
M4G¶
The M4G mode is similar to the IMU mode, but instead of using the gyroscope signal to detect rotation, the changing orientation of the magnetometer in the magnetic field is used.
Since the magnetometer has much lower power consumption than the gyroscope, this mode is less power consuming in comparison to the IMU mode. There are no drift effects in this mode which are inherent to the gyroscope.
However, as for compass mode, the measurement accuracy depends on the stability of the surrounding magnetic field. For this mode no magnetometer calibration is required and also not available.
Data¶
The sensor fusion algorithm provides raw acceleration, rotation, and magnetic field values along with quaternion values and Euler angles. Furthermore, the source of acceleration can be separated into gravity and linear acceleration and both values are also provided. Keep in mind that each sensor fusion mode has different sets of available data and produces it at different rates.
Mode |
Acc |
Gyro |
Mag |
---|---|---|---|
NDoF |
100Hz |
100Hz |
25Hz |
IMUPlus |
100Hz |
100Hz |
N/A |
Compass |
25Hz |
N/A |
25Hz |
M4G |
50Hz |
N/A |
50Hz |
Also note that the units and type casting of the sensor fusion data is different for each type of data..
Data |
Units |
Casted Data |
---|---|---|
Acceleration |
g |
MblMwCorrectedCartesianFloat |
Rotation |
deg/s |
MblMwCorrectedCartesianFloat |
Magnetic Field |
uT |
MblMwCorrectedCartesianFloat |
Quaternion |
None |
MblMwQuaternion |
Euler Angles |
degrees |
MblMwEulerAngles |
Linear Acc |
g |
MblMwCartesianFloat |
Gravity |
g |
MblMwCartesianFloat |
def data_handler(self, ctx, data):
print("%s -> %s" % (self.device.address, parse_value(data)))
callback = FnVoid_VoidP_DataP(data_handler)
libmetawear.mbl_mw_sensor_fusion_set_mode(board, SensorFusionMode.NDOF);
libmetawear.mbl_mw_sensor_fusion_set_acc_range(board, SensorFusionAccRange._8G)
libmetawear.mbl_mw_sensor_fusion_set_gyro_range(board, SensorFusionGyroRange._2000DPS)
libmetawear.mbl_mw_sensor_fusion_write_config(board)
signal = libmetawear.mbl_mw_sensor_fusion_get_data_signal(board, SensorFusionData.QUATERNION);
libmetawear.mbl_mw_datasignal_subscribe(signal, None, callback)
libmetawear.mbl_mw_sensor_fusion_enable_data(board, SensorFusionData.QUATERNION);
libmetawear.mbl_mw_sensor_fusion_start(board);
sleep(10.0) # TIME PASSES
libmetawear.mbl_mw_sensor_fusion_stop(board);
signal = libmetawear.mbl_mw_sensor_fusion_get_data_signal(board, SensorFusionData.QUATERNION);
libmetawear.mbl_mw_datasignal_unsubscribe(signal)
libmetawear.mbl_mw_debug_disconnect(board)