コンテンツにスキップ

はじめに

英語版が正です。この文書は 2026-09-22 時点の英語版に対応しています。

このページでは、素の ROS 2 環境から、最初の ros2 transport list、statistics、web viewer までを通します。動作環境は Linux です。ツールは Fast DDS を観測するので、観測対象のノードは rmw_fastrtps_cpp (Jazzy、Lyrical、Rolling の既定 RMW) か rmw_fastrtps_dynamic_cpp を使っている必要があります。

ROS 2 ディストリビューション Fast DDS 備考
Humble (Ubuntu 22.04) 2.6 予測のみ: Humble のバイナリには statistics モジュールが無く --stats は何も測れない。同一ホストの相手は SHM locator しか見えない (仕組み 参照)
Jazzy (Ubuntu 24.04) 2.14 主対象
Lyrical (Ubuntu 26.04) 3.6 現行 LTS
Rolling 3.x ベストエフォート (CI は失敗を許容)

Kilted は 1.0.0 までの対応で、2026 年 12 月に EOL を迎えるため 1.1.0 以降は対象外です。 1.0.0 タグは Kilted でもビルドでき、動作します。

1. ビルド

src/ に 2 つのパッケージがあります: fastdds_transport_viz (C++ のツール本体) と ros2transport (ros2 transport コマンド)。他の ROS 2 パッケージと同じように colcon ワークスペースでビルドします。

ネイティブ環境 (推奨)

前提: ROS 2 の desktop または base インストール、python3-colcon-common-extensions、 rosdep (初回のみ sudo rosdep init && rosdep update)。

mkdir -p ~/ws/src && cd ~/ws
git clone https://github.com/atinfinity/fastdds_transport_viz.git src/fastdds_transport_viz
source /opt/ros/jazzy/setup.bash              # or humble / lyrical / rolling
rosdep install --from-paths src --ignore-src -y
colcon build --symlink-install
source install/setup.bash

rosdep はビルド依存 (rclcpp、Fast DDS のヘッダ、nlohmann-json)、実行時依存 (rmw_fastrtps_cpp、例で使う demo_nodes_cpp)、テスト依存を入れます。ツールを動かす シェルでは毎回 source install/setup.bash が必要で、これが ros2 transport コマンドも 登録します。

Docker: ビルド済みイメージ (GHCR)

2.1.0 以降の各リリースは、そのまま動くイメージとして x86_64 と arm64 向けに公開されます:

タグ 内容
ghcr.io/atinfinity/fastdds_transport_viz:jazzy (:latest) ROS 2 Jazzy 上の最新リリース
ghcr.io/atinfinity/fastdds_transport_viz:humble, :lyrical Humble / Lyrical 上の最新リリース
ghcr.io/atinfinity/fastdds_transport_viz:<X.Y.Z>-<distro> 特定のリリース (例: 2.1.0-jazzy)

イメージは ros:<distro>-ros-core に両パッケージ (と例で使う demo_nodes_cpp) を入れた もので、コマンドを指定しなければ ros2 transport list を実行します。Docker ホスト上の ノードを観測するには、ホストのネットワーク名前空間と IPC 名前空間で、ノードと同じ ディストリビューションのタグを使って実行します:

docker run --rm --net host --ipc host ghcr.io/atinfinity/fastdds_transport_viz:jazzy \
    ros2 transport list -v

--net host が無いとコンテナからはホスト上の何も発見できません。--ipc host が無いと コンテナは自分専用の /dev/shm を持ちます。ペアの予測は出ますが、共有メモリの行は !shm-not-visible を報告し、ホストではなくコンテナの /dev/shm を表示します。これが 動くのは Linux の Docker ホストだけです。Docker Desktop (macOS、Windows) のホスト ネットワークはその VM のもので、ノードが動いているマシンのものではありません。

