2013-03-27 75 views
11

我使用Android重力和磁场传感器通过SensorManager.getRotationMatrix和SensorManager.getOrientation来计算方向。这给了我方位角,音高和方位号码。当设备平放在桌子上时,结果看起来很明智。当我的Android设备不平坦时,我应该如何计算方位角,俯仰角,方向?

不过,我有纵向和横向之间切换禁用清单中,让getWindowManager()。getDefaultDisplay()。getRotation()始终为零。当我将设备旋转90度以使其垂直时,我遇到了麻烦。有时候这些数字看起来相当不对,我意识到这与Gimbal lock有关。但是,其他应用程序似乎没有这个问题。例如,我将我的应用与两个免费的传感器测试应用(Sensor Tester (Dicotomica)Sensor Monitoring (R's Software))进行了比较。我的应用在设备平坦时与这些应用一致,但是当我将设备旋转到垂直位置时,可能会有显着差异。这两个应用似乎彼此都认同,那么他们如何解决这个问题呢?

回答

7

我认为当设备不平时定义方位角度的最好方法是使用一个更合适的角坐标系统,即从SensorManager.getOrientation(...)得到的标准欧拉角。我建议我描述一个here on math.stackexchange.com。我也已经把一些代码实现在an answer here中。除了方位角的良好定义之外,它还具有俯仰角的定义,其正好是在此处的另一个答案中提到的Math.acos(rotationMatrix[8])给出的角度。

你可以从我在第一段已经给这两个环节的全部细节。但是,总之,您的旋转矩阵R来自SensorManager.getRotationMatrix(...)是

equation with definition of R matrix

其中(E X,E ÿ,E Ž),(N X,N ÿ,N Ž)和(G X,G y,G z)是指向正东,北和向重力方向的矢量。然后你想要的方位角是由

equation defining the azimuth angle

+0

不幸的是,这对我从'SensorManager.getRotationMatrixFromVector'获得的旋转矩阵(使用传感器'TYPE_ROTATION_VECTOR')不起作用。当我计算'double a = Math.toDegrees(Math.atan((r [1] - r [3])/(r [0] + r [4])));'(其中r是旋转矩阵)我总是以-90 <='a' <= 90的角度结束 – Zardoz 2016-07-19 11:01:12

9

当设备是不平坦的,你必须调用getOrientation之前调用remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);

azimuth返回通过getOrientation由设备单元Y axis正交伸入世界East-North plane,然后计算所得到的投影矢量和北轴之间的角度获得。

现在我们通常认为的方向,其中后置摄像头指向的方向。这是-Z的方向,其中Z是指出屏幕的设备轴。当设备平坦时,我们不会考虑方向并接受曾经给过的东西。但是当它不是平坦的,我们预计它是-Z的方向。但getOrientation计算Y axis的方向,因此,我们需要在调用getOrientation之前互换Y and Z axes。这正是remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR)所做的,它保持完整的X axis和地图Z to Y

现在,那么你如何知道什么时候remap与否。你可以通过检查来做到这一点

float inclination = (float) Math.acos(rotationMatrix[8]); 
if (result.inclination < TWENTY_FIVE_DEGREE_IN_RADIAN 
      || result.inclination > ONE_FIFTY_FIVE_DEGREE_IN_RADIAN) 
{ 
    // device is flat just call getOrientation 
} 
else 
{ 
    // call remap 
} 

上面的倾角是设备屏幕和世界东北飞机之间的角度。它显示了设备倾斜的程度。

+0

感谢您的答复。然而,这不是这两个免费的传感器应用程序所做的,因为当倾角超过25度(或155度)时,根据您的建议,由于轴的切换,俯仰和滚动数字会跳跃。免费传感器应用程序的俯仰和滚动数字不会跳跃。另外,轴向AXIS_X和AXIS_Z的切换仅适用于一个方向上的倾斜,而在其他方向上的倾斜会导致不正确的方位角跳动(尽管通过调整正在切换的轴可能是正确的)。 – gisking 2013-04-07 11:23:01

+0

表示您不调用重映射的俯仰和滚转值,仅用于方位角。我不明白你的意思是在另一个方向上倾斜吗?如果你的意思是屏幕没有面对你,那么当然屏幕朝向你的方向是相反的。 – 2013-04-07 19:03:12

+0

Thsnks您的想法,但其他答案似乎提供了一个更一致的spproach。 – gisking 2013-05-06 11:58:13

相关问题