ロボットの「遅い」「失敗した」という記録を、原因の追跡につながる観測へ変えるには何が必要かを整理します。
先に結論
ロボットの遅延や失敗を再現可能な形で調べるには、単一ノードのログではなく、センサー取得からアクチュエータ応答までを一つの実行単位として記録します。各境界に run_id、trace_id、span_id、親子関係、メッセージのシーケンス番号、複数の時刻、処理状態を付与し、分散トレースとメッセージ記録を組み合わせるのが基本です。
遅延は推論時間だけでなく、センサー取得、通信、キュー待ち、前処理、推論、制御計算、出力送信まで分解します。コード、モデル、設定、キャリブレーション、QoS、ファームウェア、乱数種、クロック設定も同じ調査単位に保存します。これにより、認識誤り、通信遅延、制御逸脱、安全停止の発生箇所と条件を追跡しやすくなります。
なぜ横断的な観測が必要か
Physical AIでは、センサー、ROS 2通信、前処理、推論、計画、制御、ドライバ、アクチュエータが別々の処理として動きます。「入力を受けた」というノードの記録は、センサーの露光時刻を示すとは限りません。同様に、制御コマンドをpublishした時刻と、アクチュエータが実際に受け付けた時刻も異なる可能性があります。
そのため「推論が遅い」という症状だけでは、原因が通信、executorの待ち時間、キュー滞留、前処理、推論、出力送信のどこにあるか分かりません。処理経路を共通の相関情報で結び、区間ごとの時間と状態を比較できるようにします。
前提となる仕組み
OpenTelemetryのトレースは、処理経路を複数の span の集合として表します。spanには開始・終了時刻、属性、イベント、ステータスを付けられます。ログが個別の出来事、メトリクスが集計値を扱うのに対し、トレースは一回の処理経路を表します。
W3C Trace Contextは、trace-id や parent-id などを分散コンポーネント間で伝播する標準形式を定義しています。ただし、ROS 2のDDS通信でこのコンテキストが自動的に伝播するとは確認できません。ROS 2ノード、メッセージ、middleware、またはブリッジ側で接続方法を設計する必要があります。
ROS 2には、LTTngとROS 2固有のtracepointを使い、ノード、通信、コールバック、executorなどを時系列で観測する ros2_tracing があります。アプリケーション固有の前処理、推論、制御には追加の計測点を設けます。rosbag2 はROS 2のトピックメッセージを記録・再生する仕組みで、トレースとは異なり、入力や中間メッセージを再利用するための記録系です。
計測する境界とデータフロー
個別のspanまたはイベントとして、次の境界を計測します。
- センサー取得、ドライバ内のcapture
- middlewareへのpublishと受信
- キューへの投入・取り出し、callbackの開始・終了
- 前処理、推論、計画またはポリシー出力の開始・終了
- 制御計算、制御出力の生成
- アクチュエータへの送信と応答
各記録には、ノード名、トピック名、入力・出力時刻、成功・失敗・期限超過などの状態も含めます。高頻度センサーのペイロードをトレースへ常時埋め込むのではなく、参照ID、ハッシュ、要約統計を置き、完全なデータは別の記録系で保持する構成が扱いやすくなります。
flowchart LR A["センサー取得・ドライバcapture"] --> B["middleware publish"] B --> C["middleware受信"] C --> D["キュー投入・取り出し"] D --> E["callback開始・終了"] E --> F["前処理"] F --> G["推論"] G --> H["計画・ポリシー出力"] H --> I["制御計算・出力生成"] I --> J["アクチュエータ送信"] J --> K["アクチュエータ応答"] M["共通の相関情報\nrun_id または episode_id\ntrace_id・span_id・親span\nシーケンス番号・処理状態"] -.-> A M -.-> B M -.-> C M -.-> D M -.-> E M -.-> F M -.-> G M -.-> H M -.-> I M -.-> J M -.-> K T["時刻の併記\nSteady Time: 経過時間\nROS Time: 再生・シミュレーション\nSystem Time: ホスト間相関"] -.-> A T -.-> K
時刻を用途別に分ける
遅延や経過時間の計測には、単調増加を前提とするSteady Timeを使います。シミュレーションや再生上の時系列にはROS Timeを使いますが、外部クロックやシミュレーション時間を扱える一方、クロック更新や時間のジャンプが起こり得ます。複数ホストの相関や人間向けの記録にはSystem Timeを併記します。
| 時刻 | 主な用途 | 注意点 |
|---|---|---|
| Steady Time | 区間時間、遅延、キュー待ち | 時刻のジャンプを前提にしない |
| ROS Time | シミュレーション、再生、外部クロック | 時間のジャンプがあり得る |
| System Time | ホスト間の相関、人間向けの時刻 | 経過時間の基準として単独利用しない |
遅延と失敗を同じ実行単位で読む
エンドツーエンド遅延は、次の区間を連結して確認します。
センサー取得 → 通信 → キュー待ち → callback → 前処理 → 推論 → 制御計算 → 出力送信 → アクチュエータ応答
平均値だけでなく、どの区間でジッターや期限超過が発生したかを見ます。終点は、制御コマンドのpublish、ドライバ受信、モータードライバへの送信、実際の機械応答のどれを採用するかで意味が変わります。目的に合わせて終点を明示し、必要なら複数の指標として保存します。
失敗ログには、失敗したステージ、期待値と観測値、エラーコード、タイムアウトまたは期限超過、入力データ参照、直前のspan、実行環境、採用した安全動作を含めます。通信ではアプリケーションログだけでなく、ROS 2 QoSのdeadline、liveliness、lifespan、キュー状態、メッセージ欠落も観測します。reliability、durability、history、depth などの実行時設定も保存対象です。
観測手段の使い分け
| 手段 | 得意な対象 | 主な用途 | 制約 |
|---|---|---|---|
| 分散トレース | span間の経路と区間時間 | 遅延、因果関係、親子処理 | 大容量ペイロードには不向き |
| 構造化ログ | エラー、状態、期待値と観測値 | 失敗理由、安全動作の確認 | 経路全体の時間関係は別設計 |
| メトリクス | 遅延分布、欠落、期限超過 | 常時監視、異常検知 | 個別runの入力内容は分からない |
| rosbag2 | ROS 2メッセージ | 入力・中間データの再利用 | 物理状態や外界は再現しない |
通常時は低負荷のトレース、メトリクス、構造化ログ、bagへの参照を保存し、期限超過、キュー滞留、安全停止、推論異常を検知したrunでは全量保存またはtail-based保存に切り替えます。異常直前のデータを残せることが重要です。
リプレイの範囲と制約
rosbag2の再生は、記録済みのROS 2メッセージを再投入する仕組みです。未記録のハードウェア状態、外界の変化、executorのスケジューリング、乱数、アクチュエータの副作用まで含む完全な決定論的再現は保証しません。
調査単位には、bagまたは同等のメッセージ記録に加え、コードリビジョン、モデルのダイジェスト、コンテナや依存関係、設定、キャリブレーション、ROS 2ディストリビューション、RMW実装、DDS QoS、ファームウェア、乱数種、クロック設定を保存します。実機の問題では、ドライバ、ハードウェア、外部計測器に追加のタイムスタンプ点を設けます。ソフトウェアトレースだけで、センサーの露光やアクチュエータの物理応答まで観測できるとは限りません。
採用判断
原因が一つのノード内で完結するなら、構造化ログとメトリクスから始めます。複数ノード、複数ホスト、推論アクセラレータ、DDS通信をまたぐなら、ros2_tracing または同等のspan計測と相関IDを導入します。入力データや認識結果を確認したい場合はrosbag2を併用します。
実機の安全動作や物理応答が問題になる場合は、ドライバやハードウェア側の計測を追加します。なお、ros2_tracing、OpenTelemetry、rosbag2を同時に有効化した際のCPU負荷、ストレージ容量、リアルタイム性への影響は、機器と記録設定ごとのベンチマークが必要です。観測そのものが制御周期を乱さないかを導入前に確認します。
まとめ
ロボットの可観測性は、ログを増やすことではなく、センサーから行動出力までの因果関係を同じ実行単位で結ぶ設計です。相関ID、シーケンス番号、区間span、用途別の時刻、QoS状態、入力データ、実行環境を揃えます。トレースは経路、rosbag2はメッセージ、ログは失敗理由、メトリクスは傾向を担わせ、異常時には保存粒度を上げます。
参考情報
- Using ROS 2 tracing
- rosbag2: ROS 2 bag file format and recording/playback
- W3C Trace Context
- Traces | OpenTelemetry
- Clock and Time
- About Quality of Service settings
エンドツーエンド遅延の区間分解
flowchart LR A["センサー取得\nsensor_age"] --> B["通信\ntransport"] B --> C["キュー待ち\nqueue_wait"] C --> D["callback"] D --> E["前処理\npreprocess"] E --> F["推論\ninference"] F --> G["制御計算\ncontrol"] G --> H["出力送信\noutput_transport"] H --> I["アクチュエータ応答\nactuator_ack"] X["区間ごとに開始・終了時刻を記録し、遅延とジッターを比較"] -.-> A X -.-> I Y["異常イベント\nタイムアウト・欠落・再送\ndeadline miss・キュー滞留"] -.-> C Y -.-> B Y -.-> I
通常時の観測から異常時の再現までの保存パイプライン
flowchart TD
A["実行run"] --> B{"異常を検知したか"}
B -- "いいえ・通常時" --> C["低負荷の分散トレース"]
B -- "いいえ・通常時" --> D["メトリクス"]
B -- "いいえ・通常時" --> E["構造化ログ"]
B -- "いいえ・通常時" --> F["rosbagへの参照ID"]
B -- "はい・期限超過や安全停止など" --> G["対象runの保存粒度を上げる"]
G --> H["全量またはtail-basedのメッセージ記録"]
G --> I["トレース・ログ・メトリクス"]
G --> J["コード・モデル・設定・キャリブレーション\nQoS・ファームウェア・乱数種・クロック設定"]
H --> K["再現用manifestとreplay環境"]
I --> K
J --> K
K --> L["rosbag2再生と条件比較"]
L --> M["未記録の物理状態や外界は別途確認"]可観測性の設計では、記録量を増やすことより、処理経路と再現条件を結び付けることが鍵になります。
AI利用に関する注記
本サイトの記事は、複数のAIエージェントによる調査・執筆・レビューを経て公開しています。正確性と品質の向上に努めていますが、内容については必ず一次情報をご確認ください。