.. highlight:: cpp 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. :: #include "metawear/sensor/sensor_fusion.h" void configure_sensor_fusion(MblMwMetaWearBoard* board) { // set fusion mode to ndof (n degress of freedom) mbl_mw_sensor_fusion_set_mode(board, MBL_MW_SENSOR_FUSION_MODE_NDOF); // set acceleration rangen to +/-8G, note accelerometer is configured here mbl_mw_sensor_fusion_set_acc_range(board, MBL_MW_SENSOR_FUSION_ACC_RANGE_8G); // write changes to the board 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 ============== ======= ============================ :: #include #include "metawear/core/datasignal.h" #include "metawear/core/data.h" #include "metawear/core/types.h" void stream_quaternion(MblMwMetaWearBoard* board) { auto quaternion = mbl_mw_sensor_fusion_get_data_signal(board, MBL_MW_SENSOR_FUSION_DATA_QUATERNION); mbl_mw_datasignal_subscribe(quaternion, [](const MblMwData* data) -> void { MblMwQuaternion* quaternion = (MblMwQuaternion*) data->value; std::printf("{w: %.3f, x: %.3f, y: %.3f, z: %.3f}\n", quaternion->w, quaternion->x, quaternion->y, quaternion->z); }); mbl_mw_sensor_fusion_enable_data(board, MBL_MW_SENSOR_FUSION_DATA_QUATERNION); mbl_mw_sensor_fusion_start(board); }