toio.jsのモーションセンサー(姿勢角検出とシェイク検出)を使って画面上のルービックキューブを操作する


はじめに

昨年はtoioのDo!コンに参加させて頂きました。

こんな形でサンプルとして紹介して頂けたり、関連のYouTube配信等でも取り上げて頂き、楽しませて頂きました。

このコンテストは応募要件として、Scratchによる実装が必須でしたが、事前にアイデア審査があり、そちらではtoio.jsを使ってデモ動画を作成し実現性をアピールしていました1

toio.js

toioのキューブをBLE経由で制御するTypeScriptで書かれたライブラリです。型チェックが効くため効率的にプロトタイプができます。実際、上記コンテストのアイデア応募段階でも、キューブの最新の技術仕様2を参考に、

  • 簡易カードの読み取り (53d429bab)
  • 加速度指定付きモーター制御 (70dea04)

等をローカルで追加した上で、何か面白い動きはできないかと模索していました。

toioのプログラミングを取り巻く環境としては、キューブのBLEのCharacteristicの仕様が公開されており、toio.jsを使わなくとも直接コントロールできてしまうのと、toio SDK for Unityの方が積極的にメンテナンスされている印象で、実際toio.jsの更新も1年以上止まっているようです。

toio.jsにローカルで機能追加

スライドパズルからパズルつながりで、ルービックキューブにも興味を持ったのと、ローカルで修正を加えたtoio.jsの環境があったので

  • 「toioキューブ2台を両手で持って画面上のパズルを解く」

という体験を目指し、作りっぱなしの物がありました。今回Qiita初投稿という形で改めて整理してみます。

変更点1:Web Bluetooth 経由の2台接続

toio.jsはブラウザでも動作します3。以下の素晴らしい記事を参考にさせて頂きました。

ただ手元で試した限り2台接続には失敗しました。症状としてはこちらの問題(#318)と同じで、内部で利用しているnobleの実装が原因で、BLEのAdvertisingの再Scanが走らないようでした。SDKのAPIを無理やり変更して回避します。

変更点2:姿勢角検出(モーションセンサー)

ルービックキューブの各面を回転させる操作と回し心地(!?)は、是非toioのセンサーで実現したいものです。toioから取得できるセンサーの角度の詳細はこちらの記事が参考になります。

が、いざ試してみようとすると、toio.jsでは未実装。こんな感じで足してみました。

あとはWebのUIと繋げるだけです4。注意点は座標系の向きです。Webの場合CSSの座標は左手系で画面から向かってくる方向がZ軸の正になります。一方toioのスペックでは右手系でキューブの底に向かってZ軸が正です。

モーションセンサーのみでルービックキューブを操作

以上で最低限の準備は揃いました。早速2台のキューブを使って、1台には視点操作、もう1台には回転操作を割り当てて動作を見てみます。

6面あるルービックキューブの面から回転させる面を絞り込むのが難しいため、3面に限定して動作をみてみた様子がこちらです。

toioの姿勢角の推定値そのものは応答もよく精度は高そうです。が、姿勢角の値から回転方向への変換がときどき失敗したり、手でキューブを操作しているうちに徐々に回転させる軸がずれたりで、実用的な感じにはならなそうでした。そこで、他の入力(ボタンやシェイク検出)も合わせた操作も検討します。

変更点3:シェイク検出

キューブを振る動作が数値として取得できます。アプリで使い易い印象です。先ほどの姿勢角の変更と同様の実装をtoio.jsに追加します。

こちらも先ほどと同様にWebBluetoothでコントロールする記事がありました。

姿勢角検出とシェイク検出でルービックキューブを操作

候補面の選択

回転させる面を選ぶ良い方法が思い浮かばなかったので、明示的に選択することにしました。シェイク検出を使ってモードを切り替えるイメージで、予め回転させる面を指定します。

またモーションセンサーの結果が思い通りに取れなくても、ボタンを使って回転させられるようにもしてみました。

最終的な操作のアイデアは以下です。

  • 1台目のキューブ(視点操作とモード切り替え)
入力 取得できる値 操作での利用方法
モーションセンサ 姿勢角 画面上のルービックキューブの回転
シェイク検出 シェイクされた大きさのレベル 候補面選択モードとの切り替え
ボタン(予備) 長押し 押下時のみ候補面選択モードを表示
  • 2台目のキューブ(ルービックキューブの面の回転)
入力 取得できる値 操作での利用方法
モーションセンサ 姿勢角 選択された面の回転
シェイク検出 シェイクされた大きさのレベル 回転される候補面の切り替え
ボタン(予備) シングルクリック 選択された面を時計回りに回転
ダブルクリック 選択された面を反時計回りに回転

toio.jsの機能をフル活用して操作はできるようになりましたが、やはり姿勢角のみでキューブを操作したいところです5

最後に

今回は操作部分のみでしたが、ルービックキューブのデータ構造とか解法等、興味深い話題が多くまだまだ勉強が必要なようです。今年もtoioと並行して学びつつ、再度どこかを掘り下げてみたいと思っています。


  1. Do!コンアイデア応募動画 - https://youtu.be/N8ly1ICyyJo 

  2. toio™コア キューブ 技術仕様 - https://toio.github.io/toio-spec/ 

  3. 試せていないですが、p5.toio もあるようです。 

  4. https://codepen.io/Omelyan/pen/BKmedK を利用させて頂きました。 

  5. 角度の時間的な変化からキューブの操作へのマッピングの辺りにもう一工夫したかったです。