原文:与众不同 windows phone (19) - Device(设备)之陀螺仪传感器, Motion API

[索引页]
[源码下载]

与众不同 windows phone (19) - Device(设备)之陀螺仪传感器, Motion API

作者:webabcd

介绍
与众不同 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();
_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");
}
}
}

2、演示如何使用 Motion API
MotionDemo.xaml

<phone:PhoneApplicationPage
x:Class="Demo.Device.MotionDemo"
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="lblMotionSupported" />
<Button Name="btnStart" Content="打开 Motion 监测" Click="btnStart_Click" />
<Button Name="btnStop" Content="关闭 Motion 监测" Click="btnStop_Click" />
<TextBlock Name="lblMotionStatus" />
<TextBlock Name="lblTimeBetweenUpdates" />
<TextBlock Name="lblMsg" /> </StackPanel>
</Grid> </phone:PhoneApplicationPage>

MotionDemo.xaml.cs

/*
* 演示如何使用 Motion API
*
* Motion - Motion API,其作用为:整合各个传感器 Accelerometer, Gyroscope, Compass 的数据,通过复杂的运算计算出易用的数据
* IsSupported - 设备是否支持 Motion API
* IsDataValid - 是否可从 Motion API 中获取到有效数据
* CurrentValue - Motion API 当前的数据,MotionReading 类型
* TimeBetweenUpdates - 触发 CurrentValueChanged 事件的时间间隔,如果设置的值小于 Motion API 允许的最小值,则此属性的值将被设置为 Motion API 允许的最小值
* Start() - 打开 Motion 监测
* Stop() - 关闭 Motion 监测
* CurrentValueChanged - 当 Motion API 获取到的数据发生改变时所触发的事件,属性 TimeBetweenUpdates 的值决定触发此事件的时间间隔
* Calibrate - 当系统检测到 Motion API 用到的数字罗盘传感器需要校准时所触发的事件
*
* MotionReading - Motion API 数据
* AttitudeReading - 设备的姿态(AttitudeReading 类型,可以获得 Yaw Pitch Roll 数据)
* DeviceAcceleration - 设备的加速度(Vector3 类型)
* DeviceRotationRate - 设备的旋转速率(Vector3 类型)
* Gravity - 重力(Vector3 类型)
* DateTimeOffset - 从 Motion API 中获取到数据的时间点
*
* 注:
* 如果设备缺少必要的传感器,那么 Motion API 将无法正常工作
* 例如,如果只有 Accelerometer, Compass 而没有 Gyroscope,那么虽然 Motion API 是被支持的,但是部分数据是不精准的
* 例如,如果只有 Accelerometer 而没有 Compass, Gyroscope,那么 Motion API 是不被支持的
*
*
*
* 手机坐标系:以手机位置为参照,假设手机垂直水平面放(竖着放),屏幕对着你,那么
* 1、左右是 X 轴,右侧为正方向,左侧为负方向
* 2、上下是 Y 轴,上侧为正方向,下侧为负方向
* 3、里外是 Z 轴,靠近你为正方向,远离你为负方向
* 以上可以用相对于手机位置的右手坐标系来理解
*
* Yaw - 围绕 Y 轴旋转
* Pitch - 围绕 X 轴旋转
* Roll - 围绕 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 System.Windows.Navigation;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework; namespace Demo.Device
{
public partial class MotionDemo : PhoneApplicationPage
{
private Motion _motion; public MotionDemo()
{
InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 判断设备是否支 Motion API
if (Motion.IsSupported)
{
lblMotionStatus.Text = "此设备支持 Motion API";
}
else
{
lblMotionStatus.Text = "此设备不支持 Motion API"; btnStart.IsEnabled = false;
btnStop.IsEnabled = false;
}
} private void btnStart_Click(object sender, RoutedEventArgs e)
{
if (_motion == null)
{
// 实例化 Motion,注册相关事件
_motion = new Motion();
_motion.TimeBetweenUpdates = TimeSpan.FromMilliseconds();
_motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>>(_motion_CurrentValueChanged); lblTimeBetweenUpdates.Text = "TimeBetweenUpdates 设置为 1 毫秒,实际为 " + _motion.TimeBetweenUpdates.TotalMilliseconds.ToString() + " 毫秒";
} try
{
// 打开 Motion 监测
_motion.Start();
lblMotionStatus.Text = "Motion 监测已打开";
}
catch (Exception ex)
{
lblMotionStatus.Text = "Motion 监测打开失败";
MessageBox.Show(ex.ToString());
}
} private void btnStop_Click(object sender, RoutedEventArgs e)
{
if (_motion != null)
{
// 关闭 Motion 监测
_motion.Stop();
lblMotionStatus.Text = "Motion 监测已关闭";
}
} void _motion_CurrentValueChanged(object sender, SensorReadingEventArgs<MotionReading> e)
{
// 注:此方法是在后台线程运行的,所以需要更新 UI 的话注意要调用 UI 线程
Dispatcher.BeginInvoke(() => UpdateUI(e.SensorReading));
} // 更新 UI
private void UpdateUI(MotionReading motionReading)
{
AttitudeReading attitude = motionReading.Attitude;
Vector3 deviceAcceleration = motionReading.DeviceAcceleration;
Vector3 deviceRotationRate = motionReading.DeviceRotationRate;
Vector3 gravity = motionReading.Gravity; // 在 UI 上显示相关参数
lblMsg.Text = "yaw: " + MathHelper.ToDegrees(attitude.Yaw).ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "pitch: " + MathHelper.ToDegrees(attitude.Pitch).ToString("0.0");
lblMsg.Text += Environment.NewLine;
lblMsg.Text += "roll: " + MathHelper.ToDegrees(attitude.Roll).ToString("0.0");
}
}
}

OK
[源码下载]

与众不同 windows phone (19) - Device(设备)之陀螺仪传感器, Motion API的更多相关文章

  1. 与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器

    原文:与众不同 windows phone (18) - Device(设备)之加速度传感器, 数字罗盘传感器 [索引页][源码下载] 与众不同 windows phone (18) - Device ...

  2. 与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态

    原文:与众不同 windows phone (23) - Device(设备)之硬件状态, 系统状态, 网络状态 [索引页][源码下载] 与众不同 windows phone (23) - Devic ...

  3. 与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频)

    原文:与众不同 windows phone (22) - Device(设备)之摄像头(硬件快门, 自动对焦, 实时修改捕获视频) [索引页][源码下载] 与众不同 windows phone (22 ...

  4. 与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频)

    原文:与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频) [索引页][源码下载] 与众不同 windows phone (21) - Device ...

  5. 与众不同 windows phone (20) - Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器

    原文:与众不同 windows phone (20) - Device(设备)之位置服务(GPS 定位), FM 收音机, 麦克风, 震动器 [索引页][源码下载] 与众不同 windows phon ...

  6. 与众不同 windows phone (2) - Control(控件)

    原文:与众不同 windows phone (2) - Control(控件) [索引页][源码下载] 与众不同 windows phone (2) - Control(控件) 作者:webabcd介 ...

  7. 如何解决Windows 10系统下设备的声音问题

    如何解决Windows 10系统下设备的声音问题? 请阅读下面的说明来解决Windows 10设备上的声音问题. 1. 检查设备管理器 打开开始菜单,键入设备管理器, 从出现的结果中选择并打开它. 在 ...

  8. 与众不同 windows phone 8.0 & 8.1 系列文章索引

    [源码下载] [与众不同 windows phone 7.5 (sdk 7.1) 系列文章索引] 与众不同 windows phone 8.0 & 8.1 系列文章索引 作者:webabcd ...

  9. 与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirectionsTask, MapDownloaderTask

    [源码下载] 与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirec ...

随机推荐

  1. File类常见方法

    package file; import java.io.File; public class FileTest2 { public static void main(String[] args) { ...

  2. 10 - 应用程序间通信、本地通知、加速计、URL传输中文

    一.应用间通信 URL 调用系统服务: tel:11111 sms:xxx@163.com http:// URL深入 类型://主机:端口/地址?参数 label框等于文字大小快捷键:command ...

  3. poj 1182食物链(并查集)

    算法思路:把那些确定了相对关系的节点放在同一棵树里(可以同时存在多棵树,单独每棵树中节点的相对关系确定),每个节点对应的 v[] 值记录他与根节点的关系( 0:同类: 1:根吃他: 2:他吃根 ).当 ...

  4. 用Eclipse做Android开发时出现java.lang.NoClassDefFoundError问题

    之前有遇到过这个问题,后来解决了,今天又遇到了,但是忘了当时是怎么解决的,费了好长时间,终于又找回解决的方法,现在记录下来,以防以后又遇到. 这个错误出现在我的某一个Activity,但是我反复确认了 ...

  5. java中int,char,string三种类型的相互转换

    如何将字串 String 转换成整数 int? int i = Integer.valueOf(my_str).intValue(); int i=Integer.parseInt(str); 如何将 ...

  6. HDU 2045 不easy系列之(3)—— LELE的RPG难题

    思路: 1.若前n-1位涂的颜色是符合条件的,则因为首尾不同,再加入一位时,仅仅有1种方法:即s[n] = s[n-1] 2.若前n-1位组成的串不符合,再加入一位后合法.即由于首尾同样而引起的不合法 ...

  7. Java学习——何为JNDI

    曾记得在做机房收费系统的时候就接触到了API,由于它的功能非常强大,可是自己对它却不怎么了解.所以当时是又爱又怕.现在,一路走来才明确,事实上它就是一组接口.仅仅要我们去了解它就会发现.它事实上也没想 ...

  8. poj 百练 2765 八进制小数(精度问题)

    2765:八进制小数 查看 提交 统计 提示 提问 总时间限制:  1000ms  内存限制:  65536kB 描写叙述 八进制小数能够用十进制小数精确的表示.比方,八进制里面的0.75等于十进制里 ...

  9. android第一天-------环境搭建

    今天正式第一天学习android的. 1.昨晚下班后回家跟同事刘江龙打了四把dota.还好,都赢了把对面虐成狗了.大多都是1300到1450的局,玩的很爽. 2.dota打完后给在湖南常德的女朋友打了 ...

  10. EasyUI - Menu 菜单

    效果: html代码: <div id="mm" class="easyui-menu"> <div id =">New< ...