2010年11月28日日曜日

加速度から向きの算出

引き続き、XNAとWiimoteLibで3Dオブジェクトを操作の解析を行います。

過去50個の平均をとってならしている部分を省くと、
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args) { WiimoteState ws = args.WiimoteState; //WiimoteStateの値を取得 x = ws.AccelState.Values.X } protected override void Draw(GameTime gameTime) { x = (-x * 90.0f); x = x / 180 * 3.14f; effect.World = Matrix.CreateFromYawPitchRoll(0, y, x); }
という感じです。y も同じコード。
AccesState.Values に角度に比例した値、具体的には -1..1 の範囲に丸めた値が入っているのかな?


イベントハンドラ

一番上の ws とは何かというと、
this.wm = new Wiimote(); this.wm.SetReportType(InputReport.IRExtensionAccel, true);//レポートタイプの設定 this.wm.WiimoteChanged += wm_WiimoteChanged; //イベント関数の登録
という手順で登録されたイベントハンドラの引数。

イベントハンドラ登録前の
Wiimote.SetReportType Method (InputReport, Boolean)
  Set Wiimote reporting mode (if using an IR report type, IR sensitivity is set to WiiLevel3)

  public void SetReportType(InputReport type, bool continuous)
    continuous: Continuous data
InputReport はおいといて、continuous は data が連続的な値になるみたいですね。
1byte の値そのままじゃなくて、実数に丸め込むのかな?
しかし AccelState には Values だけでなくて RawValues ってフィールドもあるから両方取れるのだが…。
ちょっと具体的にはよく分からないけれど、こういうパラメータがあることだけ覚えておきましょう。

続いて InputReport は、
InputReport Enumeration
  The report format in which the Wiimote should return data 

Member nameDescription
Status
Status report
ReadData
Read data from memory location
OutputReportAck
Register write complete
Buttons
Button data only
ButtonsAccel
Button and accelerometer data
IRAccel
IR sensor and accelerometer data
ButtonsExtension
Button and extension controller data
ExtensionAccel
Extension and accelerometer data
IRExtensionAccel
IR sensor, extension controller and accelerometer data
IRExtensionAccel は IR と Extension と Accel なイベントを有効にする、ということのようです。
内部的にはビットベクトルになってそうです。


イベント

Wiimote.WiimoteChanged Event Event raised when Wiimote state is changed Syntax public event EventHandler WiimoteChanged
とのことで、状態が変わったら呼ばれるようです。

このイベントオブジェクトには WiimoteState がメンバ変数にあって、WiimoteState は
WiimoteState Members
NameDescription
AccelCalibrationInfo
Current calibration information
AccelState
Current state of accelerometers
BalanceBoardState
Current state of the Wii Fit Balance Board
Battery
Calculated current battery level
BatteryRaw
Raw byte value of current battery level
ButtonState
Current state of buttons
ClassicControllerState
Current state of Classic Controller extension
DrumsState
Current state of Drums extension
Extension
Is an extension controller inserted?
ExtensionType
Extension controller currently inserted, if any
GuitarState
Current state of Guitar extension
IRState
Current state of IR sensors
LEDState
Current state of LEDs
MotionPlusState
Current state of the MotionPlus controller
NunchukState
Current state of Nunchuk extension
Rumble
Current state of rumble
TaikoDrumState
Current state of the Taiko TaTaCon drum controller
いろいろメンバがありますね。
おそらくはこのライブラリで取得できるリモコンの値はこれで全部なのでしょう。


AccelState

長々とイベントハンドラの仕組みを追いましたが、結局のところすぐ上の AccelState.Values を使っています。

AccelState.Values は、WiimoteLib のヘルプによると
Normalized accelerometer data. Values range between 0 - ?, but values > 3 and < -3 are inaccurate.

0からの範囲に正規化した値のようです。プラスマイナス3を超えた値は不正確であると。

正規化というのは具体的には何でしょう。
センサから取れる加速度は 1byte の値なので、これをプラスマイナス3の範囲になるように変換したと思われます。
ゼロはおそらく静止状態でしょう。

件のソースコードでは、この値が 1 のときに 90度であるとみなしていました。
力を加えていない時にリモコンを傾けた時に、重力のX方向成分はサインカーブを描きます。
ということは、正規化とは有効値を 3 に収めるのではなくて、リモコン回した時の重力加速度の変化が 1 になるようにしたものということかな。

しかし値はあくまで加速度の成分で、角度に変換されているとはちょっと考えにくい気がします。
おそらくは、サンプルプログラムだから簡単に、サインカーブと比例直線を同じとみなして扱っているのでしょうか。

と、大体予想がついたところで、次はライブラリのソースみたり実測して確認をしましょう。

0 件のコメント:

コメントを投稿