今までずっとEuro Truck Simulator 2をXboxのゲームパッドで遊んでましたが、やっぱりハンドルを握りたいなぁ、と思ってハンドルコントローラー(通称ハンコン)を買ってしまいました。ハンドルだと高速道路の緩いカーブの操作がしやすくていいですね!しかし完璧とまではいきませんでした。
ウィンカーレバーがない!
こうゆうハンコンて主にレースゲーム向けのものなので、そもそもウィンカーって必要ないんですよね。でもETS2のような、まったりと道路を走るゲームには割と重要な要素なんです。交差点の右折左折や車線の変更、一般道から高速道への合流などなど、ウィンカーを使う場面が多いです。ハンコン上のボタンやシフトレバーパドルに割り当てることもできますが、ハンドルは回転するので、VRで手元が見えない状態ではやはり不便なのです。
バックするのにブレーキペダルを踏むのは変
私はオートマ派です。ゲームパッドのときは特に気にならなかったのですが、ハンコンにしてから、バックするときにブレーキペダルを踏むのに違和感がありました。これはトランスミッションの設定をシンプルオートマチックにしているためで、リアルオートマチックにすれば変更できます。しかしここで問題が。ギアのドライブ/リバースの設定でボタンを割り当てることはできるのですが、常にボタンが押されている状態でなければなりません。ハンコン上のボタンは押すのをやめればオフになってしまいます。
無ければ作ろう!
ということでここからが本題。今回はウィンカーレバーとギアを変更するシフトレバーを自作することにします。コントローラーはATOMS3を使い、BLE (Bluetooth Low Energy)でPCと接続します。ESP32-BLE-Gamepadというライブラリを使うと、デバイスを簡単にゲームパッド化できます。
今回使用したパーツ
- M5Stack ATOMS3
- M5Stack ATOMICプロトキット
- 3Pトグルスイッチ 中点OFF付 1回路2接点 パネル取付用 x2 →秋月電子
- レバー(3Dプリンターで作成)
- スイッチのケース(3Dプリンターで作成)
レバーとケースの作成
レバー部分とスイッチのケースは3Dプリンターで作成しました。STLファイルをこちらにアップしておきました。3Dプリントしたレバーをスイッチのレバーに填め込むのに、そのままだと入らないと思います。熱した鉄の棒(カーテンフックがGOOD)で樹脂を溶かしてスイッチに差し込むとうまい感じに溶けて固まってくれると思います。力ずくで押し込むとスイッチが壊れるので注意。
ATOMICプロトキットで配線
ATOMICプロトキットはATOMS3の底面にあるソケットから配線を引き出せるケースです。これを使えば綺麗に配線をまとめることができます。今回はウインカーの左・右、シフトの前・後で、計4個のGPIOを使用します。ATOMS3のGPIOの設定はプルダウンにして、スイッチがONになったときに3.3Vになるようにしています。写真でいうと赤い線が3.3Vです。
プログラム
続いてArduino IDEでプログラムを作成します。今回はBLE接続のゲームパッドとして動作させるために、はじめにESP32-BLE-Gamepadのライブラリをインクルードしておきます。プログラムは BLE_ETS2_GamePad.ino にアップしたので参考にしてみてください。
スイッチは中点つきに3点スイッチで、倒した方向に固定されるスイッチです。ETS2のボタン設定ではウィンカーは短押しですが、スイッチ側は倒した方にオン状態のままです。そこでスイッチが切り替わったことを検出して、1回ボタンを押すようにしています。bleGamepad.press() bleGamepad.release() でボタンの状態を指定するだけでできるの簡単でいいですね。
if (digitalRead(GPIO_WINKER_LEFT) && winker_last != 1) {
bleGamepad.press(BTN_WINKER_LEFT);
bleGamepad.release(BTN_WINKER_RIGHT);
sp("Winker: LEFT");
winker_last = 1;
autowinkeroff = millis() + 250;
update = true;
}
そして250ms後に押したボタンを離してます。これブログ書いてて気づいたんですけど…、delay()でもよかったですね。UnityだとUpdate()に1フレーム内で行う処理を書くので、delay()を入れないようにとちょっと勘違いしてました。まぁ動くのでこのままいきます。
シフトレバーについては、ドライブ・ニュートラル・リバースの3種類の状態を2つのボタンで指示します。こちらは単純にどちらがONになっているかだけで、同様にスイッチが切り替わったことを検出してボタンを押しています。前進する場合はドライブのボタンをオン、リバースのボタンをオフにします。
if (digitalRead(GPIO_GEAR_FORWARD) && gear_last != 1) {
bleGamepad.press(BTN_GEAR_FORWARD);
bleGamepad.release(BTN_GEAR_BACK);
sp("Gear: FORWARD");
gear_last = 1;
update = true;
}
bleGamepad.press() .release() でボタンの状態を送信する際に、loop() で回していると大量のデータが送信されてしまって、BLEの接続が不安定になってしまいます。このプログラムで static ~ xxx_last という変数は前の状態を保持する変数になっていて、状態が変化したときだけBLEのデータを送信しています。これで無駄にデータが飛ばなくなるので安定するはずです。
動作チェック
配線とプログラムの書き込みが完了したら、PCで動作チェックをします。はじめにBluetoothのデバイスをペアリングして、接続状態にしておきます。Bluetoothとデバイス>デバイス、その他のデバイスとプリンターの設定を開くと、デバイスの中にETS2 Gamepadというのがあります。右クリック→ゲームコントローラーの設定を開き、8軸16ボタンデバイスはっとスイッチ付きを選択してプロパティを開きます。そうするとボタンの状態を確認できる画面が表示されるので、ここでスイッチのレバーを動かしてみましょう。ボタンのところが反応すればOKです。
組み立て
ここまでできたらハンコン本体に取り付けます。今回作成したスイッチのケースはとても手抜きで、フタは接着剤(PLAなら二塩化メチレン)で固定します。ハンコンとの固定はアクリルフォーム両面テープが強力で、しかも剥がしやすくて跡も残らなくて便利です。
ウインカーレバーはハンドルと本体の間に固定します。ハンドルを握った状態のまま、指を伸ばせばレバーに当たる距離は、本物の車と同じ感覚で操作できます。今回ケースを自作したのは、ハンドルと本体の隙間に入れるためで、既製品のケースだとなかなかこのサイズのものが無いんですよね。この辺はこだわりポイントでもあります。
ETS2側の設定
私の場合1つ目のコントローラーをキーボード+ハンコン、2つ目のコントローラーをゲームパッドにしています。今回作成したコントローラーを3つ目に追加しました。
トランスミッションがリアルオートマチックの場合は、オートマチックギアボックスのドライブとリバースのところを設定します。
ウインカーもも同様に設定します。このJoy 3というのが、3番目のコントローラーのって意味らしいです。
あと、ATOMS3の本体のボタンもゲームパッドのボタンとして機能しています。私はトレーラーの連結に割り当ててます。VRだとハンコン上のボタンは見えなくて押しづらいので、手で触れてすぐに判別できるボタンだと押しやすいですね。まだATOMS3にはGPIOがたくさん余ってるので、改造されたい方は挑戦してみてください。
ウインカー自動オフを無効にする
こちらが今回の妥協箇所。ゲームプレイの設定でウインカーを自動で消灯のところのチェックを外します。この設定を有効にしていると、交差点を曲がってハンドルを戻したときに自動的にウィンカーを消してくれます。実際の車もこうですね。でもこれはウインカーレバーと相性が悪いのです。ウインカーレバーは倒すと片側に固定されているので、当然ですが勝手に戻りません。そうするとゲーム上では戻っているのに現実では戻ってない状態のままになってしまい、次に曲がるときにおかしくなります。
じゃあモーメンタリースイッチを使えばいいじゃん!そう思いますよね。実は最初にそうしていました。しかし実際にモーメンタリースイッチ(手を離すと中点に戻るスイッチ)でやってみると、車線変更でおかしくなります。車線変更のような大きくハンドルを切らない状況では、ゲーム上では自動的にウインカーは消えないので、そうすると出っ放しになってしまうのです。
ちょっと手間は増えますが、現実の動作とゲーム上の動作が一致している方が違和感がなくていいと思います。
快適な配送ライフを!
我ながら、最高のゲーム体験に進化しました!
ウインカーレバー、まじいいです!
2023.7.23 追記
3Dプリントモデルをアップデートしました。ファイルはThingiverseからダウンロードできます。