Статьи

31 Дней Манго | День № 5: Гироскоп

Эта статья является 5-м днем ​​в серии под названием « 31 день манго» .

Day5-гироскоп

Сегодня мы поговорим о новом доступном нам датчике — гироскопе. Этот датчик доступен только в телефонах, выпущенных после запуска Mango, и даже тогда не у всех телефонов будет гироскоп. Однако это мощный инструмент, которым мы должны воспользоваться, когда он будет доступен, и эта статья покажет вам, как это сделать.

Что такое гироскоп?

Согласно Википедии , «гироскоп — это устройство для измерения или поддержания ориентации». Многие из вас, вероятно, видели пример гироскопа раньше, но вот иллюстрация физического гироскопа (любезно предоставленного Википедией ):

Как вы можете видеть, он может вращаться по трем осям, осям X, Y и Z (так же, как акселерометр, который мы рассмотрели в День № 11 из 31 Дня Windows Phone ). В то время как акселерометр измеряет ускорение, гироскоп измеряет скорость вращения.

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

Использование гироскопа в вашем приложении

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

Это означает, что вы можете более точно и плавно измерить текущую ориентацию устройства. Это станет особенно удобным при создании приложений, которые выполняют дополненную реальность. Однако в большинстве случаев вы, вероятно, не будете обращаться к гироскопу самостоятельно. Есть несколько причин для этого:

  • Не все телефоны Windows будут иметь гироскоп. На самом деле, только телефоны, которые выйдут после релиза Mango, смогут иметь гироскоп, и это все еще дополнительный аппаратный компонент.
  • Microsoft создала класс Motion, который объединяет данные из акселерометра, компаса и гироскопа в один класс, который мы можем использовать более эффективно (мы рассмотрим это в следующей статье). Если вас интересует расположение устройства (тангаж, рыскание, крен), вам нужно сосредоточиться на классе Motion.

Однако в случае, если вам необходимо использовать гироскоп независимо от класса Motion, его всегда следует проверять, чтобы определить, поддерживает ли устройство пользователя датчик гироскопа. Для этого нам понадобятся два конкретных фрагмента кода. Это первый оператор использования для пространства имен Microsoft.Phone.Sensors. Вторым является оператор IF, который проверяет значение Gyroscope.IsSupported. В этом простом состоянии ваш файл с выделенным кодом будет выглядеть так:

using System;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;

namespace Day5_Gyroscope
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();

            if (Gyroscope.IsSupported)
            {
                // DO SOMETHING
            }
        }
    }
} 

 

Теперь нам просто нужно заполнить комментарий «Делать что-то». Чтобы сделать это, давайте начнем с пользовательского интерфейса, который будет отображать данные нашего гироскопа.

образ

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

<Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--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="31 DAYS OF MANGO" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="gyroscope" 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 Height="30" HorizontalAlignment="Left" Margin="20,100,0,0" Name="xTextBlock" Text="X: 1.0" VerticalAlignment="Top" Foreground="Red" FontSize="28" FontWeight="Bold"/>
            <TextBlock Height="30" HorizontalAlignment="Center" Margin="0,100,0,0" Name="yTextBlock" Text="Y: 1.0" VerticalAlignment="Top" Foreground="Yellow" FontSize="28" FontWeight="Bold"/>
            <TextBlock Height="30" HorizontalAlignment="Right" Margin="0,100,20,0" Name="zTextBlock" Text="Z: 1.0" VerticalAlignment="Top" Foreground="Blue" FontSize="28" FontWeight="Bold"/>
            <Line x:Name="xLine" X1="240" Y1="350" X2="340" Y2="350" Stroke="Red" StrokeThickness="4"></Line>
            <Line x:Name="yLine" X1="240" Y1="350" X2="240" Y2="270" Stroke="Yellow" StrokeThickness="4"></Line>
            <Line x:Name="zLine" X1="240" Y1="350" X2="190" Y2="400" Stroke="Blue" StrokeThickness="4"></Line>
            <TextBlock Height="30" HorizontalAlignment="Center" Margin="6,571,6,0" Name="statusTextBlock" Text="" VerticalAlignment="Top" Width="444" />
        </Grid>
    </Grid> 

 

