From my Android device I can read an array of linear acceleration values (in the device's coordinate system) and an array of absolute orientation values (in Earth's coordinate system). What I need is to obtain the linear acceleration values in the latter coord. system.
How can I convert them?
EDIT after Ali's reply in comment:
All right, so if I understand correctly, when I measure the linear acceleration, the position of the phone completely does not matter, because the readings are given in Earth's coordinate system. right?
But I just did a test where I put the phone in different positions and got acceleration in different axes. There are 3 pairs of pictures - the first ones show how I put the device (sorry for my Paint "master skill") and the second ones show readings from data provided by the linear acc. sensor:
And now - why in the third case the acceleration occurs along the Z axis (not Y) since the device position doesn't matter?
The automotive coordinate system is a human-defined coordinate system fixed at a point of the car. As a reference coordinate system of the car system itself and each sensor coordinate system are linked by external reference.
The world coordinate system usually encompasses the whole earth and has its origin fixed somewhere on the earth (geocentric), in the form of geocentric and Dicard coordinate systems.
The orientation of the camera coordinate system is generally: X -> Right, Y -> Down, Z -> Front LiDAR can be divided into 2D and 3D, and each frame of information is a point cloud. Each point in the point cloud can be expressed in polar (distance and angle) or Cartesian (x, y, z) coordinates, which are in the LIDAR coordinate system.
I finally managed to solve it! So to get acceleration vector in Earth's coordinate system you need to:
float[16]
so it could be used later by android.opengl.Matrix
class) from SensorManager.getRotationMatrix()
(using SENSOR.TYPE_GRAVITY
and SENSOR.TYPE_MAGNETIC_FIELD
sensors values as parameters),android.opengl.Matrix.invertM()
on the rotation matrix to invert it (not transpose!),Sensor.TYPE_LINEAR_ACCELERATION
sensor to get linear acceleration vector (in device's coord. sys.),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!!
Based on @alex's answer, here is the code snippet:
private float[] gravityValues = null; private float[] magneticValues = null; @Override public void onSensorChanged(SensorEvent event) { if ((gravityValues != null) && (magneticValues != null) && (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)) { float[] deviceRelativeAcceleration = new float[4]; deviceRelativeAcceleration[0] = event.values[0]; deviceRelativeAcceleration[1] = event.values[1]; deviceRelativeAcceleration[2] = event.values[2]; deviceRelativeAcceleration[3] = 0; // Change the device relative acceleration values to earth relative values // X axis -> East // Y axis -> North Pole // Z axis -> Sky float[] R = new float[16], I = new float[16], earthAcc = new float[16]; SensorManager.getRotationMatrix(R, I, gravityValues, magneticValues); float[] inv = new float[16]; android.opengl.Matrix.invertM(inv, 0, R, 0); android.opengl.Matrix.multiplyMV(earthAcc, 0, inv, 0, deviceRelativeAcceleration, 0); Log.d("Acceleration", "Values: (" + earthAcc[0] + ", " + earthAcc[1] + ", " + earthAcc[2] + ")"); } else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) { gravityValues = event.values; } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { magneticValues = event.values; } }
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