Поделиться через


Положение датчиков в пространстве

Данные датчика из классов Accelerometer, Gyrometer, Compass, Inclinometer и OrientationSensor определяются их ссылочными осями. Эти оси определяются эталонным фреймом устройства и поворачиваются с устройством по мере его поворота. Если приложение поддерживает автоматическую смену и перенацеливает устройство, так как пользователь поворачивает его, необходимо настроить данные датчика для поворота, прежде чем использовать его.

Важные API

Ориентация отображения и ориентация устройства

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

Примечание.

Положительная ось z расширяется с экрана устройства, как показано на следующем рисунке. Ось Z для ноутбука

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

На этой схеме показана ориентация отображения и устройства в альбомной среде.

Отображение и ориентация устройства в альбомной среде

На следующей схеме показана ориентация дисплея и устройства в LandscapeFlipped.

Отображение и ориентация устройства в LandscapeFlipped

На этой окончательной схеме показана ориентация отображения в альбомной области, а ориентация устройства — "АльбомFlipped".

Ориентация отображения в альбомной области, а ориентация устройства —

Значения ориентации можно запрашивать с помощью класса DisplayInformation с помощью метода GetForCurrentView со свойством CurrentOrientation. Затем можно создать логику, сравнивая перечисление DisplayOrientations . Помните, что для каждой поддерживаемой ориентации необходимо поддерживать преобразование ссылочных осей в эту ориентацию.

Альбомные и книжные устройства

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

Ориентация Альбом-первый Книжный первый
Альбомная Альбомное устройство в альбомной ориентации Книжно-первое устройство в альбомной ориентации
Книжная Альбомное устройство в книжной ориентации Книжно-первое устройство в книжной ориентации
АльбомнаяFlipped Альбомное устройство в ориентации LandscapeFlipped Книжно-первое устройство в ориентации LandscapeFlipped
КнижныйFlipped Альбомное устройство в ориентации PortraitFlipped Книжно-первое устройство в ориентации PortraitFlipped

Устройства, вещательные устройства и устройства без головы

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

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

Отображение ориентации и заголовка компаса

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

Ориентация отображения Эталонная ось для заголовка компаса Заголовок компаса API при переходе на север (альбом-первый) Заголовок компаса API при переходе на север (книжный первый) Компенсация заголовок компаса (альбом-first) Компенсация заголовок компаса (портрет-первый)
Альбомная Z 0 270 Заголовок (Заголовок + 90) % 360
Книжная Y 90 0 (Заголовок + 270) % 360 Заголовок
АльбомнаяFlipped Z 180 90 (Заголовок + 180) % 360 (Заголовок + 270) % 360
КнижныйFlipped Y 270 180 (Заголовок + 90) % 360 (Заголовок + 180) % 360

Измените заголовок компаса, как показано в таблице, чтобы правильно отобразить заголовок. В следующем фрагменте кода показано, как это сделать.

private void ReadingChanged(object sender, CompassReadingChangedEventArgs e)
{
    double heading = e.Reading.HeadingMagneticNorth;
    double displayOffset;

    // Calculate the compass heading offset based on
    // the current display orientation.
    DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();

    switch (displayInfo.CurrentOrientation)
    {
        case DisplayOrientations.Landscape:
            displayOffset = 0;
            break;
        case DisplayOrientations.Portrait:
            displayOffset = 270;
            break;
        case DisplayOrientations.LandscapeFlipped:
            displayOffset = 180;
            break;
        case DisplayOrientations.PortraitFlipped:
            displayOffset = 90;
            break;
     }

    double displayCompensatedHeading = (heading + displayOffset) % 360;

    // Update the UI...
}

Ориентация отображения с акселерометром и гирометром

Эта таблица преобразует данные акселерометра и гирометра для ориентации отображения.

Ссылки на оси X Y Z
Альбомная X Y Z
Книжная Y -X Z
АльбомнаяFlipped -X -Y Z
КнижныйFlipped -Y X Z

В следующем примере кода эти преобразования применяются к гирометру.

private void ReadingChanged(object sender, GyrometerReadingChangedEventArgs e)
{
    double x_Axis;
    double y_Axis;
    double z_Axis;

    GyrometerReading reading = e.Reading;  

    // Calculate the gyrometer axes based on
    // the current display orientation.
    DisplayInformation displayInfo = DisplayInformation.GetForCurrentView();
    switch (displayInfo.CurrentOrientation)
    {
        case DisplayOrientations.Landscape:
            x_Axis = reading.AngularVelocityX;
            y_Axis = reading.AngularVelocityY;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.Portrait:
            x_Axis = reading.AngularVelocityY;
            y_Axis = -1 * reading.AngularVelocityX;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.LandscapeFlipped:
            x_Axis = -1 * reading.AngularVelocityX;
            y_Axis = -1 * reading.AngularVelocityY;
            z_Axis = reading.AngularVelocityZ;
            break;
        case DisplayOrientations.PortraitFlipped:
            x_Axis = -1 * reading.AngularVelocityY;
            y_Axis = reading.AngularVelocityX;
            z_Axis = reading.AngularVelocityZ;
            break;
     }

    // Update the UI...
}

Ориентация и ориентация устройства

Данные OrientationSensor должны быть изменены по-другому. Думайте об этих разных ориентациях как повороты счетчика со стрелкой на оси z, поэтому нам нужно изменить поворот, чтобы вернуть ориентацию пользователя. Для данных кватерниона можно использовать формулу Euler для определения поворота со ссылкой кватерниона, и мы также можем использовать матрицу поворота ссылок.

Формула Эйлера

Чтобы получить нужную относительную ориентацию, умножьте эталонный объект на абсолютный объект. Обратите внимание, что эта математика не является коммутативной.

Умножение эталонного объекта на абсолютный объект

В предыдущем выражении абсолютный объект возвращается данными датчика.

Ориентация отображения Поворот по счетчику по часовой стрелке вокруг Z Кватернион ссылок (обратная смена) Матрица ссылочного поворота (обратная поворота)
Альбомная 0 1 + 0i + 0j + 0k [1 0 0
0 1 0
0 0 1]
Книжная 90 cos(-45 Ctrl) + (i + j +k)*sin(-45 2) [0 1 0
-1 0 0
0 0 1]
АльбомнаяFlipped 180 0 - i - j - k [1 0 0
0 1 0
0 0 1]
КнижныйFlipped 270 cos(-135 Ctrl) + (i + j +k)*sin(-135 20) [0 -1 0
1 0 0
0 0 1]

См. также

Интеграция датчиков движения и ориентации