将加速度计的数据从设备坐标转换为现实世界坐标
如果这是一个非常基本的问题,我真的很抱歉,但我别无选择,只能问:您如何将加速度计数据从设备坐标转换为现实世界坐标?
I'm really sorry if this is a very basic question, but I have not choice but ask it: How do you translate the accelerometer data from the device coordinates to real world coordinates?
我的意思是,假设加速度计给我这样的声音 (Ax,Ay,Az) -在设备坐标中-,我应该应用什么转换来将值转换为 (Ax',Ay',Az') -在现实世界的坐标-,所以我可以在现实世界中使用加速度矢量坐标来计算设备是否正在加速向北、向东、向西南等方向加速?
I mean, assuming that the accelerometer is giving me somenting like (Ax,Ay,Az) -in device's coordinates-, what transformations should I apply to transform the values into (Ax',Ay',Az') -in real world's coordinates-, so I can use the acceleration vector in real worlds coordinates to calculate if the device is accelerating north, east, south-west,etc?
过去几天我一直在解决这个问题.一开始我觉得应该不难,但是找了几十页也没找到什么实用的.
I have been working around this issue during the past few days. At first I thought that it shound't be difficult, but after searching dozens of pages I haven't come up with anything functional.
顺便说一下,这里有一些我目前已经实现的代码:
By the way, here is some code with what I've implemented so far:
private SensorEventListener mSensorEventListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy){
}
public void onSensorChanged(SensorEvent event) {
switch(event.sensor.getType()){
case Sensor.TYPE_ACCELEROMETER:
accelerometervalues = event.values.clone();
AX.setText(accelerometervalues[0]+"");
AY.setText(accelerometervalues[1]+"");
AZ.setText(accelerometervalues[2]+"");
break;
case Sensor.TYPE_ORIENTATION:
orientationvalues = event.values.clone();
azimuth.setText(orientationvalues[0]+"");
pitch.setText(orientationvalues[1]+"");
roll.setText(orientationvalues[2]+"");
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomagneticmatrix =event.values.clone();
TAX.setText(geomagneticmatrix[0]+"");
TAY.setText(geomagneticmatrix[1]+"");
TAZ.setText(geomagneticmatrix[2]+"");
break;
}
if (geomagneticmatrix != null && accelerometervalues != null) {
float[] R = new float[16];
float[] I = new float[16];
SensorManager.getRotationMatrix(R, I, accelerometervalues, geomagneticmatrix);
//What should I do here to transform the components of accelerometervalues into real world acceleration components??
}
}
};
我有:
acceleratorvalues
中原生坐标中的加速度向量.
A vector of accelerations in native coordinates in accelerometervalues
.
geomagneticmatrix
中的磁场值向量.
orientationvalues
中的方位角、俯仰和滚转.
Azimuth, pitch and roll in orientationvalues
.
旋转矩阵R
.倾角矩阵I
.
我认为所有必要的信息都在那里,方位角、俯仰和滚转应该描述设备坐标系相对于现实世界坐标系的位移.另外,我相信 R
是/甚至可以用作设备坐标内的真北向量.
I think all the necessary information is there, azimuth, pitch and roll should describe the displacement of the device's coordinate system in relation with the real world coordinate system. Also, I believe that R
is/can even be used as a true north vector inside the devices coordinates.
在我看来,获得现实世界中的加速度值只是对这些数据的数学变换.我就是想不通.
It seems to me that obtaing the values of acceleration in real world is just a mathematical transformation away from those data. I just can't figure it out.
提前致谢.
我曾尝试将 accelerometervalues
的分量与旋转矩阵 R
(trueaccel=accel*R) 直接相乘,但没有奏效.
I have tried directly multipliying the components of accelerometervalues
with the rotation matrix R
(trueaccel=accel*R) but it didn't work.
trueacceleration[0]= accelerometervalues[0]*R[0]+accelerometervalues[1]*R[1]+accelerometervalues[2]*R[2];
trueacceleration[1]= accelerometervalues[0]*R[1]+accelerometervalues[1]*R[4]+accelerometervalues[2]*R[7];
trueacceleration[2]= accelerometervalues[0]*R[2]+accelerometervalues[1]*R[5]+accelerometervalues[2]*R[8];
我也试过将 accelerometervalues
与倾角矩阵 I 相乘.同时与 R 和 I 相乘(trueaccel=accel*R*I),但这也不起作用.调用 remapcoordinates()
然后以任何前面的形式相乘也不会.
I have also tried multipliying accelerometervalues
with the inclination matrix I. Also multipliying with both R and I (trueaccel=accel*R*I) and that didn't work either. Neither does calling to remapcoordinates()
and then multiply in any of the previous forms.
有人知道我做错了什么吗?
Does anybody have an idea about what am I doing wrong?
Oki,我自己用数学方法解决了这个问题,所以请耐心等待.
Oki, I have worked this out mathematically myself so please bear with me.
如果您想将加速度矢量 accelerationvalues
转换为以现实世界坐标表示的加速度矢量 trueacceleration
,一旦您将方位角、俯仰角和滚转角存储在 orientationvalues
向量,只需执行以下操作:
If you want to translate an acceleration vector accelerationvalues
into an acceleration vector trueacceleration
expressed in real world's coordinates, once you have azimuth,pitch and roll stored in a orientationvalues
vector, just do the following:
trueacceleration[0] =(float) (accelerometervalues[0]*(Math.cos(orientationvalues[2])*Math.cos(orientationvalues[0])+Math.sin(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.sin(orientationvalues[0])) + accelerometervalues[1]*(Math.cos(orientationvalues[1])*Math.sin(orientationvalues[0])) + accelerometervalues[2]*(-Math.sin(orientationvalues[2])*Math.cos(orientationvalues[0])+Math.cos(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.sin(orientationvalues[0])));
trueacceleration[1] = (float) (accelerometervalues[0]*(-Math.cos(orientationvalues[2])*Math.sin(orientationvalues[0])+Math.sin(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.cos(orientationvalues[0])) + accelerometervalues[1]*(Math.cos(orientationvalues[1])*Math.cos(orientationvalues[0])) + accelerometervalues[2]*(Math.sin(orientationvalues[2])*Math.sin(orientationvalues[0])+ Math.cos(orientationvalues[2])*Math.sin(orientationvalues[1])*Math.cos(orientationvalues[0])));
trueacceleration[2] = (float) (accelerometervalues[0]*(Math.sin(orientationvalues[2])*Math.cos(orientationvalues[1])) + accelerometervalues[1]*(-Math.sin(orientationvalues[1])) + accelerometervalues[2]*(Math.cos(orientationvalues[2])*Math.cos(orientationvalues[1])));