改め Objective Technician

はぐれ技術者のやりたい放題

Wiiリモコン加速度センサの仕様調査

2009-10-18 00:22:24 | プログラミング
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]

まで測れることになるよね。









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);
		}		
	}	
}


復帰試合

2009-10-17 22:52:02 | 陸上競技
10月17日(土) 宮城野 晴 涼


11:50~
100m
4組8レーン4着 11"97(-2.1)

14:00~
200m
3組5レーン2着 23"53(0.0) 公認自己新




左足が持ちこたえてくれたおかげで、現時点でのベストは尽くせたかと思う。

某日本記録保持者の言葉を借りれば、「一息で走れた」。




この調子のままもういくつか記録会出たいなぁ…










そういえば、仙台では割と有名だと思われる、あの全身ピンクい人を見た。

彼に遭遇できたのはこれで4回目だ。











あの人を見るとすごく勇気付けられる気がするなんでかな。

再帰的走法

2009-10-15 19:04:14 | 陸上競技
「5%理論」はパレートの法則のシビア版だと思う。



10月11日(日) 評定 夕 涼

ドリル
150m×3
100m×3


10月12日(月) 宮城野 夕 涼

ドリル
150mスパイク×3
スタブロ
100m加速走×2


10月13(火), 14(水)
肉抜き


10月15日(木) 宮城野 昼 涼

ドリル
流し
スタブロ




W-UPの段階でタータンがすっごい弾んで、久しぶりにワクワクした気持ちになった。

でもスタブロがダメすぎる。




とりあえず最低限走れるコンディションまでには戻せたかな…

でも本当に最低限だ。



明後日は肉離れませんように…









Wii リモコンでジャイロマウス

2009-10-13 22:03:51 | プログラミング
Wii リモコンの Motion Plus でジャイロマウスを作った。



Wiimote GyroMouse



空中でリモコンを動かすとマウスカーソルがヌルヌル動く。
IRセンサや加速度センサと違ってジャイロセンサはどんな場所や姿勢からでも操作できるのがいい。

これはプレゼンで使える。


市販のジャイロマウスだと1万円以上するのに、Wii リモコン と Motion Plus だとその半額以下で作れてしまう。というか、ジャイロスコープが1500円で買えるのが信じられない。




モノがそろってれば、下のやり方でソフトを起動するだけですぐに Wiiリモコンがジャイロマウスになります。


使い方

1:実行ファイル をダウンロード・解凍

2:.NET を入れてない場合はインストール

3:Wii リモコンに Motion Plus を装着して、パソコンと Bluetooth で接続 (リモコンの電池カバーを外すと SYNC ボタンがある)。

4:解凍したフォルダの中の "WiimoteGyroMouse.exe" を起動。

5:"CONNECT" ボタンを押すと Wii リモコンが(リモコンのBボタンを押している間)ジャイロマウスになる。"DISCONNECT" を押すとリモコンとの接続が切れる。

6:Wii リモコンボタンのキーバインドは以下のとおり

"A" → マウス左クリック
"B" → 押している間だけジャイロセンサが有効
十字キー → キーボードの十字キー
"-" → Back Space
"+" → Enter
"home" → Windows キー
"1" → マウス右クリック
"2" → ALT キー



操作しているうちに少しずつ座標マッピングがずれていったり、細かい操作が難しかったりするのは、そのうち気が向いたら直すかもしれない。




ソースはこちら


WiimoteLib v1.8 Beta 1 を使って Visual C# で実装してますよ

FlashDevelopインストールと初期設定メモ

2009-10-12 22:44:30 | プログラミング
ActionScript3.0 の統合開発環境 FlashDevelop の導入手順の自分メモ。


前にも書いたけど、FlashDevelop は補完機能がハンパじゃなく便利で、他の IED と比べて体感10倍増ぐらいで使いやすい。

だけど、初期設定をちょっといじらないと使えない部分があったりするので、主にその設定変更について。というかほぼリンク集。



