company_banner

Пару слов о Motion API


    Вместе с новой версией Windows Phone 7.5, широко известной под кодовым именем «Манго», разработчики получили возможность использовать для своих приложений, в дополнение к GPS и акселерометру, гироскоп и компас (вернее, магнитометр). Также стал доступен набор API под названием Motion API, который комбинирует в себе данные со всех датчиков и выдаёт обработанный результат, в виде положения в пространстве и характеристик движения устройства. Motion API – результат исследований Microsoft Research, которым теперь могут воспользоваться все разработчики под Windows Phone.

    Обратите внимание, чтобы на устройстве было доступно Motion API, в дополнение к акселерометру, необходим, по крайней мере, компас.

    Достаточно часто можно встретить даже упоминания Motion Sensor, поскольку это API доступно в пространстве имён Microsoft.Devices.Sensors и работа с ним аналогична работе со всеми остальным сенсорами на устройстве.
    Прежде чем перейти к простому примеру использования Motion API, давайте посмотрим, какие данные он нам позволяет получить.
    Attitude, позволяет нам получить положение устройства в пространстве, в разнообразных представлениях:
    • Pitch, Roll, Yaw
    • Quaternion
    • RotationMatrix
    Помимо этого мы можем получить DeviceAcceleration – линейное ускорение устройства; DeviceRotationRate – скорость вращения устройства, Gravity – гравитационный вектор.

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

    Перейдём к простому примеру. После запуска программы будем просто отображать в виде поворота стрелок значение Pitch, Roll, Yaw.

    Для этого создадим новый проект из шаблона Windows Phone Application и разместим на стартовой странице XAML код, со стрелками, также изменим название проекта и название страницы. Для поворота стрелок я буду использовать возможности Projection — я буду поворачивать стрелку на соответствующую величину. Поэтому в каждый объект XAML Polyline, представляющий стрелку, я добавлю Projection и назову его подходящим образом.

    Результирующий код XAML представлен ниже:
    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock x:Name="ApplicationTitle" Text="ПЛАТФОРМА WINDOWS PHONE" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="motion api" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>
    
    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <TextBlock Name="MotionNotPresented" Text="на устройстве не доступно Motion API" FontSize="22" Visibility="Collapsed"></TextBlock>
        <Polyline Name="ArrowPitch" HorizontalAlignment="Center" VerticalAlignment="Center"
                    Points="0,0 -10,150 0,140 10,150 0,0" Stroke="Green" StrokeThickness="2"                
                    Fill="Green" Margin="-300 -300 0 0">
            <Polyline.Projection>
                <PlaneProjection x:Name="MotionPitchProjection"></PlaneProjection>
            </Polyline.Projection>
        </Polyline>
        <Polyline Name="ArrowRoll" HorizontalAlignment="Center" VerticalAlignment="Center"
                    Points="0,0 -10,150 0,140 10,150 0,0" Stroke="Yellow" StrokeThickness="2"                
                    Fill="Yellow" Margin="300 -300 0 0">
            <Polyline.Projection>
                <PlaneProjection x:Name="MotionRollProjection"></PlaneProjection>
            </Polyline.Projection>
        </Polyline>
        <Polyline Name="ArrowYaw" HorizontalAlignment="Center" VerticalAlignment="Center"
                    Points="0,0 -10,150 0,140 10,150 0,0" Stroke="Red" StrokeThickness="2"                
                    Fill="Red">
            <Polyline.Projection>
                <PlaneProjection x:Name="MotionYawProjection"></PlaneProjection>
            </Polyline.Projection>
        </Polyline>
        <TextBlock Height="50" HorizontalAlignment="Left" Margin="25,250,0,0" Text="Pitch" VerticalAlignment="Top" FontWeight="Bold" Foreground="Green" FontSize="40" />
        <TextBlock FontSize="40" FontWeight="Bold" Foreground="Yellow" Height="50" HorizontalAlignment="Right" Margin="0,250,45,0" Text="Roll" VerticalAlignment="Top" />
        <TextBlock FontSize="40" FontWeight="Bold" Foreground="Red" Height="50" HorizontalAlignment="Left" Margin="185,396,0,0" Text="Yaw" VerticalAlignment="Top" />            
    </Grid>
    


    Для удобства я добавли к стрелкам подписи и текстовую индикацию недоступности Motion API на устройстве.

    Теперь, к проекту нужно добавить ссылку (Reference) на Microsoft.Devices.Sensors и добавить пространство имён в using блок кода:
    using  Microsoft.Devices.Sensors;


    Определение доступности API, его инициализацию и регстрацию обработчика изменений даных буду делать в обработчике события Loaded:
    
    Motion motion = null;
            
    // Constructor
    public MainPage()
    {
        InitializeComponent();
    
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
    
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (Motion.IsSupported)
        {
            motion = new Motion();
            motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>>(motion_CurrentValueChanged);
            motion.Start();
        }
        else MotionNotPresented.Visibility = Visibility.Visible;
    }
    


    В обработчике motion_CurrentValueChanged буду получать данные и выполнять поворот стрелок вокруг оси Z:
    
    void motion_CurrentValueChanged(object sender, SensorReadingEventArgs<MotionReading> e)
    {
        Dispatcher.BeginInvoke(() =>
            {
                MotionPitchProjection.RotationZ = e.SensorReading.Attitude.Pitch * 180 / Math.PI;
                MotionRollProjection.RotationZ = e.SensorReading.Attitude.Roll * 180 / Math.PI;
                MotionYawProjection.RotationZ = e.SensorReading.Attitude.Yaw * 180 / Math.PI;
            });
    }
    


    Теперь, если у вас есть устройство с компасом, а лучше с компасом и гироскопом, вы сможете протестировать пример. К сожалению, поскольку в эмуляторе отсутствует эмуляция компаса или гироскопа, Motion API в нём не доступно.

    Полезные ссылки:
    Создание простого приложения дополненой реальности
    Центр разработки Windows Phone на MSDN
    Windows Phone SDK 7.1
    Форумы по разработке под Windows Phone на русском языке
    • +21
    • 1.4k
    • 4
    Microsoft
    209.80
    Microsoft — мировой лидер в области ПО и ИТ-услуг
    Share post

    Similar posts

    Comments 4

      +3
      Удобно.

      Уже представил космическую леталку, где рулить можно положением устройства, к тому же ускорение поворота устройства вполне можно превратить в скорость наклона космического корабля.
      При этом компас можно использовать для ориентации в космическом пространстве — понятное дело, что в космосе компас не помощник, но можно оформить север как «базу», например.
        +1
        Недавно писал приложение с дополненной реальностью, использовал библиотечку GART, написаную поверх Motion API. Очень удобно и просто, дополненная реальность прикручивается к приложению за один день.
          –7
          > комбинирует в себе данные со всех датчиков
            0
            Спасибо, как раз планировал на днях наконец сесть поэксперементировать с WP.
            Всегда приятнее сразу добиться подобной маленькой победы, это мотивирует на более глубокое изучение.

            P.S. Парочка опечаток закралась:
            1) и добавить пространстов имён в usign блок кода:
            2) Оперделение доступности API, его инициализацию и регстрацию

            Only users with full accounts can post comments. Log in, please.