CommonRoad solution checker の判定リファレンス
1 回の再生について PASS / FAIL を言うものが 2 つあり、それぞれ別の問いに答えて います。
| 誰が問うか | 何を意味するか | いつ得られるか | |
|---|---|---|---|
| 公式 4 検査 | commonroad-drivability-checker | この解は本当に planning problem を解いたか | solution の隣に .verdict.json を読ませたとき |
| drawtonomy 自身の判定 | drawtonomy (再生中) | この再生は、あなたが書いた fail 条件を踏んだか | 常に。追加のファイルは不要 |
drawtonomy 自身の判定は「何も入れずにすぐ見える目安」、checker の判定が「権威」です。 どちらも他方を上書きしません。verdict は失格を足すことはあっても、消すことは ありません。drawtonomy が衝突を見た解を checker が通していたら、両方の答えが出ます。
公式 4 検査
Section titled “公式 4 検査”drawtonomy-cr verdict が回すのはちょうどこの 4 つで、その結果をそのまま書きます。
| 検査 | 落ちる条件 |
|---|---|
obstacle_collision | ego の footprint がシナリオの障害物と重なった。タイムステップ区間と障害物 id 付きで報告されます。 |
boundary_collision | ego が走行可能な道路境界の外に出た。必要な triangle パッケージが無いときは SKIP で報告されます。 |
goal_reached | 軌跡が planning problem のゴール (位置、および速度区間が設定されていればそれも) を一度も満たさなかった。 |
solution_feasible | 記録された軌跡が、解が宣言している車両モデル (KS / PM …) で再現できない。許容される入力ではその状態列に到達できない。 |
solution_feasible は drawtonomy 自身には到達できない種類の判定です。衝突がなくても、
どんな車にも走れない軌跡はあり得ます。
SKIP: 判定できなかった検査
Section titled “SKIP: 判定できなかった検査”検査は SKIP で返ることもあります。これは合格でも不合格でもありません。
checker が答えに辿り着けなかったので、その解について言えることが何も無い、という
状態です。現在これが起きるのはちょうど 1 つの場合だけです。boundary_collision は
道路を三角形分割するのに triangle パッケージを必要としますが、triangle は
商用利用が無償ではないため既定では
入れていません。入れるときは [boundary] extra を使ってください
(pip install "drawtonomy-commonroad[checker,boundary]")。
これ以外の例外は、ego が実際に道路外に出た場合も含めて、今までどおり FAIL です。 パッケージが無いことが「あなたの軌跡が道路から出た」と読めてはいけません。
SKIP はバッジの数え上げから外します。
boundary_collision が SKIP で残り 3 検査が判定されて合格なら、表示は
PASS 3/4 ではなく Checker PASS 3/3 です。分母は常に「実際に答えが出た検査の数」で、
分子は手前の語と同じものを数えます。PASS n/N なら n は合格数、FAIL m/N なら
m は不合格数です。Checker FAIL 3/4 は「判定した 4 件のうち 3 件が FAIL」です。
CLI では括弧に次の一手が付いた 1 行になり、exit code は 0 のままです。
[SKIP] boundary_collision (pip install triangle)drawtonomy 自身の判定
Section titled “drawtonomy 自身の判定”再生中に評価されるのは FAIL CONDITIONS で、なかでも重要なのが Collision です。 これは描いたシナリオでも import したシナリオでも既定で入っています。衝突させる つもりのシナリオは、その条件を外すまで FAIL になります。これは fail 条件に対する 実行時判定であって、シナリオそのものの検証ではありません。
バッジを読む
Section titled “バッジを読む”再生が終わると transport 行にバッジが出ます。verdict が載っていれば、checker の答えも その tooltip に畳み込まれます。

checker が通した解。tooltip には replay のファイル名、車両モデル (KS)、状態数、
そして何件通ったかが並びます。通った検査は数えるだけで、名前は並べません。

