Android sensor: getRotationMatrix()返回错误的值,为什么?

时间:2022-10-21 18:32:27

It's past several days since I started using this function and have not yet succeeded in obtaining valid results.

我使用这个函数已经有好几天了,还没有取得有效的结果。

What i want is basically convert acceleration vector from device's coordinates system, to real world coordinates. I' know that is possible because i have acceleration in relative coordinates and i know the orientation of the device in real world system.

我想要的是把加速度矢量从设备的坐标系转换成真实的坐标系。我知道这是可能的,因为我有相对坐标的加速度,我知道在现实世界系统中设备的方向。

Reading Android developers seems that using getRotationMatrix() i get R = rotation matrix.

阅读Android开发人员,似乎使用getRotationMatrix()可以得到R =旋转矩阵。

So if i want A (acceleration vector in world system) from A' (acceleration vector in phone system) i must do simply:

因此,如果我想要一个(世界系统中的加速度矢量)来自电话系统中的加速度矢量,我必须做的很简单:

  A=R*A'

But i cant'n understand why the vector A has ALWAYS the first and the second component zero (example: +0,00;-0,00;+6,43)

但是我不明白为什么向量A总是第一个和第二个分量为0(例如:+0,00;-0,00;+6,43)

My current code is similar to this:

我目前的代码与此类似:

  public void onSensorChanged(SensorEvent event) {
     synchronized (this) {   
        switch(event.sensor.getType()){
        case Sensor.TYPE_ACCELEROMETER:
            accelerometervalues = event.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            geomagneticmatrix =event.values.clone();
            break;
        }
        if (geomagneticmatrix != null && accelerometervalues != null) {
            float[] Rs = new float[16];
            float[] I = new float[16];
            SensorManager.getRotationMatrix(Rs, I, accelerometervalues, geomagneticmatrix);
            float resultVec[] = new float[4];
            float relativacc[]=new float [4];
                relativacc[0]=accelerationvalues[0];
                relativacc[1]=accelerationvalues[1];
                relativacc[2]=accelerationvalues[2];
                relativacc[3]=0;
            Matrix.multiplyMV(resultVec, 0, Rs, 0, relativacc, 0);

            //resultVec[] is the vector acceleration relative to world coordinates system..but doesn't WORK!!!!!

        }
      }
   }

This question is very similar to this one Transforming accelerometer's data from device's coordinates to real world coordinates but there i can't find the solution...i had tried all the ways..

这个问题与把加速度计的数据从设备的坐标转换成现实的坐标非常相似,但是我找不到解决方案。我已经试过各种方法了。

Please help me, i need help!!!

请帮帮我,我需要帮助!!

UPDATE:

更新:

Now my code is below, i had tried to explain matrix product, but nothing change:

现在我的代码在下面,我试着解释矩阵乘积,但没有变化:

            float[] Rs = new float[9];
            float[] I = new float[9];
            SensorManager.getRotationMatrix(Rs, I, accelerationvalues, geomagneticmatrix);
            float resultVec[] = new float[4];

            resultVec[0]=Rs[0]*accelerationvalues[0]+Rs[1]*accelerationvalues[1]+Rs[2]*accelerationvalues[2];
            resultVec[1]=Rs[3]*accelerationvalues[0]+Rs[4]*accelerationvalues[1]+Rs[5]*accelerationvalues[2];
            resultVec[2]=Rs[6]*accelerationvalues[0]+Rs[7]*accelerationvalues[1]+Rs[8]*accelerationvalues[2];

Here some example of data read and result:

这里有一些数据读取和结果的例子:

Rs separated by " " Rs[0] Rs[1]....Rs[8]
Av separated by " " accelerationvalues[0] ...accelerationvalues[2]
rV separated by " " resultVec[0] ...resultVec[2]

Android sensor: getRotationMatrix()返回错误的值,为什么?

As you can notice the component on x and y axes in real world are zero (around) even if you move speddy the phone. Instead the relative acceleration vector detect correctly each movement!!!