1:インストール
ここに書いてある通りに FlashDevelop と Flex SDK をインストール。


2:trace() で出力できるようにする
デフォルトではコンソールに何かを出力する命令が効かなくて、デバッグができない。ここの通りに設定して trace() を有効にする。


3:各種ライブラリ

fl.controls.*
tweener
Papervision3D
Box2D
WiiFlash

swc なら、Project → Properties → Compiler Options → SWC Libralies にファイル名を含むパスを追加。
非圧縮のフォルダなら、Project → Properties → Classpaths → Edit Global Classpaths でパスを通す。


4:画面背景色の変更

白背景は眼が疲れてしょうがないので、眼に優しい黒背景にする。基本中の基本である。

設定ファイルは、隠しフォルダ "C:¥Documents and Settings¥user name¥Local Settings¥Application Data¥FlashDevelop¥Settings" の "ScintillaNET.xml" と "Languages¥AS3.xml" 。

自分で一つずつ設定するのは面倒なので、ここから好きなのを落として、設定ファイルを上書きするのが楽。

管理人の設定ファイル


5:新規プロジェクト

Project → New Project → AS3 Project で作れる。
新規クラスは src を右クリックで Add → New Class





関係ないけど、ずば抜けて使いやすいのにデフォルト状態じゃ使い物にならないところが、なんかナイスペファイヤーボールと似てるなぁと思う。


あと7日

2009-10-10 00:36:48 | 陸上競技

10月5日(Mon) 評定 夜

ドリル
鉄棒
150m×3
100m×3


10月6日(Tue) 評定 夜

ドリル
鉄棒
100m×3×2


10月7日(Wed) 片平 夕

ジョグ


10月8日(Thu) ずいほう 夜

坂ダッシュ
80m×3


10月9日(Fri) ずいほう 夜

jog
ドリル
坂ダッシュ
80m×3×2





















対象を正視し続けることが思考の自由な働きを妨げる

2009-10-09 00:24:29 | 勉強
このあいだ研究会で聴いた話から。


人間の視覚機能のしくみが、怪しげな思想的な解釈ではなくきちんとした工学の理論(信号処理)で説明できることの一例。



運動検出器を時空間周波数座標での傾き検出器にすり替えて考えることで、仮現運動とサンプリング定理の概念が結びつく。


予備知識
 仮現運動:不連続に変化する絵なのに動きが見える現象。テレビとかパラパラマンガとか。
 ○○検出器:視覚系に割と低次のレベルから存在する、視覚像から特徴を選択的に抽出する神経基盤。線分の方位検出器や運動の速度検出器など。



まず、十分に細かいサンプリングで光点の運動を記録したときの時空間プロットの例が左図、この時空間周波数成分が右図。


この時空間周波数座標の丸で囲ったあたり(下図)の範囲に、周波数軸上での傾きを何らかの方法で検出する機構があれば、それはつまり運動検出器になる。







次に、サンプリング間隔を2倍に粗くしたときの時空間座標と周波数座標はこんな↓。周波数座標上に元信号のコピーが彼方から現れ、じりじりと迫ってきている。




でも、下図みたいに時空間周波数軸上での傾き検出器(= 運動検出器)が感度をもつ範囲にかかってなければ、上の方のニセ信号はローパスフィルタでカットされるので運動情報は完全に復元できる。この場合の仮現運動と実運動とは違いがないので区別できない。





さらに、サンプリング間隔を4倍にしたとき↓。周波数軸上でのコピー成分の間隔がどんどんせまくなっていく。




これが、下図みたいに検出器が感度を持つ範囲に入ると、ニセ信号が拾われてしまうので運動情報を元通り復元できなくなる。こうなると運動が不自然にカクカクして見えて、初めて自然な実運動とは違うことが分かる。







でも、サンプリングが相当粗い場合でも、人間の視覚系は積極的に動きを見よう(仮現運動を作ろう)としてくれるので、特に困ることはないもの。




逆に、サンプリングが一定値より細かければそれは実運動と区別できないので、それ以上にムダにディスプレイのリフレッシュレートを上げても知覚上は意味ないんですよという話。




