3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

今年も自動運転AIチャレンジが盛り上がっています。
特に今年から新設された End to End AI部門がアツそうです。

そんな折、以下Xの投稿を見ました。
Autoware Foundation が GPU・LiDAR不要のE2E自動運転をリリースしたそうです。
Alpamayoはどうやっても手元で動かないしなあ…AutoE2Eはpre-trainedモデルが無さそうだしなあ…と思っていたので、こちらを自動運転AIチャレンジ環境に取り込んでみました。

先に結論を書くと、取り込みはできましたが、最初のカーブすら曲がり切れず、
安定してコース周回するまでには至っていません

vision_pilot.gif

発進して制御は入りますが、そのまま直進し続けます。モデル出力を制御指令に正しく変換できていない or そもそもモデル出力が不適切が現状切り分けられていないですが、E2E部門のベースラインとして、一旦ここまででやったこと・まだできていないことを整理しておきます。

※ コードは以下に公開しています。

想定読者

  • 自動運転AIチャレンジ2026 (E2E AI部門) 参加者
  • オープンソース・オープンウェイトなE2E自動運転に興味がある方

Vision Pilotとは

Vision Pilotは、単眼カメラ画像を入力して次の3モデルを並列に動かす構成のようです。

モデル 主な役割 アーキテクチャ
AutoDrive CIPOまでの距離、曲率、CIPO確率を推定 YOLOv11系カスタムCNN×2フレーム+MLP
AutoSteer 進行方向を表す64点の画像座標ウェイポイントを推定 YOLOv11系カスタムCNN+ウェイポイントhead
AutoSpeed 物体検出とCIPO関係を推定 YOLOv11系カスタムCNN+物体検出head

CIPO(Closest In-Path Object)は、自車の走行経路上にいる最も近い物体を指します。一般には先行車両と思います。Vision Pilotでは、AutoDriveがCIPOの存在確率と距離を推定し、AutoSpeedの物体検出結果と融合して、CIPOの距離・速度を縦方向の加減速制御に使います。

元のVision Pilotでは、3モデルの出力をそのまま制御指令にするのではなく、次のように融合してPlanningへ渡しています。

横方向
  AutoSteerのウェイポイント
    -> 路面座標へ投影してCTE・yaw誤差・曲率を計算
  AutoDriveの曲率
    -> AutoSteer由来の曲率と融合
  融合したCTE・yaw誤差・曲率
    -> MPCで操舵角を計算

縦方向
  AutoSpeedの物体検出
    -> 走行経路上の最も近い物体と距離を推定
  AutoDriveのCIPO確率・距離
    -> AutoSpeed由来の距離と融合
  融合したCIPO距離・速度と道路曲率
    -> 加減速度を計算

つまりAutoSteerが横方向の主役で、AutoSpeedが前方物体検出の主役です。AutoDriveは、道路曲率とCIPO情報を画像から直接推定し、それぞれに対する別系統の観測値として使われています。単独でTrajectoryや操舵指令を出すモデルではありません。

今回のAIチャレンジ環境でもFusionまでの流れは使っていますが、元実装のCppAD/IPOPTによるMPCは依存関係の都合で使わず、簡易コントローラへ置き換えています。

今回やったこと

雑多にまとめておきます。

1. Vision Pilotのアダプタ・ノード作成

Vision Pilotをaichallenge_submit配下へ取り込み、起動時に次のように制御方式を選べるようにしました。

control_method:=vision_pilot

AIチャレンジ側とVision Pilot側ではROS 2のインターフェースが異なるため、アダプタも追加しています。

/vehicle/status/velocity_status
  -> /vehicle/speed

/vehicle/steering_cmd
/vehicle/throttle_cmd
  -> /control/command/control_cmd

これで、AWSIMのカメラ画像を入力し、Vision Pilotの指令でレーシングカートを動かすところまでを一本につなぎました。

2. 推論速度を計測

3つのINT8 ONNXモデルを並列実行し、GPUとCPUで処理時間を比較しました。測定環境はGPUがNVIDIA GeForce RTX 3060(VRAM12GB)、CPUがIntel Core i7-8700K(6コア12スレッド、3.70 GHz)です。

処理 GPU(RTX 3060, CUDA) CPU(Core i7-8700K)
前処理 約25 ms 約19〜20 ms
AutoDrive 約91 ms 約413〜440 ms
AutoSteer 約87 ms 約323〜396 ms
AutoSpeed 約75 ms 約295〜333 ms
3モデル全体 約91〜105 ms 約413〜440 ms
推論能力の目安 約9〜11 Hz 約2.3〜2.4 Hz

