はじめに
ROS Advent Calendar 2021の2日目の記事です!
前回の記事(【ROS/WSL2】WSL2上のROSと外部PCで通信してみたかった)でWSL2上のROSと、外部PCとのROSの通信を試みたのですが、うまくいきませんでした。
今回は、ROS Bridgeを使用することで通信することができたので紹介します!
ROSノードは以下で公開しています。
超概要はこんな感じです。
これを使用すると、
- 複数マシン&複数ROS master(roscore)間の通信が可能になります。
- 任意のトピックをもう一方へpublishすることができます。
- トピック名を区別することも可能です。もちろん、そのままもできます。
例(どちらのパターンもできます):
/cmd_vel => /cmd_vel
/cmd_vel => /robot_a/cmd_vel
環境
以下の環境での動作を確認しています。
- PC1
- Jetson Nano
- ROS Melodic
- PC2
- Windows10
- WSL2
- ROS Melodic
Ubuntu 16.04では動作の確認ができていません
(roslibpyのインストールが正常にできない)
環境の準備
依存関係のインストール
使用するソフトウェアは
- ROS Bridge (サーバー)
- ROS Bridge (Pythonクライアント)
- ROSpy Message Converter (http://wiki.ros.org/rospy_message_converter)
になります。
以下のコマンドでインストールします。
$ sudo apt-get install ros-<rosdistro>-rosbridge-server
$ pip install roslibpy
$ sudo apt-get install ros-<rosdistro>-rospy-message-converter
※WSL2を使用する場合
WSL2用の設定
WSL2を使用する場合、WindowsからWSL2上のUbuntuへポートフォワーディングの設定とファイアフォールの設定を行う必要があるため以下のコマンドを実行してください。ここではROS bridgeを9090ポートで使用する前提になります。
$ netsh.exe interface portproxy add v4tov4 listenport=9090 connectaddress=(wsl -d Ubuntu-18.04 exec hostname -I).trimend()
$ New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort 9090 -Action Allow -Protocol TCP
$ New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort 9090 -Action Allow -Protocol TCP
起動
ここで起動方法を紹介するROSノードは、デフォルトでは起動時にrostopic list
で確認できるすべてのトピックをブリッジします。
もちろん除外するトピックの指定や、特定のトピックのみをブリッジすることも可能です。
ROS bridgeのWebsocketサーバを起動しておきましょう
複数マシンで試す際はどちらのマシンでも起動してください。
$ roslaunch rosbridge_server rosbridge_websocket.launch
※確認のため、例えばカメを動かしたい場合はこのタイミングで起動しておきます。
$ rosrun turtlesim turtlesim_node
$ rosrun turtlesim turtle_teleop_key
起動方法
詳細は後述しますが起動方法です。ローカルでsubscribeし、publishさせたい方(ブリッジさせたい方)のみの起動で動作の確認はできます。
起動時のパラメータも以下にまとめます。リモートのホストのIPアドレスを入力するremote_host
を変更することで外部のPCへ接続します。他のパラメータは必要に応じて変更してください。
$ roslaunch ros_to_rosbridge rosbridge_to_rosbridge.launch remote_host:={remote PC ip address}
パラメータ名 | デフォルト | 説明 |
---|---|---|
local_host | 127.0.0.1 | ローカルのWebsocketサーバが起動しているのIPアドレス |
local_port | 9090 | ローカルのWebsocketサーバが起動しているポート |
remote_host | 127.0.0.1 | リモートのWebsocketサーバが起動しているIPアドレス(※多くの場合は要変更) |
remote_port | 9090 | リモートのWebsocketサーバが起動しているのポート |
use_id_for_ns | false | confファイルのidをトピックにつけるか否か(/cmd_velトピックが、/id/cmd_velのようになります。) |
設定ファイル
ros_to_rosbridge/conf
フォルダにブリッジするトピックなどの設定ファイルがあります。
デフォルトは以下のようになっています。
/turtle1/*
のように、ワイルドカードの指定も可能です。
include_topics
でトピックを指定すると、そのトピックのみブリッジします。
id : robot_a
exclude_topics:
- /rosout
- /rosout_agg
- /client_count
- /connected_clients
# - /turtle1/*
include_topics:
# - name : /cmd_vel
# type : geometry_msgs/Twist
# - name : /odom
# type : nav_msgs/Odometry
項目 | 説明 |
---|---|
id | ブリッジ先のトピック名冒頭につけるid |
exclude_topics | ブリッジが除外されるトピック |
include_topics | ブリッジされるトピック(トピック名とデータ型) |
ROSノードの概要
実は今回は、2種類の方法で実装してみました。
↑の起動は1の方です。2はGitHubのここにひっそりとあります。
- ローカルのROS bridge から リモートのROS Bridgeへ
- ローカルのROSの通信からリモートのROS bridgeへ
メリット(特徴)とデメリットは以下だと思っています。
# | メリット(特徴) | デメリット |
---|---|---|
1 | コード内でメッセージ型を呼び出さずに実装できる | ローカルの通信でもわざわざwebsocket通信を使う |
2 | ローカル通信はROS | メッセージ型はハードコーディングになる |
以下にイメージ図を示します。赤い資格で囲まれたROSノードが今回紹介しているノードです。
1のイメージは以下になります。
2のイメージは以下になります。赤矢印部分が1と異なる部分です。
WSL2上のROSと通信する
このシステムは、WSL2上のROSでも使用することができます。
というかそれがやりたくて色々探していたら思っていたより大きめなシステムになってしまいました。
ポートフォワーディングの設定をすることで、以下のように通信することができます。
おそらく9090番という特定のポートだけを開ければよかったので通信が実現できたのではないかと思います。
おわりに
なんとか目指していたシステムを作ることができました!
GitHubにちゃんと上げて公開するのは初めてです。何もないかもしれませんが覗くだけでも覗いていってくれたらうれしいです。
LGTMなども励みになります!最後までご覧いただきありがとうございました。
参考