← ラボノート

ブラウザーのタブでステアリングホイールを動かす

私たちは、ブラウザー用運転シミュレーター「Seat Time」を人工知能(AI)のコーディングエージェントと作っています。そのエージェントは誰も、私たちのホイールに触れたことがありません。10月25日、G923はエラーもなく力のコマンドを受け付けました。それでも手には何も伝わりません。リム(ホイールの握る部分)が軽くなっただけでした。

目標は、ホイールをつないでChromeを開き、そのまま走ることでした。認識できた機種なら、設定の質問なしで操舵とペダルを割り当てたかったのです。Logitechの従来型の力コマンドは10月10日から送っていました。コードを手で評価できる状態にするには、もっと時間がかかりました。

前回:すべての数値に出典を。

Chromeにはホイールが見えていませんでした

最初の問題は、力を返す前に起きました。macOS版Chromeの標準ゲームパッド診断では、デバイスがゼロでした。使っていたのはPlayStationモードのG923です。エージェントは受信専用の記録ツールを作りました。続いて、ブラウザーから機器にアクセスするWebHIDで入力デコーダーを作りました。

まず、ホイールが何を送っているのか知る必要がありました。Gamepad仕様は、ゲームコントローラー用のブラウザーインターフェースを定義しています。WebHIDは、Human Interface Deviceプロトコルを使う機器へのアクセスを提供します。標準の入力経路で足りない部分に、別の経路を使えました。ChromeのWebHIDガイドには、機器の選択、受信データ、送信コマンドの説明があります。

デコーダーは受信データを操舵とペダルの値に変換します。力を返すフォースフィードバックは逆方向です。モーターに、どれだけ引くかをコマンドで伝えます。入力を読めても、出力が動く証明にはなりません。どちらが動いても、運転感覚までは分かりません。

エージェントには手の感覚をテストできません

実装済み、合成入力でテスト済み、実機で確認済みを分けて記録しました。合成データなら、機器なしでデコードや状態遷移を試せます。しかし、リムが動くかは分かりません。コードのテストが通っても、実機の未確認欄はそのままです。

使い慣れた初期値も、この機器には合いませんでした。操舵のデッドゾーンは、中央付近の動きを無視する範囲です。ゲームパッド用の5%を引き継いでいました。900°のホイールでは、中央から約22°回すまで反応しない計算です。私たちは0.2%を選びました。コード上の判断はできても、走って確かめるのは私たちです。

私たちの報告が次の修正になりました

ペダルは、足を離していても100%を示していました。ゲームにはアクセルが未割り当てと表示されます。クラッチ検出後には、メニューの選択位置が勝手に動くこともありました。設定なしで走りたいという目標からは、まだ遠い状態でした。

エージェントは管理用のDebugタブに、Copy reportボタンを追加しました。その後、実際に開いていたSettings画面へ移しました。これで走行後に報告をコピーし、「まだおかしい」以上の情報を渡せます。画面で見た症状と、コードが受け取った値がつながりました。

離したペダルの値は+1でした。一方、ある軸は最初に動かすまで古いゼロを保持していました。これなら、一見妥当な割り当てでも、休止状態を全開と誤認します。後の報告で、アクセルとブレーキの割り当てを実機確認できました。私たちが物理的な観察を渡し、エージェントが次の変更を返す流れができました。

「とても緩い」は操舵比の問題でした

操舵の「とても緩い」感覚には、入力の対応関係という原因がありました。ゲームは900°全域を、各車のタイヤの最大切れ角に対応させていました。選んだカートの操舵形状では、リムの端から端までの角度は86°です。必要な角度の約10倍も回していたことになります。

修正では、車ごとにリムの最大角を設定しました。カートは±43°、Formula Hybridは±145°です。Formula Club 1600は±224°、GT3は±357°としました。これはシミュレーションで選んだ値で、実車の測定値ではありません。この修正を実機で走って確かめる作業は、まだ残っていました。

ステアリングリムの中央から片側への回転角の設定値は、カート43°、Formula Hybrid 145°、Formula Club 1600 224°、GT3 357°で、リムの片側450°以内です。
ステアリングの比率を決めるのは機器の全可動域ではなく、車の切れ角です。

届いた力も途中で消えていました

