ROS2を簡単に始めてみよう(Docker使用編)

この記事は、[Code Polaris Advent Calendar 2023](https://qiita.com/advent-calendar/2023/code-polaris, "https://qiita.com/advent-calendar/2023/code-polaris")の 15日目の記事です。直前に内容を変更したので、大遅刻しました。すみません。

## はじめに
初投稿なので、今まで行ってきたROSの工夫についてではなくそもそもROS2をどうやって使用しているか、ROSを簡単に試すにはどうすれば良いかなどを纏めます。
全くROSを知らない方も、シミュレーションでロボットを動かすような遊びが出来れば良いなと考えています！


## 動作確認済みの環境
私はUbuntuを使っていますが、出来る限りWSLとUbuntuどちらの情報も共有していきたいと思います。複数の環境にて確認を行えています。確認済みの環境を以下に載せます。

|  |  |
|:-:|:-:|
| OS | Ubuntu 20.04, 22.04 |
| RAM | 8GB~ |
| プロセッサ | AMD, ARM |

## Dockerを導入しよう
実験の試行回数が非常に多いため、私達のチームではDockerを用いてROS2を使用しています。なので、今回はDockerを導入し、試行錯誤した結果のオプション(ほぼ秘伝のタレのようになっています)を公開します。
とりあえずdockerをapt installします。
以下の手順を最後まで進めて、dockerのバージョンが表示されればdockerのインストールは完了です。この部分はちょっと本題の外なので説明少なめです。困ったら[ドキュメント](https://docs.docker.com/engine/install/ubuntu/, "Install Docker Engine on Ubuntu")を見るのがオススメです。
```
$ sudo apt update && sudo apt upgrade -y
$ sudo apt install ca-certificates curl gnupg lsb-release
$ sudo mkdir -m 0755 -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin 
$ docker -v #バージョンの確認
```
Dockerのインストールが完了したら、使い始めます。このままだとsudoが毎回必要になるので、適切な権限を与えます。
```
$ sudo groupadd docker
$ sudo usermod -aG docker $USER
```
ここで再起動します。再起動が終わったら、以下のコマンドを打ちます。
```
$ newgrp docker
$ docker run hello-world
```

最後のdocker runは少しだけ待ちます。docker runが終了したときに
```
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
```
と表示されればdockerの導入は成功です！

## ROSを使用していく
やっと、ROSを使用することが出来ます！
AMDの場合と、ARMの場合で使用するイメージが違うので、ちょっとだけコマンドが異なります。
ちなみに、イメージを引っ張ってくる必要があるので、初回はめちゃくちゃ時間がかかります。
```docker:AMDの場合
$ docker run -it --net=host --name コンテナの名前 --device=/dev/dri:/dev/dri -e DISPLAY=${DISPLAY} -v /tmp/.X11-unix:/tmp/.X11-unix --privileged=true osrf/ros:ROSのDISTRO-desktop
```
```docker:ARMの場合
docker run -it --net=host --device /dev/ttyACM0:/dev/ttyACM0 --device /dev/ttyUSB0:/dev/ttyUSB0 --device /dev/bus/usb/:/dev/bus/usb --name コンテナの名前 arm64v8/ros:ROSのDISTRO
```
ROS2にはいくつかバージョンがあり(ROSDISTROといいます)、このバージョンによって少しずつ仕様が異なります。
個人的なおすすめ(一番使っている)のは、Humbleというバージョンなので、この先はROS2 Humbleのつもりで話を進めていきます。

ちなみに、ubuntu側で特に大事だと思っているオプションは以下の3つです。
| オプション | 説明 |
|:-:|:-:|
| -net=host | 振られるipが仮想のものではなく、PCと同一になります。 |
| -e DISPLAY=${DISPLAY} | dockerから画面を表示できるようにします。 |
| --name | コンテナの名前です。設定しないと変な名前になります。 |
| --privileged=true | 特権モードでコンテナを作成します。 |

もうROS自体の準備は終了です。ちなみに、Dockerコンテナをたてた直後は何も入っていないので、apt updateをして色々と入れなければなりません。私のおすすめ(というかほぼ必須)は以下のものです。
```
$ apt update && apt upgrade -y
$ apt install vim byobu net-tools
```
後は~/.bashrcに以下の行を追加しておきましょう。書いたら`source ~/.bashrc`しましょう。
```
export ROS_DOMAIN_ID=30
export LDS_MODEL=LDS-02
export TURTLEBOT3_MODEL=burger
source /opt/ros/ROSのDISTRO/setup.bash
```

## おすすめの動作確認
通信が出来ているかどうかを確認できて初めてやっとROSデビューです！
byobuを上でインストールしたのは、コンソールの画面を分割して動作確認をしたいからです。
まず、
```
$ byobu
```
と入力してbyobuを立ち上げます。`Shift+F2`で画面を分割し、`Shift+F3`,`Shift+F4`で画面を移動します。
これを駆使して画面を2つ立てて下さい。
それぞれのターミナルで
```
$ ros2 run demo_nodes_cpp talker
```
```
$ ros2 run demo_nodes_cpp listerner
```
とします。
listenerの方で、
```
[INFO] [1702623753.270337500] [listener]: I heard: [Hello World: 1]
[INFO] [1702623754.270229636] [listener]: I heard: [Hello World: 2]
...
```
のような文言が表示されたら成功です！お疲れ様でした！