ここ1ヶ月ぐらいずっとWiiRemoteにどっぷり。
もちろんその間にフルペーパー論文を1.5本ぐらい書いていたりもするのですが。
「どっぷり」といっても、半分ぐらいは他人が書いたコードの動作と解析、つまり調査。
あとはVirtoolsのBuilding Blockが30%、のこりは純粋なテストコードを今流行の「スクラップ&スクラップ!!」という感じです。
もちろん面白い成果もいろいろ出てきてるんですけどねえー、まだBlogではかけません。すみません。
…といいつつUSBの5V電源で動作する「USBセンサーバー」の回路図とか載せておきます(Thanks>かいせい君)。
まあ普通にUSBから電源とって制限抵抗はさんで、並列にした赤外線LED(900nm近辺)を点灯させて、ついでにカラーのパイロットランプもつけた…って代物です。
抵抗とかLEDの定格とか、気になる人はちゃんと計算したらいいですが、DIY的にやりたいならこれで動きますので。
(使わないときはUSBポートから抜いておきましょう、安全とLEDの寿命のために)
で、ソフトの解析のほうに話を戻します。
実際、世界中ですごい勢いで「俺はWiimote使えるようになったぜー」的なソフトウェアプロジェクトが乱立してます。
しかしオープンソースで拝見させてもらった動いているプロジェクトの多くが、とりあえず動いていますが「ええーっ?」という感じのプログラムでした。
コード読ませてもらって本当に申し訳ないんですが、たぶんハードウェアのことをあまり知らない人が書いた感じのが多いです。
加えて言うと、マン・マシン・インタラクションについてもあまりよくわかってない感じのコードが多いです。
たぶん、ゲームプログラミングしか知らないと、そういう感じに書いてしまうのが普通なのかもしれない、アマチュアだからかもしれない。
素直に「他人のソースを読むのは勉強になるなあ」と言いたいところなんですが、まずは思ったところを書いておきます。
■とにかく初期化がいい加減
OSからみるとHID(Human Interface Device)として動作するコンシューマデバイスとはいえ、ホストOSからみたら外部のデバイスなんだから、もうすこしまじめに初期化してもいいんじゃないか、みんな!!
自分も「そっち(任天堂の内)側の人」ではないのでなんともいえませんが、『マルチスレッド立てて毎ループで初期化するようなデバイスじゃないだろう!!』とだけは言っておこう。
■BlueSoleil経由でしか動かないプログラムがある
まあ野プログラマーが自分で持ってる環境でしか試さない、というのは当然なんですけど、上記の初期化のお作法が原因と思われる問題がこれです。
具体的な問題としては、大きく分けると『BlueSoleilスタックからのみアクセスできるプログラム』と、『DELL等のTOSHIBA Bluetooth Managerからアクセスできないプログラム』、それから『何でも使えるプログラム』があります。MicrosoftのBluetooth(Acerのラップトップなど)ではまだ試していませんが、少なくとも『BlueSoleilだけ』のやつは動きませんでした。この種類のプログラムは初期化に癖があって、ちょっと長めに待ってあげるとDELL(TOSHIBA)でも動いたりしますが確実ではありません。
☆BlueSoleilでしか動かないプロジェクトの例
・cWiiMote http://simulatedcomicproduct.com/2006/12/cwiimote-02.php
・WiiTools Building Block (cWiiMoteを使っている)
☆DELLでもBlueSoleilでも動くプロジェクト
・GlovePIE http://carl.kenner.googlepages.com/glovepie
・WiinRemote (Microsoftでは動作しない)
Delphiでなければよかったんですけど・・・
・Kako.comのtiny_hid_dllを使った一連のサンプル
http://www.kako.com/neta/2006-019/2006-019.html
↑基本的にこちらがお勧めです!
☆DELLで動くがBlueSoleilで動かないプロジェクト
・Wiim http://digitalretrograde.com/projects/wiim/
(ゲームつきサンプルはすばらしいけど初期化で落ちる)
・wiimote4virtools
http://code.google.com/p/wiimote4virtools/
svnでソースコードが手に入ります。
(内部でWiimを使用しているらしいので、たぶん初期化で落ちます)
☆まだ試してません(Delphi関係とか、単なるHIDアクセスのためのサンプルとか)
・SimpleHIDWriteWii
・HIDKomponente
■エラー処理まったくなし
「俺はソース公開しているからエラー処理は書かないぜ!」という書き方なら許しますが、if文の塊、変な関数で初期化しておいて、さらにそのreturnで、別の初期関数を呼んで…なんて書き方は、「俺はまったくエラーハンドルする気がないぜ!」と言ってるようなもんです。
エラーが発生しないと言い切れるならともかく、可能性がありありなら、コメントぐらい書いておくとか、戻り値にfalse返すぐらいしてもいいと思う。
■無駄にクラス化しないで
クラス化したがる気持ちは判るんですが、自信を持って「ハッキング終了!!」と言えないうちは無理にクラス化する意味はないと思う。
たとえば「インスタンスでデバイス初期化」とかすると、接続失敗したときはどうするんだ、と突っ込み。
Bluetooth経由の接続ってのは実は意外と簡単で、スタックに接続さえされていれば、必要な情報ってのは、ベンダーIDとプロダクトID、それからWiimoteの複数接続をサポートするかってところ。
プログラミング的にはデバイスハンドルが返ってきさえすればいいし、残りのコールはローレベルファイルアクセス(fopen/fread/fwrite)とあまりかわらない。
あとはWiili.orgに書いてあるようなリポートIDに対する各バッファの解釈だけなので、つまらん関数をたくさん用意する意味は(バイトの並びを理解する目的以外)全く無いかも。
■無駄に正規化
結局、モーションセンサーの加速度は各軸0-255の値しかとらない。なのにわざわざfloatやdoubleで無理に-1~+1に正規化したりするクラスは無意味だと思う。
たとえば学習とか××とかの手法を使いたいときは、わざわざノイズを乗せてることになる。
てゆーか、そんな計算はアプリケーションプログラマがやるべき。クラス化するなら生値にアクセスさせたらいいわけで。
■無駄にマルチスレッド化
どうやらWiimoteは動作に変化が無いときはデータを送らない仕様みたい。
まあ当然と言えば当然。そこらじゅうにWiimoteがあったら、Bluetoothのバンド幅がすぐにいっぱいになってしまう。
でも多くのサンプルがマルチスレッドにして、必要以上にWiimoteに問い合わせを行ってる。
マルチスレッドプログラミングはそれなりに面倒だから「えらいなあ」ってことなんだけど、問題は作成したスレッド内で「⊿t」を取得してない例があるってこと。
たとえば、メインのループで⊿tを取得しても、それぞれのフレームで得られた値は必ずしも微小時間内の加速度を示しているとは限らない(こともある)。
この辺がしっかりしてないと「⊿t時間での加速度を積分して位置を出す」という演算がとても難しい、と言うか無理。
■HIDへのアクセス
上記のとおりBluetooth周りのアクセスはOSにインストールしたBluetoothスタック、ドライバがやってくれます。あとはHIDクラスのデバイスとして振舞うわけです。
「HIDってなんじゃい」ってのが最初の印象だとは思うんですが、HIDは一番面倒がないデバイスクラスだと思います。
MicrosoftはWindowsNT以降DDK(Driver Developer Kit)でSDKをフリーで提供していますし(何故か.libと.hを再配布しているプロジェクトもある)、フリーで使えるVisual Express2003/2005でもPlatformSDKをインストールすれば開発できます。
つまり「全部タダ!」で開発できるわけなんです。
あとは「クールなHIDデバイスの初期化サンプル」さえあればいいはずなのに、多くのプロジェクトがとてもごたいそうです。
■ソース長すぎ
というわけで上記のようにシンプルなはずなローレベルアクセスをうまく関数化して「1画面に収まるサンプル」を書けている人がなかなかいません。
ソース公開している人の中ではKako.comの「SDLとバッチファイル、コマンドラインビルド(cl.exe)」で動いちゃうサンプルが最高にいけてます。
コーディングスタイルもロボ魂っぽくて好感が持てます。
いろいろ世界中のサンプルをあさって、結局最初のサンプルに戻ってきてしまった、というわけです。
まあでもおかげでtiny_hidの内部処理とその利点は他のサンプルからだいたい理解した、と言うところなんですけど(でもソースほしいです、参考のために!)。
■誰もがモーション解析にたどりつけてない
上のいろんな問題が絡み合っているから、もしくはそっち系の研究者がいまいち深く入り込めていないせいか、もしくは研究向けの論文書ければオープンにしなくてもいいかー、とか「先生が公開するなと言ったので」とかいろんな理由があってか、まともなモーション解析を行えているサンプルがトンと見つからない(探しきれていないだけかもしれないので「俺は知ってるぜ」と言う人は教えてください)。
ハッキリ言って自分も含めてホビープログラマーとか学生さんとかは、上記のサンプルから、大量のIF文つかってモーション解析を書いてしまうわけです。
しかも物理の知識があやふや。
姿勢の取得とか重力のキャンセルとかもできない。
(えらそうに書いているように見えますが、普通に難易度ありますよ)
(日本の、いや世界各国そうなんですけど)ゲーム会社がそんなに数学や物理の得意な人ばかりで構成されているわけではないので、任天堂がどの程度のミドルウェアを提供しているのか非常に気になります。
以上です。
「ソース公開しているんだからいいじゃん!」って人、ホントすみません。
私も公開したいんですけど、自分への戒めの意味もあってとりあえずメモ書きしてみました。
まあこれもソース公開して共有する意味だとも思いますし、何かのためになれば、という感じです。
さて、自分も公開できるよう、がんばりますか…。
☆上記の内容は変化があれば、メンテナンスしようと思います。可能であれば。
【補足】
☆試してみたい
任天堂がサードパーティ向けに用意しているというAiLive社「LiveMove」。
DarwiinRemoteのhiroakiさん情報提供感謝です。
http://www.nintendo.co.jp/wii/topics/interview/vol4/ailive.html
http://www.ailive.net/papers/LiveMoveWhitePaper_jp.pdf
http://d.hatena.ne.jp/wapa/20061020/p1
コンテクストラーニング(context learning)ってあまり知らないんですが、手書き認識とかで使える技術は使えますよね。