【ROS2】Galactic - Humble 間で通信しようとしたらうまくいかなかった時の解決策

Galacticを入れたPCとHumbleを入れたPCの間でトピック通信をさせようとしたら、お互いにノードもトピックも見えなかった。

原因: 既定のRMW(DDS実装)が違う

ROS2はDDSを直接呼ぶのではなく、RMW(ROS Middleware Interface)という抽象レイヤを挟んでいる。そしてどのDDS実装を既定で使うかはディストリごとに決まっており、GalacticとHumbleでは異なる。

ディストリ既定のRMWDDS実装
Galacticrmw_cyclonedds_cppEclipse Cyclone DDS
Humblermw_fastrtps_cppeProsima 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

ROS on DDS