Android 传感器:getRotationMatrix() 返回错误值,为什么?
我开始使用这个功能已经过去几天了,但还没有成功获得有效的结果。
我想要的是基本上将加速度矢量从设备的坐标系转换为现实世界坐标。我知道这是可能的,因为我有相对坐标的加速度,并且我知道设备在现实世界系统中的方向。
阅读Android开发人员似乎使用getRotationMatrix()我得到 R = 旋转矩阵。
因此,如果我想要 A'(电话系统中的加速度矢量)中的 A(世界系统中的加速度矢量),我必须简单地做:
A=R*A'
但我无法理解为什么矢量 A 的第一个和第二个分量始终为零< /strong> (示例:+0,00;-0,00;+6,43)
我当前的代码与此类似:
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!!!!!
}
}
}
这个问题与这个问题非常相似 将加速度计数据从设备坐标转换为现实世界坐标但我找不到解决方案...我已经尝试了所有方法..
请帮助我,我需要帮助!
更新:
现在我的代码在下面,我试图解释矩阵乘积,但没有任何变化:
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];
这里是一些数据读取和结果的示例:
Rs separated by " " Rs[0] Rs[1]....Rs[8]
Av separated by " " accelerationvalues[0] ...accelerationvalues[2]
rV separated by " " resultVec[0] ...resultVec[2]
您可以注意到,即使您快速移动手机,现实世界中 x 轴和 y 轴上的分量也为零(左右)。相反,相对加速度矢量正确检测每个运动!
解决方案 编号中的错误与浮点变量乘法相关,与双倍乘法不同。 综上所述,如果手机正在加速,即使方向相同,旋转矩阵也不是恒定的。 所以在运动过程中不可能将加速度矢量转换为绝对坐标... 这很难,但这就是现实。
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.
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)
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]
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!!!
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最后我找到了答案:
数字中的错误与浮点变量乘法相关,与双乘法不同。 这里有解决方案。
综上所述,如果手机正在加速,即使方向相同,旋转矩阵也不是恒定的。所以不可能在运动过程中将加速度矢量转换为绝对坐标......这很难,但这是现实。
仅供参考,方向矢量由磁力数据和重力矢量组成。这导致了一个循环问题:转换相对加速度需要方向需要磁场和重力,但只有当手机通过相对加速度停止时我们才知道重力。所以我们回到开始。
这在Android 开发人员在哪里解释旋转矩阵给出 true仅当手机未加速(例如,他们谈论自由落体,实际上不应该进行重力测量)或不在非常规磁场中时才会产生结果。
在其他世界中,完全没有用......
你可以相信这个东西在桌子上用 Android Senor 或类似的东西做简单的实验。
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.
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.
In others world, fully un-useful...
You can trust this thing doing simple experiment on the table with Android Senor or something like this..
在担心旋转、加速度或其他任何问题之前,您必须先找出这个算术错误。
您已经确认这
给了您
所以再次简化。试试这个:
编辑:
最后一个给出
resultVec[0]=1.36
,所以让我们试试这个:You must track down this arithmetic error before you worry about rotation, acceleration or anything else.
You have confirmed that
gives you
So once again, simpify. Try this:
EDIT:
The last one gave
resultVec[0]=1.36
, so let's try this:如果您使用附加的打印值进行求和,我得到的
值并不像您所拥有的那么小。因此存在算术错误!
问题可能是您在最后一个块中使用了
accelerationvalues[]
,然后又使用了accelerometervalues[]
吗?If you do the sums, using the printed values you have appended, I get
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, andaccelerometervalues[]
later?我开发了几个使用 android 传感器 的应用程序,所以我正在回答其中之一根据我的经验,你的问题是:
我也用加速度传感器和磁场传感器观察到这个问题。某些轴的读数为零(当您指向时为两个,或者在其他情况下仅为一个)。当您刚刚启用传感器 (registerListener()) 时会发生此问题,我认为它与某种传感器初始化有关。
就加速度传感器而言,我观察到,只要设备轻微晃动,它就会开始给出正确的传感器读数。
正确的解决方案是使用提供有关传感器状态的正确信息的方法onAccuracyChanged()。它应该返回 SensorManager.SENSOR_STATUS_UNRELIABLE 的状态,但相反,它在我迄今为止测试过的所有物理设备上永久返回 SensorManager.SENSOR_STATUS_ACCURACY_HIGH。通过正确实现 onAccuracyChanged() 方法,您可以忽略错误的读数或要求用户在传感器初始化时等待。
I have developed several applications that make use of android sensors, so I am answering to one of your questions according to my experience:
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.
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.