1

ROS 2 アプリケーションのリアルタイム性検証の取り組み
CARET によるEnd-to-End レイテンシ評価

ROSCon JP 2021
2021/9/16
システム計画研究所
長谷川 敦史本プロジェクトは東大様および Tier IV 様と合同で進めているプロジェクトです。

会社紹介

2

◼ （株）システム計画研究所（ISP）◼ 1977 年創業◼ 研究開発型のソフトウェア会社◼ 事業分野

人工知能

医療情報

画像処理

技術情報サイト
宇宙・制御

通信
ネットワーク◼ 東大様および Tier IV 様と合同で Autoware の性能解析に取り組む

背景｜ROS に求められる性能要求3◼ ロボット（ROS）は正常な動作のために、パフォーマンスやリアルタイム性が求められる所定の処理に時間要求があること

システム
Sense

PlanAct
通信の遅延

CameraNode

NodeController
Node

LiDAR
Node

Node

Node
ノードの遅延アプリケーション（End-to-End）の遅延

外界・環境指針を立てるためにも、まずは測定することが重要

性能測定の手法｜トレース

4◼ プログラムに測定用のソースコード埋め込み、コードが実行される度に記録をしていく方法
tracepoint(“start”);
task();
tracepoint (“end”);

実行時間 ＝ t end – t start [s]◼ トレースポイントには付加情報をつけることもある
tracepoint(“publish”, データサイズ);

バンド幅 [Byte/s] = 1 秒間あたりのデータ量

性能測定の手法｜プロファイリング

5◼ 特定のイベントが一定数発生した際に実行状態を記録
event

event

event

割り込み処理sample の記録- プログラムカウンタ- スタック

event

event

event

割り込み処理sample の記録

event

時間 [s]◼ クロックを event とした場合、実行時間の多い処理ほどサンプルが多くなる⇒ ボトルネックがサンプル数の多い処理として検出される◼ event は キャッシュミス、ページフォルトなど指定可

既存ツールの紹介｜Linux の測定ツール

6◼ プロファイリングツール：perf, vtune, ...
◼ トレースツール：Linux Trace Toolkit ng, ...

perf の 出力例 （ Flame Graph ）vtune の出力例 （System Overview）◼ ボトルネックとなっている処理やリソース特定などに有用◼ プロセス単位の測定なので、ノードの評価が困難なことも既存ツールの紹介｜ROS 2 の測定ツール◼ ros2 topic$ ros2 topic hz /topic：メッセージ受信周波数 [Hz]$ ros2 topic bw /topic：メッセージのバンド幅 [Byte/s]$ ros2 topic delay /topic ： 現在時刻 – msg.header.stamp [s]※ メッセージの型に header が必要※ publish 時、現在時刻を msg.header.stamp に代入する必要あり◼ ros2 trace$ ros2 trace：トレースポイントの記録$ ros2 trace-analysis：記録したトレース結果の解析※ Linux のみ。 ros2 trace 関連の追加インストールが必要
コールバック実行時間
user code (callback)rclcpp初期化時の情報も出力

トレースポイントros2 trace の主要なトレースポイントと測定対象

7

既存ツールの課題・新規ツール開発の動機

8◼ 課題◼ Linux ツール：ROS アプリケーションの内部動作が把握しにくい◼ ROS ツール：評価対象が限定的・メッセージ型の制約
ros2 trace の拡張
Apache 2.0※Galactic のみ対応

◼ 動機

◼ ノードやアプリケーションの評価がしたい⇒ Chain-Aware ROS Evaluation Tool (CARET) を開発◼ 通信◼ コールバック

ROS ツール[.msg]Header header***CARET◼ ノード◼ アプリケーション[.msg]***ROS ツール
要 Header

CARET
任意の型

測定対象

測定可能なメッセージの型

ROS アプリケーションのより詳細な評価が可能

任意のメッセージ型の測定が可能

CARET｜測定対象

9
NodeNode◼ メッセージの流れをトラッキングCallback◼ コールバックグラフを再構築し、トレース結果からノードレイテンシなどを算出

Callback

NodeCallback

コールバックグラフ
End-to-Endレイテンシ
コールバック実行時間

ノード実行時間

user code (callback)
RCL の通信レイテンシ

rclcpp メッセージの流れ
rcl
rmw

publishDDS の通信レイテンシ

DDS

CARET の主要なトレースポイントと測定対象

Callback

CARET｜サンプルアプリケーションの測定

10◼ ロボットのノード構成を単純化したアプリケーションを例に、
CARET による測定方法を説明していきます
周波数はすべて 10 Hz/drive/sensor’/topic3/msg_driven/filter/sensor/topic4/timer_driven/actuator/topic2/topic1
評価対象のサンプルアプリケーション
エグゼキュータ：MultiThreadedExecutor
各トピックの周波数は 9.8~10 Hz
平均値上はおおむね動いている様子「意図せず以下の実装となっていた」というシナリオで CARET で測定します。
QoS history size : 10/filter コールバックの実行時間はまれに 200 ms

CARET による評価の流れ

11
今回はここから説明

STEP0

STEP1

STEP2

STEP3

STEP4

環境構築

測定の設定

測定

評価準備

性能評価

トレース
結果

アーキテクチャ
ファイル

ビルド
CARET

CARET

トレース用
フックライブラリ

解析用
パッケージ

ROS App

コールバックグラフを記述したファイル

CARET｜

STEP1,2測定の設定・測定12

