コンテンツにスキップ

CommonRoad シナリオを書き出す

drawtonomy の CommonRoad 対応でできることは 3 つあり、いずれも同じキャンバス上で 完結します。

何ができるか入口
描いて書き出す手描き・AI 生成・開いた OpenSCENARIO ファイルのどのシーンも、lanelet 網・dynamicObstacle の軌跡・planningProblem を持つ CommonRoad 2020a シナリオになりますExport ▸ CommonRoad (.xml)
読み込んで往復させるCommonRoad .xml を開くと lanelet の id と接続関係を保ったままキャンバスに載ります。drawtonomy が描かない要素はそのまま持ち越されるので、無編集で書き出せば原文どおりに戻りますキャンバスにドロップ、または Import…
再生して判定するplanner の solution.xml が ego として再生され、公式 checker の判定が再生バッジに載りますsolution.xml (+ .verdict.json) をドロップ、または drawtonomy-cr open

このページで扱うのは 1 行目、CommonRoad の書き出しがファイルを書く前に何を必要と するかです。

planningProblem を持たない CommonRoad シナリオには、planner が解くべきものが どこにもありません。そのためエクスポートが求めるのはちょうど 2 つで、揃うまでは 1 行の理由を出して止まります。

  1. ego: 外部制御される車両を 1 台指定します。これが planning problem の初期状態 になります
  2. ゴールレーン: ego が到達すべき lanelet、またはその一区間。<goalState><position> になります

これ以外 (道路網、他車、その軌跡) はすべて描いたものから導出されます。

車両に印が付くまで、CommonRoad の書き出しは (シナリオも solution も) 次の 1 行を 出して止まります。

CommonRoad needs a planning problem. Select the vehicle, turn on "Ego (external control)" in the Attributes panel, then pick its Goal lane in the "CommonRoad" section that appears below it.

車両を選択し、Attributes パネル上部のチェックボックスを入れます。

Ego という名前の車両の Attributes パネル。「Ego (external control)」がチェックされ、その下に COMMONROAD グループが開いていて Goal 行に「Pick lane」ボタンが見えている

チェックボックス 1 つ。この車両を「被試験対象 (SUT)」= drawtonomy ではなく planner (または外部シミュレータ) が動かす actor として指定します。

この印が、あらゆる場面での「ego」を決めます。エクスポート時の planning problem に なるのもこの車両で、読み戻した解が適用されるのもこの車両です。印を持てるのは 1 台だけです。

チェックボックスの下の COMMONROAD グループがゴールを持ちます。Pick lane を押すと、 キャンバスは「ゴールを始めたいレーン上の位置」のクリックを待ちます。

drawtonomy のキャンバス。上部に「Click the lane where the goal starts (Esc to cancel)」のヒントが出てレーンが青く色付き、右の Attributes パネルでは Goal 行の Pick lane ボタンが押された状態になっている

Pick lane でキャンバスが待機状態になります。Esc ならゴールを変えずに中断します。

レーンをクリックすると、その地点から前方 50 m の区間がゴール領域になり、キャンバス上で ハイライトされ、パネルに名前が出ます。

1 本のレーンの 50 m 区間がゴール領域として薄い黄土色でハイライトされたキャンバスと、Goal 行に「Lane 10」、その横に 62.1 と 112.1 m の 2 つの数値欄とクリアボタンを表示している Attributes パネル

ゴール区間。道路上でハイライトされ、パネルにはレーン名が出ます。レーン名の横の 2 つの数値がレーン沿いの始点と終点 (メートル) です。レーン名はそのまま別のレーンを 選び直すボタンで、× はゴールを消します。

