2019年8月11日日曜日

USB HID

 日頃の行いの悪さを悔いる今日このごろ。PC調子悪いし、インターネット調子悪いし、その他諸々。

 まぁ、それはさておき。

 久しぶりにSTM32で遊んでる。
 CubeMXでUSB device HIDのテンプレートを出して、レポートディスクリプタを書き換えてみた。とりあえずボタン1個のデバイスは動いたので、なんとかなりそう。
 HIDのレポートデスクリプタは、usb.orgが配布してるHID Descriptor Tool (DT)というツール(使いづらい!)を使って生成できる。転送したデータの何バイト目はどういうデータですと、というのをDTで定義してやるのだが、XY軸やボタン以外にも、Throttleとかも定義できる。なるほど、市販のジョイスティックをフライトゲートかにつないでいきなりスロットルやヨーに適切に割り当てられるのはこういう仕組みなのか。

 ところで、スロットル以外にも、様々な種類がある。多すぎて列挙するのが面倒なのだが、シミュレーター類で使われるコントロールはsim.upgファイルに定義されている。前半の方はシミュレーターの種類、後半はシミュレーターで使われる操作、の定義のようだ。
 シミュレーターの種類というのは、例えば飛行機だったり、自動車だったり、戦車だったり、宇宙船や潜水艦、ヨット、バイク、ヘリコプター、あげくのはてには"Magic Carpet"(魔法のじゅうたん)なんてモノまで定義されている(そんなデバイスがあるのか?)。複数のコントローラーが接続されている場合、ゲーム側はこの種類を見てデフォルトのコントローラーを決定するのかもしれない。
 操作の種類だと、エルロン、エルロントリム、チャフ、コレクティブ、エレベーター、ラダー、といった基本的なものから、ウェポンアーム、ウェポンセレクト、みたいなものもある。フラップは有るがスポイラーは無いあたり、あまりしっかりと定義しているわけではなく、よく使われる操作だけ定義しているようだ。そういうのが必要なら適宜適当な軸を割り当てろ、ということなのだろう。

 他にも、gaming.upgにはゲームコントローラーの操作が割り当てられている。ピンボールとか、ガンデバイスとか。
 さすがゲームデバイスの定義だけあって、銃の操作だけで7種類もある。Bolt、Clip(リロード?)、Selector、Single Shot、Burst、Automatic、Safety、とか。おそらくアナログ軸だと思うので、Selectorの位置によってSafe/Single/Burst/Autoを切り替えるような実装でも良さそうな気がする。Safe/Single/Burst/Autoにそれぞれ操作を割り当てるにしても、トリガー操作はOn/Offの2値だから、ボタンで割り当ててもいい気がする。あるいは、トリガープル(シアが落ちる距離)を調整できるようにアナログ系になってるんだろうか? 右側のトリガーを引けばセミオート、左側のトリガーを引けばフルオート、トリガープルは左右で独立して調整可能、みたいなゲーミングデバイスが存在するんだろうか。


 さて、それ以外のベーシックな操作は、desktop.upgに定義されている。アナログで使えそうな名前は10個程度かなぁ。
 A-10やF/A-18、F-15とかをイメージしたジョイスティックではスロットルを2本備えた物もあるから、同じ操作も重複して定義できるのかもしれないが、そうすると左右の定義とかがどうなるんだろうか? 1つ目のスロットルが左側、2つ目のスロットルが右側、みたいな割当になるんだろうか。同じ名前が重複できるとはいえ、Xを2個とか定義しても混乱の元だろうしなぁ。

 あとは、ボタンに関しては、最大で63個まで定義できるようだ。普通のゲームコントローラーで考えれば63個もあれば十分だろうが、コックピットのパネルを再現する、とかだとちょっと厳しい気がする。もっとも、機能ごとにデバイスを分割してやればなんとかなりそうな気もするが。


 STBee F4miniとかを使う場合、アナログ入力は9本くらいは確保できるはず。2値入力はマトリクスにすれば64個くらい余裕なはず。

 自作ゲームコントローラー用のプログラム書き込み済みの基板を買おうかと思っていたが、どうやらそうする必要はないようだ。

 あとは大量のボタンを用意して、キートップをどうにかして、配置をどうにかして…… うーん、やることがたくさん……
 キートップは3Dプリンタで作れるが、キーを並べるベースプレートをどうするかなぁ。3Dプリンタでそれっぽいのを作ってもいいけど、キーピッチ19mmとすると15cmのワークエリアだと36キーが限界になる。MDFのレーザー加工を外注するとかの手もあるけど。まぁ、あまりに大きすぎても置く場所に困るだけだし、15x15cmの大きさにスイッチをいくつか並べた入力デバイス、とかでも良さそうな気もする。

 フライトシミュとかやると大量にキーが必要になるので、とりあえずDCS F-16が発売になる頃までにはある程度のキー入力デバイスとして使えるように組み上げたい。