コンテナはまっさらな環境で起動するので、ノードが発見と RMW のために設定しているものは -e で渡します。違いがあるとノードが見えなくなったり予測が変わったりします:

  • ROS_DOMAIN_ID
  • RMW_IMPLEMENTATION (イメージでは rmw_fastrtps_cpp。rmw_fastrtps_dynamic_cpp も 入っています)
  • ROS_AUTOMATIC_DISCOVERY_RANGE と ROS_STATIC_PEERS (Jazzy 以降)、 ROS_LOCALHOST_ONLY (Humble)
  • ROS_DISCOVERY_SERVER、ROS2_EASY_MODE
  • FASTDDS_DEFAULT_PROFILES_FILE / FASTRTPS_DEFAULT_PROFILES_FILE。ファイルは同じパスに マウントします (-v /path/profiles.xml:/path/profiles.xml:ro)

5 章 の web viewer は、ホストの http://127.0.0.1:8765/ で開けます (コンテナは ホストのネットワーク上にあるので、既定の 127.0.0.1 はホストのものです):

docker run --rm -it --net host --ipc host ghcr.io/atinfinity/fastdds_transport_viz:jazzy \
    ros2 run fastdds_transport_viz transport_viz_web --stats --interval 1

コンテナ内のツールは root で動くため、その participant がホストの /dev/shm に作る SHM ファイルは root の所有になります。止めるときは Ctrl-C を使います (そのための -it)。 コンテナを kill すると (docker kill、またはタイムアウトした docker stop)、残った セグメントが !shm-stale-files として表示され、一般ユーザーには削除できません。同じ ディストリビューションのイメージで削除してください。Humble と Jazzy (Fast DDS 2.x) の fastdds shm clean が扱うのは fastrtps_* のファイルだけで、Lyrical (3.x) のものは fastdds_* のファイルだけです:

docker run --rm --ipc host ghcr.io/atinfinity/fastdds_transport_viz:jazzy fastdds shm clean

Docker: 開発用イメージ

リポジトリには compose.yaml があり、開発用イメージ (ros:jazzy、または ROS_DISTRO=humble / lyrical / rolling)、/ws にマウントしたリポジトリ、ホストの共有メモリが ツールから見えるようにする ipc: host を定義しています:

docker compose build
docker compose run --rm dev bash
colcon build --symlink-install && source build/$ROS_DISTRO/install/setup.bash

このページの残りはそのシェルの中でも同じように動きます。コンテナはネットワーク名前空間が 別なので、同じコンテナ内のノードは観測できますが Docker ホスト上のノードは観測できません。 そのための hostnet サービスは development.md (英語) を参照してください。

2. 最初の実行

デモノードを 2 つ起動して見てみます:

ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_cpp listener &
ros2 transport list -v --explain
TOPIC     TYPE                 PUBS  SUBS  TRANSPORT  LATENCY  HZ  LOSS  REASON
/chatter  std_msgs/msg/String  1     1     SHM x1     -            -     same-host-guid,datasharing-disabled-writer,both-shm-locators
    /talker@local -> /listener@local  SHM  -    -  same-host-guid,datasharing-disabled-writer,both-shm-locators

shared memory: /dev/shm 2.19 MB used of 16.7 GB (16.7 GB free) | Fast DDS 2.19 MB in 3 segment(s), 6 port(s), 0 data-sharing histories

Reason codes:
  both-shm-locators
      Both endpoints announce a shared-memory locator ...

見えているもの:

  • トピックごとに 1 行、(-v で) writer → reader のペアごとに 1 行。予測された transport と、 その根拠の理由コード (--explain で説明を表示、ros2 transport codes で全コードを一覧)。
  • shared memory: の行は、ツールが動いている環境の /dev/shm の状態です (how-it-works.ja.md)。

共有メモリを使えない 2 つ目の listener を作ると、判定が変わります:

FASTDDS_BUILTIN_TRANSPORTS=UDPv4 ros2 run demo_nodes_cpp listener &
ros2 transport list -v                 # second pair: UDPv4, reader-no-shm-locator

ここまで、観測対象のノードには何も要求していません。判定はどの Fast DDS participant も 広告する discovery データから求めています。

ノードと同じ場所で実行する

discovery データは同じ DDS ドメインからしか見えず、共有メモリは同じ IPC 名前空間からしか 見えません。観測するノードと同じ環境変数 (ROS_DOMAIN_ID、FASTDDS_BUILTIN_TRANSPORTS、 XML プロファイル、Discovery Server の設定)、同じネットワーク/IPC 名前空間でツールを 実行してください。how-it-works.ja.md を参照。