3モデルは並列に動くため、全体の処理時間は3つの合計ではなく、最も遅いモデルに近い値になります。CPUでも推論から制御出力まで動作しましたが、Vision Pilotだけで約10コア相当を使用しました。

実際の制御周期

上記よりGPUなら約10 Hzで処理できるはずですが、実際のE2E出力は約5 Hzでした。Vision Pilotを停止して測り直しても、AWSIMの画像topic自体が実時間で約5 Hzだったため、GPU推論時のボトルネックは画像入力です。

一方、画像のtimestampはシミュレーション時刻で正確に0.1秒刻みでした。AWSIMは設定どおり10 Hzで画像を生成していますが、今回のWSLg環境ではReal Time Factorが約0.5だったため、実時間では約5 Hzに見えていたようです。AWSIMのカメラが5 Hz固定というわけではない?ようです。

以上から、今回の環境では次の結果になりました。

  • GPU:画像入力が律速となり、E2E出力は約5 Hz
  • CPU:推論が律速となり、E2E出力は約2.3 Hz

GPUなしでも動きますが、GPUありのほうが早いです、当たり前ですが

3. デバッグ機能

推論が動いた、というログだけでは何が起きているか分かりにくいため、次のデバッグtopicを追加しました。

/vision_pilot/debug/image
/vision_pilot/debug/model_outputs

デバッグ画像には、次の情報を重ねています。

  • AutoSteerが出した64点のウェイポイント(緑点)
  • AutoSpeedの検出矩形(赤枠)
  • AutoDriveの距離、曲率、CIPO確率(画像上の黄色文字)
  • 各モデルの推論時間(画像上の青文字)
  • 最終的な操舵指令(画像上の青文字)

vision_pilot.jpg

この可視化で、「モデルは動いているが、想定した走行ラインを見ていない」「画像上ではそれらしいが、車両座標へ変換すると不自然」など改善のきっかけが得られるようにしています。

なお今回のAWSIM実行は--npcs 0だったため、本来CIPOになる先行車両は登場しません。それでも出力された検出矩形やCIPO確率は、壁や背景などを車両として見た誤検出の可能性があります。他車を配置したシナリオで正しく検出・追従できるかは、今後確認が必要です。

4. 推論結果で車両を制御

今回の実装では、AutoSteerから出力される画像座標ウェイポイントをそのままAutowareのTrajectoryとして配信しているわけではありません。

現在の流れは次の通りです。

AutoSteerの正規化された画像座標
  -> 画像ピクセル座標へ戻す
  -> Homographyで前方・横方向の座標へ射影
  -> RANSACで2次曲線をフィッティング
  -> CTE、yaw誤差、曲率を計算
  -> AutoDriveの曲率と融合
  -> 操舵角を直接生成
  -> AckermannControlCommandとして配信

操舵は、曲率から求めるfeed-forwardに、CTEとyaw誤差のfeedbackを加えた簡易コントローラです。

つまり現在は、Autoware標準のMPCへTrajectoryを渡して追従させる構成をバイパスしています。デバッグ画面上の緑の点はデバッグ表示としては有用ですが、そのまま物理的に正しいbase_link座標の走行軌跡を意味するものではありません。改善の余地ありです。

5. WSLg上の描画

本質ではないですが、WSLでAWSIMの画面が表示されない問題にも対応しました。
以下を参考にさせていただきました、感謝。

今回はAWSIMを--camera cpuで起動しています。これはROS 2へ画像を渡すreadback経路の指定であり、AWSIMの画面描画やVision Pilotの推論までCPUになるわけではありません。画面描画はVulkan GPU、モデル推論はCUDA GPUです。--camera gpuも試しましたが、Dozen環境ではCameraRos2Publisherで例外が発生したため使用していません。

まだできていないこと

1. AWSIMカメラに合った座標変換

現在の設定(H.yaml)は、元実装のOpenLane向け1920×1080カメラを前提とした例です。ファイルにも、異なるカメラでは行列を修正する必要があると明記されています。

AWSIMのカメラ位置、姿勢、画角、内部パラメータに合わせてHomographyを再計算できていないため、画像上の点を車両座標へ移した結果はまだ信頼できません。壁へ向かう最大の原因候補です。

2. AutowareのTrajectoryとして下位制御へ入力

本来やりたいのは、おそらく次の構成です。

画像上のウェイポイント
  -> カメラ幾何を使って路面上へ投影
  -> base_link座標の軌跡へ変換
  -> 点の間隔、向き、速度、時刻を補完
  -> autoware_auto_planning_msgs/Trajectory
  -> MPCまたはPure Pursuitで追従

