本主题将带您完成创建陀螺仪应用程序,该应用程序为您提供陀螺仪数据的数字显示以及图形表示。本示例应用程序还向您显示如何计算传感器读数的总和来确定设备的累计旋转。
陀螺仪概述
陀螺仪传感器测量设备沿着其三个主轴的旋转速度。当设备静止时,所有轴的陀螺仪读数都为零。如果设备面向您围绕其中心点旋转,就像飞机螺旋桨一样,那么 Z 轴上的旋转速度值将大于零,设备旋转的速度越快,该值越大。旋转速度的测量以弧度/秒为单位,其中 2 * Pi 弧度就是全程旋转。如果您对确定设备在空间的绝对方向(yaw、pitch、roll)感兴趣,我们建议您使用组合运动 API,可以使用 Motion 类访问此 API。
创建陀螺仪应用程序
以下步骤向您介绍如何创建陀螺仪应用程序。
在 Visual Studio 中,创建一个新的“Windows Phone 应用程序项目”。此模板在“Silverlight for Windows Phone”类别中。该应用程序需要引用包含传感器 API 和 XNA Framework 的程序集,因为陀螺仪数据采用 XNA Framework Vector3 对象的形式传递。从“项目”菜单中,单击“添加引用...”,选择“Microsoft.Devices.Sensors”和“Microsoft.Xna.Framework”,然后单击“确定”。在 MainPage.xaml 文件中,将以下 XAML 代码放置在名为“ContentPanel”的 Grid 元素中。该代码创建 TextBlock 元素,这些元素用于显示应用程序的当前状态以及以数字形式显示当前陀螺仪读数。还有三个 Line 元素,它们用于以图形形式表示沿着每个轴的旋转速度。由于该应用程序也会保留设备旋转的累积总数,因此提供另一组 TextBlock 和 Line
XAML
复制
这就是显示 UI 的方式。向 MainPage.xaml 中添加的最后一个 UI 代码是具有一个按钮的应用程序栏的定义,该按钮将开始和停止从罗盘获取数据。将以下代码粘贴到项目模板中包含的已注释掉的应用程序栏代码上。 复制
现在,打开 MainPage.xaml.cs 代码隐藏页面并向该页面顶部的其他 using 复制
在 MainPage 复制
第一个变量是 Gyroscope 类型的对象,它将用于从罗盘传感器获取数据。接下来,声明一个 DispatcherTimer,它将用于定期更新 UI。currentRotationRate 和 cumulativeRotation 变量将用于将获取的数据存储在 Gyroscope 类的 CurrentValueChanged 事件中并且将用于在 DispatcherTimer 的 Tick 事件中更新 UI。lastUpdateTime 将用于计算累积旋转并且 isDataValid在页面的构造函数中,查看其上运行应用程序的设备是否支持陀螺仪传感器。并非所有设备都支持所有传感器,因此使用传感器之前您应该始终进行检查。如果不支持陀螺仪,则会向用户显示一个消息并且隐藏应用程序栏。如果支持陀螺仪,则会初始化 DispatcherTimer 复制
为应用程序栏按钮添加 Click 事件的处理程序。根据上面添加 XAML 代码的方式,Visual Studio 可能已为您添加此处理程序。如果是这样,则删除该处理程序中的任何代码。如果该处理程序是自动添加的,请将以下空函数复制并粘贴到 MainPage 复制
在应用程序栏按钮单击处理程序中,首先查看 Gyroscope 对象是否不为 null 以及是否正在接收数据。如果是这种情况,则用户单击该按钮以停止陀螺仪,以便为 Gyroscope 和 DispatcherTimer 调用 Stop()()()()。将以下代码粘贴到空的按钮单击处理程序中。 复制
接下来,该代码将处理用户正在启动陀螺仪的情况。如果 Gyroscope 对象为 null,则创建一个新的实例。设置所需的更新时间间隔。请注意,不同设备上的传感器支持不同的更新间隔;在此示例中,该属性将在设置之后进行查询,以便向用户显示传感器的实际间隔。接下来,为陀螺仪具有新数据时引发的 CurrentValueChanged 事件添加一个事件处理程序。将该代码粘贴到按钮单击处理程序中,放置在之前的代码部分之后。 复制
现在,使用 Start()()()() 方法启动陀螺仪。调用 Start 有可能会失败,因此您应该将此调用放置在一个 try 块中。在 catch 块中,您可以警告用户陀螺仪可能无法启动。该代码还启动 DispatcherTimer。将该代码粘贴到按钮单击处理程序中,放置在之前的代码部分之后。 复制
现在,实现 CurrentValueChanged 事件处理程序。具有新陀螺仪数据的系统会以使用 TimeBetweenUpdates 指定的频率调用该方法。该处理程序接收包含陀螺仪数据的 GyroscopeReading 对象。在对 UI 没有访问权限的后台线程上调用该处理程序。因此,如果您想通过该方法修改 UI,则必须使用 Dispatcher.Invoke 方法在 UI 线程上调用指定的代码。本示例使用一个计时器来更新 UI,因此不需要这样做。该代码将 isDataValid 变量设置为 Gyroscope 对象的 IsDataValid 成员。接下来,该代码查看之前是否已设置 lastUpdateTime 成员。如果未设置,则将该变量设置为陀螺仪读数的 Timestamp 属性并退出该方法。如果之前已设置 lastUpdateTime,则 currentRotationRate 变量设置为 GyroscopeReading 类的 RotationRate 成员。接下来,从 TimeStamp 值中减去 lastUpdateTime 以确定更新之间经过的时间(秒的小数)。自从上次读数更新以来旋转的数量为当前的旋转速率乘以自从上次更新以来的秒数。将这两个的乘积与 cumulativeRotation 复制