I am trying to filter out the noise from the orientation/compass sensor in my magic phone.
Some of the readings seem to be 90-180 degrees off and there is a lot of jiggle. I have tried different things with limited success, so I was wondering if anyone could recommend an algorithm to filter this sort of noise to get a stable output.
BR, Mads
You need Low Pass Filter. There are explanation and simple algorithm on wikipedia
This is really late but it might help people like me who came to this question.
Use Type Rotation vector sensor. No need to use a low pass filter or calculate an average value of the last x sensor values.
Here's some code:
private float[] mMatrixR = new float[9];
private float[] mMatrixValues = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ROTATION_VECTOR:
// Get rotation matrix
SensorManager.getRotationMatrixFromVector(mMatrixR, event.values);
SensorManager.getOrientation(mMatrixR, mMatrixValues);
// Use this value in degrees
mAzimuth = Math.toDegrees(mMatrixValues[0]);
}
I found the values very fast and smooth and use these in my app. I used accelerometer and magnetometer as a backup in case rotation type vector isn't present in the device, it's a software based sensor (Sensor fusion) which uses the magnetometer, accelerometer and gyro (if present).
I got rid of most of the noise by just using a slower update time. I'm not sure if Android has a built-in filter for these, but it seems to stabalize a lot. Something like:
mSensorManager.registerListener(
mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
// SENSOR_DELAY_UI, instead of SENDOR_DELAY_FASTEST (or similar)
// seems to iron out a lot of the jitter
SensorManager.SENSOR_DELAY_UI
);
SensorManager offers:
SENSOR_DELAY_FASTEST
: get sensor data as fast as possibleSENSOR_DELAY_GAME
: rate suitable for gamesSENSOR_DELAY_NORMAL
: rate (default) suitable for screen orientation changesSENSOR_DELAY_UI
: rate suitable for the user interface What have you tried? How many readings do you get per second?
I would suggest something along the lines of an average of the last X number of readings to get rid of the "jiggles" and throw away any readings that are wildly different from the current direction to stop any crazy "jumping" of values. Depending on how many readings you are getting, and how much averaging you are doing, your app may lose responsiveness.
The following link might be useful. http://www.chem.uoa.gr/applets/appletsmooth/appl_smooth2.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With