nomurabbitのブログ

nomurabbitのブログはITを中心にした技術ブログです。

nomurabbitのブログ

Compass、Motion、ときどきGyroscope

<はじめに>
WP7で使えるセンサーについて調べてみました。フレームワークで使えそうなクラスにGyroscope、Compass、Motionがあったので、それぞれを使って実装を試してみました。


<プログラム>

public partial class MainPage : PhoneApplicationPage
{
    //--------------------------------------------
    // インスタンス変数
    //
    Gyroscope gyroscope;
    Compass compass;
    Motion motion;

    //--------------------------------------------
    // コンストラクタ
    //
    public MainPage()
    {
        InitializeComponent();

        GyroscopeInitialize();
        CompassInitialize();
        MotionInitialize();
    }

    #region センサー初期化メソッド

    //--------------------------------------------
    // ジャイロスコープ
    //
    public void GyroscopeInitialize()
    {
        gyroscope = new Gyroscope();

        gyroscope.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<GyroscopeReading>>(gyroscope_CurrentValueChanged);

        //gyroscope.Start();
    }

    //--------------------------------------------
    // コンパス
    //
    public void CompassInitialize()
    {
        compass = new Compass();

        compass.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<CompassReading>>(compass_CurrentValueChanged);

        compass.Start();
    }

    //--------------------------------------------
    // モーション
    //
    public void MotionInitialize()
    {
        motion = new Motion();

        motion.CurrentValueChanged += new EventHandler<SensorReadingEventArgs<MotionReading>>(motion_CurrentValueChanged);

        motion.Start();
    }

    #endregion 

    #region イベント用メソッド

    //--------------------------------------------
    // ジャイロスコープ
    //
    void gyroscope_CurrentValueChanged(object sender, SensorReadingEventArgs<GyroscopeReading> e)
    {
        GyroscopeReading gyroscopeReading = e.SensorReading;

        Vector3 rotationRate = gyroscopeReading.RotationRate;

        Dispatcher.BeginInvoke(() => this.textBlockRotationX_value.Text = rotationRate.X.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockRotationY_value.Text = rotationRate.Y.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockRotationZ_value.Text = rotationRate.Z.ToString());
    }

    //--------------------------------------------
    // コンパス
    //
    void compass_CurrentValueChanged(object sender, SensorReadingEventArgs<CompassReading> e)
    {
        CompassReading compassReading = e.SensorReading;

        double headingAccuracy     = compassReading.HeadingAccuracy;
        double magneticHeading     = compassReading.MagneticHeading;
        Vector3 magnetometerRating = compassReading.MagnetometerReading;
        double trueHeading         = compassReading.TrueHeading;

        Dispatcher.BeginInvoke(() => this.textBlockheadingAccuracy_value.Text = headingAccuracy.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockMagnetic_value.Text        = magneticHeading.ToString());

        Dispatcher.BeginInvoke(() => this.textBlockMagnetX_value.Text = magnetometerRating.X.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockMagnetY_value.Text = magnetometerRating.Y.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockMagnetZ_value.Text = magnetometerRating.Z.ToString());

        Dispatcher.BeginInvoke(() => this.textBlockTrueHeading_value.Text     = trueHeading.ToString());
    }

    //--------------------------------------------
    // モーション
    //
    void motion_CurrentValueChanged(object sender, SensorReadingEventArgs<MotionReading> e)
    {
        MotionReading motionReading = e.SensorReading;

        AttitudeReading attitude   = motionReading.Attitude;
        Vector3 deviceAcceleration = motionReading.DeviceAcceleration;
        Vector3 deviceRotatingRate = motionReading.DeviceRotationRate;
        Vector3 Gravity            = motionReading.Gravity;

        Dispatcher.BeginInvoke(() => this.textBlockPitch_value .Text = attitude.Pitch.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockYaw_value.Text    = attitude.Yaw.ToString());
        Dispatcher.BeginInvoke(() => this.textBlockRoll_value.Text   = attitude.Roll.ToString());
    }

    #endregion
}


<まとめ>
端末に機能がないのかGyroscopeは上手く使えなかったのですが、CompassとMotionからは値の取得ができました。センサー関連のクラスは使い方がほぼ同じなのでいろいろ活用できそうです。