zoukankan      html  css  js  c++  java
  • 与众不同 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(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");
            }
        }
    }


    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(1);
                    _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
    [源码下载]

  • 相关阅读:
    wget命令
    Linux常用命令大全
    centos7 中文乱码问题解决方法
    Linux软件安装的补充
    redis在Linux上的安装
    Linux下tomcat的安装
    Linux常见命令
    Linux下jdk安装过程
    JAVA中日期处理
    JAVA中File类的使用
  • 原文地址:https://www.cnblogs.com/webabcd/p/2624560.html
Copyright © 2011-2022 走看看