8

I'd like to get accelerometers on Android and have them on the earth coordinate system, just like on this topic Acceleration from device's coordinate system into absolute coordinate system or here Transforming accelerometer's data from device's coordinates to real world coordinates but these solutions don't work for me. I'm working on Processing. The project is simply to track the phones accelerations in space, no matter how it is (standing, on the side...). I'm new to Android too. I'd appreciate your help! Thank you.

Edit : I don't need the phones exact position, only accelerations.

Community
  • 1
  • 1
user3645663
  • 141
  • 1
  • 7
  • *"these solutions don't work for me."* Please explain: Why? Do you get wrong results? *"The project is simply to track the phones position in space"* This has come up a zillion times. You cannot do it with double-integrating the acceleration. You either need an external source of reference (for example GPS) or some domain specific assumption (for example the foot doesn't move when it is on the ground). – Ali May 16 '14 at 20:05
  • Hi, well it simply does not work (results can be completely random), comments say the same : "I've tested your snippet and all I get is a quite noisy random signal in return." The project is not really to be able to track the position in space but at least get acceleration values in earth referential. I'm well aware that I cannot get position by double-integrating values. I'd like to get acceleration values no matter the position of the phone. – user3645663 May 17 '14 at 11:57
  • I am afraid I don't follow. I didn't post any snippet nor does any comment say "I've tested your snippet and all I get is a quite noisy random signal in return." under my answer. What's wrong with `Sensor.TYPE_LINEAR_ACCELERATION`? As I understand your question that is exactly what you are looking for. – Ali May 17 '14 at 12:24
  • @Ali `Sensor.TYPE_LINEAR_ACCELERATION` gives me acceleration without gravity, but still in the phones coordinates. I need to have the accelerations values in the earth coordinates. [link](http://stackoverflow.com/questions/11578636/acceleration-from-devices-coordinate-system-into-absolute-coordinate-system) these drawings explain it perfectly : if the phone is standing and moving toward North, it's not giving the same values as when it's on the side, still moving towards North. – user3645663 May 17 '14 at 13:01
  • OK, I see. What's wrong with the accepted answer to [Acceleration from device's coordinate system into absolute coordinate system](http://stackoverflow.com/q/11578636/341970)? Please don't say "it does not work" but explain what you have tried (with code) and what the outcome was. – Ali May 17 '14 at 14:12
  • Well it's just that I don't completely understand what I should write, I tried to do what's written in the answer but I got a bunch of different errors, (multiplying not working...) and the values where still wrong. As he is just explaining and not giving the code I have some trouble understanding. As I said I'm new to this (matrices, Android), and I'd like to put this in a project I have to finish for Monday. Basically I record values in a csv file so I can export it, get data, and analyse it. I appreciate your help! – user3645663 May 17 '14 at 14:28

2 Answers2

6

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!

user3645663
  • 141
  • 1
  • 7
0

The accelerometers are given in term of the device coordinate system. To express the accelerometers in term of the earth coordinate system you need to find the change of basis matrix from the device coordinate system to the earth coordinate system. This is what the rotation matrix is in getRotationMatrix method.
Thus you have to register for TYPE_MAGNETIC_FIELD and filter TYPE_ACCELEROMETER values or using TYPE_GRAVITY in order to get the rotation matrix. Once you get the rotation matrix M it is simple to convert the accelerometer vector in the device coordinate system to the earth coodinate system.

A_E = M * A_D

That is

A_E[0] = M[0] * A_D[0] + M[1] * A_D[1] + M[2] * A_D[2];
A_E[1] = M[3] * A_D[0] + M[4] * A_D[1] + M[5] * A_D[2];
A_E[0] = M[6] * A_D[0] + M[7] * A_D[1] + M[8] * A_D[2];

Where A_D is the accelerometers returned in onSensorChanged

Hoan Nguyen
  • 18,033
  • 3
  • 50
  • 54
  • First, thanks for helping. I don't know how to multiply these matrices as I can only multiply 4*4 matrices with `multiplyMM` (I tried to make a 3*3 matrix for accelerometer values) so I had : `android.opengl.Matrix.multiplyMM(earthAcc, 0, accMatrix, 0, Rotate, 0);` I tried also `multiplyMV(earthAcc, 0, Rotate, 0, acc_values, 0);` and I get `FATAL EXCEPTION: Animation Thread java.lang.IllegalArgumentException: length - offset < n`. Matrices are all 3*3 (accMatrix is simply `x, 0, 0, 0, y, 0, 0, 0, z`. – user3645663 May 18 '14 at 08:53
  • The rotation matrix is define as an array so you just have to use regular multiplication. – Hoan Nguyen May 18 '14 at 09:08
  • Then I get `operator * cannot be applied to float[],float[]` if I write `earthAcc = acc_values*Rotate;` – user3645663 May 18 '14 at 09:13
  • Well I still get quite random values. Here is my what I wrote : `monSensorManager.getRotationMatrix(Rotate, I, gravity_values, mag_values); earthAcc[0] = Rotate[0] * acc_values[0] + Rotate[1] * acc_values[1] + Rotate[2] * acc_values[2]; earthAcc[1] = Rotate[3] * acc_values[0] + Rotate[4] * acc_values[1] + Rotate[5] * acc_values[2]; earthAcc[2] = Rotate[6] * acc_values[0] + Rotate[7] * acc_values[1] + Rotate[8] * acc_values[2];` I tried without updating `getRotationMatrix` every time, still quite random. Thanks for helping tho, I really need it ! – user3645663 May 18 '14 at 09:54
  • The accelerometers will fluctuate, I do not know what do you mean by random. You have to calculate the Rotation matrix every single time the onSensorChanged is called. Even when you lay the device still on a table you will still see fluctuation but the value should not be drastically different unless you have a strong magnetic interference. – Hoan Nguyen May 18 '14 at 10:22
  • By random I mean when I move toward one direction 2 values of the accelerometers fluctuate, the values mean nothing. Some time the values don't even fluctuate at all when I move it. It's wired. I'll make some tests later in the afternoon. If you have a complete code I can test, that would be awesome ! Thank you ! – user3645663 May 18 '14 at 10:56