11分

VDA 5050の時系列障害を根拠付きで診断するOSS vda5050-lab

roboticsvda5050rustmqttopen-source

VDA 5050を使った倉庫ロボットのcommissioningでは、JSON Schemaへの適合だけでは判断できない障害が発生します。個々のorderやstateが構文上正しくても、複数topicをまたぐ時系列、接続の切り替わり、送信主体、観測漏れを考慮しなければ原因を特定できません。

この課題に対して、MQTT traceから観測事実・仕様上の期待・不足証拠・次に確認すべき対象を分けて出力するOSS vda5050-lab を実装しました。

課題

対象とする課題は次の4点です。

  1. 単一メッセージの検証では状態遷移を評価できません。 reconnect、order update、cancel、action lifecycleは複数メッセージの前後関係で決まります。
  2. 受動ログでメッセージの不在を常に証明できるとは限りません。 capture開始前の状態、QoS 0の欠落、観測地点の違いを区別する必要があります。
  3. 多台数ではidentityの誤結合が診断結果を変えます。 topic、serialNumber、MQTT ClientId、participant、connection epochをrobotごとに分離しなければなりません。
  4. 再現用デモの表示と診断対象のtraceが一致している必要があります。 画面上の動きだけを別に作ると、診断器の実動作を検証できません。

v0.2.0では、このうち再接続診断を対象に、1・2・5・10・50・100台を同じ契約で接続・記録・診断する検証基盤を実装しました。

1・2・5・10・50・100台のVDA 5050デモを並べたoverview
1・2・5・10・50・100台のVDA 5050デモを並べたoverview

解決方針と実装

デモは、隔離したDockerネットワーク内で次を一気通貫に実行します。

  1. 使い捨てのEclipse Mosquittoを起動します
  2. N台の仮想Mobile Robot、Fleet Control、Recorderを同時接続します
  3. 全ロボットへ固有のVDA serialNumber、topic、MQTT ClientId、order ID、経路を割り当てます
  4. demo-001だけを異常切断し、brokerのLWTでCONNECTION_BROKENを発行します
  5. 同じparticipantを新しいconnection epochで再接続しますが、意図的にretained ONLINEを送りません
  6. broker-egressの観測をcanonical traceへ保存します
  7. ネットワークを持たないDoctorコンテナがtraceをオフライン診断します
  8. manifest、trace、evidence、reportの整合性を検証して全コンテナを破棄します
Scenario runner
  └─ Docker internal network
      ├─ Mosquitto
      ├─ Virtual robots × N
      ├─ Fleet actor
      └─ Recorder

            ├─ run-manifest.json
            ├─ trace.canonical.jsonl
            └─ synthetic-evidence.json

                         ▼ network disabled
                   vda5050-doctor

                         └─ doctor-report.json

brokerのportはホストへ公開しません。Doctorにはnetwork_mode: noneを指定しています。retained messageを使うため、規模ごと・fault/controlごとに新しいbrokerとnetworkを作り、前回の状態が次の判定へ混入しないようにしました。

多台数でのidentity分離検証

このデモではN台すべてが同じbrokerへ同時接続し、それぞれ別のidentityと経路を持ちます。renderer上のrobot数だけでなく、run manifestとcanonical traceに含まれる固有identity数も検証します。

ロボット数同時MQTT接続上限記録されたbroker-egressメッセージ
1310
2418
5742
101282
5052402
100102802

接続数は「N台 + Fleet Control + Recorder」です。メッセージ上限、60秒の実行時間、actor数、MQTT接続数をrun manifestに先に固定し、超過したrunは不完全な成功ではなく失敗にします。

100台の固有identityとx/y経路を表示したVDA 5050デモ
100台の固有identityとx/y経路を表示したVDA 5050デモ

x/y座標の定義

各ロボットの位置は、VDA messageに入るプロジェクト固有のmap座標として生成します。mapIdwarehouse-demo、単位はメートル、左下原点はこの合成デモだけの表示規約です。

0始まりのrobot indexをiとすると、座標は次のとおりです。

column       = floor(i / 10)
row          = i mod 10
start        = (6 × column,     2 × row)
released_end = (6 × column + 4, 2 × row)
horizon_end  = (6 × column + 4, 2 × row + 1)

