android — Обзор ориентации телефона Android, включая компас" />

Обзор ориентации телефона Android, включая компас

Некоторое время я пытался разобраться с датчиками ориентации Android. Я думал, что понял это. Тогда я понял, что нет. Теперь я думаю (надеюсь), что снова чувствую это лучше, но я все еще не на 100%. Я попытаюсь объяснить мое неоднозначное понимание этого, и, надеюсь, люди смогут исправить меня, если я ошибусь по частям или заполню пробелы.

Я представляю, что стою на 0 градусов долготы (основной меридиан) и 0 градусов широты (экватор). Это место на самом деле в море у побережья Африки, но потерпите меня. Я держу телефон перед лицом, чтобы нижняя часть телефона указывала на мои ноги; Я смотрю на север (в сторону Гринвича), поэтому правая сторона телефона указывает на восток в сторону Африки. В этой ориентации (со ссылкой на диаграмму ниже) у меня ось X направлена ​​на восток, ось Z направлена ​​на юг, а ось Y - на небо.

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

Прежде чем я вернусь к этому, представьте, что вы снова стоите на этом воображаемом клочке земли на 0 градусов широты и долготы, стоя в указанном выше направлении. Представьте также, что вы с завязанными глазами и ваши ботинки закреплены на кольцевой развязке на детской площадке. Если кто-то толкнет вас в спину, вы упадете (к северу) и вытяните обе руки, чтобы прервать свое падение. Точно так же, если кто-то толкнет вас в левое плечо, вы упадете на правую руку. В вашем внутреннем ухе есть «гравитационные датчики» (клип на YouTube) , которые позволяют вам определить, падаете ли вы вперед /назад, или падаете влево /вправо или падаете (или вверх !!). Поэтому люди могут обнаружить выравнивание и вращение вокруг тех же осей X и Z, что и телефон.

А теперь представьте, что кто-то поворачивает вас на 90 градусов на перекрестке с круговым движением, чтобы вы теперь смотрели на Восток. Вы вращаетесь вокруг оси Y. Эта ось отличается, потому что мы не можем обнаружить ее биологически. Мы знаем, что находимся под некоторым углом, но мы не знаем направления относительно магнитного северного полюса планеты. Вместо этого нам нужно использовать внешний инструмент ... магнитный компас. Это позволяет нам определить, в каком направлении мы стоим. То же самое относится и к нашему телефону.

Теперь в телефоне есть 3-осевой акселерометр. Я НЕТ представляю, как они на самом деле работают, но способ, которым я это представляю, состоит в том, чтобы представить себе гравитацию как постоянный и равномерный «дождь», падающий с неба, и представить оси на рисунке выше как трубы, которые могут обнаруживать количество дождя, протекающего через. Когда телефон держится вертикально, весь дождь будет проходить через 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? Это вещь эффективности? Вот что подразумевается в одном из комментариев к аналогичномуhref = "https://stackoverflow.com/questions/3514808/how-to-get-android-compass-reading/3515412#3515412"> вопрос , но вам все равно нужно зарегистрировать другой тип слушателя в development /samples /Compass/src/com/example/android/compass/CompassActivity.java пример.

Теперь я хотел бы поговорить о матрице вращения. (Это где я больше всего не уверен) Итак, выше у нас есть три цифры из документации Android, мы будем называть их A, B и C.

A = SensorManger.getRotationMatrix (..) фигура метода и представляет мировую систему координат

B = Система координат, используемая API SensorEvent.

C = SensorManager.getOrientation (..) метод рисунок

Итак, я понимаю, что A представляет «мировую систему координат», которая, как я предполагаю, относится к тому, как местоположения на планете задаются как пара (широта, долгота) с необязательным значением (высота). X - это "восточная" координата, Y - " север " координата. Z указывает на небо и представляет собой высоту.

Система координат телефонов показана на рисунке B исправлена. Его ось Y всегда указывает на вершину. Матрица вращения постоянно рассчитывается телефоном и позволяет отображать между ними. Так правильно ли я считаю, что матрица вращения преобразует систему координат B в C? Поэтому, когда вы вызываете метод SensorManager.getOrientation(..), вы используете values[] массив со значениями, которые соответствуют рисунку С. Когда телефон направлен в небо, матрица вращения - это единичная матрица (матричный математический эквивалент 1), что означает, что отображение не требуется, поскольку устройство выровнено по мировой системе координат.

