The sample code for this section follows the same pattern as the code for the gyroscope. The viewmodel’s Start
method first tests whether the motion sensor is supported, and then creates a new Motion
instance, subscribes to its CurrentValueChangedEvent
, and calls its Start
method. See the following excerpt:
public void Start()
{
if (!Motion.IsSupported)
{
MessageService.ShowMessage(
"Motion is not supported on this device.");
return;
}
motion = new Motion();
double interval = motion.TimeBetweenUpdates.TotalMilliseconds;
motion.CurrentValueChanged += HandleMotionCurrentValueChanged;
motion.Start();
}
The Motion
sensor’s TimeBetweenUpdates
property is, by default, set to 17 milliseconds.
When the CurrentValueChanged
event is raised, a SensorReadingEventArgs<MotionReading>
object is passed to your event handler. MotionReading
reading contains the following properties:
Attitude (of type AttitudeReading)—Gets the attitude (yaw, pitch, and roll) of the device, in radians
DeviceAcceleration (of type Vector3)—Gets the linear acceleration of the device, in gravitational units
DeviceRotationRate (of type Vector3)—Gets the rotational velocity of the device, in radians per second
Gravity (of type Vector3)—Gets the gravity vector associated with the Microsoft.Devices.Sensors.MotionReading
Timestamp (of type DateTimeOffset)—Gets the time at which the reading was calculated
The Attitude
reading is useful in allowing you to determine the position of the device, which is broken down into pitch, roll, and yaw. Table 16.3 describes each of the AttitudeReading
properties.
The CurrentValueChanged
handler, within the viewmodel, assigns the reading to various properties within the viewmodel. The reading’s DeviceAcceleration
and DeviceRotationRate Vector3
properties are converted to a ThreeDimensionalVector
using an extension method. See the following excerpt:
void HandleMotionCurrentValueChanged(
object sender, SensorReadingEventArgs<MotionReading> e)
{
MotionReading reading = e.SensorReading;
AttitudeReading = reading.Attitude;
DeviceAcceleration
= reading.DeviceAcceleration.ToThreeDimensionalVector();
DeviceRotationRate
= reading.DeviceRotationRate.ToThreeDimensionalVector();
Gravity = reading.Gravity.ToThreeDimensionalVector();
AttitudeReading attitude = reading.Attitude;
Attitude = new ThreeDimensionalVector(
attitude.Pitch, attitude.Roll, attitude.Yaw);
}
Within the view, the reading vector values are represented in the same manner as for the gyroscope; lines are rotated using a RotateTransform
that is bound to the reading value. In this case, however, values are supplied in radians and must be converted to degrees. For this, a custom IValueConverter
called RadiansToDegreesConverter
is used (see Listing 16.11).
public class RadiansToDegreesConverter : IValueConverter
{
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
float f = System.Convert.ToSingle(value);
float result = MathHelper.ToDegrees(f);
return result;
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
float f = (float)value;
float result = MathHelper.ToRadians(f);
return result;
}
}
A ControlTemplate
is used to display the four ThreeDimensionalVector
objects on the page. A Rectangle
represents each vector component, and the RadiansToDegreesConverter
, defined as page level resource, converts the source value to degrees for the RotateTransform
. See the following excerpt:
<Rectangle Canvas.Left="195" Canvas.Top="0"
Width="10" Height="200" Fill="Honeydew">
<Rectangle.RenderTransform>
<RotateTransform Angle="{Binding X,
Converter={StaticResource RadiansToDegressConverter}}"
CenterX="5" CenterY="200" />
</Rectangle.RenderTransform>
</Rectangle>
Figure 16.8 shows the various readings displayed on the MotionView page. The attitude meter shows the pitch, roll, and yaw as the vector components X, Y, and Z, respectively. The other three reading types, acceleration, rotation rate, and gravity, are also displayed.
The Motion
class also includes a Calibrate
event that indicates when the compass needs calibrating. This event provides your app with the opportunity to display the calibration dialog, as discussed previously in the “Measuring Direction with the Compass” section of this chapter.
18.219.31.220