路線バス運転シミュレータ開発記

OMSIを使って路線バスの運転シミュレータを製作しています。備忘録的にゆるーく書いていきたいと思いますので、お付き合いいただければ幸いです。

スイッチによる入力について

ウインカーなど物理的なスイッチによってOMSIを制御したい場合、以下のようにいくつかの方法が考えられます。

1)スイッチをarduinoに接続して入力値を監視し続け、取得した値で毎回OMSIの内部値を上書きする方法
2)スイッチをarduinoに接続して入力値を監視し続け、状態が変化したらキーイベントを発生させる方法
3)スイッチがONになったと同時にキーイベントを発生させる方法

この中で一番理想的なのは1)で、この方法だと何もしなくても物理的なスイッチの状態とOMSIの状態が常に一致するので問題ありません。
一方、2)と3)の方式は初期値を物理スイッチとOMSIで合わせていないとあべこべな動作になってしまうのが難点です。

しかし、今回はOMSIの内部値を変更する方法がわからなかったので2)と3)を採用することにしました。
出力ピンからOMSIの状態を取得して、物理スイッチの入力とともに論理回路(ANDとか)を通して一致していれば入力とみなすというように工夫することも考えましたが、面倒だったのでやめました。
あるいはHW的にやらなくてもSW的にも同様なことができますが、入出力ピンが減るのが嫌でやめました。

2)の方法はトグルスイッチのようにON/OFFを切り替えるような場合に使い、3)は押しボタンのように一瞬だけONになるような場合に使えます。

一般的にマイコンで入力回路をつくるときは、単に入力ピンにスイッチをつなぐだけではなく、プルアップ抵抗あるいはプルダウン抵抗が必要になります。
これは回路がどこにも接続されず入力値が不定にならないようにすべての入力ピンに必要なのですが、幸いarduinoの場合はプルアップ抵抗が内蔵されているので省略できます。setup()の中でpinModeを設定する際に第2引数でINPUT_PULLUPを指定し、入力ピンにスイッチを取り付け、もう一方をGNDに接続するだけで完了です。この場合、スイッチがONになった場合LOWになり、スイッチがOFFになった場合HIになります。

f:id:poplar1930:20210829142238p:plain

それと、KOMSIは基本的にArduino Mega2560を使うことを前提としていますが、このタイプはキーボード入力のエミュレーションができないので、入力については別途Leonardoなどのキーボードエミュレーションができるボードを用意する必要があります。当初はMega2560をそのまま使い、COMポート経由でPCに文字を送信して、PC側で常駐しているアプリがキーイベントを起こすような仕組みを考えたのですが、結局テキストエディタではうまくいっても、OMSIでは動作しませんでした。フリーで配布されていたこの常駐アプリはおそらく内部的にアクティブになっているウインドウに対してウインドウメッセージを送信するようなつくりになっているのではないかと思うのですが、OMSIはキーボードの押下状態を直接見に行っているらしく、この方法ではうまくいきませんでした。

あとはif文で入力ポートを見に行ってその状態によってキーイベントを起こすようなロジックを書いていきます。Keyboard.press()によってキーが押された状態をつくりだし、Keyboard.release()でキーを離すような感じで難しいことはありません。ただ、注意しないといけないのがKeyboard.press()とKeyboard.release()の間に50msくらいのディレイを入れないとキーを押して離したというようにPCに認識されないようです。

それと似た関数でKeyboard.write()とかKeyboard.println()というものがありますが、これらは内部的な動作が異なるようでテキストエディタに文字を打つことはできるのですが、OMSIではこれらの関数を使ってもキーボードイベントとして認識しませんでした。

また、Keyboard.press()で押したい文字を指定するとき、通常は小文字を指定します。ここで大文字を指定するとOMSI上では[Shift]を押しながらそのキーが押されたと認識するので注意が必要です。

 実際動かしてみるとわかるのですが、このままではOMSIを使っていない時にスイッチを操作するとアクティブになっているウインドウにキーが入力されてしまいます。それを回避するためにキースイッチがONになっているときだけキーイベントを起こすようにしています。 

 

※キーボードのエミュレーションについては以下のサイトを参考にさせていただきました。

qiita.com

qiita.com