ROS複数Docker通信

## 背景
・開発環境／ランタイムのアプリ依存は完全に排除することは非常に困難。
・ROSアプリによっては特定のversionやpackageに依存する。(例えば、melodic依存など)
・docker使えば、上記は排除できるし、アプリ提供者がシステムを気にしなくてもいい。
・開発環境もランタイムもアプリごとに自由だし、界面もdockerでわかりやすい。

## ここで試してみること
1. ROSノードを複数のdockerで起動して通信できることを確認する。
2. ROS2ノードを複数のdockerで起動して通信できることを確認する。
3. ROS/ROS2ノードを複数のdockerで起動し、ros1_bridgeを利用してROS/ROS2間で通信できることを確認する。
(*) ROSのrosmasterはhostで動作させることにする。他のROS/ROS2ノードはすべてdockerでの実行。

## 環境
Host Linux: Ubuntu16.04.5 LTS
Docker: 18.09.0, build 4d60db4
Host Linux ROS version: kinetic

## Docker imageの準備
Host LinuxのROS及びdocker自体のインストール設定は省きます。(ググればOK)

```
docker pull ros:kinetic
docker pull ros:melodic
docker pull osrf/ros2:bouncy-desktop
docker pull osrf/ros2:bouncy-ros1-bridge

docker images
REPOSITORY          TAG                  IMAGE ID            CREATED             SIZE
ros                 melodic              9425ec5f7a7f        3 days ago          1.27GB
osrf/ros2           bouncy-ros1-bridge   495f9879df9e        2 weeks ago         1.2GB
osrf/ros2           bouncy-desktop       3e9aa775362d        2 weeks ago         2.41GB
ros                 kinetic              6f91828bbf93        4 weeks ago         1.19GB
```

### 1. ROSノード複数Docker通信
[Overview]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/112819/b7ec6953-3ef8-c6ba-89ab-5e744bb906fb.png)

[Procedure]
1-1. Host Linuxでroscore起動

```
# docker networkを利用するので以下の設定でroscoreを起動する。
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.1
roscore
...
```

1-2. ros:kinecit dockerでpublisher起動

```
# docker ros:kinetic start
docker run -it 6f91828bbf93

# net-tools install (IP addressを念の為確認するため)
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.2

# topic publish start
rostopic pub -r 10 /chatter std_msgs/String "this is ros:kinetic"
```

1-3. ros:melodic dockerでsubscliber起動

```
# docker ros:melodic start
docker run -it 9425ec5f7a7f

# net-tools install (IP addressを念の為確認するため)
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.3

# topic publish start
root@c489bf255877:/# rostopic echo /chatter
data: "this is ros:kinetic"

...
```

(当然ですが、)ROSノード間でPub/Sub通信できていることが確認できました。

### 2. ROS2ノード複数Docker通信
[Overview]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/112819/4c9c2c46-345f-b0a9-ee65-915e5c1ff0d3.png)

2-1. ros2:bouncy-desktop dockerでpublisher起動

```
# docker ros2:bouncy-desktop start
docker run -it 3e9aa775362d

# topic publish start
ros2 topic pub /chatter std_msgs/String "data: this is ros2:bouncy-desktop"
publisher: beginning loop
publishing #1: std_msgs.msg.String(data='this is ros2:bouncy-desktop')
```

2-2. ros2:bouncy-desktop dockerでsubscriber起動

```
# docker ros2:bouncy-desktop start
docker run -it 3e9aa775362d

# topic subscriber start
ros2 topic echo /chatter std_msgs/String
data: this is ros2:bouncy-desktop
```

ROS2ノードでdocker間通信ができました。

### 3. ROS/ROS2ノード複数Docker通信
[Overview]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/112819/91dcbd00-0380-f07f-2dc1-ab66ba2fc110.png)

3-1. Host Linuxでroscore起動

```
# docker networkを利用するので以下の設定でroscoreを起動する。
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.1
roscore
...
```

3-2. ros:melodic dockerでpublisher起動

```
# docker ros:melodic start
docker run -it 9425ec5f7a7f

# net-tools install (IP addressを念の為確認するため)
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.2

# topic publish start
rostopic pub /chatter std_msgs/String "this is ros:melodic"
```

3-3. docker ros2:bouncy-ros1-bridge start

```
# docker ros2:bouncy-ros1-bridge start
docker run -it 495f9879df9e

# net-tools install (IP addressを念の為確認するため)
apt update
apt install net-tools
ifconfig

# ROS IP setting
export ROS_MASTER_URI=http://172.17.0.1:11311
export ROS_IP=172.17.0.5

# ROS/ROS2 bridge start
ros2 run ros1_bridge dynamic_bridge /chatter std_msgs/String
created 1to2 bridge for topic '/chatter' with ROS 1 type 'std_msgs/String' and ROS 2 type 'std_msgs/String'
```

3-4. ros2:bouncy-desktop dockerでsubscriber起動

```
# docker ros2:bouncy-desktop start
docker run -it 3e9aa775362d

# topic subscriber start
ros2 topic echo /chatter std_msgs/String
data: this is ros:melodic
```

ROS bridgeを利用して、docker間でROS/ROS2通信を確認できました。

ということで、dockerを使えばROS分散型開発が簡単にできる。