ノードやトピックのリマップと名前空間

コマンドラインでノードやトピックの名前を変更する方法を学びます.

目的

アプリケーション開発を進めるとノードやトピック等名前が衝突(複数が同一の名前)するケースがあります. このような問題を回避するための方法として,名前を変更するリマップと呼ばれる操作が有効です. また,名前空間を利用することでトピック名に任意の文字列を加えることができます. 今回はコマンドラインによりノードを起動する際にリマップする方法について学びます. より詳細なリマップの方法についてはこちらのドキュメントをご参照ください.

ノード名の変更

2つのターミナルを起動し,それぞれで下記のコマンドラインにより簡易シミュレータであるturtlesimを起動してみましょう.

1
$ ros2 run turtlesim turtlesim_node

下記のコマンドラインにより起動したノードを確認してみてください.

1
2
3
4
$ ros2 node list 
WARNING: Be aware that are nodes in the graph that share an exact name, this can have unintended side effects.
/turtlesim
/turtlesim

全く同じ名前のノードが起動している場合,意図しない問題が発生する可能性があるという警告が表示されます. ノードと同様に,トピックも同じ名前で配信されるため,一方のノードから配信されたトピックを購読できない問題が発声します.

1
2
3
4
5
6
ros2 topic list 
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

これを防ぐためには,プログラムを書き換えて実行すれば解決できますが非効率的です.

この問題を解決するために,ノードの名前を変更してノードを起動するリマップと呼ばれる操作があります. 上記で起動したノードの1つを終了し,下記のコマンドラインでturtlesimを起動してみましょう. 引数に--ros-args --remap __node:=[node_name]を与えることで,任意のノードの名前(下記はmy_turtle)にリマップできます.

1
$ ros2 run turtlesim turtlesim_node --ros-args --remap __node:=turtlesim2

先ほどと同様に起動しているノードを確認します.

1
2
3
$ ros2 node list 
/turtlesim
/turtlesim2

ノードの名前が変わっていることが確認できました. 複数の同じノードを起動したい場合には,上記のリマップで対応することができますが,同一のトピックが配信,購読される問題は解決できません.

1
2
3
4
5
6
$ ros2 topic list 
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

名前空間の利用

上記の問題を解決する方法の1つとして名前空間(name space)を利用する方法があります. 名前空間を利用すると,ノードやトピックの名前に/と任意の文字列が付与されます. 名前空間を用いてノードを起動する場合には,コマンドラインでノードを起動する際に__ns:で任意の文字列を与えます.

1
$ ros2 run turtlesim turtlesim_node __ns:=/turtle2

/turtle2という名前空間を加えてノードを起動することができました. 名前空間を与えた際のノードとトピックの名前を確認してみましょう.

1
2
3
$ ros2 node list
/turtle2/turtlesim
/turtlesim

/turtle2という名前空間を与えることで,もとのノードの名前の前に/turtle2という文字列が追加されました. リマップではノードの名前を任意の文字列に変更することができましたが, 名前空間を利用する方法では,元の名前に任意の文字列を加えることノードを起動することができました. 次にトピックを確認しましょう.

1
2
3
4
5
6
7
8
9
$ ros2 topic list 
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
/turtle2/turtle1/cmd_vel
/turtle2/turtle1/color_sensor
/turtle2/turtle1/pose

もとのトピック名の前に/turtle2という文字列が追加されました. リマップでは別々のトピックとして区別できませんでしたが, 名前空間を利用することで別々のトピックとして扱うことができます.

購読するトピック名の変更

既存のパッケージに含まれているノードを起動する際には,やり取りするトピック名が決められています. ソースコードをダウンロードして,やり取りするトピック名を変更することもできますが手間がかかります. このような場合には,ノードを立ち上げる際に配信するトピック名を変更する方法が便利です.

簡易シミュレータturtlesimを起動してください.

1
$ ros2 run turtlesim turtlesim_node 

次にキーボード操作によりロボットを動かすノードを立ち上げます. turtlesim上のロボットを操作するノードが用意されていますが,今回は汎用的なノードを使用することにします.

1
$ ros2 run teleop_twist_keyboard teleop_twist_keyboard

上記のノードではキーボードによりロボットを操作することができません. シミュレータturtlesimが購読するトピックとteleop_twist_keyboardが配信するトピックが一致しないためです. やり取りしているトピックを確認してみましょう.

1
2
3
4
5
6
7
$ ros2 topic list 
/cmd_vel
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

teleop_twist_keyboardはトピック/cmd_velを配信していますが, turtlesim/turtle1/cmd_velを購読しようとするためトピック名が一致していません. このような場合には,ノードを起動する際にトピック名を変更して配信しましょう. teleop_twist_keyboardを終了して下記を実行してください.

1
ros2 run teleop_twist_keyboard teleop_twist_keyboard cmd_vel:=turtle1/cmd_vel

上記のコマンドラインは,teleop_twist_keyboard起動する際にトピックcmd_velturtle1/cmd_vel(/turtle1/cmd_velではないことに注意してください)に変更してノードを起動します. 先ほどは操作できなかったロボットをキーボードで操作することが可能です. 確認のため,teleop_twist_keyboardが配信するトピックを確認しましょう.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ ros2 node info /teleop_twist_keyboard 
/teleop_twist_keyboard
  Subscribers:

  Publishers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
    /turtle1/cmd_vel: geometry_msgs/msg/Twist
  Service Servers:
    /teleop_twist_keyboard/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /teleop_twist_keyboard/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /teleop_twist_keyboard/get_parameters: rcl_interfaces/srv/GetParameters
    /teleop_twist_keyboard/list_parameters: rcl_interfaces/srv/ListParameters
    /teleop_twist_keyboard/set_parameters: rcl_interfaces/srv/SetParameters
    /teleop_twist_keyboard/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:

Publishersを見ると/cmd_velではなく/turtle1/cmd_velが配信されています. オープンソースソフトウェアを利用する際には,トピック名を適切に設定しなければ動かないことが多いです. そのような場合には,こちらの方法を採用すると任意のトピック名で配信できるため便利です.