はじめに
学校のWifiというのは、専らMulticastが通りません。セキュリティ上しかたないし、ネットワークが重くなるのを防ぐ為でもあるのか分かりませんが、取り敢えず通りません。
ですから、avahi
は通りませんし、ROS2
のノード発見も基本的に出来ません。しかしながら、自前のルータを使っているとインターネット接続ができませんし、Tailscale
等VPNで外部からアクセスしたりする事も出来ない為色々と不便です。
ここで紹介する手法は学校Wifiに限らず、Multicastがブロックされている環境で有効だと思います。
Solution
Multicastが駄目ならUnicastを使えば良いだけの話です。ここで紹介するのが、Discovery Server
です。
Discovery Server
では、Node同士が直接Multicastをせず、中央のサーバを経由して発見情報をやり取りし、全通信は基本的にUnicastで行われます。
詳しい情報は以下のリソースを参照して下さい。
https://docs.ros.org/en/humble/Tutorials/Advanced/Discovery-Server/Discovery-Server.html
実際の使い方
以下のコマンドをServer
側のPC, Client
側のPCのそれぞれで叩くだけです。Client側Nodeはいくつ接続しても問題ありません。(現実的な数字なら)
# Server側
$ fastdds discovery --server-id 0
$ export ROS_DISCOVERY_SERVER=ip address(server):11811
# Client側
$ export ROS_DISCOVERY_SERVER=ip address(server):11811
両方のexportしている環境変数は全く同じです。ipアドレスはサーバー側のものを代入してください。
恐らくご存知かと思いますが、Server側のipアドレスは以下で確認できます。
# Server側で
$ hostname -I
# または
$ ip a
Dockerを使う場合
Linuxを使っている場合は、docket-compose.yml
にnetwork_mode: host
を追加すれば、コンテナはホストと同じネットワーク空間に入るはずです。
ネットワークモードの設定と、環境変数さえ揃えてやれば、Docker
を使っていても通信が通るはずです。
以下例です。(雑ですみません)
services:
ros2:
build:
context: .
dockerfile: Dockerfile
container_name: ros2_container
tty: true
privileged: true
network_mode: host
working_dir: /root/ros_ws
environment:
- ROS_DOMAIN_ID=0
- DEBIAN_FRONTEND=noninteractive
- ROS_DISCOVERY_SERVER=100.121.25.123:11811
volumes:
- ~/.ssh:/root/.ssh:ro
- ./ros_ws:/root/ros_ws
- ~/.ccache:/root/.ccache
devices:
- /dev:/dev
Windows/macOSを使っている場合は多少複雑になるのと、恐らくUbuntuを使っている方が多いと思うので割愛します。
おわりに
雑な説明にはなってしまいましたが、ROS2 Discovery Server
の紹介をしました。詳しくは公式Docsを読んで使ってみてください。