9

我试图构建一个简单的增强现实应用程序,所以我开始使用传感器数据。Android:计算设备方向的问题

根据这一线索(Android compass example)和实例(http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html),定向的使用Sensor.TYPE_ACCELEROMETERSensor.TYPE_MAGNETIC_FIELD计算并不真正适合。

所以我无法获得“好”的价值。方位角值完全没有任何意义,所以如果我只是将电话向上移动,则值会发生极大的变化。即使我只是旋转手机,这些值也不代表手机方向。

有没有人有一个想法,谁来改善根据给定的例子值的质量?

回答

0

您是否尝试过组合(传感器融合)类型Sensor.TYPE_ROTATION_VECTOR。这可能会产生更好的结果: 转到https://developer.android.com/reference/android/hardware/SensorEvent.html并搜索'rotation_vector'。

+1

好吧,那么有没有任何示例如何使用此传感器?我得到x * sin(θ/ 2),y * sin(θ/ 2)和z * sin(θ/ 2)的值。但是,我如何获得价值,我需要建立我的指南针。我应该再次使用getRotationMatrix吗?谢谢你的帮助。 –

+0

“X被定义为矢量积Y.Z(它与设备当前位置的地面相切,大致指向东)。 Y在设备当前位置与地面相切并指向磁北。“ Z指向天空并垂直于地面。” 除尘几何课本或谷歌它:),你应该能够弄清楚。 –

19

你在什么样的方向使用这个示例应用程序?从代码中可以看出,支持的唯一方向是桌面上的纵向或平面,取决于设备。 “好”是什么意思?

旋转设备时,该值不是“好”是正常的,设备坐标系应该在纵向工作,或者平坦不知道(Y轴垂直沿着屏幕朝上,Z轴指向屏幕中心的屏幕,垂直于Y轴的X轴沿着屏幕向右)。有了这个,旋转设备不会旋转设备坐标系,您必须重新映射它。

但是,如果你想在纵向方向的装置的航向,这里是一段代码,为我的作品好:在

@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    // It is good practice to check that we received the proper sensor event 
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) 
    { 
     // Convert the rotation-vector to a 4x4 matrix. 
     SensorManager.getRotationMatrixFromVector(mRotationMatrix, 
       event.values); 
     SensorManager 
       .remapCoordinateSystem(mRotationMatrix, 
         SensorManager.AXIS_X, SensorManager.AXIS_Z, 
         mRotationMatrix); 
     SensorManager.getOrientation(mRotationMatrix, orientationVals); 

     // Optionally convert the result from radians to degrees 
     orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); 
     orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); 
     orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); 

     tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " 
       + orientationVals[1] + "\n Roll (not used): " 
       + orientationVals[2]); 

    } 
} 

你会得到航向(或方位):

orientationVals[0] 
+1

为了记录,我试着用3x3代码矩阵,但它只适用于4x4(又名浮动[16]) – MonoThreaded

+0

我的也可以使用4 * 4(又名浮动[16]) –

7

大概迟到了派对。反正这里是我是如何得到的方位

private final int sensorType = Sensor.TYPE_ROTATION_VECTOR; 
float[] rotMat = new float[9]; 
float[] vals = new float[3]; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    sensorHasChanged = false; 
    if (event.sensor.getType() == sensorType){ 
     SensorManager.getRotationMatrixFromVector(rotMat, 
       event.values); 
     SensorManager 
       .remapCoordinateSystem(rotMat, 
         SensorManager.AXIS_X, SensorManager.AXIS_Y, 
         rotMat); 
     SensorManager.getOrientation(rotMat, vals); 
     azimuth = deg(vals[0]); // in degrees [-180, +180] 
     pitch = deg(vals[1]); 
     roll = deg(vals[2]); 
     sensorHasChanged = true; 
    } 
} 

希望它可以帮助

+0

'remapCoordinateSystem'调用只是身份转换,所以它是多余的。使用'rotMat'输入和输出,文档明确说你不应该这样做 – Thomas

+0

感谢这工作! – Bogdan

11

回答提伯是好的,但如果你日志回滚价值,你会期待不规则的号码。 (卷是AR浏览器很重要)

这是由于

SensorManager.remapCoordinateSystem(mRotationMatrix, 
        SensorManager.AXIS_X, SensorManager.AXIS_Z, 
        mRotationMatrix); 

你必须使用不同的矩阵进出重映射的。以下代码适用于我的滚动值正确:

@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    // It is good practice to check that we received the proper sensor event 
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) 
    { 
     // Convert the rotation-vector to a 4x4 matrix. 
     SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values); 
     SensorManager.remapCoordinateSystem(mRotationMatrixFromVector, 
        SensorManager.AXIS_X, SensorManager.AXIS_Z, 
        mRotationMatrix); 
     SensorManager.getOrientation(mRotationMatrix, orientationVals); 

     // Optionally convert the result from radians to degrees 
     orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); 
     orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); 
     orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); 

     tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " 
       + orientationVals[1] + "\n Roll (not used): " 
       + orientationVals[2]); 

    } 
} 
+0

是的,你可以检查源代码: public static boolean remapCoordinateSystem(float [] inR,int X, int Y, float [] outR) * @param outR *转换后的旋转矩阵。 inR和outR不应该是相同的 *数组。 – codevscolor