ROS2ではノード間の通信にDDS(Data Distribution Service)を使用しています((DDSについては@youtalkさんの記事が詳しいです。 DDS (Data Distribution Service) とは | ros.youtalk.jp https://ros.youtalk.jp/2017/05/28/dds.html))。コンピュータ同士(今回はノートPCとロボットのRaspberry Pi)で通信する際にもDDSが使われていますが、同じコンピュータ上でノードを複数立ち上げる場合とは異なり、まれに通信相手のノードが見つからないことがありました。その対処方法をメモしておきます。
今回説明する内容はUbuntu 18.04をネイティブ環境にインストールしたコンピュータ同士の通信を想定しています。仮想環境ではホストマシンのファイアウォールの設定などが影響する場合もあります。
コンピュータ同士で通信する際に確認したいこと
- 同じセグメントのネットワークに通信するコンピュータ同士が存在すること
- コンピュータ同士が通信できることUbuntu 16.04など一部の環境ではファイアウォールの設定を変える必要があるようです((ROS2 Talker cannot communicate with Listener - ROS Answers: Open Source Q&A Forum
https://answers.ros.org/question/300370/ros2-talker-cannot-communicate-with-listener/))-
ROS_DOMAIN_IDが適切に設定されていること
私が遭遇したほとんど場合では、これらについて確認すればコンピュータ同士で通信できるようになっていました。
通信できていることの確認方法としては、それぞれのPCでdemo_nodes_cppのtalkerとlistenerを起動するものがあります。
まず、コンピュータA側からdemo_nodes_cppのtalkerを起動します。
ros2 run demo_nodes_cpp talker次にコンピュータB側からdemo_nodes_cppのlistenerを起動します。
ros2 run demo_nodes_cpp listenerコンピュータA側では、以下のようにトピックが送信されているのを確認できます。
[INFO] [talker]: Publishing: "Hello world: 1"[INFO] [talker]: Publishing: "Hello world: 2"コンピュータB側では、以下のようにトピックを受信しているのを確認できます。トピックを受信できれば無事にコンピュータ同士でDDSを使って通信ができています。
[INFO] [listener]: I heard: [Hello world: 1][INFO] [listener]: I heard: [Hello world: 2]今回遭遇した問題とその対処方法
先ほどの条件を満たした上でも、ノートPCとロボットのRaspberry Piの間で通信できない場合に遭遇しました。今回はマルチキャストを手動で行うことでコンピュータ同士で通信ができるようになりました。また、デーモンを起動しておくことでコンピュータ同士のノードが見つかりやすくなった(※個人的な意見です)ので、その方法を紹介します。
ros2 multicast
参考にしたのは以下のページです。
- https://index.ros.org/doc/ros2/Troubleshooting/#enable-multicast
- https://github.com/ros2/ros2cli/tree/master/ros2multicast
まず、コンピュータA側(今回はロボットのRaspberry Pi)でマルチキャストを受信できるようにします。
ros2 multicast receive次にコンピュータB側(今回はノートPC)でマルチキャストを行います。
ros2 multicast sendコンピュータB側では、以下のようにUDPマルチキャストを行っていることを確認できます。
$ ros2 multicast sendSending one UDP multicast datagram...コンピュータA側では、以下のようにコンピュータB側で行ったUDPマルチキャストを受信したことを確認できます。
$ ros2 multicast receiveWaiting for UDP multicast datagram...Received from 192.168.1.116:45000: 'Hello World!'このあとコンピュータAとコンピュータBでdemo_nodes_cppのtalkerとlistenerをそれぞれのPCで起動したところ通信できていることが確認できました。
仮想環境を使用している場合、ホストマシンのファイアウォールの設定により、マルチキャストを行うことはできても受信することができないなどの現象が発生することがあるようです。
ros2 daemon
また、ros2 daemonを起動することでノードを発見するためのデーモンをバックグラウンドで起動することができます((ROS 2コマンドラインインタフェース | ros.youtalk.jp
https://ros.youtalk.jp/2017/07/11/ros2cli.html))。バックグラウンドでこのデーモンを起動しておくと、クエリ(例:ノード名のリストなど)に関してより早く応答できるようになります。
以下のコマンドでデーモンの状態を確認できます。The daemon is runningまたはThe daemon is not runningのいずれかの結果を得ることができます。
ros2 daemon status以下のコマンドでデーモンを起動することができます。startをstopに変えたコマンドを実行すればデーモンを停止させることができます。
ros2 daemon startまとめ
ROS2でコンピュータ同士が通信できない場合に確認したいことをリストにしてみました。だいたいの場合はPCの設定で解決できると思いますが、それでも解決できない場合にマルチキャストを行うことで通信できるようになる場合もあったのでその方法を紹介しました。
関連記事
- TurtleBot3 + Gazebo + Navigation2 (ROS 2 Jazzy)ROS 2 JazzyでGazebo(旧Ignition)上のTurtleBot3をNavigation2(Nav2)を動かすまで+その過程で調べたことのメモです。
- (Updated )CHAMPをROS 2 Humbleへアップグレードした際にやったこと4脚ロボット制御用のROSパッケージであるCHAMPを、ROS 2 Humbleに対応させるためにPull Requestを作成しました。その際に遭遇した内容については、その他のROS 2パッケージにおいてもROS 2 GalacticからROS 2 Humbleに移行する際に影響する可能性がありそうなので共有します。
- (Updated )osrf/rockerを使ってPC内に複数のROS distroの開発環境を整える方法Dockerを使ってGUIアプリケーションを起動するには、起動にちょっと工夫が必要だったり一筋縄では行かないことが多いです。 osrf/rockerというツールを使うと一筋縄では行かない部分を少しだけ簡単にできるので、その使い方を紹介します。
- turtlesimを全方向移動に対応させるPRをマージしてもらった話ROSのチュートリアルでよく使われるシミュレータにturtlesimがあります。このturtlesimをholonomic motion、つまり、オムニホイールやメカナムホイールを搭載したロボットのように全方向移動できるようにするためのPull Request(PR)を出して、無事にマージしてもらえました(rostut
- JetsonでROS1/ROS2を使う際のCUDA互換性問題と解決策古いJetson上でROS 1/ROS 2とCUDAを組み合わせる際に直面するJetPack・Compute Capability・GCCバージョンの制約と、共有ライブラリ分離やカスタムL4T Baseイメージによる解決策をまとめた調査メモ。