#toio の目標指定付きモーター制御の仕様を確認して使ってみる（ #GWアドベントカレンダー 5/3 ） #おうちでロボット開発

こちらは、[下記の #GWアドベントカレンダー](https://gw-advent.9wick.com/calendars/2020/69) の 5日目の記事です。

●日数分だけ記事を書く！（ @youtoy ） | GWアドベントカレンダー
　https://gw-advent.9wick.com/calendars/2020/69

## はじめに
この記事は[ロボットトイの「toio」](https://toio.io/)に関する開発で、以下の記事でも使った「開発者向けマット（仮）」を活用するための下調べの過程を記録したものです。

●[#toio の開発者向けマット（仮）をビジュアルプログラミングで使ってみる（ #GWアドベントカレンダー 5/2 ） #おうちでロボット開発 - Qiita](https://qiita.com/youtoy/items/cb018dd44bf3e533e42b)

この専用マットは下記のキャンペーンで入手したものになりますが、後日、スイッチサイエンスさんで販売される予定があるようです。
　[●スイッチサイエンス「toio」取り扱い開始記念～「toio」ではじめよう、おうちでロボット開発キャンペーン～ – スイッチサイエンス マガジン](https://mag.switch-science.com/2020/04/23/robot-programming-with-toio/)

### ビジュアルプログラミングでマットの座標を扱う

上記の記事の中では、ビジュアプルプログラミングで toio の開発を行い、そこでは開発者向けマット（仮）上の座標指定の仕組みの細かな部分は、それほど意識することなく利用できていました。
補足すると、位置座標を指定する処理も現在の位置座標を取得する処理も、プログラミングで使うブロックを見れば座標の値の指定・取得をどう組み立てれば良いかが分かる感じでした（※以下の画像の部分）。
<img width="331" alt="座標指定をビジュアプルプログラミングで.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/941d7574-1911-56e1-9b8e-e8abbac6d0d3.jpeg">

### toio.js でマットの座標を扱う

また、[公式の JavaScriptライブラリ（toio.js）](https://github.com/toio/toio.js)を利用する場合も、GitHubの「[/examples/chase](https://github.com/toio/toio.js/tree/master/examples/chase)」の[ソースコード（index.js）](https://github.com/toio/toio.js/blob/master/examples/chase/index.js)を見てみると、以下の赤矢印で示した部分などが関連していそうです。
サンプル・ライブラリを活用して開発をする分には、座標情報の取得などは割とシンプルに行えそうな感じがします。
<img width="421" alt="toio.jsでの位置座標情報.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b16e00ae-3938-0d43-0ea5-672d88470749.jpeg">

### 上記以外の方法でマットの座標を扱う

あとは、[過去の作品](https://qiita.com/youtoy/items/37f70bb4ce630e6cbd92)でも使ったPC等のブラウザ上で動くプログラムから [Web Bluetooth API](https://webbluetoothcg.github.io/web-bluetooth/) を使って制御するパターン等もありますが、こちらは toio 関連の処理部分にはライブラリ等を用いず開発するため、BLE通信の仕様を見て対応する必要があります。
この通信の仕様を見ながらの開発という話は、これ以降に少し深掘りしていきます。

なお、昨年の「[toio™(ロボットトイ | toio（トイオ）) Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/toiotomo)」の記事などに、ライブラリが出されていない 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つ目のほうの「[目標指定付きモーター制御](https://toio.github.io/toio-spec/docs/ble_motor#%E7%9B%AE%E6%A8%99%E6%8C%87%E5%AE%9A%E4%BB%98%E3%81%8D%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E5%88%B6%E5%BE%A1)」のところを見れば良さそうです。

全体像は以下の部分（2020年5月3日現在）に書かれています。
<img width="520" alt="モーター_·_toio™コア_キューブ_技術仕様_目標指定.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/13e0289c-1f59-2458-f6cc-b6251b925e47.jpeg">
そして、上記の表の「内容」の列に関する補足も書かれています。
例えば「移動タイプ」という項目は、以下の動きを指定することができるもののようです。
<img width="524" alt="モーター_·_toio™コア_キューブ_技術仕様_移動タイプ.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e0c0104e-d438-55bf-a423-645cfa3c5c4a.jpeg">

## 開発者向けマット（仮）の仕様を確認する
開発者向けマット（仮）の座標の値は、以下のページで確認できます。
　[●『「toio」ではじめよう、おうちでロボット開発キャンペーン』と『開発者向けマット（仮称）』について｜toio™公式](https://note.toio.io/n/n15ace43c69e6)

今回、「#1」のマットの表面を利用してみることにします。
<img width="640" alt="マットの座標.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1bf70012-2822-a22f-8184-71afc7d877f9.jpeg">
上記の仕様によると、x座標の範囲が 98〜402 で、y座標の範囲が 142〜358 となるようです。

## ブラウザからのモーター制御でマット上の座標指定を利用する
[過去の作品](https://qiita.com/youtoy/items/37f70bb4ce630e6cbd92)の[ソースコード](https://github.com/yo-to/API_Test/blob/master/WebAPI/test10_test09_and_AudioRecognition/test02_c.html)でモーターの制御は仕様「[時間指定付きモーター制御](https://toio.github.io/toio-spec/docs/ble_motor#%E6%99%82%E9%96%93%E6%8C%87%E5%AE%9A%E4%BB%98%E3%81%8D%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E5%88%B6%E5%BE%A1)」を使っていました。そして、[そのソースコード](https://github.com/yo-to/API_Test/blob/master/WebAPI/test10_test09_and_AudioRecognition/test02_c.html)中でのモーター制御用データ（バイト列）は以下の部分でした。

```JavaScript
// 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 ]);
```

```JavaScript
const motor_buf_a = new Uint8Array([ 0x02, 0x01, 0x01, 0x14, 0x02, 0x01, 0x14, 0x1A ]); // 仕様： https://toio.github.io/toio-spec/docs/ble_motor
```

これを「[目標指定付きモーター制御](https://toio.github.io/toio-spec/docs/ble_motor#%E7%9B%AE%E6%A8%99%E6%8C%87%E5%AE%9A%E4%BB%98%E3%81%8D%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E5%88%B6%E5%BE%A1)」のためのデータに書きかえてみます。
今回の記事でこの部分の詳細は割愛しますが、書きかえ後の内容（※絶対位置座標を指定したものを3つ準備）と、それを使って toio の制御を行った結果の動画は以下となります。

```JavaScript
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 ]);
```

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブラウザで動く JavaScript のプログラムで、Web Bluetooth API を使い <a href="https://twitter.com/hashtag/toio?src=hash&amp;ref_src=twsrc%5Etfw">#toio</a> を制御。<br><br>以前、単純な移動と回転は実装したことがありましたが（機械学習を組み合わせたもの）、今回は先日入手した toio用の開発者向けマット（仮）を使い、座標指定での移動を実装。<a href="https://twitter.com/hashtag/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E9%96%8B%E7%99%BA?src=hash&amp;ref_src=twsrc%5Etfw">#おうちでロボット開発</a> <a href="https://twitter.com/hashtag/toiotomo?src=hash&amp;ref_src=twsrc%5Etfw">#toiotomo</a> <a href="https://t.co/xsDrNbKcKR">pic.twitter.com/xsDrNbKcKR</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1256963911158345729?ref_src=twsrc%5Etfw">May 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

上記の動画の内容を実装する中で 1点、ハマってしまった部分がありました。
仕様の以下のページで「[データ構造の表記](https://toio.github.io/toio-spec/docs/ble_how_to_communicate#%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%AE%E8%A1%A8%E8%A8%98)」に「[タイプ](https://toio.github.io/toio-spec/docs/ble_how_to_communicate#%E3%82%BF%E3%82%A4%E3%83%97)」に書いてあるとおり「バイトオーダーは全てリトルエンディアン」となります。
　●機能の利用 · 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 を使った開発で軽く試してみました。
試したのは簡易なものだったため、もう少し踏み込んだ内容もやっていければと思います。