M5StickC 3Dマウスを動かしてみる
目次
M5StickC 3Dマウス
M5StickCの6軸慣性センサMPU6886(加速度センサ3軸、ジャイロセンサ3軸)を利用して、3Dマウスを作成されている方がいらっしゃる。
動画でかなり精度よく3Dオブジェクトを操作、クリックできている。
ソースコード
M5StickCを水平に設置した際に、XY方向の加速度(重力)の大きさにより、マウスの移動方向を決定している。
初めはX方向、Y方向のジャイロセンサを利用していると思った、Y方向の回転によりマウスが上下するのは良いが、X方向の回転でマウスが動作しないため、違和感を感じてソースを見てみると、XY方向の重力の大きさでマウスを上下・左右に動かしていた。
ジャイロでも良いと思われる。
HID OVER GATT (BLE入力)がうまくできない場合
技術的には、HID OVER GATTという通信規格を使っています。
GATT対応のBluetoothデバイスがあるPCで「Bluetoothデバイスを追加する」を押すと、
ESP32 BLE Keyboardという名称が見えるると、後は選択すれば接続が完了します。
ただし、接続されていてもキー入力できない場合があります。
その場合、デバイスマネージャからBluetooth関連の全てのデバイスを削除するのが良いです。(PC再起動しなくとも基本的に接続できます)
PCに接続されたBluetoothデバイスのドライバは自動で追加されます。
また、BLEデバイスもデバイスを追加した際に、ドライバが自動で追加されます。
Windows10の場合、外部からドライバを追加インストールする必要はありません。
(追加で入れると相互に影響する可能性があるので入れないほうが良いです。自分はこれで接続できずにはまった気がします。)
所感
Fantazy Earth ZeroというMMO対人ゲームのコントローラに利用したいと思っており、視点移動・スキル実行を行う際、マウス一つでは加速度かジャイロを用いた視点移動程度しかできず、8つのスキルをM5StickC側で区別して入力する手立てがない。
やはり、マウス入力はBLEで行っており、コードはキーボード用、マウス用、ゲームパッド用の3つがある。
視点移動・スキル実行を一つのM5StickCで行う場合、①マウスで視点移動/キーボードでスキル実行、もしくは②ゲームパッドで全てを行う必要がある。
②の場合、視点移動は3Dマウスのソースを活用させてもらえばよい。その場合、スキル実行はボタンを押しながらの加速度の変化に応じて特定の入力を行う。
①の場合、視点移動は3Dマウスのソースに加え、加速度の変化に応じて特定の入力を行う。
まずは①からやってみよう。
最終的に4パターン程度あるため、何が良いかは順次試す必要がある。
①+加速度のみ
①+ジャイロも利用
②+加速度のみ
②+ジャイロも利用
Pitch/Roll/Yawの取得
3Dマウスは加速度を利用しているが、Pitch/Roll/Yawを直接取れないものかと思った。M5.IMU.getAhrsData()でPitch/Roll/Yawを直接取得できるようだが、Yaw方向にドリフト誤差ががあるようだ[1]。
[2]を参考に、M5StickCで取得した値をMadgwickフィルタで処理してみた所、赤Roll 青Pitch 緑Yawとなり、Yawの傾きが大きくドリフト誤差が生じている。
[3]を参考にオフセットを入れてみるとかなり良くなった。
尚、地磁気センサは利用していません。
青線(roll)は0度-180度と180度の境目のためスパイクが立っているが、誤差は少ない。
[1]M5StickC(MPU6886)+ENV Hatで6+3軸IMUの値を取得する - Qiita
[2]パソコン上のM5Stackの3Dモデルを、M5Stackの動きに合わせて動かす - AmbientでIoTをはじめよう
[3]M5StickC(MPU6886)+ENV Hatで姿勢推定する(Madgwickフィルタ編) - Qiita
FEZのインターフェイスへの利用
BLE 3Dマウス
◎ Aimモードでの動作はある程度マウスと同じようにできる。微調もできる。6軸姿勢推定では積分誤差が大きくなってくるので、加速度だけを利用したほうが良いと思われる。9軸姿勢推定では問題ない?
△ BLEマウスのソースコードがキー入力に対応していないため、任意スキルの実行ができない。BLEキーボードかBLEゲームパッドを同時に動かせられればよいが、現状できない。→口述するように二台でやってみている。
△ WIndowsへの左クリック、右クリック、ホイールクリック、進むクリック、戻るクリックは100%効くが、FEZ上だと30%程度の確率でしか成功しない。BLEの送信頻度を変更しても変わらない。原因不明。そのため、クリックでスキル実行するには、クリック入力を連続して30回程度は行う必要があり、この場合成功確率は 10万回に3回失敗する程度。1-(1-0.3)^10=0.9999
△ ホイール移動 move(0,0,1) or move(0,0,-1)は FEZでは連続実行できない。
delayを5msまで入れてみたが効果がない
BLE ゲームパッド
〇 Aimモードで視点移動ができるが、微調はマウスに劣る。
〇 任意のキー入力もできる。
△ 視点を滑らかに動かせない
BLE キーボード
× 視点移動ができない。
BLEゲームパッドで進めることにする。
BLE 3Dゲームパッド(左手) + BLE マウス(右手)
〇:移動(左手)と視点(右手)を行える。
マウスのスキル選択・実行が失敗することが多いため、スキル選択を20回選択→30ms待機→スキル実行を20回実行にした。これでレート30Hzまでなら問題ない。
〇:微妙な視点移動ができる。
移動は加速度。
視点はジャイロの加速度により細かい制御、ジャイロ速度により早い移動をできるようにした。
×: ポケット3/4が使えない
BLE キーボード(左手) + BLE マウス(右手)
〇:移動(左手)と視点(右手)を行える。
サンプリングレート30Hzなら問題ないが、それ以上だとパケット衝突のためかBLE キーボードの入力が遅れているかもしれない?
→スキル実行は遅れるため、2台同時は非常に難しい。2台動かすには、スキル実行や選択がなぜ100%成功しないのか、ライブラリを解読するなどして突き止める必要がある。
×:キーボードもマウスもスキル実行時、ある程度連続送信しないとスキル実行されない。
〇:ポケット3/4が使える?
USB DDRマット + BLE マウス(右手 )
〇:移動(足)と視点(右手)を行える。
×: ポケット3/4が使えない
所感・残務
1.キー入力が遅れる場合のデバッグ用にサンプリングレートを変更できるようにする。
→30Hz程度なら特に問題ない。
2.キー入力の失敗
ゲーム依存なのかスキル選択・実行は失敗することがある。連続実行により対応する。
3.キー入力は加速度のみで判定しており、誤判定/未実行がかなり発生するため、変位で検出してみる。参考 [Arduino] IMUから速度と角度を求める - Qiita
→ 移動平均により平滑化した。
4.視点変更を誤差のある6軸RPYで無く、加速度のみにしてみる。
→ ジャイロ速度の利用により、微妙な操作が可能。
5.視点変更を9軸RPYにしてみる
6.Boothに出店