Windows Phone 7 Motion Sensor User Guide

Windows Phone 7 Motion Sensor User Guide

1. Why introduce Motion API?

In the last " Windows Phone 7 Digital Compass User Guide ", we have already learned about the sensors in WP7. In fact, WP7 uses these sensors to obtain information such as the current posture and position of the phone. However, for developers, what they care about is not the value of the data itself, but the meaning of the data. For example, when doing a Windows Mobile device positioning application before, it generally involved the acquisition of GPS data. On the WM2003 platform, developers need to write their own serial communication classes to realize the analysis of NEMA data. Analyzing this process, the meaningful data we finally provide to the application is actually information such as latitude, longitude and time, rather than the original NEMA protocol data. Therefore, Microsoft introduced GPSID (that is, GPS middle layer driver) in the WM5.0 platform. For applications, GPSID provides information such as latitude and longitude; and the process of dealing with GPS hardware is handed over to GPSID. In this way, application developers are freed from it.

    So, in my opinion, the essence of what Motion API does is similar to GPSID. In the application development process, if our developers obtain the original sensor data and then analyze the data to determine the posture and movement direction of the phone, such a processing flow is indeed a bit complicated and sometimes difficult to process. For example, the return value of the acceleration sensor not only includes the acceleration of the mobile phone, but also includes the acceleration of gravity (in fact, on Windows Phone OS 7.0, when processing the acceleration sensor, we do need to go through the above process).

Therefore, in Windows Phone OS 7.1 (Mango), Motion API is introduced to analyze and process the underlying sensor data, so as to obtain the information that the developer needs, such as the device's posture (yaw, pitch, and roll) , Rotational acceleration and linear acceleration . We can compare the original acceleration sensor information with the acceleration sensor information in Motion API to understand the difference. As shown in Figure 1 below, the left side is the page for obtaining the raw data of the acceleration sensor, and the right side is the page for obtaining the Motion data.

Figure 1: The raw data of the acceleration sensor is compared with the data obtained by Motion

Judging from the Y-axis data, the original acceleration sensor data includes the acceleration of gravity and the acceleration of the mobile phone under the action of external force. From the acceleration data obtained from the Motion API, it has excluded the influence of the acceleration of gravity for us. Therefore, for developers, Motion API helps simplify the development of applications.

2. Prerequisites for using Motion API

    First of all, it should be noted that the first generation of Windows Phone 7 phones did not open Motion API. Therefore, if you want to write Motion-based applications on Windows Phone OS 7.0, it is impossible. However, since Microsoft provided the Mango upgrade at the beginning of this month, many device manufacturers have pushed Mango updates to their WP7. After the OS upgrade, some devices provide support for Motion API. For example, my Samsung Focus i917 supports it, so I have the following attempts. The following content, refer to the article on MSDN: How to: Use the Combined Motion API for Windows Phone .

3. How to use Motion API in the application?

    Here takes the silverlight application as an example to show how to use the Motion API in the application.

(1) Add references to Microsoft.Devices.Sensors and Microsoft.Xna.Framework, as shown in Figure 2 below:

Figure 2: Add the namespace related to Motion API

