Sensor Fusion Drift
Hi all,
I am developing with MetaMotionR sensor from quite a while. Yesterday,
for the fist time I had some serious problems of quaternion data
drifting. The sensors are running the last firmware version. Their
battery level was 99%. This happened with 2 out of 3 sensors that were streaming simultaneously to an Android App. Do you have any idea on why this is happening? Have you ever experienced something similar?
Thank you
Cheers
I am developing with MetaMotionR sensor from quite a while. Yesterday,
for the fist time I had some serious problems of quaternion data
drifting. The sensors are running the last firmware version. Their
battery level was 99%. This happened with 2 out of 3 sensors that were streaming simultaneously to an Android App. Do you have any idea on why this is happening? Have you ever experienced something similar?
Thank you
Cheers
This discussion has been closed.
Comments
This is how the data normally look like when the sensor is clipped to the upper trunk of a subject performing exercises.
From when the problem has occurred this is how the data in the same condition looks like:
https://imgur.com/a/sqboU
The sensors is expected to register little motion, since it is fixed on the upper part of the trunk while the subject is sitting and performing movements with his arm.
The code of the App we used to generate the file is quite rich so I have extrapolated the parts regarding quaternion configuration and streaming. Hope it is useful to you.
// parameters class
public class ConnectionParams {
private SensorFusionBosch.Mode mMode;
private float mMaxConnectionInterval;
/**
* Creates a new {@link ConnectionParams}. By default sensor fusion mode is set to
* {@link SensorFusionBosch.Mode#NDOF}, accelerometer data range is set to
* {@link SensorFusionBosch.AccRange#AR_16G} and gyroscopes data range is set to
* {@link SensorFusionBosch.GyroRange#GR_2000DPS}. Max connection interval is set by default to
* 11.25 milliseconds for Android version 23 and above, to 7.5 milliseconds for previous
* versions
*/
private ConnectionParams(){
this.mMode = SensorFusionBosch.Mode.NDOF;
this.mAccRange = SensorFusionBosch.AccRange.AR_16G;
this.mGyroRange = SensorFusionBosch.GyroRange.GR_2000DPS;
this.mMaxConnectionInterval = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? 11.25f : 7.5f;
}
public SensorFusionBosch.Mode getMode() { return this.mMode; }
public float getMaxConnectionInterval() { return this.mMaxConnectionInterval; }
/**
* Using the Builder design pattern to create a {@link ConnectionParams} object
*/
public static class Builder {
private ConnectionParams mObj;
/**
* Creates a {@link Builder} that can be used to generate a {@link ConnectionParams}
* object.
*/
public Builder() {
this.mObj = new ConnectionParams();
}
/**
* Returns a new instance of {@link ConnectionParams} built from the given configuration.
* Once the method has been called, the builder is invalidated and can not be used to create
* a second instance of {@link ConnectionParams}.
* @return a new instance of {@link ConnectionParams}
*/
public ConnectionParams build() {
ConnectionParams tmp = this.mObj;
this.mObj = null;
return tmp;
}
/**
* Sets the sensor fusion operation mode.
* @param mode the mode to set
* @return the {@link Builder} instance to chain calls
*/
public Builder setMode(SensorFusionBosch.Mode mode) {
this.mObj.mMode = mode;
return this;
}
/**
* Set the max connection interval of the BLE connection. Reducing this value allows higher
* streaming frequencies.
* @see <a href="https://devzone.nordicsemi.com/question/60/what-is-connection-parameters/">
* https://devzone.nordicsemi.com/question/60/what-is-connection-parameters/</a>
* @param interval The max connection interval in milliseconds
* @return the {@link Builder} instance to chain calls
*/
public Builder setMaxConnectionInterval(float interval) {
this.mObj.mMaxConnectionInterval = interval;
return this;
}
}
}
// configuration
private SensorFusionBosch mSF;
private void configure (ConnectionParams params) {
this.mSF = this.mBoard.getModule(SensorFusionBosch.class);
this.mSF.configure()
.mode(params.getMode())
.accRange(params.getAccRange())
.gyroRange(params.getGyroRange())
.commit();
this.mQuatProducer = this.mSF.quaternion()
this.mSettings.editBleConnParams()
.slaveLatency((short)0)
.maxConnectionInterval(params.getMaxConnectionInterval())
.commit();
}
// streaming
if(params.isQuatEnabled()){ //stream quaternions
task = task.continueWithTask((Task<Void> t) ->
this.mQuatProducer.addRouteAsync((RouteComponent source) -> {
if(params.isQuatLimited())
source = source.limit(hzToMS(params.getQuatFrequency()));
source.stream((Data data, Object... env) -> {
clbks.onNewQuaternion(data);
});
}).continueWith((Task<Route> t2) -> {
mRouteQuat = t2.getResult();
mQuatProducer.start();
return null;
}));
}
[/code]
Yes, it does
Yes, we did. The sensors showed this behavior for a couple of trials and than got back to normal without any intervention.
Not yet. We were quite happy about the NDoF results, but we can have a look to the alternatives. AS I understand IMUPlus calculates relative orientation in space taking by reference the initial position. What does "Initial position" mean exactly? the position in which the sensor is placed when it stars streaming? Is it possible to force the sensors to reset the initial position to current position?
The problem went away without any intervention. Therefore now we are worried this can randomly append again while we are collecting important data.
We didn't know that was useful. Where can we find this kind of suggestions?
Since we are acquiring in an hospital, it is impossible to exclude all the magnetic fields. However this is the first time in a couple of months of acquisitions we are experiencing something like this. We are trying to figure out if they have acquired some new machinery that could have caused this new issue. Do you think that using IMUPlus can help us in this condition?