正如你所注意到的,在现实世界中x轴和y轴上的分量是零(周围),即使你移动手机。相反,相对加速度矢量检测正确的每一个运动!!!

SOLUTION The errors in the numberrs are relative to float vars multiplication that is not the same as a double multyplication. This sums to the fact that rotation matrix isn't costant if the phone, even if with the same orientation, is accelerating. So is impossible translate acceleration vector to absolute coordinates during motion... It's hard but it's the reality.

解决数字中的错误是相对于浮点乘,这与双多重乘是不同的。这就证明了一个事实,如果手机,即使有相同的方向,也在加速,那么旋转矩阵就不是恒定的。所以在运动过程中,不可能将加速度矢量转化为绝对坐标。这很难,但这是现实。

4 个解决方案

#1


5  

Finnaly i found the answer:

最后我找到了答案:

The errors in the numbers are relative to float vars multiplication that is not the same as a double multyplication. Here there is the solution. This sums to the fact that rotation matrix isn't costant if the phone, even if with the same orientation, is accelerating. So is impossible translate acceleration vector to absolute coordinates during motion... It's hard but it's the reality.

数字中的错误是相对于浮点乘,这与双多重乘不同。这就是解决方案。这就证明了一个事实,如果手机,即使有相同的方向,也在加速,那么旋转矩阵就不是恒定的。所以在运动过程中,不可能将加速度矢量转化为绝对坐标。这很难,但这是现实。

FYI the orientation vector is made from magnetomer data AND gravity vector. This cause a ciclic problem: convert relative acc needs oirentation needs magnetic field AND gravity, but we know gravity only if the phone is stop by relative acc..so we are return to begin.

方向矢量由磁力仪数据和重力矢量构成。这就产生了一个问题:转换相对acc需要磁场和重力,但我们只有在手机被相对acc停止时才知道重力。所以我们又开始了。

This is confirmed in Android Developers where is explained that rotation matrix give true result only when the phone isn't accelerate (e.g. they talk of free fall, infact there shouldn't be gravity mesaurement) or when it isn't in a non regulare magnetic field.

这在Android开发人员中得到了证实,他们解释说旋转矩阵只有在手机没有加速时才会给出真实的结果(例如,他们谈论*落体,事实上不应该有重力测量),或者当它不在非规则磁场中时才会给出真实的结果。

The matrices returned by this function are meaningful only when the device is not free-falling and it is not close to the magnetic north. If the device is accelerating, or placed into a strong magnetic field, the returned matrices may be inaccurate.

该函数返回的矩阵只有在设备不*下落且不靠近磁北时才有意义。如果设备正在加速,或者放置在强磁场中,返回的矩阵可能不准确。

In others world, fully un-useful... You can trust this thing doing simple experiment on the table with Android Senor or something like this..

在另一些世界里,完全没用……你可以相信这个东西用Android Senor或类似的东西在桌子上做简单的实验。

#2


1  

You must track down this arithmetic error before you worry about rotation, acceleration or anything else.

在考虑旋转、加速度或其他问题之前,您必须跟踪这个算术错误。

You have confirmed that

你有确认

resultVec[0]=Rs[0]*accelerationvalues[0];

gives you

给你

Rs[0]: 0.24105562
accelerationValues[0]: 6.891896
resultVec[0]: 1.1920929E-7

So once again, simpify. Try this:

再一次,simpify。试试这个:

Rs[0] = 0.2;
resultVec[0] = Rs[0] * 6.8

EDIT:
The last one gave resultVec[0]=1.36, so let's try this:

编辑:最后一个给出了resultVec[0]=1.36,我们试试这个:

Rs[0] = 0.2;
accelerationValues[0] = 6.8
resultVec[0] = Rs[0] * accelerationValues[0];

#3


0  

If you do the sums, using the printed values you have appended, I get

如果你计算和,使用你附加的打印值,我得到

