はじめに
昨年はtoioのDo!コンに参加させて頂きました。
#Doコン の応募作品を #toioDo のサンプルとして掲載して頂きました。ありがとうございます!
— devdelights (@devdelights_) June 21, 2021
https://t.co/ThObMUy2Tf
こんな形でサンプルとして紹介して頂けたり、関連のYouTube配信等でも取り上げて頂き、楽しませて頂きました。
このコンテストは応募要件として、Scratchによる実装が必須でしたが、事前にアイデア審査があり、そちらではtoio.jsを使ってデモ動画を作成し実現性をアピールしていました1。
toio.js
toioのキューブをBLE経由で制御するTypeScriptで書かれたライブラリです。型チェックが効くため効率的にプロトタイプができます。実際、上記コンテストのアイデア応募段階でも、キューブの最新の技術仕様2を参考に、
等をローカルで追加した上で、何か面白い動きはできないかと模索していました。
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と並行して学びつつ、再度どこかを掘り下げてみたいと思っています。
-
Do!コンアイデア応募動画 - https://youtu.be/N8ly1ICyyJo ↩
-
toio™コア キューブ 技術仕様 - https://toio.github.io/toio-spec/ ↩
-
https://codepen.io/Omelyan/pen/BKmedK を利用させて頂きました。 ↩
-
角度の時間的な変化からキューブの操作へのマッピングの辺りにもう一工夫したかったです。 ↩