トピックハブ

ROS 2とミドルウェア

ROS 2のプログラムの構成と接続の仕組み。ノードグラフ、パラメータ、ローンチとtf2、DDSとZenohを含むrmw層、メッセージを黙って遮断するQoSの規則、ros2_control、micro-ROS、現行のディストリビューションを扱います。

更新 2026年11月14日 · ROS 2、ノード、トピック、サービス、アクション、パラメータ、ローンチ、tf2、DDS、QoS、rmw、Zenoh、ros2_control、micro-ROS、Jazzy、Lyrical

概要

ROS 2はオペレーティングシステムではありません。型付きのメッセージをやり取りするプロセスのグラフとしてロボットソフトウェアを構築するための、ライブラリ・ツール・規約の集まりです。その下にはミドルウェア層があり、ディスカバリと通信を担います。デフォルトのミドルウェアはDDSです。ドライバからMoveIt 2やNav2まで、オープンなロボットソフトウェアの大半はROS 2を前提にしています。このハブは、初めてノードを書くエンジニアや、より大きなシステムの構成を決めようとしているエンジニア向けです。当サイトのコードはROS 2 Jazzy Jalisco(LTS、2024年5月)でテストしています。

重要な考え方

グラフ:ノード・トピック・サービス・アクション

ノードは、カメラドライバやプランナのような1つの計算単位です。ノード間の通信方法は3つあります。トピックは匿名のパブリッシュ・サブスクライブです。パブリッシャもサブスクライバも任意の数を持てますが、メッセージ型は1つです。センサのストリームや状態の配信に向きます。サービスはリクエストとレスポンスの組で、「この地図を読み込む」のような短い呼び出しに使います。アクションはフィードバックとキャンセルを備えた長時間実行のゴールで、「この位置姿勢まで移動する」のような用途に使います。内部はトピックとサービスで構成されています。各ノードは型付きのパラメータも持ち、起動時に設定することも、実行中に変更することもできます。ローンチファイルはPython、XML、YAMLのいずれかで書き、多数のノードをまとめて起動・設定します。tf2はタイムスタンプ付きの座標系のツリーを保持します。そのため、どのノードからでも、任意の時刻における2つの座標系間の変換を問い合わせられます。

cameradetectorトピック /imageplannermap_serverサービス: リクエストレスポンスmissionnavigatorアクション: ゴールフィードバック、次に結果自作のノードrclpy, rclcpprcl (Cコア)rmw インターフェースFastDDSCycloneConnextZenohネットワーク
左は、ROS 2のノードが通信する3つの方法。右は、自作のコードとネットワークの間にある層。クライアントライブラリはrclの上にあり、rmwインターフェースによってノードのコードを変えずにミドルウェアを差し替えられます。

ミドルウェア・ディスカバリ・QoS

ROS 2はrmwインターフェースを通じてミドルウェアにアクセスします。Lyricalのサポート対象プラットフォームのページによれば、ROS 2 Lyrical Luthのデフォルト実装はrmw_fastrtps_cpp(eProsima Fast DDS)で、Cyclone DDS、RTI Connext、ZenohもTier 1です。DDSには中央のマスタがありません。ノードはネットワーク上で互いを発見し、同じネットワークを共有するグループはROS_DOMAIN_IDで分離します。Zenohでは、代わりにルータがディスカバリを担います。

すべてのパブリッシャとサブスクライバはQoSプロファイルを持ちます。その項目は、信頼性(reliable または best effort)、耐久性(volatile または transient local)、履歴の深さ、デッドライン、ライブネスです。両端のQoSに互換性がないと、接続は確立されません。ログに警告が出るだけで、メッセージは届きません。reliableのサブスクライバは、best effortのパブリッシャからのデータを受け付けません。これが、センサドライバからノードが「何も受信しない」典型的な原因です。次のコードはJazzyのコンテナで動作し、この現象を示します。

# ros2
import rclpy
from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy
from std_msgs.msg import Int32


def count_received(pub_rel: ReliabilityPolicy, sub_rel: ReliabilityPolicy) -> int:
    node = rclpy.create_node("qos_demo")
    pub_qos = QoSProfile(depth=10, history=HistoryPolicy.KEEP_LAST, reliability=pub_rel)
    sub_qos = QoSProfile(depth=10, history=HistoryPolicy.KEEP_LAST, reliability=sub_rel)
    received = []
    pub = node.create_publisher(Int32, "counter", pub_qos)
    node.create_subscription(Int32, "counter", lambda msg: received.append(msg.data), sub_qos)
    for i in range(40):
        pub.publish(Int32(data=i))
        rclpy.spin_once(node, timeout_sec=0.05)
    node.destroy_node()
    return len(received)


