WiiFlash0.4.5 を使った場合の、Wiiリモコン加速度センサの仕様を簡単に調べてみた。
下図は、リモコンを静止させた状態で加速度センサの値を1秒間計測したときの x, y, z 方向のセンサの値 (平均値をゼロに直している)。
横軸はサンプル個数、縦軸はセンサが記録した加速度 (1.0のとき1G)。
まず、1秒間で約100回サンプリングされていたので、センサの更新間隔はだいたい 10 ミリ秒 (100[Hz])。
これは Wiiリモコンのハード側の仕様なのか、それとも WiiFlashのソフト側の仕様なのかは知らん。
インターンのときはたしか 5ミリ秒って聞いたことがあった気がするけど…
でも、加速度が 100[Hz] で取れるってすごい性能だ。
※ 2009/10/19 追記
WiimoteLib v1.8 Beta 1 と Visual C# の環境でも WiimoteChanged イベント関数は 100 [Hz] で呼ばれた。
次。静止状態でもセンサ値に変動があって、その振れ幅が離散的だった。値が揺らいだ理由は置いといて、この振れが最小幅なら加速度センサの精度は 0.04G ( = 0.39[m/ss]) になる。
でも、Wiiリモコンを手に持った場合なんかは、センサ自体の精度に比べて手ぶれが大きすぎてあんまり細かい桁数の話は意味無いんじゃないかと思う。
実際にリモコンの傾きに合わせて絵が傾くようなプログラムを作ると、センサが敏感すぎてかなりブレる。
静止時じゃなくて、動いたときの追従の速さとか収束の速さとかはちゃんと調べないと分からん。
でも、人間が見て遅れているとは分からないくらい速いのは確か。
あと、リモコンを思いっきり振ったらセンサの値は ±5 でサチったので、ひとつのセンサで測れる加速度の最大値は 5G (±49 [m/ss]) で間違いないはず。
ちなみに、Wiiリモコン加速度センサ3軸それぞれに対して 45°傾いた方向なら、直行する3軸のベクトル合成だと思えば
5 × √3 = 8.7G = 85 [m/ss]
まで測れることになるよね。
下図は、リモコンを静止させた状態で加速度センサの値を1秒間計測したときの x, y, z 方向のセンサの値 (平均値をゼロに直している)。
横軸はサンプル個数、縦軸はセンサが記録した加速度 (1.0のとき1G)。
まず、1秒間で約100回サンプリングされていたので、センサの更新間隔はだいたい 10 ミリ秒 (100[Hz])。
これは Wiiリモコンのハード側の仕様なのか、それとも WiiFlashのソフト側の仕様なのかは知らん。
インターンのときはたしか 5ミリ秒って聞いたことがあった気がするけど…
でも、加速度が 100[Hz] で取れるってすごい性能だ。
※ 2009/10/19 追記
WiimoteLib v1.8 Beta 1 と Visual C# の環境でも WiimoteChanged イベント関数は 100 [Hz] で呼ばれた。
次。静止状態でもセンサ値に変動があって、その振れ幅が離散的だった。値が揺らいだ理由は置いといて、この振れが最小幅なら加速度センサの精度は 0.04G ( = 0.39[m/ss]) になる。
でも、Wiiリモコンを手に持った場合なんかは、センサ自体の精度に比べて手ぶれが大きすぎてあんまり細かい桁数の話は意味無いんじゃないかと思う。
実際にリモコンの傾きに合わせて絵が傾くようなプログラムを作ると、センサが敏感すぎてかなりブレる。
静止時じゃなくて、動いたときの追従の速さとか収束の速さとかはちゃんと調べないと分からん。
でも、人間が見て遅れているとは分からないくらい速いのは確か。
あと、リモコンを思いっきり振ったらセンサの値は ±5 でサチったので、ひとつのセンサで測れる加速度の最大値は 5G (±49 [m/ss]) で間違いないはず。
ちなみに、Wiiリモコン加速度センサ3軸それぞれに対して 45°傾いた方向なら、直行する3軸のベクトル合成だと思えば
5 × √3 = 8.7G = 85 [m/ss]
まで測れることになるよね。
package { import flash.display.Sprite; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.Timer; import org.wiiflash.Wiimote; import org.wiiflash.events.WiimoteEvent; public class Main extends Sprite { private var wii:Wiimote; private var timer:Timer; private var value:Array; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point wii = new Wiimote(); wii.connect(); value = new Array(); timer = new Timer(1000.0, 1); timer.addEventListener(TimerEvent.TIMER, onTimeUp); timer.start(); wii.addEventListener(WiimoteEvent.UPDATE, onWiimoteStateChange); } private function onTimeUp(event:TimerEvent):void { wii.removeEventListener(WiimoteEvent.UPDATE, onWiimoteStateChange); for each(var v:Number in value) trace(v); } private function onWiimoteStateChange(event:WiimoteEvent):void { value.push(wii.sensorX); } } }