ROS2ではノード間の通信にDDS(Data Distribution Service)を使用しています[1]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など一部の環境ではファイアウォールの設定を変える必要があるようです[2]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/
- Ubuntu 16.04など一部の環境ではファイアウォールの設定を変える必要があるようです[2]ROS2 Talker cannot communicate with Listener – ROS Answers: Open Source Q&A Forum
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 send
Sending one UDP multicast datagram...
コンピュータA側では、以下のようにコンピュータB側で行ったUDPマルチキャストを受信したことを確認できます。
$ ros2 multicast receive
Waiting 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
を起動することでノードを発見するためのデーモンをバックグラウンドで起動することができます[3]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の設定で解決できると思いますが、それでも解決できない場合にマルチキャストを行うことで通信できるようになる場合もあったのでその方法を紹介しました。
コメント