AS3物理エンジンBox2DのMouseJointで引力/斥力っぽい実装

2009-10-07 20:53:45 | プログラミング


前期にやってた物理シミュレーションの実装バイトが教授に気に入られて後期もやることになったので、これで大手を振って Flash 作りに興じられるようになった。

もっと、Papervision3D とか Tweener とか Box2D とか使い倒してみたい。


Flash で遊ぶ大義名分が立ったところで、物理エンジン Box2D のジョイントまわりをいじってみた。



物体どうしを結びつけるジョイントには、一定距離を保つ、ピン止め回転、ピストン、プーリー、ギア、マウス関連、の6種類が用意されている。





ところで、Box2D が剛体の物理演算ライブラリを名乗るからには、離れて働く力も簡単に扱えるのかと当初は期待してたけど、引力/斥力の類は自分でベクトル計算して b2Body に ApplyForce するしかないらしい。



それなら、代わりに伸び縮みするジョイントがあっても良いような気がするけど、これもない。


ただマウスジョイントというものが、マウスポインタと b2Body とを力で結びつける機能を持っている。


b2MouseJoint は本来 b2Body どうしを結ぶものではないけど、これをむりやり b2Body 同士の双方向に張って互いに引き合うようにするには、こんな↓雰囲気でやればいい。(一方向に張るだけだと張った側に反作用が働かない。)

	private function setJoint():void {
		joint = b2MouseJoint(world.CreateJoint(getMouseJointDef(target)));
		joint2 = b2MouseJoint(world.CreateJoint(getMouseJointDef(body)));
	}
		
	private function getMouseJointDef(obj:b2Body):b2MouseJointDef {

		var mouseJointDef:b2MouseJointDef = new b2MouseJointDef(); 

		mouseJointDef.body1 = world.GetGroundBody();
		mouseJointDef.body2 = obj;
		mouseJointDef.target = obj.GetWorldCenter();             
		mouseJointDef.maxForce = force;			
		mouseJointDef.timeStep = timeStep; 			

		return mouseJointDef;
	}


	private function onEnterFrame(event:Event):void {
		joint.SetTarget(body.GetPosition());
		joint2.SetTarget(target.GetPosition());
	}




試しにこれで適当に作ってみたところ、見た目にはそれっぽい動きをしている。

画像クリックで動きます↓


AS3ソースはこちら


Box2D 側の実装を詳しく見てないからわからないけど、たぶんこれは距離に関係なく一定の力がかかってるから、万有引力とか静電気力とかを表現するとなるとあと少し工夫が必要なはず。



あと、作ってみて気がついたけど、b2Body どうしが密集したときになんか集団がバネらしき動きをしてるので、これを使って弾性体っぽいものが表現できるかもしれない。

Wiiリモコンと物理エンジンでデビルスティック

2009-10-05 00:39:21 | プログラミング
Flashで動く物理エンジン(Box2D)とWiiFlashでバーチャルデビルスティックを作…


ろうとしたけど、これはデビルスティックになってない。


Wiimote Devil Sticks (WiiFlash + Box2D)


AS3ソースはこちら


パラメータのチューニングをちゃんとやれば、もっとそれっぽいのができるかもしれない。



WiiFlash で Wiiリモコンを複数台使いたいときは、単純に Wiimote インスタンスを複数定義して、それぞれ new Wiimote() して connect() すればいい。

そうすると、WiiFlashServer に接続された順番で WiiFlash から 複数台の Wiiリモコンが使えるようになる

ひざカックン

2009-10-04 20:20:50 | 陸上競技
~ 10月1日
坂ダッシュとか


10月3日(Sat) 評定 涼 夜

ドリル
鉄棒
150m×3
100m×3


10月4日(Sun) 評定 涼 夜

ドリル
150m×3
100m×2
鉄棒




持久力とキレが少し戻ってきた。



ここで調子に乗ってまたムリしないように…。




さもないと
















あと12日!