Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Acceleration from device's coordinate system into absolute coordinate system

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:

  1. device put on left side

first positionfirst readings

  1. device lying on back

second positionsecond readings

  1. device standing

enter image description hereenter image description here

And now - why in the third case the acceleration occurs along the Z axis (not Y) since the device position doesn't matter?

like image 220
alex Avatar asked Jul 20 '12 11:07

alex


People also ask

What is the automotive coordinate system?

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.

What is the world coordinate system?

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.

What is the orientation of the camera coordinate system in LIDAR?

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.


2 Answers

I finally managed to solve it! So to get acceleration vector in Earth's coordinate system you need to:

  1. get rotation matrix (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),
  2. use android.opengl.Matrix.invertM() on the rotation matrix to invert it (not transpose!),
  3. use Sensor.TYPE_LINEAR_ACCELERATION sensor to get linear acceleration vector (in device's coord. sys.),
  4. 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!!

like image 112
alex Avatar answered Oct 24 '22 20:10

alex


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;         }     } 
like image 27
orak Avatar answered Oct 24 '22 21:10

orak