Направление по компасу различается в зависимости от ориентации телефона

Моему приложению дополненной реальности требуется компасный пеленг камеры, и есть много примеров получения направления от сенсорного менеджера.

Однако я считаю, что результирующее значение различается в зависимости от ориентации телефона - альбомная ориентация, повернутая вправо, примерно на 10 градусов отличается от альбомной, повернутой влево (разница между ROTATION_0 и ROTATION_180 меньше, но все же другая). Этой разницы достаточно, чтобы испортить любой AR-эффект.

Это как-то связано с калибровкой? (Я не уверен, что правильно делаю цифру 8 - я пробовал разные способы, которые нашел на YouTube).

Есть идеи, почему есть разница? Я напортачил с матрицей вращения? У меня есть возможность ограничить приложение одной ориентацией, но меня по-прежнему беспокоит, что показания компаса по-прежнему не очень точны (хотя после фильтрации оно довольно стабильно)

public void onSensorChanged(SensorEvent event) {
        if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
            return;
        }

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)  mGravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mGeomagnetic = event.values;

        if (mGravity != null && mGeomagnetic != null) {

            float[] rotationMatrixA = mRotationMatrixA;
            if (SensorManager.getRotationMatrix(rotationMatrixA, null, mGravity, mGeomagnetic)) {

                float[] rotationMatrixB = mRotationMatrixB;

                Display display = getWindowManager().getDefaultDisplay(); 
                int deviceRot = display.getRotation();

                switch (deviceRot)
                {
                // portrait - normal
                case Surface.ROTATION_0: SensorManager.remapCoordinateSystem(rotationMatrixA,
                        SensorManager.AXIS_X, SensorManager.AXIS_Z,
                        rotationMatrixB);
                break;
                // rotated left (landscape - keys to bottom)
                case Surface.ROTATION_90: SensorManager.remapCoordinateSystem(rotationMatrixA,
                        SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_X,
                        rotationMatrixB); 
                break;
                // upside down
                case Surface.ROTATION_180: SensorManager.remapCoordinateSystem(rotationMatrixA,
                        SensorManager.AXIS_X, SensorManager.AXIS_Z,
                        rotationMatrixB); 
                break;
                // rotated right
                case Surface.ROTATION_270: SensorManager.remapCoordinateSystem(rotationMatrixA,
                        SensorManager.AXIS_MINUS_Z, SensorManager.AXIS_X,
                        rotationMatrixB); 
                break;

                default:  break;
                }

                float[] dv = new float[3]; 
                SensorManager.getOrientation(rotationMatrixB, dv);
                // add to smoothing filter
                fd.AddLatest((double)dv[0]); 
            }
            mDraw.invalidate();     
        }
    }
6
задан Mush 24 December 2011 в 16:59
поделиться