`(0.00112, -0.0004, 10)`

which is not as small as what you have. Therefore there is an arithmetic error!

它不像你拥有的那么小。因此有一个算术错误!

Could the problem be that you are using accelerationvalues[] in the last block, and accelerometervalues[] later?

问题可能是您在上一个块中使用了加速值[],而在后面使用了加速计值[]?

#4


0  

I have developed several applications that make use of android sensors, so I am answering to one of your questions according to my experience:

我已经开发了几个使用android传感器的应用,根据我的经验,我正在回答您的一个问题:

But i cant'n understand why the vector A has ALWAYS the first and the second component zero (example: +0,00;-0,00;+6,43)

但是我不明白为什么向量A总是第一个和第二个分量为0(例如:+0,00;-0,00;+6,43)

I have observed this problem with the acceleration sensor and the magnetic field sensor, too. The readings are zero for some of the axis (two as you point, or just one in other occasions). This problem happens when you have just enabled the sensors (registerListener()) and I assume that it is related to some kind of sensor initialization. In the case of the acceleration sensor, I have observed that just a small shaking of the device makes it to start giving correct sensor readings.

我也观察过加速度传感器和磁场传感器的问题。一些轴的读数为零(当你指向两个轴时,或者在其他场合只有一个轴)。当您刚刚启用传感器(registerListener())时,这个问题就会发生,我假设它与某种类型的传感器初始化有关。在加速度传感器的情况下,我观察到,只有一个小的震动装置使它开始提供正确的传感器读数。

The correct solution would be the method onAccuracyChanged() giving the correct information about the sensor state. It should be returning a staus of SensorManager.SENSOR_STATUS_UNRELIABLE, but instead of that, it permanently returns SensorManager.SENSOR_STATUS_ACCURACY_HIGH on all physical devices that I have tested so far. With the method onAccuracyChanged() properly implemented, you could ignore bad readings or ask the user to wait while the sensor is being initialized.

正确的解决方案应该是onAccuracyChanged()方法,该方法提供关于传感器状态的正确信息。它应该是返回一个传感器管理器。sensor_status_constant返回SensorManager,而不是不可靠的。到目前为止我测试过的所有物理设备上的SENSOR_STATUS_ACCURACY_HIGH。通过正确实现方法onAccuracyChanged(),您可以忽略错误读数,或者在初始化传感器时要求用户等待。

#1


5  

Finnaly i found the answer:

最后我找到了答案:

The errors in the numbers are relative to float vars multiplication that is not the same as a double multyplication. Here there is the solution. This sums to the fact that rotation matrix isn't costant if the phone, even if with the same orientation, is accelerating. So is impossible translate acceleration vector to absolute coordinates during motion... It's hard but it's the reality.

数字中的错误是相对于浮点乘,这与双多重乘不同。这就是解决方案。这就证明了一个事实,如果手机,即使有相同的方向,也在加速,那么旋转矩阵就不是恒定的。所以在运动过程中,不可能将加速度矢量转化为绝对坐标。这很难,但这是现实。

FYI the orientation vector is made from magnetomer data AND gravity vector. This cause a ciclic problem: convert relative acc needs oirentation needs magnetic field AND gravity, but we know gravity only if the phone is stop by relative acc..so we are return to begin.

方向矢量由磁力仪数据和重力矢量构成。这就产生了一个问题:转换相对acc需要磁场和重力,但我们只有在手机被相对acc停止时才知道重力。所以我们又开始了。

This is confirmed in Android Developers where is explained that rotation matrix give true result only when the phone isn't accelerate (e.g. they talk of free fall, infact there shouldn't be gravity mesaurement) or when it isn't in a non regulare magnetic field.

这在Android开发人员中得到了证实,他们解释说旋转矩阵只有在手机没有加速时才会给出真实的结果(例如,他们谈论*落体,事实上不应该有重力测量),或者当它不在非规则磁场中时才会给出真实的结果。

