Updated on: 2018-01-11
ROS 1とROS 2の通信プロトコルは全く違うので、直接繋がることはできません。 しかしROS 1にあってROS 2にないフィーチャーはまだたくさんあります。 おかげでROS 1とROS 2は一緒に利用することが望ましいです。
この問題を解決するためにROS 2がros1_bridge
というプロトコル通訳用(「ブリッジ」)のパッケージを提供します。
本セクションでros1_bridge
を利用してROS 1のノードとROS 2のノードの一緒に利用する方法を説明します。
注意:ros1_bridge
を利用するためにROS 1もROS 2も同時インストールすることが必要です。
注意:下記の説明通りに実習するために、端末は自動的にROS 1もROS 2も有効にしないようにしてください。(source /opt/ros/melodic/setup.bash
等を実行しません。)端末によってどちらを利用するか変わります。
ROS 1とROS 2に含まれているデモノードを利用してブリッジの起動方法を説明します。
まずは4つの端末を起動します。
端末1にROS 1の環境を有効にして、roscore
を起動します。
1
2
$ source /opt/ros/melodic/setup.bash
$ roscore
端末2にROS 1とROS 2の環境を有効にして、ros1_bridge
パッケージ内のdynamic_bridge
ノードを起動します。
1
2
3
$ source /opt/ros/melodic/setup.bash
$ source /opt/ros/crystal/setup.bash
$ ros2 run ros1_bridge dynamic_bridge
dynamic_bridge
は定期的にROS 1側とROS 2側に利用中のトピッkうを探します。
トピックがあったら、そのトピックで流れているデータを反対側で送信します。
利用するために同じメッセージ名がROS 1にもROS 2にも存在することが必要です。
端末3にROS 1のtalker
サンプルノードを起動します。
1
2
3
4
5
6
7
$ source /opt/ros/melodic/setup.bash
$ rosrun rospy_tutorials talker
[INFO] [1515642714.321480]: hello world 1515642714.32
[INFO] [1515642714.421406]: hello world 1515642714.42
[INFO] [1515642714.521378]: hello world 1515642714.52
[INFO] [1515642714.621575]: hello world 1515642714.62
...
最後に、端末4でROS 2のlistener
サンプルノードを起動します。
1
2
3
4
5
6
7
$ source /opt/ros/crystal/setup.bash
$ ros2 run demo_nodes_cpp listener
[INFO] [listener]: I heard: [hello world 1515642733.42]
[INFO] [listener]: I heard: [hello world 1515642733.52]
[INFO] [listener]: I heard: [hello world 1515642733.62]
[INFO] [listener]: I heard: [hello world 1515642733.72]
...
ROS 1側で送信されているメッセージがROS 2側で受信されています。
もちろん、逆方向も可能です。
端末3でROS 1のlistener
ノードを起動して、端末4でROS 2のtalker
ノードを起動するとメッセージはブリッジを通じて逆方向に流れます。
1
2
3
4
5
$ ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
[INFO] [talker]: Publishing: 'Hello World: 3'
[INFO] [talker]: Publishing: 'Hello World: 4'
1
2
3
4
5
$ rosrun rospy_tutorials listener
[INFO] [1515647471.965369]: /listener_7925_1515647462461I heard Hello World: 1
[INFO] [1515647472.965250]: /listener_7925_1515647462461I heard Hello World: 2
[INFO] [1515647473.964986]: /listener_7925_1515647462461I heard Hello World: 3
[INFO] [1515647474.965300]: /listener_7925_1515647462461I heard Hello World: 4
ros1_bridge
はサービスも通訳できます。
使い方はメッセージと同様です。
上記のセクションの4つの端末をまた利用します。
端末3にROS 1のadd_two_ints_server
サンプルノードを起動したから、 端末4にROS 2のadd_two_ints_client
サンプルノードを起動します。
1
2
3
$ rosrun roscpp_tutorials add_two_ints_server
[ INFO] [1515648143.985914494]: request: x=2, y=3
[ INFO] [1515648143.985952552]: sending back response: [5]
1
2
$ ros2 run demo_nodes_cpp add_two_ints_client
[INFO] [add_two_ints_client]: Result of add_two_ints: 5
リソースを無駄に利用しないように、dynamic_bridge
は動的にトピックが利用されているかどうかを判断して、利用されていないトピックを向こう側で送信しません。
「トピックが利用されている」という条件は、どこかにデータが送信されていて、そしてブリッジの反対側でそのトピックにサブスクライブするノードがあるということです。
おかげで、dynamic_bridge
を起動することだけの状態でrostopic list
等は反対側のトピックを表示しません。
例えば、ROS 1側でtf
のトピックがパブリッシュされていても、ROS 2側でtf
にサブスクライブするノードがなければブリッジはROS 2側にトピックを作成しません。
トピックをリストすることやrosbag
でデータを保存することには全トピックの見えることが必要です。
dynamic_bridge
を起動するときに--bridge-all-topics
オプションを渡すと、トピックが利用されていなくても反対側で見えるようにします。
端末2でdynamic_bridge
をオプションなしで起動します。
1
$ ros2 run ros1_bridge dynamic_bridge
端末4でROS 2のtalker
サンプルノードを起動します。
1
2
3
$ ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 1'
[INFO] [talker]: Publishing: 'Hello World: 2'
端末2でなにも出力されていないことは確認できます。
端末3でrostopic list
を実行すると/chatter
トピックは表示されていないと確認できます。
1
2
3
$ rostopic list
/rosout
/rosout_agg
端末4のtalker
ノードを終了します。
それから端末2でdynamic_bridge
を終了して、そして--bridge-all-topics
オプションを渡してもう一度起動します。
1
$ ros2 run ros1_bridge dynamic_bridge --bridge-all-topics
端末4でまたROS 2のtalker
サンプルノードを起動します。
端末2で下記のような出力が表示されます。ノードがトピックを作成することだけでブリッジが通訳し始めました。
1
2
created 2to1 bridge for topic '/chatter' with ROS 2 type 'std_msgs/String' and ROS 1 type 'std_msgs/String'
[INFO] [ros1_bridge]: Passing message from ROS 2 std_msgs/String to ROS 1 std_msgs/String (showing msg only once per type)
そしてrostopic list
のアウトプットに/chatter
トピックが見えます。
1
2
3
4
$ rostopic list
/chatter
/rosout
/rosout_agg