Получить угол наклона Эйлера на устройстве Android

Я пытаюсь получить рыскание устройства Android, выраженное в углах Эйлера.

Чтобы быть ясным, я не хочу, чтобы "Азимут" (это угол к магнитному северу), я хочу вращение оси "z" устройства Android, как показано на этом рисунке.

введите описание изображения здесь

Это (ИМХО) должно быть осью, используемой в некоторых автомобильных играх для определения степени рулевого управления.

Насколько я понимаю, я мог бы просто использовать значения акселерометра (без магнитных полей), но я не могу получить определенное значение. (вероятно, из-за отсутствия понимания того, как работает матрица вращения).

Может ли кто-нибудь указать мне правильное направление?

1 ответ

Если вы хотите вычислить вращение вокруг оси z устройства независимо от положения устройства (плоского или не плоского), вам необходимо отслеживать несколько вещей. Если приложение поддерживает как "Портрет", так и "Пейзаж", то это более сложно, я собираюсь дать ответ, когда действие ограничено только Портретом.

Таким образом, плоскость здесь означает, что угол наклона меньше 25 или более 155 градусов и не ровный в противном случае.
Когда устройство находится в переходе из плоского состояния в не плоское и наоборот, в пользовательском интерфейсе возможно некоторое несоответствие.

Зарегистрируйтесь для TYPE_GRAVITY а также TYPE_MAGNETIC_FIELD (необходимо для квартиры) и сделайте расчет ниже.

  • getRotationMatrix

    a [0] a [1] a [2]
    а [3] а [4] а [5]
    а [6] а [7] а [8]

  • подсчитывать pitch = Math.asin(-R[7])

  • С помощью pitch чтобы определить плоскостность устройства (я думаю, что вы можете использовать менее 45 и более 135 для определения плоскостности, вам просто нужно поэкспериментировать, чтобы увидеть, azymuth значение верное)
  • если устройство не плоское, вращение - Math.atan2(a[6], a[7])

  • Если устройство плоское, чтобы начать с получения начального azymuth = Math.atan2(R[1], R[4]) а затем взять разницу с последующим azymuths чтобы получить вращение.

  • Если устройство переходит из плоского состояния в не плоское, проблем не должно быть, вращение - это просто вращение для не плоского сверху.

  • Если устройство переходит из не плоской в ​​плоскую, то вам нужно получить начальный azymuth, Этот начальный azymuth можно установить в направлении задней камеры Math.atan2(-a[2], -a[5]), если устройство находится в вертикальном положении и вращение происходит только вокруг оси z, это направление не должно меняться. В действительности это, вероятно, изменится на несколько градусов, поэтому вам нужно будет взять среднее значение.

Вся математика, кроме Math.atan2(a[6], a[7]), объяснена в Android: алгоритмы для SensorManager.getRotationMatrix и SensorManager.getOrientation()
Итак, позвольте мне дать объяснение для поиска вращения, когда устройство не является плоским.

Как объяснено в ссылке выше, вы должны указать фиксированный вектор и изменяющийся вектор, чтобы вычислить угол между ними. В этом случае изменяющийся вектор представляет собой вектор, лежащий на оси y устройства, а фиксированный вектор представляет собой проекцию вектора гравитации на плоскость xy устройства. В матрице вращения над последней строкой находится нормализованный гравитационный вектор в координате устройства, поэтому проекция на плоскость xy устройства имеет вид (a[6], a[7]). Теперь с помощью простой тригонометрии видно, что Math.atan2(a[6], a[7]) - это угол между осью y устройства и гравитационной проекцией. (Нарисуйте картинку, если вы ее не видите).

Другие вопросы по тегам