こんにちは。ソフトウェア担当のYDです。
今回は前回紹介したキューブがぐるぐる回るデモについて解説したいと思います。
▼前回の記事:CEDEC 2019で登壇およびデモ展示をしてきました。
https://note.toio.io/n/nad19d5a9beb2
リアルタイム絶対位置検出について
toio の大きな特徴の一つとして「リアルタイム絶対位置検出」があります。
これはマットの上に置かれたキューブの絶対位置と角度(向いている方向)をリアルタイムに検出する技術です。これらの情報を使うことでキューブを特定の位置に移動させたり、複数のキューブが互いを認識しているかのような動きを作ることができます。
キューブを特定の位置に移動させるには?
では具体的に特定の位置にキューブを移動させるにはどうしたらよいでしょうか?
キューブは左右のタイヤを前後に回転させて移動します。そのため真横には移動できず、特定の位置にキューブを移動させるためには左右のタイヤの回転のバランスを調整しながら動かす必要があります。
目標位置に対して左右のタイヤをどれくらい回転させるかについてはロボットのナビゲーションの分野で様々なアルゴリズムが開発されていますが、冒頭のデモでは非常に単純なアルゴリズムを使っています。
アルゴリズム全体の流れとしては次の3ステップで構成されます。
以下は実際に左右のタイヤの速度を計算するコード例(JavaScript)です。(このコードはtoio.jsのchaseサンプルで動作を確認できます)
// キューブ1とキューブ2の位置と方向の情報をもとに // キューブ2に与える左右のタイヤの速度を計算 function calculateSpeed(position1, position2) { // ① キューブ1とキューブ2の距離を計算 const diffX = position1.x - position2.x const diffY = position1.y - position2.y const distance = Math.sqrt(diffX * diffX + diffY * diffY) // ある程度近い場合は到達したと判定 // 50くらいだとぶつからずに止まります if (distance < 50) { return [0, 0] } // ② キューブ2に対するキューブ1の位置への角度を計算 let relAngle = (Math.atan2(diffY, diffX) * 180) / Math.PI - position2.angle // 便宜上、角度の範囲を[-π, π]に変換 relAngle = relAngle % 360 if (relAngle < -180) { relAngle += 360 } else if (relAngle > 180) { relAngle -= 360 } // ③ 進行方向に合わせて左右のタイヤの速度比を計算 const ratio = 1 - Math.abs(relAngle) / 90 // 基準速度を決めて左右のタイヤの速度を計算 const speed = 80 if (relAngle > 0) { return [speed, speed * ratio] } else { return [speed * ratio, speed] } }
(コメント・空行を省くと約20行!)
ステップ③のratioやspeedの値を工夫することで、「蛇行しながら進む」「ゆっくり近づいて止まる」などの動きを付けることができます。
また、この処理で得られた速度でキューブを動かしますが、動かすとキューブ同士の位置関係が変わるので再度計算が必要です。デモでは50msごとに速度の計算とキューブへのタイヤの回転指示を行っています。
6台ぐるぐるデモの構成
最後に冒頭でも紹介した6台ぐるぐるデモの構成について簡単に紹介します。
使っているもの
・ MacBook Pro x 1
・ toio 本体セット x 3 (toio コア キューブ x 6)
・ トイオ・コレクション x 1 (同梱マット x 1)
このデモでは6台のキューブをMacBook Proに接続し、50msごとにそれぞれ前のキューブとの位置関係から各キューブの左右のタイヤの速度を計算し、移動の指示をしています。
キューブとしてはMacBook Proと接続して位置情報を送り、MacBook Proから送られてきた速度指示の通りにタイヤを回転させているだけです。
一方、MacBook Proは6台のキューブと接続し、キューブを配列で管理して頭から2つづつ取り出して速度計算をしています。(マットに置いたときに一番近いキューブを追いかけるように配列に入れるときに工夫しています)
まとめ
以上がキューブがぐるぐる回るデモの解説でした。ここで紹介したアルゴリズムは、キューブを特定の位置に移動させたい時にお勧めです。toio.jsのサンプルにも入っているので是非参考にして、独自の動きへの拡張など試してみてください。
今回の解説はここで終了ですが、技術的に解説したいトピックができたときにはまたnote記事にしたいと思います。「こういう話が聞きたい!」という要望があれば、是非コメント欄や公式ツイッターまでお寄せください。よろしくお願いします!