ROS2でのZenohの利用
(掲載 2026年03月09日)
はじめに
ROS2はロボット開発において事実上の標準フレームワークとなり、分散システム構築のために
DDS(Data Distribution
Service)を採用しています。しかし、実際のロボット開発の現場では、
- ネットワークを跨ぐと通信が不安定になる
- マルチキャストが使えない環境が多い
- LAN 外の通信やクラウド連携が難しい
といった課題に直面することも少なくありません。
そこで近年注目されているのがZenohです。Zenohは、ローカルネットワークからクラウド連携までをシームレスに扱える軽量データ通信ミドルウェアで、ROS2とも相性が良いことから採用が広がっています。
Zenohとは
Zenoh(ゼノー)は Eclipse Foundation
が開発する非常に軽量で高性能なPub/Sub/Query通信プロトコルです。ロボティクスをはじめ、エッジシステムや
IoT、大規模な分散環境でも利用されています。
Zenohの特徴は以下の通りです。
- 軽量・高速で組込み環境にも向く
- 単一ポートで動作し、NATやファイアウォール越えにも強い
- ブローカーレス動作(P2P)とブローカー型の併用が可能
- DDS/ROS2と橋渡しできる
ROS2とZenohの連携方式
ROS2とZenohをつなぐ方法は大きく2つあります。
DDS ⇔ Zenoh
を橋渡しする(zenoh-bridge-dds)
最も導入しやすい方法で、既存のROS2通信(DDS)をそのまま活かしつつ、外部ネットワークへ中継する構成です。
- メリット
- 既存ROS2はそのまま(rmw実装変更不要)
- 他拠点やクラウドへ簡単に通信を拡張できる
- 導入が容易
- デメリット
- DDSとZenohのマッピングによるオーバーヘッド
RMWをZenohに置き換える(rmw_zenoh)
ROS2の通信レイヤー(RMW)そのものにZenohを使用する方式です。
すべてのROS2通信がZenohネイティブになるため、ネットワーク効率が高くなります。
- メリット
- 軽量で高速
- ローカル・WAN・クラウドを統一的に扱える
- マルチキャスト不要
- デメリット
- 若干セットアップが複雑
- DDSを使うノードとは直接互換性がない
ロボット全体の構成や開発フェーズに合わせて使い分けるのが現実的です。
Zenohを試してみる
ここでは実際にrmw_zenohを導入し、NATを越えた通信を試してみます。
以下のような構成で試します。サーバ、仮想マシンはいずれもUbuntuを想定しており、仮想マシンにはROS2(Jazzy)を導入済みの前提とします。
また、それぞれの仮想マシンはVirtualBoxのNAT接続を利用しており、仮想マシン間のネットワークは分離した状態にしてあります。
サーバ側
Zenoh Routerのインストール
https://zenoh.io/docs/getting-started/installation/
を参考に、サーバ上でZenoh Routerをインストールします。
$ curl -L https://download.eclipse.org/zenoh/debian-repo/zenoh-public-key | sudo gpg --dearmor --yes --output /etc/apt/keyrings/zenoh-public-key.gpg
$ echo "deb [signed-by=/etc/apt/keyrings/zenoh-public-key.gpg] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null
$ sudo apt update
$ sudo apt install zenoh
インストール後、zenohdでZenoh Routerを起動します。
zenohdはZenoh
Routerの実体で、ネットワーク間の中継を行う常駐プロセスです。
ROS2側
rmw_zenohのインストール
仮想マシン1、2の両方で実施します。
https://docs.ros.org/en/jazzy/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.html
を参考に、rmw_zenohバイナリをインストールします。
$ sudo apt install ros-jazzy-rmw-zenoh-cpp
環境変数の設定
仮想マシン1、2の両方でで実施します。
~/.bashrcに以下を追記します。
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
export ZENOH_CONFIG_OVERRIDE='connect/endpoints=["tcp/<Server IP Address>:7447"]'
<Server IP Adderss>はzenohdを起動しているサーバのIPアドレスを指定します。
通信の実行
仮想マシン1での操作
ターミナルを2つ開き、それぞれで以下を実行します。
ターミナル1
$ ros2 run rmw_zenoh_cpp rmw_zenohd
ターミナル2
$ ros2 run turtlesim turtlesim_node
rmw_zenohdはローカルZenoh
Peerのため手動で起動していますが、将来は不要になる可能性があります(https://github.com/ros2/rmw_zenoh
のNoteより)。
仮想マシン2での操作
ターミナルを2つ開き、それぞれで以下を実行します。
ターミナル1
$ ros2 run rmw_zenoh_cpp rmw_zenohd
ターミナル2
$ ros2 run turtlesim turtle_teleop_key
turtle_teleop_keyでのキー操作がもう一方の仮想マシンで起動したturtlesim_nodeに反映されていることを確認できます。
期待通りに動作しない場合は以下を確認してみてください。
- zenohdを起動しているマシンのポート7447がファイアウォールで塞がれていないか
- 設定した環境変数が反映されているか
- rmw_zenohdの起動を忘れていないか
まとめ
Zenohを利用することで異なるネットワーク間でのROS2通信を容易に実現できます。
SRAでは、ROSの環境構築から各種開発まで幅広く支援いたします。(お問い合わせはこちら)
参考: