4

我正在实现一个简单的 Android 应用程序,我需要在其中识别北方。

所以我已经实现SensorEventListener并使用了这样的东西:

@Override
public void onSensorChanged(SensorEvent event) {
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR)
    {
        SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
        SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, orientationVals);
        SensorManager.getOrientation(mRotationMatrix, orientationVals);

        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: "+ orientationVals[2]);
    }

}

问题是代码行

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

似乎不起作用,因为在这两种情况下(有或没有此代码行),Yaw(方位角)的值取决于手机头部的方向(让它放在背面)

我的预期是,使用我的重新映射,Yaw 会根据手机背面(后置摄像头)的方向而改变。

为什么我的重新映射不起作用?

4

2 回答 2

3

不知道你是否解决了这个问题,但你的线:

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

重新映射 mRotationMatrix 中的值,并将结果放入orientationVals。这是正确的(除了重新映射的坐标数组的变量名称令人困惑)。

但是,您随后通过调用以下方法直接覆盖此重新映射:

SensorManager.getOrientation(mRotationMatrix, orientationVals);

这将获取 mRotationMatrix 中的值并根据这些(旧的、未重新映射的)值计算方向,并将其存储在orientationVals 中。

因此,您上面的代码只是获取 mRotationMatrix 的方向,其轴尚未重新映射,这可能解释了您的问题。

以下内容可能会解决您的问题:

float[] remapCoords = new float[16];
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapCoords);
SensorManager.getOrientation(remapCoords, orientationVals);

假设您的轴重映射是您真正想要/正确的,但这是另一个问题。

我应该注意,引用的文章虽然最出色,但没有明确提到每次计算旋转矩阵时都必须调用重映射坐标系,而不仅仅是在显示更改时(即 onCreate、onSurfaceChanged 等),这可能对某些人来说是显而易见的,但对其他人来说不是。

于 2014-02-17T19:41:43.997 回答
0

我用这个:

/* Compensate device orientation */
            float[] remappedRotationMatrix = new float[9];
            switch (getWindowManager().getDefaultDisplay()
                    .getRotation()) {
            case Surface.ROTATION_0:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_X, SensorManager.AXIS_Y,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_90:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_Y,
                        SensorManager.AXIS_MINUS_X,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_180:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_MINUS_X,
                        SensorManager.AXIS_MINUS_Y,
                        remappedRotationMatrix);
                break;
            case Surface.ROTATION_270:
                SensorManager.remapCoordinateSystem(rotationMatrix,
                        SensorManager.AXIS_MINUS_Y,
                        SensorManager.AXIS_X, remappedRotationMatrix);
                break;
            }

            /* Calculate Orientation */
            float results[] = new float[3];
            SensorManager.getOrientation(remappedRotationMatrix,
                    results);

请告诉我它是否有效,因为该解决方案仍然存在问题。这是我自己的代码here。我是根据这个官方帖子写的。

于 2013-12-25T14:21:21.773 回答