Docker ComposeでROS2ノードを起動する


# はじめに

Docker Composeを使ってdemo_nodesのlistenerとtalkerを別々のDockerコンテナで起動し、それぞれのDockerコンテナ同士でROS2通信するサンプル。



# テスト環境

ホストPCのOS : ubuntu22.04.4LTS
DockerコンテナのOS：ubuntu22.04LTS
DockerコンテナのROS2 : Humble
docker のバージョン：24.0.6
docker-composeのバージョン：2.21.0


# DockerとDocker Composeのインストール

使う環境によってインストール方法が異なるため省略
ubuntu22.04にインストールする場合はこちらを参考

https://qiita.com/yoshiyasu1111/items/17d9d928ceebb1f1d26d

# ROS2のDockerイメージのインストール

以下コマンドでROS2のDockerイメージをpullする。

```bash
docker pull osrf/ros:humble-desktop
```


```bash
docker images

REPOSITORY                    TAG               IMAGE ID       CREATED         SIZE
osrf/ros                      humble-desktop      f63b30d9bcf7   3 weeks ago     3.11GB
```


# docker-compose.ymlファイルの作成

demo_nodesのtalckerとlistenerを別々のコンテナで実行し、通信させるサンプル
環境変数の`ROS_DOMAIN_ID`はなくてもよい。
`ros2`という名前のネットワークを作成してそれぞれのコンテナで使用している。

```yaml:docker-compose.yml
version: '3'
# create docker network
networks:
  ros2:
    driver: bridge

services:
  talker:
    image: osrf/ros:humble-desktop
    container_name: talker
    environment:
      - ROS_DOMAIN_ID=1
    command: ros2 run demo_nodes_cpp talker
    networks:
      - ros2
    ipc: host
    restart: always

  listener:
    image: osrf/ros:humble-desktop
    container_name: listener
    environment:
      - ROS_DOMAIN_ID=1
    command: ros2 run demo_nodes_cpp listener
    networks:
      - ros2
    ipc: host
    restart: always
```

以下は公式ドキュメントにある最小のサンプル

```yaml:docker-compose.yml
version: '2'

services:
  talker:
    image: osrf/ros:humble-desktop
    command: ros2 run demo_nodes_cpp talker
  listener:
    image: osrf/ros:humble-desktop
    command: ros2 run demo_nodes_cpp listener
    depends_on:
      - talker
```

depends_onオプションはtalker コンテナが起動してからlistenerコンテナが起動する設定。


# 実行

docker-compose.ymlのあるディレクトリで以下を実行しtalkerコンテナとlisteneコンテナをまとめて起動する。

```bash
docker compose up
```

または

```bash
docker compose -f docker-compose.yml up
```


以下のようなメッセージが出ていたら成功

```bash
Creating network "ros2_docker_compose_ros2" with driver "bridge"
Creating ros2_docker_compose_listener_1 ... done
Creating ros2_docker_compose_talker_1   ... done
Attaching to ros2_docker_compose_talker_1, ros2_docker_compose_listener_1
talker_1    | [INFO] [1664355563.968462971] [talker]: Publishing: 'Hello World: 1'
listener_1  | [INFO] [1664355563.969353969] [listener]: I heard: [Hello World: 1]
talker_1    | [INFO] [1664355564.968472582] [talker]: Publishing: 'Hello World: 2'
listener_1  | [INFO] [1664355564.969369471] [listener]: I heard: [Hello World: 2]
talker_1    | [INFO] [1664355565.969120487] [talker]: Publishing: 'Hello World: 3'
listener_1  | [INFO] [1664355565.969678627] [listener]: I heard: [Hello World: 3]
```

終了する場合

```bash
docker compose down
```

:::note warn
down で終了するとコンテナも削除されるので注意
:::

### コンテナ内に入ってトピックの中身を見たい場合

docker execでどれかのコンテナに入ってros2 コマンドを実行

```bash
docker exec -it listener bash
root@0004e67a0578:/# source /opt/ros/humble/setup.bash
root@0004e67a0578:/# ros2 topic list
root@0004e67a0578:/# ros2 topic echo /chatter
```

### ホストPCのROS2でトピックの中身を見たい場合

```bash
export ROS_DOMAIN_ID=1
ros2 topic echo /chatter
```


# 参考

https://docs.ros.org/en/humble/How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.html


https://www.moriken254.com/entry/2019/05/11/174924


https://tech.aptpod.co.jp/entry/2023/09/25/170000