Acceleration from device's coordinate system into absolute coordinate system
https://stackoverflow.com/questions/11578636/acceleration-from-devices-coordinate-system-into-absolute-coordinate-system/11614404#11614404
to get acceleration vector in Earth's coordinate system you need to:
- get rotation matrix (
float[16]
so it could be used later byandroid.opengl.Matrix
class) fromSensorManager.getRotationMatrix()
(usingSENSOR.TYPE_GRAVITY
andSENSOR.TYPE_MAGNETIC_FIELD
sensors values as parameters), - use
android.opengl.Matrix.invertM()
on the rotation matrix to invert it (not transpose!), - use
Sensor.TYPE_LINEAR_ACCELERATION
sensor to get linear acceleration vector (in device's coord. sys.), - use
android.opengl.Matrix.multiplyMV()
to multiply the rotation matrix by linear acceleration vector
1 public void onSensorChanged(SensorEvent event) { 2 if ((gravityValues != null) && (magneticValues != null) 3 && (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)) { 4 5 float[] deviceRelativeAcceleration = new float[4]; 6 deviceRelativeAcceleration[0] = event.values[0]; 7 deviceRelativeAcceleration[1] = event.values[1]; 8 deviceRelativeAcceleration[2] = event.values[2]; 9 deviceRelativeAcceleration[3] = 0; 10 11 // Change the device relative acceleration values to earth relative values 12 // X axis -> East 13 // Y axis -> North Pole 14 // Z axis -> Sky 15 16 float[] R = new float[16], I = new float[16], earthAcc = new float[16]; 17 SensorManager.getRotationMatrix(R, I, gravityValues, magneticValues); 18 float[] inv = new float[16]; 19 20 android.opengl.Matrix.invertM(inv, 0, R, 0); 21 android.opengl.Matrix.multiplyMV(earthAcc, 0, inv, 0, deviceRelativeAcceleration, 0); 22 Log.d("Acceleration", "Values: (" + earthAcc[0] + ", " + earthAcc[1] + ", " + earthAcc[2] + ")"); 23 } else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) { 24 gravityValues = event.values; 25 } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { 26 magneticValues = event.values; 27 } 28 }