ros1_bridgeでROS2とROS1の通信を実現する

ROS2で開発をしていて、どうしてもROS1で使われているパーケージを使いたいというときが出てきます。
自分の場合、あるタスクの自動化ロボットを開発していて、どうしてもロボットアームを使いたくなりました。ロボット全体の制御はROS2で行いたいのですが、ロボットアーム制御に関するパッケージは2020年現在ROS1で書かれているものが大半でROS2対応のものは少ないです。
そこで全体はROS2で開発し、ロボットアームの制御のみROS1で開発することにしました(将来的にはすべてROS2に置き換えたい)。

ROSではノード間の通信をトピックによって行っていますが、ROS1とROS2ではトピックの互換性がありません。そこでこのままでは通信できないのですが、ROS2に含まれるros1_bridgeというパッケージを使うことによりROS1メッセージとROS2メッセージの翻訳を行うことができ、ROS1とROS2の通信が実現します。

今回はros1_bridgeのデモを動かすことにより、ROS1-ROS2通信の実現の仕方を見ていきます。

本記事の内容は次のとおりです。
1. 環境構築
2. 重要な概念の紹介
3. 各パッケージのビルド
4. 各パッケージの実行

## 環境構築
今回使用する環境は以下のとおりです
Ubuntu 18.04
ROS1: [melodic](http://wiki.ros.org/melodic/Installation/Ubuntu)
ROS2: [dashing](https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Binary/)

ROS1とROS2がインストールされていない場合、それぞれインストールします。
インストール方法は公式Wikiに載っているとおりで大丈夫です。
ROS1 melodic
ROS2 dashing

セットアップファイルの実行を.bashrcに登録するところはスキップしたほうがベターです。

## 概念の紹介
ROS1とROS2を共存させるときに重要になってくるのが、現在見ているシェルでどちらの環境がセットアップされているかを理解することです。
それぞれセットアップは以下のコードで行います。
ROS1
`source /opt/ros/melodic/setup.bash`
ROS2
`source /opt/ros/dashing/setup.bash`

今後のビルド、実行の部分では以下の3種類のセットアップパターンを使用していきます。
**パターン1) ROS1のみセットアップ**
ROS1のパッケージをビルド、実行するとき
**パターン2) ROS2のみセットアップ**
ROS2のパッケージ(ros1_bridge以外)をビルド、実行するとき
**パターン3) ROS1とROS2のみセットアップ**
ros1_bridgeパッケージをビルド、実行するとき

環境によっては.bashrcにセットアップファイルの実行を書いていて、シェルが立ち上がると自動的にどちらかの環境のセットアップをしている場合があると思います。このままでも大きな問題はないのですが、予期せぬエラーにつながる可能性があるため、可能であれば.bashrcからセットアップの実行コマンドを削除しておきましょう。

## ビルド
ROS1のパッケージ、ROS2のパッケージ、ros1_bridgeをビルドしていきます。
今回はROS1、ROS2のパッケージとしてデモを使うので、ビルドの手順はスキップしますが、全体の流れは紹介します。

## ROS1のパッケージをビルド (デモではスキップ) 
ROS1で書かれているパッケージをビルドします。
シェルを開きROS1の環境をセットアップ
`source /opt/ros/melodic/setup.bash`
パッケージディレクトリに移動

```
cd　<package-dir> 
catkin build
source devel/setup.bash
```

## ROS2のパッケージをビルド (デモではスキップ) 
ROS2で書かれているパッケージ(ros1_bridge以外)をビルドします。
シェルを開きROS2の環境をセットアップ
`source /opt/ros/dashing/setup.bash`
パッケージディレクトリに移動

```
cd　<package-dir> 
colcon build --symlink-install
source install/setup.bash
```

もしROS2のワークスペース下にros1_bridgeもある場合はこれをスキップしたほうが良いです。

```
colcon build --symlink-install --packages-skip ros1_bridge
```



## ros1_bridgeのビルド
ros1_bridgeのパッケージを作成し、ビルドします。
### パッケージの作成

```
mkdir -p ros1_bridge_ws/src
```

ソースコードをクローンしてくる

```
cd ros1_bridge_ws/src
git clone -b dashing https://github.com/ros2/ros1_bridge.git
cd ..
```

### ビルド
ROS1とROS2の両方の環境をセットアップする（パターン3）。

```
source /opt/ros/melodic/setup.bash
source /opt/ros/dashing/setup.bash
```

ビルド

```
colcon build --symlink-install --packages-select ros1_bridge --cmake-force-configure
```

この部分で以下のようなエラーが出る場合は　をインストールしましょう。

エラー

```
CMake Error at CMakeLists.txt:133 (find_package):
By not providing "Findlaunch_testing_ament_cmake.cmake" in
CMAKE_MODULE_PATH this project has asked CMake to find a package
configuration file provided by "launch_testing_ament_cmake", but CMake did
not find one.

Could not find a package configuration file provided by
"launch_testing_ament_cmake" with any of the following names:

   launch_testing_ament_cmakeConfig.cmake
   launch_testing_ament_cmake-config.cmake
```

インストール方法

```
sudo apt install ros-dashing-launch*
```

参考：https://answers.ros.org/question/330417/ros2-issues-building-the-composition-demo-found-in-ros2demos/


これにてROS1のパッケージ、ROS2のパッケージ、ros1_bridgeがビルドされている状況ができました。
(今回のデモではros1_bridgeのみです。)
いよいよ実行しましょう。


## 実行
実行する段階では上記の3つのセットアップパターンのシェルを使い分けます。

### シェルA (ROS1のみ)
このシェルではroscoreを実行します。

```
source /opt/ros/melodic/setup.bash
roscore
```

### シェルB (ROS1+ROS2)
このシェルではros1_bridgeを実行します。

```bash
source /opt/ros/melodic/setup.bash
source /opt/ros/dashing/setup.bash
source ros1_bridge_ws/install/setup.bash
export ROS_MASTER_URI=http://localhost:11311
ros2 run ros1_bridge dynamic_bridge
```

### シェルC (ROS1のみ)
このシェルではROS1パッケージを実行します。
今回のデモではROS1 tutorial talkerを使用します。

```bash
source /opt/ros/melodic/setup.bash
rosrun rospy_tutorials talker
```

### シェルD (ROS2のみ)
このシェルではROS2パッケージを実行します。
今回のデモではROS2 demo_nodes_cpp listenerを使用します。

```bash
source /opt/ros/dashing/setup.bash
ros2 run demo_nodes_cpp listener
```

以上のように順に実行していくと、シェルCのROS1からpublishされたメッセージを、シェルDのROS2ノードでsubscribeしていることができました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190972/eda4ac17-3f03-9a24-cb17-980b4e3a608f.png)
画像は[リンク](https://github.com/ros2/ros1_bridge/blob/master/doc/ros1_talker_ros2_listener.png)より。