3. 予測ではなく実測する (--stats)

予測は Fast DDS の statistics モジュールで確認できます。観測対象のノードは起動前に 環境変数で有効にしておく必要があります:

export FASTDDS_STATISTICS="RTPS_SENT_TOPIC;RTPS_LOST_TOPIC;HISTORY_LATENCY_TOPIC;PHYSICAL_DATA_TOPIC;DATA_COUNT_TOPIC;RESENT_DATAS_TOPIC;HEARTBEAT_COUNT_TOPIC;ACKNACK_COUNT_TOPIC;NACKFRAG_COUNT_TOPIC;GAP_COUNT_TOPIC"
export FASTRTPS_DEFAULT_PROFILES_FILE=$(ros2 pkg prefix fastdds_transport_viz)/share/fastdds_transport_viz/config/statistics.xml
ros2 run demo_nodes_cpp talker &
ros2 run demo_nodes_cpp listener &
ros2 transport list -v --stats

ペアの行に measured=SHM 47pkt 3.20 kB が付き、LATENCY 列にそのペアの write-to-notification 遅延 (平均と最大)、HZ 列に reader に届いた 1 秒あたりのサンプル数 (statistics の一部が失われて 下限になったときは ≥ 付き)、LOSS 列に欠落と再送が出て、ホストは名前と プロセス id で表示されます。プロファイルファイルは statistics writer の リソース制限を外すためのものです。トピックの説明と回避する落とし穴は statistics.ja.md を参照してください。

4. 見続ける

ros2 transport list --watch --stats --interval 2

2 秒ごとに再観測し、前のフレームからの変化に印を付けます (+ 現れた、~ 変わった、- 消えた)。キー: q 終了、p 一時停止、v ペア表示、e 凡例、a 全トピック、l locator、f 対処 (--advise)。

5. ブラウザで見る

ros2 run fastdds_transport_viz transport_viz_web --stats --interval 1
# transport_viz_web: listening on http://127.0.0.1:8765/  (serving .../share/fastdds_transport_viz/web)

URL を開くと、ホストが列、ノードが箱、ペアが transport ごとに色分けされた矢印として ライブで更新されます。ros2 transport list --json > snapshot.json で作った文書は、同じ ページ (web/index.html) でオフラインでも開けます。web-viewer.ja.md を 参照してください。

サーバは 127.0.0.1 でだけ待ち受けます。Docker 環境では、viewer のポートを公開してシェルを起動し、 コンテナ内ではすべてのアドレスで待ち受けると、ホストのブラウザから届きます:

docker compose run --rm --service-ports dev bash
ros2 run fastdds_transport_viz transport_viz_web --bind 0.0.0.0 --stats --interval 1

同じ --bind 0.0.0.0 で、ノート PC からロボットを見ることもできます。

6. コマンドリファレンス

ros2 transport list [--domain N] [--timeout S] [--quiet S] [--topic REGEX] [--node REGEX]
                    [--all] [-v] [--explain] [--locators] [--advise] [--stats] [--json | --csv]
                    [--color auto|always|never] [--watch [--interval S]]
ros2 transport diff BEFORE.json AFTER.json [--key node|guid] [--changes-only] [--json]
                    [--topic REGEX] [--node REGEX] [--all] [-v] [--explain] [--locators]
                    [--advise] [--color auto|always|never]
ros2 transport codes

ros2 transport は fastdds_transport_viz の transport_viz バイナリを exec します。 バイナリは ros2 run fastdds_transport_viz transport_viz で直接実行でき、同じオプションに 加えて --list-codes があります。終了コード: 成功 0、使い方の誤り 2、RMW が rmw_fastrtps_cpp でも rmw_fastrtps_dynamic_cpp でもないとき (メッセージに RMW 名が出る) と、バイナリが見つからない・起動できないときの ros2 transport は 1。

ros2 transport diff は保存済みの 2 つの --json 文書を、何も観測せずに比較します (how-it-works.ja.md)。終了コードは diff(1) と同じで、 変化なし 0、変化あり 1、エラー 2 です。

