Toioがやってきた!
発表時から気になっていたToio (https://toio.io/ )を入手した。アメリカでは売っておらず、Amazon Japanのglobal shippingにも対応しておらず、結局国際転送サービスのお世話になった。これは絶対に楽しいに決まってるやつや!
こいつ、動くぞ!
めだま生物 https://t.co/q8XXH1bQ9d
— Tomoto S. Washio (@tomoto335) 2019年7月19日
遊んでみよう!
製品としての遊び方も丁寧に作られていて非常にハイクオリティなのだが、ここではもちろんハッカー流の遊び方の話である。
Toioのキューブは仕様書 (https://toio.github.io/toio-spec/ )が公開されていて、これに従ってBLEでキューブを制御できる。このキューブの特筆すべき点は、マット上に印刷された特殊なパターンとキューブに仕込まれたカメラにより、キューブの座標と姿勢を正確に把握できるということである。普通この手のロボットを正確な座標に向けて動かそうと思ったら、天井にカメラを付けて画像処理と組み合わせたり、かなりハードル高いのである。Toioならわりと簡単にこんな「一人サッカーロボット」とかできてしまう。
Toio project: Self-soccer Robot https://t.co/6gtgWZiquy
— Tomoto S. Washio (@tomoto335) 2019年7月19日
なお、キューブ操作用のライブラリは誰かが既に作っているかもしれないが、それに乗るだけでは「一番おいしいところを持ってかれる」ようなものなので自分で書く。車輪の再発明ドントコーイ(゚∀゚)!!
ソースコード
ここにどんどん放り込んでいくのでよろしく: https://github.com/tomoto/tomotoio
- 言語: Python 3.6
- OS: Linux (BLE通信にbluepyを使用しているので)
- ハード: Raspberry Pi 4 + Raspbian Stretchを使用。Windows 10上のVMwareではBLEが不安定で意図通り動かず。
- Python 3.6の仮想環境作って
pip install -e .
すれば使えるはず。
キューブのスキャン
このへん: https://github.com/tomoto/tomotoio/blob/master/tomotoio/scanner.py
接続先キューブのMACアドレスはあらかじめスキャンしてファイルに書いておく。どうせ持ってるキューブは固定なので、root権限が必要なスキャン操作を毎回走らせるのはnonsenseという考え。スキャン処理自体はbluepyの基本機能だけででき、何の変哲もない。
サンプルたち
この中にある: https://github.com/tomoto/tomotoio/tree/master/examples
簡単な順に紹介:
-
simple.py
接続と切断だけの最小のサンプル。 -
soundeffects.py
プリセットの効果音を順番に再生する。 -
notifications.py
位置・ボタン・動き情報のNotificationをコンソールにだらだら出力 -
rotate.py
キューブ#2の方向にキューブ#1を向ける。(めだま生物のキビキビ版) -
symmetric.py
キューブ#2の点対称の位置にキューブ#1を移動する。 -
circle.py
キューブ#2を中心にキューブ#1を周回させる。 -
soccer.py
上で紹介した一人サッカー。
なお utils.py
にあるのはお決まりの初期化処理。接続時にキューブに光と音で「番号、いち!に!」と言わせるのはここ。
基盤機能
キューブ操作
このへん: https://github.com/tomoto/tomotoio/blob/master/tomotoio/cube.py
インスタンスの入手は、このへん https://github.com/tomoto/tomotoio/blob/master/tomotoio/factory.py の関数にMACアドレスを指定して行う。以下のような操作ができる。
-
cube.xxx.get()
属性値(toioID, motion, button, battery)の取得 -
cube.xxx.enableNotification()
Notificationの有効化(属性値が変化するとcube.xxx.addListener()
で登録した関数が呼ばれる) -
cube.setXxx()
モーター、音、光などの設定 -
cube.release()
接続切断
「指定座標に移動」のような処理はこれだけではまだ難しいので、次回以降扱う。
BLE通信
このへん: https://github.com/tomoto/tomotoio/blob/master/tomotoio/blepeer.py
見ての通り、bluepyの薄いラッパ。Notificationの処理は下記のようにちょっとめんどうなのでここに隠蔽する。
- subscribeスレッドを上げて
waitForNotifications
呼び出しを回す -
writeCharacteristics
がwaitForNotifications
と被らないよう、write要求はスレッド間キューをかましてsubscribeスレッドの側で処理する
BLEメッセージのエンコードとデコード
このへん: https://github.com/tomoto/tomotoio/blob/master/tomotoio/messages.py
仕様書をひたすら写経しただけ。エンコード前・デコード後のデータの入れ物は https://github.com/tomoto/tomotoio/blob/master/tomotoio/data.py で定義。