環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
前回(ROS講座20)では複数のPCでROSを実行する方法を説明しました。しかし、通信する両方のPCのターミナルを操作する必要があったり、人力の作業が多かったりと面倒です。そこでremote launchを行うことでコマンド1発でリモート接続+ROSノードの起動ができるようにしましょう。
今回はROSを立ち上げる複数のPCで以下ができる必要があります。
- 固定アドレスが割り当てられていること
- note1->robot1にパスワード認証でsshができること
- robot1側にcatkin_wsがあってビルドをしていること
PC・ネットワーク構成
接続確認
前回も行いましたがpingに加えてsshでの接続の確認も必須です。
ssh r_user@192.168.1.20
robot1側での設定
robot1側では前回と同じくROS_IP
の設定が必要です。一方ROS_MASTER_URI
の設定は後述のlaunchによって自動的に行われるので不要です。しかし今回はrobot1側はターミナルを起動して設定するのではなくssh経由で起動されます。この時の環境変数などの設定はrobot1側のディレクトリの~/catkin_ws/devel/env.sh
に書きます。remote launchをされたときに最初にこのスクリプトが実行されます。
export ROS_IP=`hostname -I | cut -d' ' -f1`
note1側の設定
roslaunchコマンドを実行するマシンであるnote1側の設定です。ROS_IP
、ROS_MASTER_URI
に加えてROSLAUNCH_SSH_UNKNOWN
という3つ環境変数が必要になります。
export ROS_IP=`hostname -I | cut -d' ' -f1`
export ROS_MASTER_URI=http://`hostname -I | cut -d' ' -f1`:11311
export ROSLAUNCH_SSH_UNKNOWN=1
- 'ROS_MASTER_URI'はros masterのアドレス・ポートを設定する環境変数です。デフォルトでは
http://localhost:11311
となっていてnote1内でのみROSを動かす分には問題はなありません。しかし、remote launchを行う場合は、親側(roslaunchを行うPC)の'ROS_MASTER_URI'が子側にコピーされます。この時にlocalhost
のままだと意味をなさないので、具体的なIPアドレスを記述する必要があります。 -
ROSLAUNCH_SSH_UNKNOWN
はssh接続する相手としてknown_hostにないマシンへのssh接続を許可するかどうかという設定です。1を代入することで許可になります。
この3行をbashrcに入れておいても良いでしょう。
launchのソースコード
note1側で起動するlaunchファイルを示します。以下のlaunchではrobot1のROSも同時に立ち上げることができます。
<launch>
<machine name="robot1" address="192.168.1.20" env-loader="/home/r_user/catkin_ws/devel/env.sh" user="r_user" password="password"/>
<node name="basic_simple_listener" pkg="basic_lecture" type="basic_simple_listener" output="screen" />
<node machine="robot1" name="basic_simple_talker" pkg="basic_lecture" type="basic_simple_talker" />
</launch>
-
完全に新しく出てきた要素として
<machine>
タグがあります。これはノードを実行するPCを指定するものです。- name属性は自由につけてよい名前です。
- address属性はそのロボットのIPアドレスを示します。robot1側のIPアドレス(192.168.1.20とか)を書きます。
- env_lodar属性は初期化用のスクリプトを指定します。robot1側でlaunchが立ち上がる前に実行されるスクリプトです。上記で編集したrobot1でのファイルパスを指定します。つまりrobot1用のmachineタグで
env-loader="/home/n_user/.....
のようにnote1側のファイルを選択しようとしてもエラーになります(ファイルを転送等がされているわけではないです)。 - userとpassword属性はssh接続で使うユーザーとパスワードです。平文でパスを書くのはあまりよろしくないですが、この方法が一番お手軽です。
-
<node>
タグの中のmachine属性でそのROSノードを起動するPCを選択できます。この属性を書かないと今までの例のようにroslaunchを起動したPCでROSノードが起動します。このリモート起動を記述するうえで重要なのはmachineで指定したPCにそのROSノードがないとエラーになるということです
例えばnote1上にはtest_pkgというROSパッケージがあって、robot1上にはそのパッケージがない場合。<node name="ros_node" pkg="test_pkg" type="test_pkg_node" />
とした場合、普通にROSノードがnote1上で実行されます。<node machine="robot1" name="ros_node" pkg="test_pkg" type="test_pkg_node" />
とした場合、robot1上でROSノードが起動されるとうれしいのですが、エラーになります。リモートlaunchの機能ではROSノードをネットワーク越しに転送して実行することはできず、指定したPCにあるROSノードを起動することしかできません。
実行
以下のように普通のROSlaunchと同じように起動できます。
roslaunch basic_lecture simple_remote.launch
rosnode machine
と打つと現在のrosmasterにつながっているマシンの一覧が表示されます。
192.168.1.10
192.168.1.20
rosnode machine 192.168.1.10
と打つとそのマシンで実行されているrosノードの一覧が出ます。
/basic_simple_listener
/rosout
リモートで起動しているマシンがshutdownした場合
roslaunchを停止するのではなく、remote側でprocessをkillしたりshutdownした場合や、マシンの電源が切れた場合には不都合が起きます。
- shutdown(reboot)するとlaunchの画面には出てくるけどnodeは死なない
- rosnode infoで見るとつながらないと表示される
- rosnode killが効かない(roscoreを再起動しない限り表示され続けるゾンビノードになる)