ゴールについて知っておくとよいことがいくつかあります。

  • レーンに沿った区間は伸縮でき、書き出される形も区間で決まります。 Pick lane は クリックした地点から 50 m を置きます。ハイライトされた帯の両端のハンドルをドラッグ するか、2 つの欄に始点と終点のメートルを打ち込みます (Enter か欄を離れると反映され、 undo 1 回で戻ります)。どちらで直してももう一方が追従します。ゴールは lanelet 全長 ではなくその区間 (s0–s1) です。値はレーンの中に収まり、始点と終点は 2 m 以上 離れます。区間はレーンのその部分を覆う <polygon> として書き出され、lanelet 参照には なりません。区間をレーン全体 (0 からレーン長まで) にすると区間指定は消え、ゴールは <lanelet ref> として書き出されます。50 m 以下のレーンは最初からレーン全体がゴールに なるので、これも <lanelet ref> です。
  • ゴール速度区間は任意です。 ゴールレーンの下の Goal speed limit を入れると、 エクスポートは <velocity><intervalStart>0</intervalStart><intervalEnd>v</intervalEnd> を 書きます。これが「ゴールに v 以下の速度で 到達する」の表し方です (停止まで 求めるなら v を 0 にします)。
  • 時間窓と向きも任意です。 Goal time を入れて秒で窓を打つと、エクスポートは time step に直して書きます (round(t / dt)。dt 0.1 なら 4.3 s は step 43)。 Goal heading を入れて許す向きを度で打つと (CommonRoad と同じく +x から反時計回り)、 ラジアンで書きます。Goal heading を入れた直後はゴールレーンの向き ±15° です。 速度上限と組み合わせると「6 秒以内に、レーンに沿った向きで止まる」を表せます。 インポートしたファイルは、そのファイルの時間窓 (と、あれば向き) が入った状態で 開きます。チェックを外すとファイルの値がそのまま残ります。

再生中、ego はゴールに向かって走りません。ゴールは planner に渡す制約であって 経路ではありません。

CommonRoad の goalState は最大 4 種類の制約を持てます。パネルでは 4 種類とも 編集でき、触らなかったものは原文のまま書き戻されます。

判定基準パネルで編集可能インポート時 (無編集)
位置 (lanelet 参照)Yes: レーン全体。50 m 以下のレーンで Pick lane するか、区間を 0 からレーン長までにする原文のまま保持
位置 (レーンの一区間)Yes: それより長いレーンで Pick lane (既定 50 m) + s0–s1 の区間欄。<polygon> として書く
位置 (ファイルの矩形・円・多角形)No (レーンを選ぶと置き換わる)原文のまま保持
速度Yes: Goal speed limit チェックボックスで [0, v] を書く変更していなければ原文のまま保持
時刻Yes: Goal time (秒)。整数の time step で書く変更していなければ原文のまま保持
向きYes: Goal heading (度)。ラジアンで書く変更していなければ原文のまま保持

編集は自分の要素だけを置き換えます。ゴールレーンを選ぶと position だけ、 時間窓を変えると <time> の中の 2 つの数値だけ、向きを足すと <orientation> が 1 要素増えるだけです。触らなかったものはファイルが宣言したとおりに残ります (planner が解くべき問題そのものを定義する値だからです)。どの区間を置き換えたかは エクスポート時のトーストが伝えます。

レーンを選び直したときに原文の position を保つか置き換えるかは、以下で 決まります。

  • 原文が lanelet ゴールの場合: 選んだレーンが原文と同じ lanelet (複数参照なら同じ集合) なら位置は逐語で保持されます。パネルがその lanelet 上に区間を表示していても同じで、書き戻されるのは原文の <lanelet ref> で あり、区間は書かれません。別のレーンを選ぶと位置だけが置き換わり、 区間なら <polygon> (トーストがそう言います)、レーン全体なら <lanelet ref> になります。time / orientation / velocity の区間は そのまま残ります。
  • 原文が矩形・円・多角形ゴールの場合: インポート直後に見える区間は、 drawtonomy がその形状から導いたレーンと区間です。そこに触れなければ 原文の形状がそのまま再エクスポートされます。レーンを選ぶ、または区間を 変えると位置が置き換わり、原文の形状は失われます。区間なら <polygon>、 レーン全体なら <lanelet ref> として書かれます。
  • 原文に位置制約が無い場合: レーンを選ぶと新しく追加されます。失うものは ありません。

編集できるのはファイル内の最初の planningProblem だけです。2 つ目 (協調シナリオ) は無編集のまま持ち越されます。レーンの選択、速度上限・時間窓・ 向きの編集が変えるのは 最初の goalState だけで、それ以降の goalState (代替 ゴール) は無編集のまま持ち越されます。通知には何個保持したかが出ます。