(2) In the XAML of the main page, add 6 Textblocks to represent the three return values ​​of the mobile phone's yall, pitch, roll, and acceleration sensor. In order to make the form of expression more intuitive, three triangles are introduced, and their rotation angles are used to represent the values ​​of yall, pitch, and roll. At the same time, three mutually perpendicular axes are introduced to represent the value of the acceleration sensor. The code is as follows:

   1: <!--TitlePanel contains the name of the application and page title-->
   2: <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
   3: <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
   4: <TextBlock x:Name="PageTitle" Text="Simple Motion" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
   5: </StackPanel>
   6:   
   7: <StackPanel>
   8: <TextBlock Text="attitude" Margin="12,130,0,28" Style="{StaticResource PhoneTextLargeStyle}"/>
   9: <Grid Margin="12 0 12 0">
  10: <TextBlock Height="30" HorizontalAlignment="Left" Name="yawTextBlock" Text="YAW: 000" VerticalAlignment="Top" Foreground="Red" FontSize="25" FontWeight="Bold"/>
  11: <TextBlock Height="30" HorizontalAlignment="Center" Name="pitchTextBlock" Text="PITCH: 000" VerticalAlignment="Top" Foreground="Green" FontSize="25" FontWeight="Bold"/>
  12: <TextBlock Height="30" HorizontalAlignment="Right" Name="rollTextBlock" Text="ROLL: 000" VerticalAlignment="Top" Foreground="Blue" FontSize="25" FontWeight="Bold"/>
  13: </Grid>
  14: <Grid Height="200">
  15: <Polygon Name="yawtriangle" Points="45,135 80,50 115,135" Stroke="Red" StrokeThickness="2">
  16: <Polygon.Fill>
  17: <SolidColorBrush Color="Red" Opacity="0.3"/>
  18: </Polygon.Fill>
  19: <Polygon.RenderTransform>
  20: <RotateTransform CenterX="80" CenterY="100"></RotateTransform>
  21: </Polygon.RenderTransform>
  22: </Polygon>
  23: <Polygon Name="pitchtriangle" Points="205,135 240,50 275,135" Stroke="Green" StrokeThickness="2">
  24: <Polygon.Fill>
  25: <SolidColorBrush Color="Green" Opacity="0.3"/>
  26: </Polygon.Fill>
  27: <Polygon.RenderTransform>
  28: <RotateTransform CenterX="240" CenterY="100"></RotateTransform>
  29: </Polygon.RenderTransform>
  30: </Polygon>
  31: <Polygon Name="rolltriangle" Points="365,135 400,50 435,135" Stroke="Blue" StrokeThickness="2">
  32: <Polygon.Fill>
  33: <SolidColorBrush Color="Blue" Opacity="0.3"/>
  34: </Polygon.Fill>
  35: <Polygon.RenderTransform>
  36: <RotateTransform CenterX="400" CenterY="100"></RotateTransform>
  37: </Polygon.RenderTransform>
  38: </Polygon>
  39: </Grid>
  40: <TextBlock Text="acceleration" Style="{StaticResource PhoneTextLargeStyle}"/>
  41: <Grid Margin="12 0 12 0">
  42: <TextBlock Height="30" HorizontalAlignment="Left" Name="xTextBlock" Text="X: 000" VerticalAlignment="Top" Foreground="Red" FontSize="25" FontWeight="Bold"/>
  43: <TextBlock Height="30" HorizontalAlignment="Center" Name="yTextBlock" Text="Y: 000" VerticalAlignment="Top" Foreground="Green" FontSize="25" FontWeight="Bold"/>
  44: <TextBlock Height="30" HorizontalAlignment="Right" Name="zTextBlock" Text="Z: 000" VerticalAlignment="Top" Foreground="Blue" FontSize="25" FontWeight="Bold"/>
  45: </Grid>
  46: <Grid Height="300">
  47: <Line x:Name="xLine" X1="240" Y1="150" X2="340" Y2="150" Stroke="Red" StrokeThickness="4"></Line>
  48: <Line x:Name="yLine" X1="240" Y1="150" X2="240" Y2="50" Stroke="Green" StrokeThickness="4"></Line>
  49: <Line x:Name="zLine" X1="240" Y1="150" X2="190" Y2="200" Stroke="Blue" StrokeThickness="4"></Line>
  50: </Grid>
  51: </StackPanel>

