Я уже некоторое время пытаюсь разобраться с датчиками ориентации Android.Я думал, что понял это.Тогда я понял, что нет.Теперь я думаю (надеюсь), что снова почувствовал себя лучше, но я все еще не на 100%.Я попытаюсь объяснить мое неоднозначное понимание этого, и, надеюсь, люди смогут исправить меня, если я ошибусь по частям или заполню какие-либо пробелы.
Я думаю, что я стою на 0 градусов долготы (начальный меридиан)и 0 градусов широты (экватор).Это место на самом деле в море у побережья Африки, но потерпите меня.Я держу телефон перед лицом, чтобы нижняя часть телефона указывала на мои ноги;Я смотрю на север (в сторону Гринвича), поэтому правая сторона телефона указывает на восток в сторону Африки.В этой ориентации (со ссылкой на диаграмму ниже) у меня ось X указывает на восток, ось Z указывает на юг, а ось Y - на небо.
Теперь датчики на телефоне позволяют определить ориентацию (а не местоположение) устройства в этой ситуации.Эта часть всегда смущала меня, вероятно, потому что я хотел понять, как что-то работает, прежде чем я признал, что это действительно работает.Кажется, что телефон определяет свою ориентацию, используя комбинацию из двух различных техник.
Прежде чем я это сделаю, представьте, что вы стоите на этом воображаемом клочке земли на широте 0 градусов, а долгота стоит в указанном направлении.выше.Представьте также, что вы с завязанными глазами и ваши ботинки закреплены на кольцевой развязке на детской площадке.Если кто-то толкнет вас в спину, вы упадете (к северу) и вытяните обе руки, чтобы прекратить падение.Точно так же, если кто-то толкнет вас в левое плечо, вы упадете на правую руку.Ваше внутреннее ухо имеет «гравитационные датчики» (клип на YouTube) , которые позволяют определить, падаете ли вы вперед / назад, или падаете влево / вправо или падаете (или вверх !!).Поэтому люди могут обнаружить выравнивание и вращение вокруг тех же осей X и Z, что и телефон.
Теперь представьте, что кто-то поворачивает вас на 90 градусов на круговом перекрестке, чтобы вы теперь смотрели на Восток.Вы вращаетесь вокруг оси Y.Эта ось отличается, потому что мы не можем обнаружить ее биологически.Мы знаем, что находимся под некоторым углом, но мы не знаем направления относительно магнитного северного полюса планеты.Вместо этого нам нужно использовать внешний инструмент ... магнитный компас.Это позволяет нам определить, в каком направлении мы стоим.То же самое относится и к нашему телефону.
Теперь в телефоне есть 3-осевой акселерометр.У меня есть NO представление о том, как они на самом деле работают, но я представляю себе их гравитацию - представить гравитацию как постоянный и равномерный «дождь», падающий с неба, и представить оси на рисунке выше в виде трубок, которые могут обнаружитьколичество дождя течет через.Когда телефон удерживается в вертикальном положении, весь дождь будет проходить через Y-образную трубку.Если телефон поворачивается постепенно, так что его экран обращен к небу, количество дождя, проходящего через Y, уменьшится до нуля, а громкость через Z будет постоянно увеличиваться до тех пор, пока не пройдет максимальное количество дождя.Точно так же, если мы теперь перевернем телефон на бок, X-трубка в итоге соберет максимальное количество дождя.Поэтому в зависимости от ориентации телефона путем измерения количества дождя, протекающего через 3 трубки, вы можете рассчитать ориентацию.
В телефоне также есть электронный компас, который ведет себя как обычный компас - его «виртуальная стрелка» указывает на магнитный север.Android объединяет информацию от этих двух датчиков, так что всякий раз, когда генерируется SensorEvent
из TYPE_ORIENTATION
, массив values[3]
имеет значения
[0]: Азимут - (компас, относящийся к востоку от магнитного севера)
значения[1]: шаг, вращение вокруг оси x (телефон наклоняется вперед или назад)
значения [2]: поворот, вращение вокруг оси y (телефон наклоняется влево или вправо)
Так что я думаю (т.е. я не знаю) причина, по которой Android дает азимут (направление по компасу), а не показание третьего акселерометра, в том, что направление по компасу просто более полезно. Я не уверен, почему они отказались от этого типа датчика, так как теперь кажется, что вам нужно зарегистрировать слушателя в системе для SensorEvent
s типа TYPE_MAGNETIC_FIELD
. Массив value[]
события должен быть передан в метод SensorManger.getRotationMatrix(..)
, чтобы получить матрицу вращения (см. Ниже), которая затем передается в метод SensorManager.getOrientation(..)
.
Кто-нибудь знает, почему команда Android устарела Sensor.TYPE_ORIENTATION
? Это вещь эффективности? Это то, что подразумевается в одном из комментариев к похожему вопросу , но вам все равно нужно зарегистрировать другой тип слушателя в development / samples / Compass / src / com / example / android / compass / CompassActivity.java пример.
Теперь я хотел бы поговорить о матрице вращения. (Это где я больше всего не уверен)
Итак, выше у нас есть три цифры из документации Android, мы будем называть их A, B и C.
A = SensorManger.getRotationMatrix (..) фигура метода и представляет мировую систему координат
B = Система координат, используемая SensorEvent API.
C = метод SensorManager.getOrientation (..) рисунок
Итак, я понимаю, что A представляет «мировую систему координат», которая, как я предполагаю, относится к тому, как местоположения на планете задаются как пара (широта, долгота) с необязательной (высота). X - это "восточная" координата, Y - "северная" координата. Z указывает на небо и представляет собой высоту.
Система координат телефонов, показанная на рисунке B, является фиксированной. Его ось Y всегда указывает на вершину. Матрица вращения постоянно рассчитывается телефоном и позволяет отображать между ними. Так правильно ли я считаю, что матрица вращения преобразует систему координат B в C? Поэтому, когда вы вызываете метод SensorManager.getOrientation(..)
, вы используете массив values[]
со значениями, которые соответствуют рисунку C.
Когда телефон направлен в небо, матрица вращения является единичной матрицей (матричный математический эквивалент 1), что означает, что отображение не требуется, поскольку устройство выровнено по мировой системе координат.
Ok. Я думаю, мне лучше остановиться сейчас. Как я уже говорил, я надеюсь, что люди скажут мне, где я напутал или помог людям (или еще больше запутал людей!)