既存の OpenSCENARIO を開いて CommonRoad として書き出す

Section titled “既存の OpenSCENARIO を開いて CommonRoad として書き出す”

シーンを描く必要はありません。既に持っている .xosc も、同じ 2 つの前提を通せば CommonRoad シナリオになります。

  1. OpenSCENARIO ファイルを開く。 .xosc と .xodr を一緒にキャンバスへ ドロップするか、Import… で .xosc を選び、続けて .xodr を指定します。 道路網はレーンに、各アクターは軌跡を持つ車両になります。詳しい手順は .xosc を開いて再生する。

  2. GitHub から直接開くこともできます。 ダウンロード不要で、ファイルの GitHub URL を ?open= に続けるだけです。隣にある .xodr とカタログはその URL からの相対で解決されます。

    https://drawtonomy.com/?open=https://github.com/esmini/esmini/blob/master/resources/xosc/cut-in.xosc
  3. 一度再生する。 軌跡は再生の記録から作られるので、書き出しには 1 回の 再生が必要です。無い場合は他車の初期状態だけが書かれ、その旨が表示されます。

  4. ego に印を付け、ゴールレーンを選ぶ (上記のとおり)。OpenSCENARIO の ego は そのままでは CommonRoad の planning problem になりません。CommonRoad には ゴールも必要で、それがどのレーンかを知っているのは作った人だけです。

  5. Export ▸ CommonRoad (.xml)。

引き継がれるもの: lanelet としての道路網、各アクターが走った軌跡を持つ dynamicObstacle、ego の初期状態、選んだゴールレーン。引き継がれないもの: OpenSCENARIO の storyboard そのもの。CommonRoad にはトリガーもアクションも 無いので、planner が受け取るのはストーリーそのものではなく、それを dt = 0.1 s でサンプリングした 結果 です。

OpenSCENARIO の時間は連続する秒数、CommonRoad の時間は 0 起点の離散 ステップ数です。どちらの向きも次の規則で対応します。

方向規則
インポート (CommonRoad → シナリオ)ステップ k は t = k · dt になる (dt はファイルの timeStepSize)
再生drawtonomy はファイルの dt によらず、内部固定の 0.05 s ステップで再生する
停止条件シナリオの SimulationTimeCondition は (最終ステップ) · dt + 1 秒に設定される。これは最後の障害物またはゴール区間のステップより 1 秒後で、軌跡が終わる前に再生がタイムアウトしないようにするため
エクスポート (シナリオ → CommonRoad)記録した再生を固定の dt グリッドに再標本化する (開いたファイルが別の timeStepSize を宣言していない限り既定 0.1 s)。lastTimeStep = floor(durationSec / dt)
Solution (planner の解)ステップ k は t = k · dt になり、インポートと同じ規則。drawtonomy はファイルの番号を振り直さない: ステップ 1 から始まる解は、その番号のまま再生され、0 起点に付け替えられることはない。t = 0 の state は planningProblem の initialState から取る。そのため 1 起点の解は、初期状態から続く 1 本の連続した軌跡として再生される。ただし公式 checker はそのような解を不合格にする (starts_at_correct_state は先頭 state がステップ 0 の初期状態であることを求める)。そのため初期状態から始まらない解を読み込むと、閉じるまで消えない琥珀色の通知が出る。例: Solution does not start at the planning problem's initial state (expected time_step=0, received 1). The official checker (valid_solution) rejects it.

dt 自体はキャンバスで編集できません。開いたファイルの timeStepSize が 再生・再エクスポートの両方でそのまま使われます。

verdict サイドカーの timeSteps も 0 起点です。あるステップの秒数は、そのシナリオが使う dt で step × dt になります。

シーン上の他の車両はすべて、記録済み軌跡を持つ dynamicObstacle になります。 ある actor がシナリオの一部の時間しか存在しない場合 (ストーリーボードの Add Entity で t = 4 s に登場し、Delete Entity で消える)、エクスポートは その区間をそのまま障害物の [initial, final] タイムステップとして書き、区間外では その障害物は存在しません。再生も同じで、追加前と削除後はキャンバスに居ません。 ファイルを読む planner からは「終端後もずっと走り続ける障害物」ではなく、 終わりのある障害物として見えます。