.csharpcode, .csharpcode pre {font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff;/*white-space: pre;*/} .csharpcode pre {margin: 0em;} .csharpcode .rem {color: #008000;} .csharpcode .kwrd {color: #0000ff;} .csharpcode .str {color: #006080;} .csharpcode .op {color: # 0000c0;} .csharpcode .preproc {color: #cc6633;} .csharpcode .asp {background-color: #ffff00;} .csharpcode .html {color: #800000;} .csharpcode .attr {color: #ff0000;}. csharpcode .alt {background-color: #f4f4f4; width: 100%; margin: 0em;} .csharpcode .lnum {color: #606060;}

(3) In the MainPage.xaml.cs of the main page, declare an object of the Motion class.

(4) Rewrite the OnNavigatedTo(NavigationEventArgs) method of the page , check whether the device supports Motion, initialize the Motion object, and add the CurrentValueChanged event, the code is as follows:

   1: protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
   2: {
   3://Check to see whether the Motion API is supported on the device.
   4: if (! Motion.IsSupported)
   5: {
   6: MessageBox.Show("the Motion API is not supported on this device.");
   7: return;
   8: }
   9:   
  10://If the Motion object is null, initialize it and add a CurrentValueChanged
  11://event handler.
  12: if (motion == null)
  13: {
  14: motion = new Motion();
  15: motion.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
  16: motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>>(motion_CurrentValueChanged);
  17:}
  18:   
  19://Try to start the Motion API.
  20: try
  21: {
  22: motion.Start();
  23: }
  24: catch (Exception ex)
  25: {
  26: MessageBox.Show("unable to start the Motion API.");
  27:}
  28:}

.csharpcode, .csharpcode pre {font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff;/*white-space: pre;*/} .csharpcode pre {margin: 0em;} .csharpcode .rem {color: #008000;} .csharpcode .kwrd {color: #0000ff;} .csharpcode .str {color: #006080;} .csharpcode .op {color: # 0000c0;} .csharpcode .preproc {color: #cc6633;} .csharpcode .asp {background-color: #ffff00;} .csharpcode .html {color: #800000;} .csharpcode .attr {color: #ff0000;}. csharpcode .alt {background-color: #f4f4f4; width: 100%; margin: 0em;} .csharpcode .lnum {color: #606060;}

(5) The Motion data is obtained by periodically calling the CurrentValueChanged event, but the event is called in a background process, and UI elements cannot be changed. Therefore, we need to use BeginInvoke in the UI thread to call CurrentValueChanged.

(6) Create the CurrentValueChanged method, and set the contents of 6 Textblocks and 4 graphs in it. Use the MathHelper class in XNA Framework to realize the conversion of radians and angles, the code is as follows:

   1: private void CurrentValueChanged(MotionReading e)
   2: {
   3://Check to see if the Motion data is valid.
   4: if (motion.IsDataValid)
   5: {
   6://Show the numeric values ​​for attitude.
   7: yawTextBlock.Text = "YAW: "+ MathHelper.ToDegrees(e.Attitude.Yaw).ToString("0") + "°";
   8: pitchTextBlock.Text = "PITCH: "+ MathHelper.ToDegrees(e.Attitude.Pitch).ToString("0") + "°";
   9: rollTextBlock.Text = "ROLL: "+ MathHelper.ToDegrees(e.Attitude.Roll).ToString("0") + "°";
  10:   
  11://Set the Angle of the triangle RenderTransforms to the attitude of the device.
  12: ((RotateTransform)yawtriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Yaw);
  13: ((RotateTransform)pitchtriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Pitch);
  14: ((RotateTransform)rolltriangle.RenderTransform).Angle = MathHelper.ToDegrees(e.Attitude.Roll);
  15:   
  16://Show the numeric values ​​for acceleration.
  17: xTextBlock.Text = "X: "+ e.DeviceAcceleration.X.ToString("0.00");
  18: yTextBlock.Text = "Y: "+ e.DeviceAcceleration.Y.ToString("0.00");
  19: zTextBlock.Text = "Z: "+ e.DeviceAcceleration.Z.ToString("0.00");
  20:   
  21://Show the acceleration values ​​graphically.
  22: xLine.X2 = xLine.X1 + e.DeviceAcceleration.X * 100;
  23: yLine.Y2 = yLine.Y1-e.DeviceAcceleration.Y * 100;
  24: zLine.X2 = zLine.X1-e.DeviceAcceleration.Z * 50;
  25: zLine.Y2 = zLine.Y1 + e.DeviceAcceleration.Z * 50;
  26:}
  27:}

.csharpcode, .csharpcode pre {font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff;/*white-space: pre;*/} .csharpcode pre {margin: 0em;} .csharpcode .rem {color: #008000;} .csharpcode .kwrd {color: #0000ff;} .csharpcode .str {color: #006080;} .csharpcode .op {color: # 0000c0;} .csharpcode .preproc {color: #cc6633;} .csharpcode .asp {background-color: #ffff00;} .csharpcode .html {color: #800000;} .csharpcode .attr {color: #ff0000;}. csharpcode .alt {background-color: #f4f4f4; width: 100%; margin: 0em;} .csharpcode .lnum {color: #606060;}

4. Test results

    Compass test was performed on Samsung Focus i917 (upgraded to Mango, version number is 7720.68), and the results obtained are shown in Figure 3 below:

Figure 3: Motion API test results on Focus

Reference link:

1. How to: Use the Combined Motion API for Windows Phone

2. Sensors Overview for Windows Phone

Reference: https://cloud.tencent.com/developer/article/1017680 Windows Phone 7 Motion Sensor User Guide-Cloud + Community-Tencent Cloud