rclpy.init()
matched = count_received(ReliabilityPolicy.BEST_EFFORT, ReliabilityPolicy.BEST_EFFORT)
mismatched = count_received(ReliabilityPolicy.BEST_EFFORT, ReliabilityPolicy.RELIABLE)
rclpy.shutdown()
print(f"best effort -> best effort: received {matched > 0}")
print(f"best effort -> reliable:    received {mismatched} messages")

2つ目のケースは0を出力し、信頼性ポリシーについて互換性のないQoSの警告をログに出します。耐久性も重要です。tf2_rosの静的ブロードキャスタは/tf_staticをtransient localの耐久性でパブリッシュします。そのため、遅れて起動したノードもすべての静的変換を受信できます。

ros2_controlとmicro-ROS

ros2_controlはコントローラとハードウェアを分離します。そのコントローラマネージャは、各コントローラが必要とするコマンドインターフェースと状態インターフェースを、各ハードウェアコンポーネントが提供するものと照合し、競合があればエラーを報告します。ハードウェアはロボットのURDFに記述します。これにより、ros2_controllersリポジトリの同じコントローラを、実機のアーム、シミュレータ、モックのいずれに対しても動かせます。micro-ROSは、rclをベースにしたC APIを通じて、ノード、パブリッシュ・サブスクライブ、サービス、ライフサイクルをマイコン上で使えるようにします。通信にはeProsima Micro XRCE-DDSを使い、より大きなコンピュータ上のエージェントがROS 2グラフの残りの部分との橋渡しをします。FreeRTOS、Zephyr、NuttXに対応しています。

ディストリビューション

ROS 2の新しいディストリビューションは毎年5月にリリースされます。ROS 2のリリーススケジュールによれば、偶数年のリリースはLTSで約5年間、奇数年のリリースは1.5年間サポートされます。2026年11月14日時点で、ROS 2のディストリビューションのページには次のサポート対象リリースが掲載されていました。

ディストリビューション リリース日 サポート終了 備考
Lyrical Luth 2026年5月22日 2031年5月 LTSで最新のリリース。Ubuntu 26.04とWindows 11でTier 1
Kilted Kaiju 2025年5月23日 2026年12月 非LTS
Jazzy Jalisco 2024年5月23日 2029年5月 LTS。Ubuntu 24.04でTier 1。当サイトのコードで使用
Humble Hawksbill 2022年5月23日 2027年5月 LTS
Rolling Ridley 継続的 なし 開発用ディストリビューション

Lyricalでは、macOSはTier 3プラットフォームです。つまり、ソースからのビルドが必要です。Macでは、Linuxのコンテナまたは仮想マシン上でROS 2を実行してください。

どこから始めるか

Hello ROS 2では、パブリッシャとサブスクライバを書き、Jazzyのコンテナで実行します。ROS 2のtalker・listener・tf2プロジェクトでは、パラメータ、ローンチ、変換を加えます。作業中はROS 2 CLIチートシートを開いておいてください。ロボットの記述についてはURDFとMJCFのリファレンスを参照してください。主なパッケージはROSのプラットフォームページに一覧があります。

ツールとプラットフォーム

ツール 用途 ライセンス
rclpy・rclcpp PythonとC++のクライアントライブラリ Apache-2.0
Fast DDS デフォルトのDDS実装 Apache-2.0
Cyclone DDS 代替のDDS実装 EPL-2.0またはEDL-1.0
rmw_zenoh ROS 2向けのZenohベースのミドルウェア Apache-2.0
ros2_control コントローラマネージャとハードウェア抽象化 Apache-2.0
micro-ROS マイコン上のROS 2 Apache-2.0
RViz・rosbag2 3D可視化、および記録と再生 BSD-3-Clause-Clear、Apache-2.0
SROS2 セキュリティツール(鍵、証明書、アクセス制御) Apache-2.0

よくある間違い

  • ドライバとサブスクライバの間でQoSが一致していない。ros2 topic info -vで確認する。
  • 同じネットワーク上の2台のロボットが同じROS_DOMAIN_IDを使い、互いのトピックが見えてしまう。
  • コールバック内でブロックする。シングルスレッドのエグゼキュータでは、他のすべてのコールバックが止まる。
  • 誤ったタイムスタンプで変換をパブリッシュし、tf2の問い合わせが失敗するか外挿になる。
  • マシン間でディストリビューションを混在させる。メッセージが一致しないことがある。
  • 何年も稼働し続ける必要がある製品を、非LTSリリースで構築する。

さらに深く