ROS 1とROS 2のつながり(ros1_bridge)

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のメッセージ通信

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