うまくいかないときの最初の確認

ros2 transport list --advise は、使われている理由コードを解消するには何を変えるかを ペアの下と凡例に出します (fix reader-no-shm-locator: Enable SHM on the reader's participant: unset FASTDDS_BUILTIN_TRANSPORTS ...)。ros2 transport codes は全コードの対処を 一覧します。下の表は理由コードにならないものを扱います。

症状 確認すること
ros2: error: argument Call ... invalid choice: 'transport' このシェルで source install/setup.bash (Docker イメージでは build/$ROS_DISTRO/install/setup.bash) したか。ros2transport が同じワークスペースでビルドされているか。
RMW is rmw_cyclonedds_cpp; this tool observes Fast DDS ... (exit 1) ツールは Fast DDS でしか動きません。ツールを実行するシェルで RMW_IMPLEMENTATION=rmw_fastrtps_cpp (または rmw_fastrtps_dynamic_cpp) を設定する (既定が Fast DDS の distro なら未設定でもよい)。
トピックが 1 つも出ない ノードと同じ ROS_DOMAIN_ID か。ROS_AUTOMATIC_DISCOVERY_RANGE=OFF は各 participant を自分だけに限定する。Discovery Server 使用時はツールにも同じ ROS_DISCOVERY_SERVER が必要 (自動で SUPER_CLIENT になる)。
別マシンのノードが出ない 相手のマシンにマルチキャストで届くか、ROS_STATIC_PEERS に列挙するか、双方が Discovery Server を使う。development.md (英語) 参照。
--stats で !stats-not-enabled-on-writer ノードが FASTDDS_STATISTICS 無しで起動された (変数はノードの起動前に設定する) か、その participant が SHM transport しか持たない。ツールの statistics reader は UDP か TCP で受信する。
!stats-samples-lost、または warning: ... statistics samples were lost statistics の一部がツールに届かず、配送が証明されているのに実測パケットの無いペアが 1 つ以上ある (stats.pairs_delivered_unmeasured)。実際には通信していても、ペアが (unmeasured, delivered) や none(delivered) と表示され得る。実測を失わせなかった損失は、この警告なしで N sample(s) lost とだけ出る。statistics を有効にするノードを減らすか、FASTDDS_STATISTICS を必要な別名に絞る (transport を見るだけなら RTPS_SENT_TOPIC;RTPS_LOST_TOPIC で足りる)。--timeout を延ばしても損失は減らず、より多く集めるだけ。--json では stats.samples_lost に数が出る。そのうち stats.samples_lost_latency は best-effort で受け取る HISTORY_LATENCY の分で、どのペアの実測も失わせないため警告には数えない。stats.samples_lost_at_start は reader がマッチする前の正常な分で、警告にはならない。
!shm-not-visible ノードが別の /dev/shm (別コンテナまたは別ホスト) を使っている。共有メモリの行はツールの環境だけを表す。
NONE のペアに !shm-ipc-namespace-split 2 つのノードのホスト id は同じだが /dev/shm が別 (ホストネットワークで IPC 名前空間が別) なので、Fast DDS が SHM や data-sharing を選んでも受信側には何も届かない。両方のコンテナに ipc: host を付けるか、片側の SHM (と data-sharing) を無効にする (--advise で対処を表示できる)。
!shm-stale-files クラッシュしたプロセスがセグメントを残している。fastdds shm clean で削除できる。
実際にはあるペアが表に出ない、または warning: discovery was still in progress (...) ノードが endpoint を announce し終える前に観測が終わっている。観測は discovery イベントが --quiet 秒間ないと終わるが、大規模なシステムでは announce の合間にも無音になる。メッセージが示す値で取り直す (--quiet 3 --timeout 10 から。--stats 付きなら --quiet 3 --timeout 60)。--json では discovery.complete が false になり、その文書は diff にかける価値がない。
ツール自身がノードとして出る 出ないはずです。自身のノード /_transport_viz_<pid> と participant は除外されます。出た場合は --json 出力を添えて issue を立ててください。

次は判定ルールを知る 仕組み、ツールを変更するなら Architecture (英語) へ。