【ROS2】Galactic - Humble 間で通信しようとしたらうまくいかなかった時の解決策
Galacticを入れたPCとHumbleを入れたPCの間でトピック通信をさせようとしたら、お互いにノードもトピックも見えなかった。
原因: 既定のRMW(DDS実装)が違う
ROS2はDDSを直接呼ぶのではなく、RMW(ROS Middleware Interface)という抽象レイヤを挟んでいる。そしてどのDDS実装を既定で使うかはディストリごとに決まっており、GalacticとHumbleでは異なる。
| ディストリ | 既定のRMW | DDS実装 |
|---|---|---|
| Galactic | rmw_cyclonedds_cpp | Eclipse Cyclone DDS |
| Humble | rmw_fastrtps_cpp | eProsima Fast DDS |
現在どのRMWを使っているかは ros2 doctor --report で確認できる。出力の MIDDLEWARE の項に表示される。
ros2 doctor --report
CycloneDDSとFastDDSの違い
どちらもOMGのDDS仕様と、その通信プロトコルであるDDSI-RTPSを実装したものなので、役割としては同じものである。
- Eclipse Cyclone DDS: Eclipse Foundationのプロジェクト。Galactic以前のいくつかのディストリで既定に採用されていた。
- eProsima Fast DDS: eProsimaが開発。Humbleでの既定。同一ホスト内の通信では共有メモリを使う実装になっている。
同じ仕様に基づいているため原理的には相互運用できるはずだが、実際にはdiscoveryやQoSの細かい挙動が噛み合わず、ベンダーを跨いだ組み合わせは「動くこともある」程度に考えたほうがいい。異なるRMW実装同士の通信は保証されていない。
「同一PC上では問題なかったのに、なぜPC間だとダメなのか」と最初は思ったが、同一PC上で試していたのは同じディストリのノード同士=同じRMW同士の通信だったからで、ベンダーが違う組み合わせになるのはPCを跨いだときだけだった、というだけの話だった。
解決策: RMWをどちらかに揃える
CycloneDDSかFastDDSのどちらかに統一する。今回はGalactic側の既定に合わせて、Humble側をCycloneDDSにした。
Humble側にCycloneDDSのRMWをインストールする。
sudo apt install ros-humble-rmw-cyclonedds-cpp
環境変数 RMW_IMPLEMENTATION で使用するRMWを指定する。
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
これで両PCのRMWが揃い、PCを跨いでトピックが見えるようになった。
export はそのシェルにしか効かないので、ノードを起動するすべての端末で設定する必要がある。毎回書くのが面倒なら ~/.bashrc に書いておく。
また、ROS_DOMAIN_ID が両PCで一致していることも確認しておきたい。RMWを揃えてもここが違うと見えない。
参考
Working with Eclipse CycloneDDS — ROS 2 Documentation: Humble documentation
DDS implementations — ROS 2 Documentation: Humble documentation