RasPi 戦車は、PS3 Dualshock3 コントローラーで操作できるようにしてあります。スマートフォンで WiFi 経由とか Bluetooth 経由が多い中で、コントローラーを使っているのは、まあ、ラジコンと同じ風に扱いたかったからです。これだと5歳児でも動かせますからね。PS3 Dualshock3 には、アナログスティックが2つと、上下ボタンと○×ボタン4個と…色々ついているので、車輪だけじゃない制御がしやすいそうってのもあります。サーボを制御してロボットアームを動かす予定もあって、これを使っています。
が、去年買ってみてあまり汎用的ではないので、どうせならば Bluetooth 対応のコントローラーを自作したほうがいいのですが…まあ、手元にあるということで。ちなみ、PS3 のコントローラは持っているけど、PS3 本体は持っていません。PS4 も持ってません。PS4 用の DualShock4 の場合はどうなるのか?は分からないので、持っている方は試してみてください。
Bluetooth の準備
基本は、
BrickPi + LOGO Mindstorms EV3 をゲームコントローラーでコントロールする(前編) | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5997
に書いてある手順の通りなのですが、おさらいも兼ねて、もう一度書き連ねておきます。RasPi のレポジトリも新しくなっているので。
apt-get で bluetooth 関連をインストール
1 2 | sudo apt- get install bluetooth bluez-utils bluez-compat bluez-hcidump sudo apt- get install libusb-dev libbluetooth-dev |
基本は bluetooth だけでいいはずですが、後の QtSixA のために libusb-dev あたりが必要です。
1 | /etc/init.d/bluetooth status |
で、きちんと bluetooth デーモンが動いているか確認します。
1 | lsusb |
で、Bluetooth ドングルが認識できることを確認。ここでは、Bus 001 Device 004 がそれです。
QtSixA のインストール
PS3 Dualshock3 用のドライバーを入れます。
QtSixA – Browse /QtSixA 1.5.1 at SourceForge.net
http://sourceforge.net/projects/qtsixa/files/QtSixA%201.5.1/
1 2 3 4 | tar -xvf QtSixA-1.5.1-src.tar.gz cd QtSixA-1.5.1/sixad make sudo make install |
今の環境ではきちんとビルドできて、sixpair まで出来上がります。
中身は、bluetooth SPP を解析しているだけだから、C# で書き直すのはそんなに難しくはないと思うんですよね。これは、RasPi で直接 Bluetooth を扱うときに試してみます。
PS3 Dualshock3 とペアリングする
ゲームコントローラーを USB で RasPi につなげて
1 | sudo sixpair |
を動かします。
Bluetooth ドングルの MAC ID が表示されます。MAC ID 自体は Windows 8.1 の PC に繋いでデバイスマネージャから確認できます。
動作させる。
ペアリング自体は、最初だけなので、その後はゲームコントローラーの USB を外しても大丈夫です。確か、つなげないで直接 MAC ID を書き込む方法もあります。
1 | sudo sixad -start & |
させます。うまく起動したら、ゲームコントローラーの PS ボタンを押せば接続できます。Dualshock3 の MAC ID が表示されます。
通信情報は、/dev/input/js0 に流れてくるので、
1 | sudo cat /dev/input/js0 |
接続を止める場合は、
1 | sixad -stop |
すれば大丈夫です。
コントローラーの通信を解析する
データ自体は以下の構造体で流れてきます。これをうまく読み取ってやれば、各種のボタンの判別がつきます。
1 2 3 4 5 6 7 8 9 10 11 | public struct js_event { public UInt32 time; /* event timestamp in milliseconds */ public Int16 value; /* value */ public byte type; /* event type */ public byte number; /* axis/button number */ public override string ToString() { return string .Format( "time:{0} val:{1} type:{2} num:{3}" , time, value, type, number); } } |
テストコード
https://gist.github.com/moonmile/7c44e5130617c7a76a87
ボタンの割り当てをしたのが上記になります。
このコードは以前書いたもので、ジョイスティックのチェックしかやっていませんが、今回の RasPi 戦車では上下左右ボタンにも対応させています。これは後述します。
同じものが飛んできたら捨てるような処理を入れればいいのです。