したがって、demo-001(0, 0) → (4, 0) → (4, 1)demo-100(54, 18) → (58, 18) → (58, 19)を通ります。rendererはmanifest上の予定座標ではなく、実際にtraceへ記録されたorder/state/visualization payloadのx/yを読んで描画します。

この間隔は経路を見分けるためのものです。robot footprint、制動距離、allowed deviation、衝突回避、実倉庫の安全余裕を証明する値ではありません。

証拠の強さに応じた判定

今回の診断ルールLAB-D4-RECONNECT-STATEは、VDA 5050 3.0.0のconnection lifecycleを対象にしています。異常切断ではbrokerがLWTのCONNECTION_BROKENを送り、再接続したrobotはretained ONLINEを送る、という関係を確認します。

同じ異常シナリオでも、Doctorへ渡す証拠によって結論を変えます。

入力結果意味
subscriberが観測したtraceだけINCONCLUSIVE / UNRESOLVEDpublisherの役割、connection epoch、capture完全性を証明できません
trace + 同一runに束縛されたbroker/session evidenceFAIL / MOBILE_ROBOT新epochのstateはありますが、期待するONLINEを観測できませんでした
reconnect後にONLINEを送るcontrol traceD4 findingなしこの合成controlでは期待メッセージを観測しました

「見えなかった」を即座に「送られなかった」へ変換すると、相手ベンダーを誤って責める可能性があります。VDA 5050の主要topicにはQoS 0もあるため、受動subscriberだけで不在を証明できない場面があります。そこで、raw observationと外部assertionを分離し、evidence manifestをtrace digestへ束縛しました。

なお「findingなし」は一般的なPASSや適合認証ではありません。単にこのルールの異常条件が、この合成controlでは成立しなかったという意味に限定しています。

利用方法

必要なのはDocker Compose、jq、repository checkoutです。最初は10台だけを実行できます。

git clone https://github.com/ekusiadadus/vda5050-lab.git
cd vda5050-lab
make demo-fleet DEMO_ROBOTS=10

公開している6規模をすべて実行する場合は、次のコマンドを使用します。

make demo-fleet-e2e

成功すると、各規模にrun-manifest.jsontrace.canonical.jsonlsynthetic-evidence.jsondoctor-report.jsonが残ります。READMEのGIF/MP4は、この成果物とreportのdigestを検証したrendererから生成します。表示に使う座標とidentityもtrace payloadから取得します。

バイナリ、全6規模のMP4/GIF、overview、SHA256SUMSはv0.2.0 Releaseから取得できます。

何を証明していないか

100台デモは、隔離環境で100台の仮想MQTT actorを扱い、identityを混同せず、同じ診断契約を維持できたという機能結果です。次の主張には使用できません。

  • 100台の実機を接続したわけではありません
  • 100社・100vendor間の相互運用性を確認したわけではありません
  • production fleetでのcapacityやreal-time性能を保証するものではありません
  • 衝突回避、機能安全、現場ネットワークの安全性を検証したわけではありません
  • VDA 5050全体への適合認証を行ったわけではありません

デモとベンチマークと適合試験を混ぜないことは、このプロジェクトの設計原則でもあります。

残る課題と今後の範囲

v0.2.0は、合成traceで証拠モデルを端から端まで検証した段階です。次は、匿名化できる実障害traceを集め、order update、base/horizon stitching、newBaseRequest、cancel、action lifecycle、2.1から3.0への移行診断を追加します。

対象範囲は一般的なviewerではなく、VDA 5050通信と状態遷移の診断に限定します。commissioning中のengineerがログを入力したとき、次の情報を返すことを目標とします。

  1. 何が起きたか
  2. どのmessageが証拠か
  3. どの仕様節が関係するか
  4. 何が未観測で断定できないか
  5. Robot、Fleet Control、通信のどこを次に調べるか

実際のinteroperability障害traceを共有できる場合は、GitHub Issuesからご連絡ください。公開できないtraceについては、未知fieldやparse不能payloadを安全側で拒否するpseudonymization要件を、データ提供者と確認しながら設計します。