パルスと診断用の試験コマンドで、ついにG923のリムが動きました。出力経路は確認できましたが、通常走行には別の問題がありました。そこで、要求した力から送信コマンドまでを追いました。最終的なレベルを数えると、「弱い」という報告を掘り下げられます。

使ったのは、Logitechのフォースフィードバック仕様書にある従来型のコマンドです。コミュニティーのnew-lg4ffドライバーも参照しました。私たちの出力では、力の大きさを左右それぞれ最大127レベルに対応させます。これはコマンドの尺度であり、手に届くトルクの測定ではありません。

最初の損失は、計算の順番にありました。最小力の下限を加えた後、上限用の倍率で小さくしていたのです。典型的な荷重は、127に対して約±5になりました。修正後は下限と上限の間へ対応させ、最小力に0.08を選びました。小さな力を残すための下限まで、縮めるのをやめました。

ラックトルクから車種別倍率、限界へなだらかに近づくカーブ、下限と上限を経て、左右それぞれ最大127段階の強さを出力する途中で、別々の不具合が力を失わせました。
一段階を直しても、次の段階で力が届く証拠にはなりませんでした。

診断では動いても、走行中は送っていませんでした

別の報告では、38回の送信がすべて力の診断から来ていました。走行中に力を送った記録はありません。診断でリムを動かしても、走行と出力の状態管理はつながっていなかったのです。必要な経路の一部しか証明していませんでした。

エージェントは力のOn/Offを保存する設定にしました。有効なら、走り始めると出力も自動で有効になります。トルクは一度に加えず、1秒かけて立ち上げます。この時点の実機証拠は、まだ出力診断だけでした。新しい走行中の動作は含みません。

カートの力を平らにしていた上限を直しました

実機を使わない計測では、送信前にも力が失われていました。カートの古い基準トルクでは、操舵を変える試験のほぼ全域が飽和します。飽和すると、違う荷重も同じ最大信号になります。そこで、円旋回のシミュレーションから求めた車ごとのピークを基準にしました。

その試験で、カートの飽和率は99%から0%に下がりました。力が限界へなだらかに近づくカーブも追加しました。低い上限では、フレーム間の最大変化が23~27レベルから11~12になりました。これはシミュレーションと力出力コードの計測です。ホイールは接続していません。

上限がグリップの合図を小さくしていました

出力の更新頻度には250 Hzを選びましたが、上限は全域の0.2のままでした。私たちの報告も「まだとても弱い」のままです。そこで、G923の定格2.3 N·mに対応する全域を選びました。同時に、グリップ限界の強調とスライドの合図も加えました。定格全域へ進む際、研究で提案した段階的な熱試験は私たちの判断で省略しました。

この組み合わせで、実機なしのグリップ限界の合図は2~5レベルから20~39へ広がりました。カートは別で、1から9です。操舵を徐々に増やす試験では、アンダーステア時の低下量が1~6から7~57になりました。オープンホイール車だけは0から1です。その試験では、シミュレーション上の操舵荷重自体がほとんど下がりませんでした。

この例外は大切です。出力範囲を広げても、操舵荷重にない低下は作れません。コマンドが大きくなっても、手で読み取れる証明にはなりません。数値によって、次に運転で確かめる対象が具体的になりました。

フレームの中の変化も失われていました

ミッションは、フレーム平均ではなく最後の物理ステップのトルクを送っていました。エージェントは、まず平均値に修正しました。その後、400 Hzの物理計算の各ステップを出力ループで再生する方式に変えました。Smoothingの初期値には25%、時間にして5 msを選びました。

狙いは、表示フレームの内側で起きた力の変化を残すことです。ただし、G923で走った記録はまだありません。ミッション、ステップ再生、Smoothingは、手で確かめる項目に残りました。細かな出力を実装したことと、運転で評価したことは別です。

手で確認できた範囲を残しました

ローカル開発版での最初の全出力走行は、「今のところ大丈夫」でした。一方、力がときどき「抜ける」とも報告しました。疑ったのは、手を離したと判断すると力を抑えるガードです。リムが自由に回っているように見えると作動します。ただし、原因とはまだ確認できていません。

