シナリオテストフレームワークの勉強 - myamazum/private-tips GitHub Wiki
OSS (Autoware) の技術資料の抜出し
- E2E Simulator : センサデータから車両の挙動まで走行環境全体をシミュレーションして検証するSimulator
- Log Simulator : 事前に取得したセンサデータや解析結果を元に、新たに追加した認識系の挙動を確認するデバック用のSimulator
- Planning Simulator : 認識系が正しく機能することを前提に行動系の処理が正しいかを検証するSimulator
Tier IVは、UnityをベースにしたLGSVL SimulatorをベースにE2Eを開発している。(参考 Unity Japan の公演)
また、UnityのE2Eシミュレータとして、Autoware Fundationが軽量に動作するAutoCore Simulatorを開発している。こちらは、三次元点群地図とVectorMap (Autowareが定義)、カメラ画像、GNSS情報をシミュレーション環境として利用できる。
つくばチャレンジ2020でもE2Eシミュレータが検証されたが、こちらはUnreal Engineをベースにしていた(Unityも試作したが、データのパイプラインでラグがあったとのこと)。Unreal EngineでAutowareのE2Eを試す環境としてCARLA Simulatorがある。
Tier IVは、OpenSCENARIO V0.9.2をベースとしたティアフォーの独自フォーマットについて、Simple Planning Simulatorを配布している。
OpenSCENARIOは、欧州が進めている自動運転のシナリオフォーマットの一つである。(参考文献 METI,2019)
複数のSimulatorを使う場合に起こる問題点として、以下が挙げられる。
- シナリオフォーマットがSimulatorに依存している
汎用なシナリオフォーマットはOpenSCENARIO等様々なものが提案されていますが、Simulator固有の拡張が入っていたり、SVL Simulator等独自シナリオフォーマットを中心としているようなSimulatorも多いため、一度書いたシナリオを使い回すのは簡単ではありません。
シナリオを異なるSimulatorの間でやり取りするには人力で動作確認をしながらポーティングを行う必要があり、シナリオ変更履歴のトレーサビリティの観点からも大きな問題があります。
- NPCロジックがSimulatorごとに異なる
OpenSCENARIOに対応したからと言って一度書いたシナリオがすべてのSimulatorで簡単に動くということは担保できません。
OpenSCENARIO V1.0の未定義動作の例
- 道路端点や世界の端に到達したNPCはどう振る舞うべきか
- AssignRouteActionで経路指定した結果ゴールに到達したNPCはそのまま走っていくべきか、それともその場で停止するべきか
- レーンチェンジができない場所でレーンチェンジ指示が出た場合はどのような挙動をすべきか
- SimulatorごとにIntegrationの仕方が違う
CARLAにおいては独自ブリッジでROSおよびAutowareとのIntegrationを行っており、ブリッジ内部でPID制御器が動いていたりと他のSimulatorと全く異なるロジックで制御がなされています。 SVL SimulatorはAutowareとrosbridgeで接続しており、ROSの標準的なツールを用いてインターフェースが設計されています。 Simulatorごとに根本的に異なるインターフェースが設計されており、これはクラウド上にテストパイプラインを構築、メンテナンスしていく上で大きな障害になります。
また、明示的な標準仕様がないため、新しいSimulatorをIntegrationする際には毎回設計を1からやり直す必要があり莫大な工数が発生することになります。
- シナリオフォーマットは現在も技術開発が盛んな領域
これについて、Tier IVは 以下のアプローチを実施
- Co Simulation Model を採用
NPCロジックをシナリオテストフレームワーク中の交通流Simulatorに対して実装しました。 センサSimulatorが交通流Simulatorとプロセス間通信を行い、歩調を合わせながらCo-SimulationをすることでNPCロジック共通化を実現しています。 交通流SimulatorはセンサSimulatorに対するOpenSCENARIOの「翻訳機」かのように振る舞い、OpenSCENARIOの未定義動作によるSimulatorごとの差異を吸収します。 プロセス間通信はすべて同期呼び出しで実装されており、シナリオテストフレームワークのうちROS2に依存しない部分に関しては決定性を担保しています。
- シナリオテストフレームワークとシナリオ解釈器のコンポーネント分離
シナリオテストフレームワークにC++ APIを用意し、シナリオフォーマットの解釈器がそれを叩くアーキテクチャ構成にすることで同時に複数のシナリオフォーマットをサポートしています。
- Simulatorを抽象化
SimulatorとAutowareとのインターフェースを統一し、複数のSimulatorを同時にサポートできるシナリオテストフレームワークを開発しました。 Autowareとの結合部分や、NPCロジックで使われている微分幾何アルゴリズムやHD MapとのインテグレーションをSimulatorで独自実装する必要はありません。
Tier IVのアーキテクチャは、AutowareとSenario Simulatorが交通流Simulatorを介して情報をやり取りする仕組みをとる。
シナリオは、交通流シミュレータにOpenSCENARIOの翻訳機を介して実行される。
Autowareとの通信は、ROS2のノードを介してトピックとして配信される。
一方、Sensor Simulatorなどシナリオテストフレームワークと通信してCo-Simulationを行うSimulatorはZeroMQで同期的に通信する。
この通信フォーマットは、Protocol Buffersによりシリアライズされる。
JSONとの違いはなにか、というと、Protocol Buffersはスキーマ言語であり、JSON Schemaと比較されるフォーマットである。(参考 今さらProtocol Buffersと、手に馴染む道具の話)
JSON Schemaは、データベース構造を陽に含んでいるJSON フォーマットである。(データベースをやっている人がJSON、JSONいってたのはこういう理由があったのか、と思いつつ、Schemaになってなかったのなんでだろう??みたいな疑問が浮かんだが心の中にしまっておく。)
今回のケースは、複数のSimulatorを同時にサポートすることを目的として、構文が増えるスキーマ言語を採用したとのことである。
スキーマを明確に定義してSimulator開発者がインターフェースが変わったことをすぐに把握できるよう工夫しています。
独自の実装として、以下が解説されている。
- レーン座標系のサポート
シナリオテストフレームワークでは内部にレーン座標系、ワールド座標系、物体間の相対座標系を相互に座標変換するAPIを備えており、Simulatorとプロセス間通信する際に渡される情報ではすべての物体位置はワールド座標系で記述されています。これらの座標変換はtfを介さずにフルスクラッチで実装されていますので、完全に決定性があります。
- 強化されたNPCロジック
Behavior Treeを使用してNPCロジックを大幅に強化し、以下のような挙動を明示的に指示しなくても自動的にやってくれるようにしました。
- 自動テスト
シナリオテストフレームワークの開発においてはGitHub Actionsを使用して以下のテストケースをシナリオテストフレームワーク本体のCIとして継続的に回しています。 ドキュメント化がしっかりされている。このあたり、どのように勉強されたのか知りたい。
参考資料
Autoware シナリオフレームワーク Scenario testing framework for Autoware