Sensor Fusion

Sensor fusion combines data from different sensors to compute something that cannot be calculated from one sensor alone. MetaMotion boards run a Bosch sensor fusion algorithm that performs computations using BMI160 and BMM150 data in the firmware. When using the sensor fusion algorithm, it is important that you do not simultaneously use the Accelerometer, Gyro, and Magnetometer modules. Use the SensorFusionBosch interface to configure the algorithm which in turn will appropriately configure the required sensors.

import com.mbientlab.metawear.module.SensorFusionBosch;

final SensorFusionBosch sensorFusion = board.getModule(SensorFusionBosch.class);

Configuration

There are 4 operation modes that use different combinations of the accelerometer, gyro, and magnetometer, enumerated by the Mode enum. This, along with the data ranges for the accelerometer and gyroscope are set with the module’s ConfigEditor.

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 th Earth’s magnetic field

M4G

Similar to IMUPlus except rotation is detected with the magnetometer

The data rate and sensors used by the algorithm differ on based on the selected mode.

Mode

Acc

Gyro

Mag

NDoF

100Hz

100Hz

25Hz

IMUPlus

100Hz

100Hz

N/A

Compass

25Hz

N/A

25Hz

M4G

50Hz

N/A

50Hz

import com.mbientlab.metawear.module.SensorFusionBosch.*;

// use ndof mode with +/-16g acc range and 2000dps gyro range
sensorFusion.configure()
        .mode(Mode.NDOF)
        .accRange(AccRange.AR_16G)
        .gyroRange(GyroRange.GR_2000DPS)
        .commit();

Calibration

The IMU sensors may need some calibration in order to improve their accuracy. After starting the sensor fusion algorithm, follow the calibration motions outlined in this Bosch tutorial video (YouTube).

When the sensor fusion algorithm is calibrated, it will return the IMU calibration data. The data can be written to the board after each power cycle to automatically calibrate the algorithm. You can combine this with the Macro module to store the calibration in the flash memory.

final SensorFusionBosch sensorFusion = metawear.getModule(SensorFusionBosch.class);
final CancellationTokenSource cts = new CancellationTokenSource();

sensorFusion.calibrate(cts.getToken(), state -> Log.i("MainActivity", state.toString()))
        .onSuccess(task -> {
            // calibration data is reloaded everytime mode changes
            sensorFusion.writeCalibrationData(task.getResult());
            return null;
        });

Data

The algorithm can compute quaternion values and Euler angles as well as separating acceleration sources into linear motion and gravity. Furthermore, it can use data from the other IMUs to correct the errors from the raw sensors. Note that the units and type casting of the sensor fusion data is different for each type of data.

Data

Units

Type

Acceleration

g

CorrectedAcceleration

Angular Velocity

deg/s

CorrectedAngularVelocity

Magnetic Field

T

CorrectedMagneticField

Quaternion

None

Quaternion

Euler Angles

degrees

EulerAngles

Linear Acc

g

Acceleration

Gravity

g

Acceleration

import com.mbientlab.metawear.data.Quaternion;

// stream quaternion values from the board
sensorFusion.quaternion().addRouteAsync(new RouteBuilder() {
    @Override
    public void configure(RouteComponent source) {
        source.stream(new Subscriber() {
            @Override
            public void apply(Data data, Object... env) {
                Log.i("MainActivity", "Quaternion = " + data.value(Quaternion.class));
            }
        });
    }
}).continueWith(new Continuation<Route, Void>() {
    @Override
    public Void then(Task<Route> task) throws Exception {
        sensorFusion.quaternion().start();
        sensorFusion.start();
        return null;
    }
});