В приведенном ниже примере кода мы создаем новый объект Gyroscope, и после проверки, чтобы убедиться, что Gyroscope поддерживается с логическим значением Gyroscope.IsSupported, мы создаем обработчик события для CurrentValueChanged.

using System;
using Microsoft.Phone.Controls;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;

namespace Day5_Gyroscope
{
    public partial class MainPage : PhoneApplicationPage
    {
        Gyroscope g;
        
        public MainPage()
        {
            InitializeComponent();

            if (Gyroscope.IsSupported)
            {
                g = new Gyroscope();
                g.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
                g.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<GyroscopeReading>>(g_CurrentValueChanged);
                g.Start();
            }
            else statusTextBlock.Text = "gyroscope not supported";
        }

        void g_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e)
        {
            Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
        }

        private void UpdateUI(GyroscopeReading gyroscopeReading)
        {
            statusTextBlock.Text = "getting data";
            Vector3 rotationReading = gyroscopeReading.RotationRate;

            xTextBlock.Text = "X " + rotationReading.X.ToString("0.00");
            yTextBlock.Text = "Y " + rotationReading.Y.ToString("0.00");
            zTextBlock.Text = "Z " + rotationReading.Z.ToString("0.00");

            xLine.X2 = xLine.X1 + rotationReading.X * 200;
            yLine.Y2 = yLine.Y1 - rotationReading.Y * 200;
            zLine.X2 = zLine.X1 - rotationReading.Z * 100;
            zLine.Y2 = zLine.Y1 + rotationReading.Z * 100;
        }
    }
} 

 

Gyroscope, как и Compass, позволяет нашему методу-обработчику событий срабатывать каждый раз, когда Gyroscope обнаруживает новое значение после ожидания, указанного в свойстве TimeBetweenUpdates. В нашем примере мы будем получать обновления не быстрее, чем каждые 20 миллисекунд.

Вы должны заметить, возможно, незнакомый фрагмент кода в нашем методе g_CurrentValueChanged:

Dispatcher.BeginInvoke (() => UpdateUI (e.SensorReading));

Мы используем это потому, что хотим перенести показания нашего датчика в отдельный поток обработки. Без него мы будем пытаться использовать поток пользовательского интерфейса для доступа к гироскопу, который всегда выдаст ошибку. В Windows Phone нам не разрешено блокировать поток пользовательского интерфейса, и поэтому для многих примеров, подобных этому, мы захотим поместить наш процесс в отдельный поток.

Мы по-прежнему передаем весь объект GyroscopeReading нашему новому потокобезопасному методу UpdateUI, который позволяет собирать каждое из значений X, Y и Z из значения Vector3 RotationRate. Мы отображаем значения данных в TextBlocks, но классная визуализация данных заключается в тех элементах Line, которые мы создали в нашем XAML.

Если вы представляете, что каждый отрезок линии представляет отдельную точку данных (красная горизонтальная линия — X, желтая вертикальная линия — Y, а синяя диагональная линия — ось Z. Затем вы можете манипулировать длинами этих линий, чтобы представить вращение. Скорость устройства. Каждый из этих расчетов будет увеличивать длину соответствующих линий, давая вам очень наглядный пример того, какие типы вращения испытывает ваше устройство.

Помните, что пример кода, описанный в этой статье, будет работать только на устройствах с гироскопом. Эмулятор, как и все оригинальные устройства Windows Phone 7, не имеет этого датчика. Вот краткое видео о том, как это приложение работает на устройстве с гироскопом:

Резюме

Гироскоп — это удобный маленький датчик. Это позволяет нам получить очень точную картину движения устройства в пространстве, что особенно полезно при создании приложений, использующих дополненную реальность. Чтобы загрузить пример приложения, о котором шла речь в этой статье, нажмите кнопку «Загрузить код» ниже:

скачать

Microsoft также создала новый класс в Windows Phone 7.5 под названием Motion, который объединяет данные с гироскопа, акселерометра и компаса, чтобы обеспечить нам удивительную точность. Этот класс Motion является темой завтрашней статьи, и мы подробно расскажем о нем, в том числе о том, как определить «положение» устройства, которое включает в себя наклон, рыскание и крен. Увидимся позже!

toolsbutton

Источник: 
http://www.jeffblankenburg.com/2011/11/05/31-days-of-mango-day-5-gyroscope/