Android: вычислить правильный азимут, компенсируя изменения высоты тона / наклона (устройство не ровное) - PullRequest
1 голос
/ 07 января 2020

Я в настоящее время программирую приложение камеры Android (на моем Samsung S9, работающем на Android 9), и я замечаю проблему с выходным значением азимута, когда устройство наклонено (не плоское). Разница в градусах относительно того, когда устройство начинает с плоской поверхности и поднимается, например, до угла около 90 градусов, может варьироваться от 10 до 20 градусов.

Я просматривал различные потоки StackOverflow, но, похоже, ни один из них не имел решение, которое включает в себя устройство, потенциально использующее все возможные вращения в сочетании с датчиком ROTATION_VECTOR. Причина, по которой я остановился на ROTATION_VECTOR, заключается главным образом в том, что из одного из прочитанных мной тем пользователи упоминали об этом, принимая во внимание потенциальные изменения высоты тона / наклона при расчете азимута, но это явно не относится к моей проблеме.

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

Выводимое значение азимута представляется правильным, когда устройство параллельно к земле (лежал ровно на полу), но как только он наклонился, но остался в том же направлении, азимут начинает постепенно увеличиваться / уменьшаться. Это одинаково для любого случая поворота, независимо от того, находится ли телефон в портретном или ландшафтном режиме.

Метод ниже вызывается внутри события onSensorChanged:

private float[] calculateOrientation(float[] values) {
        float[] rotationMatrix = new float[9];
        float[] remappedMatrix = new float[9];
        float[] orientation = new float[3];

        // Determine the rotation matrix
        SensorManager.getRotationMatrixFromVector(rotationMatrix, values);

        // Remap the coordinates based on the natural device orientation.
        int x_axis = SensorManager.AXIS_X;
        int y_axis = SensorManager.AXIS_Y;

        switch (screenRotation) {
            case (Surface.ROTATION_90):
                x_axis = SensorManager.AXIS_Y;
                y_axis = SensorManager.AXIS_MINUS_X;
                break;

            case (Surface.ROTATION_180):
                y_axis = SensorManager.AXIS_MINUS_Y;
                break;

            case (Surface.ROTATION_270):
                x_axis = SensorManager.AXIS_MINUS_Y;
                y_axis = SensorManager.AXIS_X;
                break;
            default: break;
        }

        SensorManager.remapCoordinateSystem(rotationMatrix, x_axis, y_axis, remappedMatrix);

        // Obtain the current, corrected orientation.
        SensorManager.getOrientation(remappedMatrix, orientation);

        angleLowPassFilter.add(orientation[0]);

        // Convert from Radians to Degrees.
        values[0] = (float) Math.toDegrees(orientation[0]);
        values[1] = (float) Math.toDegrees(orientation[1]);
        values[2] = (float) Math.toDegrees(orientation[2]);

        int correctedAzimuth = (int) ((values[0] + 360) % 360);
        TextView textView = findViewById(R.id.textView);
        textView.setText(String.format(Locale.US, "Azimuth: [%s]", correctedAzimuth));

        return values;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...