選んだ作動条件は、力と同じ方向へのリム速度が360°/sを超え、それが150 msより長く続くことです。その場合、力を全域の0.3に制限します。意図した作動と誤作動を分けるには、実機の時系列記録が必要でした。その記録は残っていませんでした。

入力とペダル、初期の走行トルクには実機での報告があります。出力確認は実走とは別で、後の切れ角設定やステップ再生は未実走です。 ダッシュは合成テストの記録がないことを示し、ミッションとステップ再生も該当します。実機チェックリストの完了結果ではありません。
合成テストと私たちの実走報告では、確かめられることが違います。

モード切り替えも未確認でした。実装はコミュニティードライバーの切り替えコードにある機器指定値に従いました。しかし、LogitechのPlayStationモード付録とは値が違います。この切り替えは実機で実行していません。確認済みの出力診断だけでは、そのときのモードも確定できません。

G29もダイレクトドライブのベースも接続していませんでした。監督付きの実機チェックリストにも、結果の記入はありません。開始時の条件は、ホイールをクランプで固定し、フォースフィードバックを切ることです。ペダル割り当てとリムの動作確認は前進ですが、全面的な対応宣言にはできません。実装した機能の隣に、まだ走っていない項目を残しました。

次は、もっと早くゲームを始めるために

シミュレーションの操舵荷重から出力コマンドまで、力が消える場所を数えられるようになりました。次に欲しいのは、タイヤがグリップを失う瞬間をホイールから読み取ることです。その前に、別の問題へ取り組みます。ゲームの読み込み時間です。

Seat Timeを開く。ChromeでG923を接続する項目は、Settings → Controls → Wheelにあります。

次回:スマートフォンからも素早く読み込む。

注記と出典

  • 計測・記録済みの実機観察: macOS版Chromeのゲームパッド診断でゼロ台、離したペダルが100%、+1と古いゼロの値、ペダル割り当ての修正確認です。「とても緩い」操舵、コマンド受理後も軽いだけのリム、パルスと診断での動作も含みます。38回の診断のみの送信、「まだとても弱い」、ローカル版の「今のところ大丈夫」「抜ける」も個別の記録です。チェックリスト全体の完了を意味しません。
  • 選択した設計値: デッドゾーン5% → 0.2%、入力範囲900°、車別の最大角±43°、±145°、±224°、±357°です。最小力0.08、立ち上げ1秒、出力250 Hz、上限0.2 → 1.0、400 Hzのステップ再生も選択値です。Smoothingは25% = 5 msです。ガードは360°/s超が150 ms超続くと、力を0.3に制限します。カートの約10倍という差は900° ÷ 86°から求めています。
  • 計測・実機なし: カートの飽和99% → 0%、低い上限でのフレーム間変化23~27 → 11~12レベルです。グリップ限界の合図はカート以外で2~5 → 20~39、カートで1 → 9でした。操舵試験の低下量は1~6 → 7~57で、オープンホイール車は別に0 → 1です。全域の比較では、グリップ強調とスライドの合図も変えています。コマンド値の結果であり、実測トルクや感覚の証明ではありません。
  • 外部出典に基づく事実: Gamepad仕様、WebHID Standard、Chromeのガイドがブラウザー側の参考資料です。Logitechの力出力仕様書とnew-lg4ffをコマンドの参考にしました。LogitechのG923製品ページは定格2.3 N·mの出典で、私たちの個体の測定値ではありません。
  • 私たちの解釈: 実機報告がエージェントの受け入れ確認の流れになりました。力が抜ける原因として、ガードを疑っています。研究中のトルク換算は、未検証の線形2.2 N·m尺度を仮定していました。そのため本文ではレベルを使い、2.3 N·mは定格としてのみ記載しています。
  • 実機で未走行・未確認: 車別最大角、モード切り替え、ミッション、ステップ再生、Smoothingです。G29とダイレクトドライブの結果もありません。監督付きチェックリストは未完了で、段階的な熱試験の結果も記録されていません。出力を上げた判断は開発の経緯であり、安全に関する推奨ではありません。

この記事の執筆と翻訳にはAIツールを使いました。Logitech、G923、G29はLogitechの商標です。PlayStationはSonyの商標です。Seat TimeはLogitechおよびSonyと提携しておらず、両社の推奨も受けていません。

あわせて読む