Reputation: 2054
I am developing an application for Android where I need to remove gravity from accelerometer readings. I have read multiple discussions on this problem, I have also found an algorithm here, but I didn't really understand it.
I want to filter gravity from each axis, not from the total acceleration.
Could you please help me out? My code should be something like:
public void onSensorChanged(SensorEvent sensorEvent) {
float vals[] = sensorEvent.values;
float accelerationX = filterGravity(vals[0]);
float accelerationY = filterGravity(vals[1]);
float accelerationZ = filterGravity(vals[2]);
}
What code should I place in the filterGravity() method?
Upvotes: 21
Views: 27740
Reputation: 1885
If you do not have a phone with TYPE_LINEAR_ACCELERATION, you are stuck with TYPE_ACCELERATION, which cannot separate gravity (tilt) from linear acceleration.
One option is to apply the low-pass filter. Another approach is using sensor fusion if the gyroscope is available. Both approaches have their advantages and disadvantages.
I have lots of working examples in the open source project Acceleration Explorer.
Upvotes: 10
Reputation: 13146
For a basic solution you would need a low pass filter other approaches like a Kalman filter are pretty tough regarding the maths behind. A simple example for Android is one click away from your link at http://developer.android.com/reference/android/hardware/SensorEvent.html#values.
Simply spoken a low pass filter builds a weighted average from all your history values. If you have for example a filtering factor of 0.1 it means that 10% of your current value is added to the previous mean value: newMeanValue = 10% of currentValue + 90% of oldMeanValue. That means even if there is an abrupt peak it will only push your mean value slowly because of the 10%.
Upvotes: 25
Reputation: 1766
Not too sure what you are trying to acomplish but if you are look for the magnitude (which will give a result between 0 and 1) then all you do is divide the result by 10
public void onSensorChanged(SensorEvent sensorEvent) {
float vals[] = sensorEvent.values;
float accelerationX = (vals[0]/10);
float accelerationY = (vals[1]/10);
float accelerationZ = (vals[2]/10);
}
In a game environment when the sensor is at full tilt your object will be at its maximum speed
Upvotes: -2