Acceleration from device's coordinate system into absolute coordinate system
I finally managed to solve it! So 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.
And there you have it! I hope I will save some precious time for others.
Thanks for Edward Falk and Ali for hints!!
Android get accelerometers on earth coordinate system
I finally worked it out! I combined 2 previous answers, here is the code :
monSensorManager.getRotationMatrix(Rotate, I, gravity_values, mag_values);
float[] relativacc = new float[4];
float[] inv = new float[16];
relativacc[0]=lin_values[0];
relativacc[1]=lin_values[1];
relativacc[2]=lin_values[2];
relativacc[3]=0;
android.opengl.Matrix.invertM(inv, 0, Rotate, 0);
android.opengl.Matrix.multiplyMV(earthAcc, 0, inv, 0, relativacc, 0);
1) Get phone unit vector in earth coordinates
2) Invert matrix to get earth unit vector in phone coordinates
3) Multiply phone acceleration by unit vector to transform phone coordinates to earth coordinates.
Thank you all for your help!
calculate acceleration in reference to true north
The accelerometer sensor returns the acceleration of the device. This is a vector in 3 dimentional space. This vector is returned in the device coordinate system. What you want is the coordinate of this vector in the world coordinate, which is simply
R = rotation matrix obtained by calling getRotationMatrix
A_D = accelerator vector return by sensor ( A_D = event.values.clone )
A_W = R * A_D is the same acceleration vector in the world coordinate system.
A_W is an array of dimention 3
A_W[0] is acceleration due east.
A_W[1] is acceleration due north.
Here is some code to compute it (assumes gravity
and magnetic
contain output from their respective sensors):
float[] R = new float[9];
float[] I = new float[9];
SensorManager.getRotationMatrix(R, I, gravity, magnetic);
float [] A_D = values.clone();
float [] A_W = new float[3];
A_W[0] = R[0] * A_D[0] + R[1] * A_D[1] + R[2] * A_D[2];
A_W[1] = R[3] * A_D[0] + R[4] * A_D[1] + R[5] * A_D[2];
A_W[2] = R[6] * A_D[0] + R[7] * A_D[1] + R[8] * A_D[2];
Transforming accelerometer's data from device's coordinates to real world coordinates
Oki, I have worked this out mathematically myself so please bear with me.
If you want to translate an acceleration vector accelerationvalues
into an acceleration vector trueacceleration
expressed in real world's coordinates, once you have azimuth,pitch and roll stored in a orientationvalues
vector, just do the following:
trueacceleration[0] =(float) (accelerometervalues[0]*(Math.cos(orientationvalues[2])*Math.cos(orientationvalues[0])+Math.sin(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.sin(orientationvalues[0])) + accelerometervalues[1]*(Math.cos(orientationvalues[1])*Math.sin(orientationvalues[0])) + accelerometervalues[2]*(-Math.sin(orientationvalues[2])*Math.cos(orientationvalues[0])+Math.cos(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.sin(orientationvalues[0])));
trueacceleration[1] = (float) (accelerometervalues[0]*(-Math.cos(orientationvalues[2])*Math.sin(orientationvalues[0])+Math.sin(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.cos(orientationvalues[0])) + accelerometervalues[1]*(Math.cos(orientationvalues[1])*Math.cos(orientationvalues[0])) + accelerometervalues[2]*(Math.sin(orientationvalues[2])*Math.sin(orientationvalues[0])+ Math.cos(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.cos(orientationvalues[0])));
trueacceleration[2] = (float) (accelerometervalues[0]*(Math.sin(orientationvalues[2])*Math.cos(orientationvalues[1])) + accelerometervalues[1]*(-Math.sin(orientationvalues[1])) + accelerometervalues[2]*(Math.cos(orientationvalues[2])*Math.cos(orientationvalues[1])));
Related Topics
Android Dialog: Removing Title Bar
How to Open One Particular Folder from Gallery in Android
Get Meta Data of Image - Android
How to Apply Primary Key on the Text Fields in Android Database
Need Some Clarification About Beta/Alpha Testing on The Developer Console
How to Programmatically Include Layout in Android
Fragment Must Be a Public Static Class to Be Properly Recreated from Instance State
Listview: Textview with Linkmovementmethod Makes List Item Unclickable
Fragmentpageradapter Getitem Is Not Called
Using Numberpicker Widget with Strings
Webview with Asynctask on Android
Android - Activity Not Found Exception
How to Animate a View in Android and Have It Stay in The New Position/Size
How to Change The Navigationview's Item Text Size
Find the Physical Address of Exception Vector Table from Kernel Module