この変換を実装して初めて、画面上の推定結果と、実際に下位制御が追従するTrajectoryを同じ土俵で比較できます。現状の簡易コントローラは動作確認用であり、ここは今後置き換えたい部分です。

3. AWSIM向けのファインチューニング

現在のAWSIM画像は、学習時のカメラ画角、取り付け位置、コース、バリア、車体の映り込みと分布が異なります。

3モデルとも再学習・ファインチューニング自体は可能ですが、リポジトリへ含めたINT8 ONNXを直接学習するのではなく、PyTorch側の学習コードとcheckpointを使い、学習後にONNX exportと量子化を行う必要があります。

まずは走行ラインに直結するAutoSteer、その次に曲率を出すAutoDriveをAWSIMデータへ合わせるのがよさそうです。他車が存在する競技シナリオではAutoSpeedも重要になります。

4. 推論高速化と評価

GPUではモデル単体の並列推論が約100 ms以内に収まっていますが、今回のWSLg環境ではReal Time Factorが約0.5となり、画像入力が実時間で約5 Hzです。AWSIM側の描画・camera readbackを含めてボトルネックを切り分ける必要があります。CPUでは推論自体が約2.3 Hzとなるため、ONNX Runtimeの最適化やモデルの軽量化も別途必要です。

また、現時点では完走率、壁接触回数、ラップタイムなどの定量評価まで進んでいません。

5. NPCを使ったCIPO検知・追従

今回の動作確認ではNPCを無効にしていたため、先行車両に対するCIPO検知は評価できていません。NPCありのシナリオで、AutoSpeedの検出枠、AutoDriveのCIPO確率、融合後の距離・速度、最終的な減速指令が一貫して変化するかを確認する必要があります。

導入手順

ざっくり使い方を載せておきます。
※ ひと通りセットアップが終わっている前提です。

まずリポジトリをクローンしてください、ブランチはfeat/vision-pilot-e2eです。

git clone https://github.com/soyaoki/aichallenge-racingkart.git
cd aichallenge-racingkart
git switch feat/vision-pilot-e2e

※ 3モデルはリポジトリにも含めていますので実行は不要ですが、欠損・破損時や再取得用にダウンロードスクリプトもあります。このコマンドは、固定したupstream commitからモデルを取得し、SHA-256を検証します。すでに正しいファイルがあれば再ダウンロードしません。

make vision-pilot-models

※ 通常のLinux環境では、NVIDIA Container Toolkitを準備し、docker-compose.gpu.ymlを重ねてGPUを渡します。WSLgの場合だけ、追加でDockerfile.dzndocker-compose.dzn.ymlを使用します。

ビルド後、AWSIMはvision-pilotモード、AutowareはCONTROL_METHOD=vision_pilotで起動します。

make autoware-build

SIM_MODE=vision-pilot ROS_DOMAIN_ID=0 \
  docker compose up -d simulator

CONTROL_METHOD=vision_pilot RUN_MODE=awsim ROS_DOMAIN_ID=1 \
  docker compose up -d autoware

※ 環境ごとのCompose overlayやROS domain設定は異なるため、上記は構成例です。WSL固有の設定を通常Linuxユーザーへ強制しないよう、Dozen対応は独立したoverlayに分けています。

おわりに

今回は、自動運転AIチャレンジ2026のE2E部門用の土台として、Autoware FoundationのVision Pilotを競技環境へ取り込みました。

カメラから3モデルをGPU推論し、結果を可視化し、実際に車両へ指令を出すところまでは到達しました。一方で、E2Eモデルが出した画像上の情報を、物理的に正しいTrajectoryへ変換して下位制御へ渡す部分は、まだ大きな課題です。

「モデル推論結果でとりあえず前に進んだ」と「早く車両が走り競技で勝てる」の間には、問題の切り分け・ボトルネック特定、カメラ幾何、座標系、Trajectory生成、下位制御、再学習・ファインチューニング…という、”それらしい”課題が残っています。同じようにE2E部門を試している方の検討材料の一部になれば幸いです。

またWSLは便利ですが、競技面では不利になりそうな点が多いですね。競技本番もネットワーク周りが気にはなるので、可能であればネイティブUbuntuな環境を用意した方がいいなあと思う今日この頃でした。

※ Vision Pilotには本記事で触れたAutoDrive, AutoSteer, AutoSpeed以外の他モデルも存在しており、DomainSeg, EgoLanes, Scene3D, SceneSegがありました。主にパーセプション関係と思われますが、気になる方はご参考ください。

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?