The matrices returned by this function are meaningful only when the device is not free-falling and it is not close to the magnetic north. If the device is accelerating, or placed into a strong magnetic field, the returned matrices may be inaccurate.

该函数返回的矩阵只有在设备不*下落且不靠近磁北时才有意义。如果设备正在加速,或者放置在强磁场中,返回的矩阵可能不准确。

In others world, fully un-useful... You can trust this thing doing simple experiment on the table with Android Senor or something like this..

在另一些世界里,完全没用……你可以相信这个东西用Android Senor或类似的东西在桌子上做简单的实验。

#2


1  

You must track down this arithmetic error before you worry about rotation, acceleration or anything else.

在考虑旋转、加速度或其他问题之前,您必须跟踪这个算术错误。

You have confirmed that

你有确认

resultVec[0]=Rs[0]*accelerationvalues[0];

gives you

给你

Rs[0]: 0.24105562
accelerationValues[0]: 6.891896
resultVec[0]: 1.1920929E-7

So once again, simpify. Try this:

再一次,simpify。试试这个:

Rs[0] = 0.2;
resultVec[0] = Rs[0] * 6.8

EDIT:
The last one gave resultVec[0]=1.36, so let's try this:

编辑:最后一个给出了resultVec[0]=1.36,我们试试这个:

Rs[0] = 0.2;
accelerationValues[0] = 6.8
resultVec[0] = Rs[0] * accelerationValues[0];

#3


0  

If you do the sums, using the printed values you have appended, I get

如果你计算和,使用你附加的打印值,我得到

`(0.00112, -0.0004, 10)`

which is not as small as what you have. Therefore there is an arithmetic error!

它不像你拥有的那么小。因此有一个算术错误!

Could the problem be that you are using accelerationvalues[] in the last block, and accelerometervalues[] later?

问题可能是您在上一个块中使用了加速值[],而在后面使用了加速计值[]?

#4


0  

I have developed several applications that make use of android sensors, so I am answering to one of your questions according to my experience:

我已经开发了几个使用android传感器的应用,根据我的经验,我正在回答您的一个问题:

But i cant'n understand why the vector A has ALWAYS the first and the second component zero (example: +0,00;-0,00;+6,43)

但是我不明白为什么向量A总是第一个和第二个分量为0(例如:+0,00;-0,00;+6,43)

I have observed this problem with the acceleration sensor and the magnetic field sensor, too. The readings are zero for some of the axis (two as you point, or just one in other occasions). This problem happens when you have just enabled the sensors (registerListener()) and I assume that it is related to some kind of sensor initialization. In the case of the acceleration sensor, I have observed that just a small shaking of the device makes it to start giving correct sensor readings.

我也观察过加速度传感器和磁场传感器的问题。一些轴的读数为零(当你指向两个轴时,或者在其他场合只有一个轴)。当您刚刚启用传感器(registerListener())时,这个问题就会发生,我假设它与某种类型的传感器初始化有关。在加速度传感器的情况下,我观察到,只有一个小的震动装置使它开始提供正确的传感器读数。

The correct solution would be the method onAccuracyChanged() giving the correct information about the sensor state. It should be returning a staus of SensorManager.SENSOR_STATUS_UNRELIABLE, but instead of that, it permanently returns SensorManager.SENSOR_STATUS_ACCURACY_HIGH on all physical devices that I have tested so far. With the method onAccuracyChanged() properly implemented, you could ignore bad readings or ask the user to wait while the sensor is being initialized.

正确的解决方案应该是onAccuracyChanged()方法,该方法提供关于传感器状态的正确信息。它应该是返回一个传感器管理器。sensor_status_constant返回SensorManager,而不是不可靠的。到目前为止我测试过的所有物理设备上的SENSOR_STATUS_ACCURACY_HIGH。通过正确实现方法onAccuracyChanged(),您可以忽略错误读数,或者在初始化传感器时要求用户等待。