Device(裝置)之陀螺儀感應器, Motion API
介紹
與眾不同 windows phone 7.5 (sdk 7.1) 之裝置
陀螺儀感應器
Motion API(運動 API)
樣本
1、示範如何使用陀螺儀感應器
GyroscopeDemo.xaml
<phone:PhoneApplicationPage x:Class="Demo.Device.GyroscopeDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <StackPanel Orientation="Vertical"> <TextBlock Name="lblGyroscopeSupported" /> <Button Name="btnStart" Content="開啟陀螺儀" Click="btnStart_Click" /> <Button Name="btnStop" Content="關閉陀螺儀" Click="btnStop_Click" /> <TextBlock Name="lblGyroscopeStatus" /> <TextBlock Name="lblTimeBetweenUpdates" /> <TextBlock Name="lblMsg" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
GyroscopeDemo.xaml.cs
/* * 示範如何使用陀螺儀感應器 * * Gyroscope - 用於訪問裝置中的陀螺儀 * IsSupported - 裝置是否支援陀螺儀 * IsDataValid - 是否可從陀螺儀中擷取到有效資料 * CurrentValue - 陀螺儀當前的資料,GyroscopeReading 類型 * TimeBetweenUpdates - 觸發 CurrentValueChanged 事件的時間間隔,如果設定的值小於 Gyroscope 允許的最小值,則此屬性的值將被設定為 Gyroscope 允許的最小值 * Start() - 開啟陀螺儀 * Stop() - 關閉陀螺儀 * CurrentValueChanged - 陀螺儀感應器擷取到的資料發生改變時所觸發的事件,屬性TimeBetweenUpdates 的值決定觸發此事件的時間間隔 * * GyroscopeReading - 陀螺儀感應器資料 * RotationRate - 擷取圍繞裝置各軸旋轉的旋轉速率(單位:弧度/秒) * DateTimeOffset - 從陀螺儀感應器中擷取到資料的時間點 * * * * 手機座標系:以手機位置為參照,假設手機垂直水平面放(豎著放),螢幕對著你,那麼 * 1、左右是 X 軸,右側為正方向,左側為負方向 * 2、上下是 Y 軸,上側為正方向,下側為負方向 * 3、裡外是 Z 軸,靠近你為正方向,遠離你為負方向 * 以上可以用相對於手機位置的右手座標系來理解 */ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Devices.Sensors; using Microsoft.Xna.Framework; namespace Demo.Device { public partial class GyroscopeDemo : PhoneApplicationPage { private Gyroscope _gyroscope; public GyroscopeDemo() { InitializeComponent(); // 判斷裝置是否支援陀螺儀 if (Gyroscope.IsSupported) { lblGyroscopeStatus.Text = "此裝置支援陀螺儀"; } else { lblGyroscopeStatus.Text = "此裝置不支援陀螺儀"; btnStart.IsEnabled = false; btnStop.IsEnabled = false; } } private void btnStart_Click(object sender, RoutedEventArgs e) { if (_gyroscope == null) { // 執行個體化 Gyroscope,註冊相關事件 _gyroscope = new Gyroscope(); _gyroscope.TimeBetweenUpdates = TimeSpan.FromMilliseconds(1); _gyroscope.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<GyroscopeReading>>(_gyroscope_CurrentValueChanged); lblTimeBetweenUpdates.Text = "TimeBetweenUpdates 設定為 1 毫秒,實際為 " + _gyroscope.TimeBetweenUpdates.TotalMilliseconds.ToString() + " 毫秒"; } try { // 開啟陀螺儀 _gyroscope.Start(); lblGyroscopeStatus.Text = "陀螺儀已開啟"; } catch (Exception ex) { lblGyroscopeStatus.Text = "陀螺儀開啟失敗"; MessageBox.Show(ex.ToString()); } } private void btnStop_Click(object sender, RoutedEventArgs e) { if (_gyroscope != null) { // 關閉陀螺儀 _gyroscope.Stop(); lblGyroscopeStatus.Text = "陀螺儀已關閉"; } } void _gyroscope_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e) { // 註:此方法是在後台線程啟動並執行,所以需要更新 UI 的話注意要調用 UI 線程 Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading)); } private DateTimeOffset _lastUpdateTime = DateTimeOffset.MinValue; // 上一次擷取陀螺儀資料的時間 private Vector3 _rotationTotal = Vector3.Zero; // 陀螺儀各軸的累積旋轉弧度 // 更新 UI private void UpdateUI(GyroscopeReading gyroscopeReading) { // 以下用於計算陀螺儀各軸的累積旋轉弧度 if (_lastUpdateTime.Equals(DateTimeOffset.MinValue)) { _lastUpdateTime = gyroscopeReading.Timestamp; } else { TimeSpan timeSinceLastUpdate = gyroscopeReading.Timestamp - _lastUpdateTime; // 陀螺儀當前旋轉速率 * 計算此速率所經過的時間 = 此時間段內旋轉的弧度 _rotationTotal += gyroscopeReading.RotationRate * (float)(timeSinceLastUpdate.TotalSeconds); _lastUpdateTime = gyroscopeReading.Timestamp; } Vector3 rotationRate = gyroscopeReading.RotationRate; // 顯示陀螺儀當前各軸的旋轉速率(單位:弧度/秒) lblMsg.Text += "RotationRate.X: " + rotationRate.X.ToString("0.0"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "RotationRate.Y: " + rotationRate.Y.ToString("0.0"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "RotationRate.Z: " + rotationRate.Z.ToString("0.0"); lblMsg.Text += Environment.NewLine; // 顯示陀螺儀各軸的累積旋轉角度 lblMsg.Text += "RotationTotal.X: " + MathHelper.ToDegrees(_rotationTotal.X).ToString("0.00"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "RotationTotal.Y: " + MathHelper.ToDegrees(_rotationTotal.X).ToString("0.00"); lblMsg.Text += Environment.NewLine; lblMsg.Text += "RotationTotal.Z: " + MathHelper.ToDegrees(_rotationTotal.X).ToString("0.00"); } } }