Ok. Я думаю, мне лучше остановиться сейчас. Как я уже говорил, я надеюсь, что люди скажут мне, где я напутал или помог людям (или еще больше запутал людей!)

104 голоса | спросил Tim 27 Jpm1000000pmThu, 27 Jan 2011 20:20:33 +030011 2011, 20:20:33

4 ответа


0

Возможно, вам захочется проверить Поворот экрана заслуживает еще одной статьи . Это объясняет, почему вам нужна матрица вращения.

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

В приложениях, которые не привязаны к одной ориентации, система координат экрана изменяется при повороте устройства. Таким образом, когда устройство поворачивается из режима просмотра по умолчанию, система координат датчика больше не совпадает с системой координат экрана. В этом случае матрица вращения используется для преобразования A в C (B всегда остается фиксированным).

Вот фрагмент кода, показывающий, как его можно использовать.

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

// Register this class as a listener for the accelerometer sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                    SensorManager.SENSOR_DELAY_NORMAL);

//...
// The following code inside a class implementing a SensorEventListener
// ...

float[] inR = new float[16];
float[] I = new float[16];
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] orientVals = new float[3];

double azimuth = 0;
double pitch = 0;
double roll = 0;

public void onSensorChanged(SensorEvent sensorEvent) {
    // If the sensor data is unreliable return
    if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        return;

    // Gets the value of the sensor that has been changed
    switch (sensorEvent.sensor.getType()) {  
        case Sensor.TYPE_ACCELEROMETER:
            gravity = sensorEvent.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            geomag = sensorEvent.values.clone();
            break;
    }

    // If gravity and geomag have values then find rotation matrix
    if (gravity != null && geomag != null) {

        // checks that the rotation matrix is found
        boolean success = SensorManager.getRotationMatrix(inR, I,
                                                          gravity, geomag);
        if (success) {
            SensorManager.getOrientation(inR, orientVals);
            azimuth = Math.toDegrees(orientVals[0]);
            pitch = Math.toDegrees(orientVals[1]);
            roll = Math.toDegrees(orientVals[2]);
        }
    }
}
ответил Levi Blackstone 24 J000000Sunday11 2011, 07:37:42
0

Крен - это функция силы тяжести, крен на 90 градусов помещает всю гравитацию в регистр x.

Тональность одинакова, при увеличении на 90 градусов все компоненты силы тяжести помещаются в регистр y.

Тяга /курс /азимут не влияет на гравитацию, он ВСЕГДА под прямым углом к ​​гравитации, поэтому независимо от того, в какую сторону вы столкнетесь с гравитацией, будет неизмеримо.

Вот почему вам нужен компас для оценки, может быть, это имеет смысл?

ответил Craig 25 52011vEurope/Moscow11bEurope/MoscowFri, 25 Nov 2011 19:16:35 +0400 2011, 19:16:35
0

Посмотрите это: 5202147 "> Stackoverflow.com: Q.5202147

Вы, кажется, в основном правы до 3 диаграмм A, B, C. После этого вы запутались.

ответил TheCodeArtist 5 MarpmSat, 05 Mar 2011 17:53:14 +03002011-03-05T17:53:14+03:0005 2011, 17:53:14
0

У меня была эта проблема, поэтому я наметил, что происходит в разных направлениях. Если устройство монтируется в ландшафтном режиме, например, в автомобильном креплении «градусы» от компаса, кажется, идут от 0-275 (по часовой стрелке) выше 269 (между западом и севером), то оно отсчитывается назад от -90 до 0, затем вперед от 0 до 269. 270 становится -90

Все еще в ландшафте, но с устройством, лежащим на спине, мой датчик дает 0-360. а в портретном режиме - 0-360, лежа на спине и стоя на портрете.

Надеюсь, это поможет кому-то

ответил hopeless bob 27 J0000006Europe/Moscow 2014, 08:27:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132