こちらは、下記の #GWアドベントカレンダー の 5日目の記事です。
●日数分だけ記事を書く!( @youtoy ) | GWアドベントカレンダー
https://gw-advent.9wick.com/calendars/2020/69
はじめに
この記事はロボットトイの「toio」に関する開発で、以下の記事でも使った「開発者向けマット(仮)」を活用するための下調べの過程を記録したものです。
●#toio の開発者向けマット(仮)をビジュアルプログラミングで使ってみる( #GWアドベントカレンダー 5/2 ) #おうちでロボット開発 - Qiita
この専用マットは下記のキャンペーンで入手したものになりますが、後日、スイッチサイエンスさんで販売される予定があるようです。
●スイッチサイエンス「toio」取り扱い開始記念~「toio」ではじめよう、おうちでロボット開発キャンペーン~ – スイッチサイエンス マガジン
ビジュアルプログラミングでマットの座標を扱う
上記の記事の中では、ビジュアプルプログラミングで toio の開発を行い、そこでは開発者向けマット(仮)上の座標指定の仕組みの細かな部分は、それほど意識することなく利用できていました。
補足すると、位置座標を指定する処理も現在の位置座標を取得する処理も、プログラミングで使うブロックを見れば座標の値の指定・取得をどう組み立てれば良いかが分かる感じでした(※以下の画像の部分)。
toio.js でマットの座標を扱う
また、公式の JavaScriptライブラリ(toio.js)を利用する場合も、GitHubの「/examples/chase」のソースコード(index.js)を見てみると、以下の赤矢印で示した部分などが関連していそうです。
サンプル・ライブラリを活用して開発をする分には、座標情報の取得などは割とシンプルに行えそうな感じがします。
上記以外の方法でマットの座標を扱う
あとは、過去の作品でも使ったPC等のブラウザ上で動くプログラムから Web Bluetooth API を使って制御するパターン等もありますが、こちらは toio 関連の処理部分にはライブラリ等を用いず開発するため、BLE通信の仕様を見て対応する必要があります。
この通信の仕様を見ながらの開発という話は、これ以降に少し深掘りしていきます。
なお、昨年の「toio™(ロボットトイ | toio(トイオ)) Advent Calendar 2019 - Qiita」の記事などに、ライブラリが出されていない C# や Rust といった言語で実装した話がありましたが、本記事と同様に通信仕様を見て実装する流れになるものだと思います。
toio の通信仕様のモーター制御まわりを確認する
toio は仕様が公開されており、移動に使うモーター制御などの利用可能な機能の情報やデータのやりとりの情報は、以下のページで概要が書かれています。
●通信概要 · toio™コア キューブ 技術仕様
https://toio.github.io/toio-spec/docs/ble_communication_overview
●機能の利用 · toio™コア キューブ 技術仕様
https://toio.github.io/toio-spec/docs/ble_how_to_communicate
そして、マット上での座標指定を行うのに関係しそうなページは、以下のものがあります。
●読み取りセンサー · toio™コア キューブ 技術仕様
https://toio.github.io/toio-spec/docs/ble_id
●モーター · toio™コア キューブ 技術仕様
https://toio.github.io/toio-spec/docs/ble_motor
今回の座標指定関連は、上記の2つ目のほうの「目標指定付きモーター制御」のところを見れば良さそうです。
全体像は以下の部分(2020年5月3日現在)に書かれています。
そして、上記の表の「内容」の列に関する補足も書かれています。
例えば「移動タイプ」という項目は、以下の動きを指定することができるもののようです。
開発者向けマット(仮)の仕様を確認する
開発者向けマット(仮)の座標の値は、以下のページで確認できます。
●『「toio」ではじめよう、おうちでロボット開発キャンペーン』と『開発者向けマット(仮称)』について|toio™公式
今回、「#1」のマットの表面を利用してみることにします。
上記の仕様によると、x座標の範囲が 98〜402 で、y座標の範囲が 142〜358 となるようです。
ブラウザからのモーター制御でマット上の座標指定を利用する
過去の作品のソースコードでモーターの制御は仕様「時間指定付きモーター制御」を使っていました。そして、そのソースコード中でのモーター制御用データ(バイト列)は以下の部分でした。
// toio のモーターの仕様: https://toio.github.io/toio-spec/docs/ble_motor
const motor_buf_01 = new Uint8Array([ 0x02, 0x01, 0x01, 0x0A, 0x02, 0x01, 0x0A, 0x32 ]);
const motor_buf_02 = new Uint8Array([ 0x02, 0x01, 0x01, 0x14, 0x02, 0x02, 0x14, 0x32 ]);
const motor_buf_03 = new Uint8Array([ 0x02, 0x01, 0x01, 0x50, 0x02, 0x02, 0x50, 0x32 ]);
const motor_buf_04 = new Uint8Array([ 0x02, 0x01, 0x01, 0x14, 0x02, 0x02, 0x14, 0x32 ]);
const motor_buf_a = new Uint8Array([ 0x02, 0x01, 0x01, 0x14, 0x02, 0x01, 0x14, 0x1A ]); // 仕様: https://toio.github.io/toio-spec/docs/ble_motor
これを「目標指定付きモーター制御」のためのデータに書きかえてみます。
今回の記事でこの部分の詳細は割愛しますが、書きかえ後の内容(※絶対位置座標を指定したものを3つ準備)と、それを使って toio の制御を行った結果の動画は以下となります。
const motor_buf_a1 = new Uint8Array([ 0x03, 0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0xf5, 0x00, 0xf5, 0x00, 0x5a, 0x00 ]);
const motor_buf_a2 = new Uint8Array([ 0x03, 0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0x78, 0x00, 0xa0, 0x00, 0x00, 0x00 ]);
const motor_buf_a3 = new Uint8Array([ 0x03, 0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0x5e, 0x01, 0x5c, 0x01, 0x5a, 0x00 ]);
ブラウザで動く JavaScript のプログラムで、Web Bluetooth API を使い #toio を制御。
— you (@youtoy) May 3, 2020
以前、単純な移動と回転は実装したことがありましたが(機械学習を組み合わせたもの)、今回は先日入手した toio用の開発者向けマット(仮)を使い、座標指定での移動を実装。#おうちでロボット開発 #toiotomo pic.twitter.com/xsDrNbKcKR
上記の動画の内容を実装する中で 1点、ハマってしまった部分がありました。
仕様の以下のページで「データ構造の表記」に「タイプ」に書いてあるとおり「バイトオーダーは全てリトルエンディアン」となります。
●機能の利用 · toio™コア キューブ 技術仕様
https://toio.github.io/toio-spec/docs/ble_how_to_communicate
そのため、仕様で「タイプ:UInt16、内容:目標地点の X 座標値」の部分に「10進数の 250、16進数の f5」を指定する場合「Uint8Array
」での指定では「0x00, 0xf5
」ではなく「0xf5, 0x00
」と書く必要がありました。
おわりに
今回、toio の目標指定付きモーター制御の仕様を確認して、Web Bluetooth API を使った開発で軽く試してみました。
試したのは簡易なものだったため、もう少し踏み込んだ内容もやっていければと思います。