描いたレーン 1 本が、長さにかかわらず lanelet 1 つになります。1 本のレーンが短い lanelet の連なりに分割されることはありません。横並びのレーンには adjacentLeft / adjacentRight が書かれますが、successor / predecessor が 書かれるのは、あるレーンの終端が次のレーンの始端に実際に接している場合 (境界の左右両方の角が 5 cm 以内) だけです。したがって並走する通し車線だけの シーンは、隣接関係はあるが successor も predecessor も 1 つも無い ファイルとして書き出されます。

直線の lanelet は頂点が 2 個しかありません

Section titled “直線の lanelet は頂点が 2 個しかありません”

境界は、描いたレーンが持つ点の数だけで書き出されます。直線は 2 点で足りるので、 leftBound / rightBound / centerVertices はいずれも、lanelet がどれだけ長くても ちょうど 2 頂点になります。一定間隔に点を水増しすることはしません。120 m の直線は 120 m 離れた 2 頂点です。

CommonRoad の 2 項目は同じ Export サブメニューにあります。

ハンバーガーメニューの Export サブメニューが開いた状態。IMAGE / MAP / SCENARIO / SHARE の見出しで分かれ、SCENARIO の OpenSCENARIO (.xosc)… に続く CommonRoad (.xml) と CommonRoad solution (.xml) が 1 つの枠で囲まれ、その下に Telemetry (.csv) / Video (.webm)… が並ぶ

項目何を書き出すか
CommonRoad (.xml)シナリオ。lanelet 網、dynamicObstacle の軌跡、ego の planningProblem。planner が読むのはこのファイルです。
CommonRoad solution (.xml)解。いまキャンバスで ego がしていることを、そのまま CommonRoadSolution として書きます。4 つの場合は下の表を見てください。

solution のエクスポートが書くもの

Section titled “solution のエクスポートが書くもの”

規則は 1 行です。キャンバスで見えている ego をそのまま書きます。 どの場合 だったかは、書き出した直後のトーストが 1 行で言います。

ego がしていること書き出されるもの
読み込んだ解のとおりに走っていて、ego を触っていないその解ファイルそのもの (バイト単位で同一)。モデルは KS なら KS のまま、時刻の起点も数値も書式も原文のままです。
読み込んだ planning trace のとおりに走っていて、ego を触っていないtrace の ego 状態列を質点モデル (pmTrajectory) の解に変換したもの。planning trace は解の形式ではないので、そのまま写せる原文がありません。trace と一緒に solution ファイルも読み込み、trace の solutionFingerprint がそれと一致していれば、代わりにその solution ファイルがバイト単位で同一のまま出ます (planning trace を参照)。
自分で与えた軌跡 (Add Path、または開始位置・初速の変更) に従っているその軌跡を質点モデルの解にしたもの。自分の編集は、読み込んだ解より優先されます。
解を読み込んでおらず、初期位置に止まったまま止まったままの解 (すべての state が初期位置・速度 0)。断らずに書き出しますが、公式 checker が受け入れるのは ego の初速が 0 から 2.0 m/s 以内のときだけです。初速がそれより大きいと公式 checker はこのファイルを不合格にする (starts_at_correct_state の速度の許容は 2.0 m/s) ので、これは置き場所としての解にすぎず、トーストもそう言います。例: The official checker (valid_solution) rejects it (expected velocity=4.0143, received 0), so it is only a placeholder. 動かす 2 つの方法 (Add Path / solution を drop) もトーストが案内します。

benchmark_id の先頭は PM<n> で、n は描いた ego の全長・全幅に一番近い VehicleType (1〜3) です。checker はこの数字から ego の箱を作るので、自分の車両に 合っていることに意味があります。

エクスポートを止めるものは 1 つだけで、直す場所を 1 行で言います。ego なし / ゴールレーンなし、上の 2 つの前提です。

録画なしでもシナリオのエクスポート自体は通りますが、そのことを言います (Play the scenario first to include NPC trajectories)。他車は軌跡なしの初期状態 だけになります。完全なファイルが欲しければ 1 回再生してから書き出してください。