CommonRoad solution checker の判定リファレンス
1 回の再生について PASS / FAIL を言うものが 2 つあり、それぞれ別の問いに答えて います。
| 誰が問うか | 何を意味するか | いつ得られるか | |
|---|---|---|---|
| 公式 7 検査 | commonroad-drivability-checker | この解は本当に planning problem を解いたか | solution の隣に .verdict.json を読ませたとき |
| drawtonomy 自身の判定 | drawtonomy (再生中) | この再生は、あなたが書いた fail 条件を踏んだか | 常に。追加のファイルは不要 |
drawtonomy 自身の判定は「何も入れずにすぐ見える目安」、checker の判定が「権威」です。 どちらも他方を上書きしません。verdict は失格を足すことはあっても、消すことは ありません。drawtonomy が衝突を見た解を checker が通していたら、両方の答えが出ます。
公式 7 検査
Section titled “公式 7 検査”drawtonomy-cr verdict が回すのはちょうどこの 7 つで、この順に、その結果を
そのまま書きます。
| 検査 | 落ちる条件 |
|---|---|
solved_all_problems | シナリオが立てた planning problem のうち、解が入っていないものがある。 |
goal_reached | 軌跡が planning problem のゴール (位置、および速度区間が設定されていればそれも) を一度も満たさなかった。 |
starts_at_correct_state | 解の最初の状態が planning problem の initialState と一致しない。全属性を比較し、許容差は 0.1 (速度は 2.0) です。 |
obstacle_collision | ego の footprint がシナリオの障害物と重なった。タイムステップ区間と障害物 id 付きで報告されます。 |
boundary_collision | ego が走行可能な道路境界の外に出た。必要な triangle パッケージが無いときは SKIP で報告されます。 |
ego_collision | 協調解 (cooperative solution) の ego 同士が衝突した。ego が 1 台だけの解ではぶつかる相手がいないので通ります。 |
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 で残り 6 検査が判定されて合格なら、表示は
PASS 6/7 ではなく Checker PASS 6/6 です。分母は常に「実際に答えが出た検査の数」で、
分子は手前の語と同じものを数えます。PASS n/N なら n は合格数、FAIL m/N なら
m は不合格数です。Checker FAIL 3/7 は「判定した 7 件のうち 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 行に RUN バッジが出ます。入力指紋が照合済みの判定だけが、そのtooltip・RUN評価・タイムラインのFAILマーカーに反映されます。
未照合の判定は、別の琥珀色 CHECK ? バッジで表示します。tooltipには同一性を確認できない理由と、ファイルが報告した検査結果を示します。その結果はRUNの合否を変えず、FAILマーカーも追加しません。指紋なしの判定 (drawtonomy-commonroad 0.1.0、または他ツールの出力) はこちらの経路です。drawtonomy自身の実行時チェックは独立に動作します。
以下の画像とPASS/FAILの説明は照合済み判定の経路を示します。画像は指紋照合と7検査への拡張より前のもので、4/4 / 2/4 と出ています。7検査がそろう照合済みサイドカーの分母は7です。現在の未照合バッジの画像ではありません。

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

FAIL のとき。通らなかった検査だけが 1 件 1 行で、検査名・相手の障害物・秒が出ます。
FAIL の出どころが checker なら、このブロック自体が理由なので、Fail condition: の
行として重ねて書きません。
読み取るべきものは 3 つです。
Checker PASS 7/7/Checker FAIL 2/7: 要約。分母は判定できた検査の数なので、 全部そろったサイドカーなら 7、SKIP があったり サイドカーがその検査を持っていなければ小さくなります (上の 2 枚が4/4/2/4なのはこのためで、7 検査になる前に書かれたサイドカーです)。分子は手前の語と同じものを 数えます (7 件が合格 / 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", "solutionFingerprint": "sha256:aacc4bad344c5b62adf139dd9889319cc3236f28d38f756445965b0862c09b50", "scenarioFingerprint": "sha256:914a4300443dcf4bc585c7e43769983b4932c22bf69be37ac02bd086c1d5ab33", "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 に置き方を知っているのは 上の公式 7 名です。messageは公式の例外をそのまま ({型}: {本文})。表示側は型の接頭辞を落として 本文だけを出します。timeStepsは[first, last](両端含む、0 起点)。秒はstep × dtです。
このファイルを作るのに drawtonomy-cr を使う必要はありません。自前の CI ジョブから
書ける程度に小さく、判定の部分は公式 API の 7 呼び出しです。引数の順は
関数ごとに違うので注意してください。
from commonroad.common.file_reader import CommonRoadFileReaderfrom commonroad.common.solution import CommonRoadSolutionReaderfrom commonroad_dc.feasibility.solution_checker import ( solved_all_problems, goal_reached, starts_at_correct_state, obstacle_collision, boundary_collision, ego_collision, solution_feasible)from commonroad_dc.feasibility.vehicle_dynamics import VehicleDynamics
scenario, pps = CommonRoadFileReader("scenario.xml").open()solution = CommonRoadSolutionReader.open("solution.xml")checks = [ ("solved_all_problems", lambda: solved_all_problems(pps, solution)), ("goal_reached", lambda: goal_reached(scenario, pps, solution)), ("starts_at_correct_state", lambda: starts_at_correct_state(solution, pps)), ("obstacle_collision", lambda: obstacle_collision(scenario, pps, solution)), ("boundary_collision", lambda: boundary_collision(scenario, pps, solution)), ("ego_collision", lambda: ego_collision(scenario, pps, solution)),]for name, fn in checks: try: fn(); print("PASS", name) except Exception as e: print("FAIL", name, e)
vehicle_dynamics = VehicleDynamics.from_model( solution.vehicle_model, solution.vehicle_type)print(solution_feasible(solution, scenario.dt, vehicle_dynamics))valid_solution(scenario, pps, solution) は 7 つを 1 呼び出しでまとめて回し、
最初に落ちたところで例外を投げます。上のループは同じ判定を検査ごとに分けたもので、
サイドカーに 1 件 1 行で書くためにこうしています。
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 つの解のもの”solutionFingerprint / scenarioFingerprint は省略可能で、値は sha256: + 小文字hex64桁です。UTF-8本文の先頭BOMを除去し、CRLF/CRをLFへ正規化してから計算します。両側に値がある場合だけ比較し、不一致は拒否、欠落は同一性未確認として読み込みを継続します。未確認は手動で閉じる琥珀色の警告と専用の CHECK ? バッジで示します。tooltip に報告された検査結果を表示しますが、RUN の合否やタイムラインの FAIL マーカーへは合流しません。シーン編集時は現在の判定を外し、原文scenario指紋を失効させます。その後の指紋なし再読込も未確認として扱います。
verdict は scenario id と、両側にある場合の solution / scenario 本文の SHA-256 指紋で対応付きます (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 側。