追記

 ボタン63個、アナログ6軸を設定してみた。


 Winのプロパティだとボタンは32個しか表示できないので、残りがちゃんと認識されてるかわからない。FSXかDCSでも起動して割当画面で操作してみればわかるだろうけど、今のところデータはゼロ埋めだからなぁ。
 アナログ軸は、X/Y/Z/Rx/Thr/Thrの設定。X/Y/X/Yの設定だと2軸しか認識されなかったので、desktop.upgの軸は同時に定義できないっぽい。スロットルは2軸認識してるので、sim.upgは複数認識できるっぽい。
 このあたりはもう少しいろいろいじくり回してみないとな。しかしDTで定義するのは結構面倒だし、それに合わせて構造体を修正するのも結構面倒。


追記

 ロジカルレンジを0-4095、レポートサイズを16に設定した軸に、ADCから読んだ値を直接突っ込んでみたら、PC側でもちゃんと12bitとして認識できてるっぽい。ゲームデバイスなんぞ解像度なんて気にするだけ無駄だろうけど、8bitに切り捨てるよりは、12bitで直で送ったほうが安心。

 試しにDialを設定してみたが、認識できなかった。同様にVxやVbrxも認識できない。なんとなく、プロパティ画面の方の問題な気がしてきた。Winのプロパティ画面だと大抵のゲームコントローラーの表示には不便しないせいか、ググっても他の確認手段があまり出てこない。FSXやDCSで直接確認するのが確実なんだろうな。
 HIDを扱いたいという需要も少ないせいか、C#でHIDを受け取るようなプログラムのサンプルもあまり無い。無いわけじゃないが、結構大変そうだ。そもそもHIDはヒューマンとオペレーションシステムの橋渡しをするものであって、アプリケーション層が気にするものじゃないから、C#でもサポートは薄いようだ。ゲームソフトを作るとなるとゲームコントローラーが使えたほうがいいけど、それならHIDに対応したゲームエンジンを使え、という話だし。

 STM32F0のチップで、外部クロック無しでUSBが使えるやつがあるらしい。QFP32なのであんまりピン数は多くないけど、24ボタン/6軸の入力デバイスくらいなら作れそうな気がする。さすがにQFPとなると基板を作る必要があるわけだけど、CNCは未だ安定稼働には程遠いからなぁ。

 とりあえず、物理的にはボタン1とZ回転だけ接続済みで、あとはゼロ埋めになってる。試しにFSXのキーコンフィグで確認してみたが、無事ボタン1とZ回転を任意の操作に割り当てることができた。ということで、あとはボタンやらボリュームやらを増やしていけば、フライトシミュ用の入力デバイスが作れる、ということになる。
 もっとも、FSXは結構ユルいが、DCSは結構厳しいので、DCSでもちゃんと設定できるかどうか。あとで確認してみようっと。
 無事に動いたとしても、大量のボリュームやボタンの配線をどう捌くか考えないとなぁ。PCBを外注するのが楽なんだが、普通に市販の入力デバイスが買えるくらいかかるからなぁ。


追記

 スロットルを12bitにしたらうまく動かなかった。Win側でキャリブレーションすれば使えるっぽいけど。それ以降のビットフィールドは正常なので、ビット数の設定は問題なさそう。キャリブレで改善するならロジカルレンジの設定がコケてるっぽい。
 スロットルはsim.upgに含まれているが、X軸のようなdesktop.upgに含まれる軸なら12bitモードでも正常に動いている。あるいは、階層の違いとかも影響があるかもしれない。DT使いづらいから設定いじるの面倒なんだよなぁ。
 Dialとか、プロパティ画面で表示できない軸を設定すると、FSXでも使えない。また、ボタンも33以上はプロパティ画面に表示されないが、FSXでも使用できない。プロパティ画面で表示できないだけでなく、アプリケーション側でも使えないようだ。
 とりあえず、サクッと使えるのは32ボタン、6軸まで、という感じか。X,Y,Z,Rx,Ry,Rzの6軸は12bitが使えるが、重複した定義はできない。スロットル等は重複した定義が可能だが、8bitでの使用が無難。

 試しにDCSでも設定してみたが、ボタン・軸共に使用できた。DCSの入力パネルを作ることはできそうだ。
 とりあえず、DCS F-15Cのコンフィグを眺めつつ、必要そうなボタン配置とかを考えてF-16に備える、という感じか。F-15Cのアビオニクスって結構独特な雰囲気だから、F-16とはそれなりに違いそうだなぁ。

0 件のコメント:

コメントを投稿