測定の設定◼ launch ファイルの修正[.launch.py]
def generate_launch_description():return launch.LaunchDescription([Trace(session_name=‘my_trace_session’,events_kernel=[],カーネルのトレースを無効化
events_ust=[‘ros2*’]
ros2 trace と CARET のトレースを有効化),
launch_ros.actions.Node(...),])◼ 環境変数の設定共有ライブラリの探索で優先される。
フックによりトレースポイントの追加$ export LD_PRELOAD=/path/to/libcaret.so

測定$ ros2 launch caret_demo end_to_end_sample.launch.py⇒ トレース結果が保存される。デフォルトでは~/.ros/tracing/my_trace_session

CARET｜

STEP3

評価準備

13

アーキテクチャファイルを作成する
コールバックグラフ構築に必要な情報を記述したファイル
トレース結果から雛形の自動生成が可能[.yaml]...
- node_name: /filter
callbacks:- callback_name: subscription_callback_0
type: subscription_callback
topic_name: /topic1
symbol: Filter::{lambda()#1}
publish:- topic_name: /topic2
callback_name: subscription_callback_0

コールバック情報◼ コールバック名◼ パラメータ◼ シンボル名

callback と publisher の紐付け

今回評価するパス/sensor’/sensor◼ ノード名

アーキテクチャファイルの中身

timer0

timer0

ノード情報

sub0/filter

sub0

sub1/msg_driven

sub0

timer0/timer_driven

アーキテクチャファイルが表現するコールバックグラフ

sub0/actuator

CARET｜

STEP4

性能評価

14

評価対象のパスを指定する◼ 評価対象のパスの始点と終点を指定し、パスの選択

import caret_analyze as caretlttng = caret.Lttng(‘トレース結果のパス’)
app = caret.Application(‘アーキテクチャファイルのパス’, file_type=‘yaml’, lttng)
path = app.search_paths(※ コールバック識別名 ＝ノード名／コールバック名‘/sensor/timer_callback_0’ ,‘/actuator/subscription_callback_0’ )[0]path.callbacks =timer0

sub0

sub0

sub1/sensor/filter/msg_driven

sub0

timer0/timer_driven

評価対象のコールバックチェーン

sub0/actuator

CARET｜

STEP4

性能評価15

コールバックチェーン上のメッセージの流れを可視化
import caret_analyze.plot as caret_plot
caret_plot.message_flow(path, granularity=‘node’)[raw / callback / node] が指定可

それぞれの線はメッセージの流れを示します。

ノードチェーン/sensor[start]

ノード間（end-start)
通信レイテンシ/sensor[end]

ノードレイテンシ/filter[start]/filter[end]/msg_driven[start]
msg_driven[end]メッセージのロスト/timer_driven[start]/timer_driven[end]/actuator[start]/actuator[end]jupyter 上での可視化を想定

時間 [s]/topic1 メッセージ数 315 個、その内 /actuator に到達したのは 290 個

CARET｜

STEP4

性能評価16◼ End-to-Endレイテンシの時系列を可視化
t, latency = path.to_timeseries()
plt.plot(t, latency * 1.0e-6)

実測：End-to-End レイテンシ：141 ~ 356 ms◼ コールバックチェーンのレイテンシを可視化
caret_plot.chain_latency(path, granularity=‘callback’)

最大 End-toEnd レイテンシの推定値＝各最大レイテンシの総和 ≒ 750 ms※ 最大値としては、楽観的（小さめ）な見積もり⇒ CARET での測定により、 ノードやアプリケーションの評価が可能にまとめ17◼ 動機◼ ROS2 アプリケーションの性能を評価したい◼ ツールの紹介◼ 既存のツール◼ Linux のツール
◼ ROS のツール

◼ CARET◼ 詳細ドキュメント
https://tier4.github.io/CARET_doc/
この成果は、国立研究開発法人新エネルギー・産業技術総合開発機構（ＮＥＤＯ）の助成事業（JPNP16007）の結果得られたものです。

参考資料

18

◼ Performance Analysis and Tuning on Modern CPUs
◼ 詳解 システム・パフォーマンス
◼ Getting started with ROS 2 tracing

19

補足資料｜アーキテクチャファイルの作成方法◼ 雛形の自動作成$ ros2 caret architecture -t trace_result –o architecture.yaml

トレースデータ

雛形の自動生成(CUI)

修正 (手作業)アーキテクチャファイル

◼ 修正コールバックグラフ◼ yaml ファイルを直接編集可視化 (CUI)◼ コールバックグラフの可視化

アーキテクチャファイル作成のフロー$ ros2 caret callback_graph –a architecture.yaml -o callback_graph.svg

コールバックグラフを可視化した例

補足資料｜メッセージフロー詳細

20

caret_plot.message_flow(path, granularity=‘raw’)# トレースポイントごとの結果を表示

トレースポイント/sensor/timer_0/start/sensor/timer_0/end/topic1/rclcpp_publish/topic1/rcp_publish/topic1/dds_write/filter/subscription_0/start/filter/subscription_0/end/topic2/rclcpp_publish/topic2/rcl_publish/topic2/dds_write/message_driven/subscription_0/start/message_driven/subscription_0/end/message_driven/subscription_1/start/message_driven/subscription_1/end/drive/rclcpp_publish/drive/rcl_publish/drive/dds_write/timer_driven/subscription_0/start/timer_driven/subscription_0/end/timer_driven/timer_0/start/timer_driven/timer_0/end/topic4/rclcpp_publish/topic4/rcl_publish/topic4/dds_write/actuator/subscription_0/start/actuator/subscription_0/end

QoS history によるバッファリング

コールバック実行時間超過

caret はノード内（コールバック間）は最新のメッセージを使用と想定。
古いメッセージは上書きによりロスト

時間 [s]
緑色で示されたメッセージのEnd-to-End レイテンシ