FAIL のとき。通らなかった検査だけが 1 件 1 行で、検査名・相手の障害物・秒が出ます。
FAIL の出どころが checker なら、このブロック自体が理由なので、Fail condition: の
行として重ねて書きません。
読み取るべきものは 3 つです。
Checker PASS 4/4/Checker FAIL 2/4: 要約。分子は手前の語と同じものを 数えます (4 件が合格 / 2 件が不合格)。verdict を読み込んだときの toast と同じ文言 なので、toast が消えたあとも同じ語で辿れます。- 通らなかった検査だけ 1 件 1 行: 検査名、checker が持っていれば障害物 id と
時刻区間が
·区切りで付きます (timeline の fail マーカーと同じ形)。通った検査は 要約の数に入るだけです。飛ばした検査はboundary_collision · SKIPと出て説明も 残します。checker の定型文 (“There is a collision between the scenario obstacles and the ego vehicle…”) は 出さず、実際の診断 (“76 of 179 state transitions … position drifts up to 149.6 cm”) は検査の下に 字下げして残します。 - 時刻は秒です (サイドカーのタイムステップから換算)。時刻を持つ検査は timeline の
その秒に fail マーカーが立ちます。時刻を持たない検査 (素の
solution_feasibleの ような軌跡全体への判定) は replay の末尾に置かれ、whole trajectoryと出ます。
サイドカー: drawtonomy-verdict/1
Section titled “サイドカー: drawtonomy-verdict/1”verdict は solution の隣に置く小さな JSON です。以下は衝突する解に対する checker の 答えです。
{ "schema": "drawtonomy-verdict/1", "benchmarkId": "PM1:JB1:ZAM_Untitled202609011139-1_1_T-1:2020a", "scenarioId": "ZAM_Untitled202609011139-1_1_T-1", "dt": 0.1, "tool": { "name": "commonroad-drivability-checker", "version": "2025.4.0" }, "generatedAt": "2026-09-03T04:52:49Z", "checks": [ { "name": "obstacle_collision", "status": "FAIL", "message": "CollisionException: There is a collision between the scenario obstacles and the ego vehicle in planning problem solution 16", "timeSteps": [127, 133], "obstacleId": 15 }, { "name": "boundary_collision", "status": "PASS" }, { "name": "goal_reached", "status": "PASS" }, { "name": "solution_feasible", "status": "FAIL", "message": "Exception: infeasible for planning problems [16]", "vehicleModel": "PM" } ]}schemaは必須。checks[].statusはPASS/FAIL/SKIP。checks[].nameは自由文字列ですが、drawtonomy が timeline に置き方を知っているのは 上の公式 4 名です。messageは公式の例外をそのまま ({型}: {本文})。表示側は型の接頭辞を落として 本文だけを出します。timeStepsは[first, last](両端含む、0 起点)。秒はstep × dtです。
このファイルを作るのに drawtonomy-cr を使う必要はありません。自前の CI ジョブから
書ける程度に小さく、判定の部分は公式 API の 4 呼び出しです。
from commonroad.common.file_reader import CommonRoadFileReaderfrom commonroad.common.solution import CommonRoadSolutionReaderfrom commonroad_dc.feasibility.solution_checker import ( obstacle_collision, boundary_collision, goal_reached, solution_feasible)
scenario, pps = CommonRoadFileReader("scenario.xml").open()solution = CommonRoadSolutionReader.open("solution.xml")for name, fn in [("obstacle_collision", obstacle_collision), ("boundary_collision", boundary_collision), ("goal_reached", goal_reached)]: try: fn(scenario, pps, solution); print("PASS", name) except Exception as e: print("FAIL", name, e)print(solution_feasible(solution, scenario.dt, pps))feasibility は「合否」より多くを言う
Section titled “feasibility は「合否」より多くを言う”公式 checker は planning problem ごとの bool しか返さないので、どこで・なぜが
分かりません。そこで drawtonomy-cr は公式の state_transition_feasibility を隣接
2 状態ごとに当て直し、車両モデルで再現できない遷移、再構成された入力がどの限界に
張り付いたか、記録状態と模擬状態のずれを報告します。数値はすべて公式 API の返り値です。
公式コーパスの ZAM_Tjunction-1_42_T-1 の KS 解では次のようになります。
{ "name": "solution_feasible", "status": "FAIL", "message": "14 of 147 state transitions (4.2-6.1 s) need a steering rate beyond the KS limit of 0.4 rad/s; position drifts up to 5.8 cm from the simulated state (tolerance 2 cm), orientation up to 0.019 rad (tolerance 0.03).", "timeSteps": [42, 61], "reason": "steering_rate", "infeasibleTransitions": 14, "transitions": 147, "maxPositionError": 0.0581, "maxOrientationError": 0.0186, "steeringRateLimit": 0.4, "accelerationLimit": 11.5, "vehicleModel": "KS" }reason は最も多く当たった限界で、steering_rate / acceleration /
friction_circle / input_bounds / state_deviation のいずれかです。timeSteps が
付くので、fail マーカーは末尾ではなく 4.2 s に立ちます。
対応付け: verdict は 1 つの解のもの
Section titled “対応付け: verdict は 1 つの解のもの”verdict は scenario id で replay と対応付きます (scenarioId、無ければ
benchmarkId から <model>:<cost>: と :2020a を剥いだもの)。一致しなければ verdict は
適用されず、両方の id を名指しした 1 行が理由を言います。
other_scenario.verdict.json was not applied: it was computed for scenario"ZAM_Other-1_1_T-1" but the loaded replay is for "ZAM_CutIn-1_1_T-1".replay 自体は載ったままです。関連するルールが 2 つあります。
- verdict だけ読ませても何も起きません。 解が載っていなければ判定する対象が ありません。先に solution を読むか同時にドロップするよう toast が促します。
- シーンを編集すると verdict は降り、replay は残ります。 checker の答えは編集前の シーンに対して計算されたものだからです。ego は planner の軌跡を追い続け、 「その trace は編集より前のものだ」と toast が言います。編集後のシーンについての 答えが欲しければ planner を回し直してください。
exit code
Section titled “exit code”drawtonomy-cr verdict:
| code | |
|---|---|
0 | サイドカーを書けた。FAIL の判定でも 0 です。失格は JSON の中身だからです。 |
3 | checker が入っていない ([checker] extra、Linux x86_64)。インストール方法を 1 行で出します。 |
- 自作 planner をつなぐ: verdict の作り方と、それが属する 1 周。
- Planning trace: 走った軌跡だけでなく、 planner が何をするつもりだったか。
- 終了条件と失敗条件: PASS / FAIL の drawtonomy 側。