Dockerコンテナ内でのROS2開発環境の構築とRVizのブラウザ表示（M1 MacBook, M4 MacBook Pro)

　初めまして．私は有志のロボット開発チーム``ARCANAIN``のメンバーとして，ROS2を使った自律走行ロボットの開発を行なっています．
　M1チップ搭載のMacBook環境でROS2の開発を進める方法としては，まずUbuntuの仮想環境を利用する方法が考えられます[^1][^2]．私も以前はUTMを用いてUbuntuの仮想環境を構築しその上で開発を行っていましたが，UTMは動作が不安定で，突然フリーズすることが何度もありました．
　そこで軽量かつ動作も安定していて，情報も豊富なDocker[^3]を使うことにしました．私はロボットの中でも特にカメラによるPerceptionの部分を担当しています．
 画像処理や画像認識の開発をする上で実際に画像を出力して確認したいことがあるので，ブラウザ経由でGUIを使用できるよう環境構築を行いました．
 
https://github.com/Arcanain

P.S. 2025.1.23 M4 Macbook Proでも動作確認できました

[^1]: [How To Install ROS 2 in Ubuntu 22.04 On M1 Mac - The Robotics Space](https://www.theroboticsspace.com/blog/How-To-Install-ROS-2-in-Ubuntu-22-04-On-M1-Mac/)
[^2]: [Apple Silicon MacでもROSでgazeboとUSBデバイスを全部使いたい！ #シリアル通信 - Qiita](https://qiita.com/B-SKY-Lab/items/c519e5bc9a37b3805fd0)
[^3]: [「Docker」を全く知らない人のために「Docker」の魅力を伝えるための「Docker」入門 #VirtualBox - Qiita](https://qiita.com/odekekepeanuts/items/4604f530fe25786240db)


# 概要<!どんな感じで可能にしているのか．ぱっと見でわかるようにする>

作成したDockerfile等は以下githubに上がっています。

https://github.com/Arcanain/arcanain_docker/tree/feature/vnc_desktop

<!---
今回は以下のGithubを参考にしました．

https://github.com/adeeb10abbas/ros2-docker-dev/tree/master
--->

# 環境構築の流れ
まずはGithubからリポジトリをクローンします.次にそのディレクトリに移動します．

```terminal
git clone https://github.com/Arcanain/arcanain_docker.git
cd arcanain_docker
git checkout feature/vnc_desktop
```

> Dockerの導入については[3]を参考にしています。一般的な方法で問題なく動作することを確認しているので、Dockerのインストール等は他の記事を参考にしてください．
> M4 Macbook Proでも動作確認済み！


<!---

--->
次にダウンロードしてきたDockerfileからイメージをビルドします．
```terminal
docker build -t ros2-dev .
```
ビルドが正常に完了したら，環境構築は完了です．

# 動作確認
起動前にまずは環境変数の設定です．
```zsh
export ROS_DEV_CONTAINER_NAME=ros2_dev_container
export ROS_PROJECT_PATH=$(pwd) # 要調整！
```

`ROS_DEV_CONTAINER_NAME`はコンテナの名前で，`ros2_dev_container`に設定していますが、自由に決めてもらって大丈夫です．

`ROS_PROJECT_PATH`は，一旦現在のディレクトリに設定しています．これは，ROSプロジェクトのソースコードや設定ファイルが格納されているホスト側のディレクトリを指定します．これを指定することで、Dockerコンテナ内で編集することができるようになります．
> ここで指定するPATHは、Macbookのディレクトリになります．ここで指定したディレクトリを　Docker コンテナ内の``~/ros2_ws/``にマウントすることになります．[gitの12~16行目あたりで設定しています](https://github.com/adeeb10abbas/ros2-docker-dev/blob/master/docker-compose.yml).


先ほどビルドしたイメージからコンテナを起動します．ビルドした時と同じディレクトリで以下のコマンドを実行しましょう．
```terminal
docker-compose up
```
今回は同ディレクトリ内の`docker-compose.yml`に定義された2つのコンテナ（ros2_dev_containerとros2-docker-dev-novnc-1）を起動させる必要があります．
 以下のコマンドでコンテナの起動状態を確認してみましょう．新たに二つのコンテナ`ros2_dev_container`,`ros2-docker-dev-novnc-1
`が起動中になっていることが確認できるはずです．
<details><summary>各コンテナの役割はこちら
</summary>

`ros2_dev_container`はROS2（Robot Operating System 2）の開発環境を提供するものです．このコンテナにはそのためのツールやライブラリがインストールされています。この環境内で開発を行います．
`ros2-docker-dev-novnc-1`はVNCサーバーを立ち上げ、リモートデスクトップ環境を提供するものです．VNC（Virtual Network Computing）はリモートデスクトップ環境を提供するためのプロトコルで，このコンテナではnoVNCを使用してブラウザを介したリモートデスクトップアクセスが可能です．特に，RVizなどのGUIツールを使用するのでこちらのコンテナも起動しておく必要があります．

 まとめると`ros2_dev_container`は開発環境の提供，`ros2-docker-dev-novnc-1`はその開発環境にブラウザでリモートアクセスするためのGUI環境を提供するものです．

</details>


```zsh
docker ps
#出力
CONTAINER ID   IMAGE                 COMMAND                   CREATED        STATUS          PORTS                    NAMES
xxxxxx123456   ros2_dev_container    "/ros_entrypoint.sh …"    *** ago     　　Up *** minutes                            ros2_dev_container
yyyyyy654321   sample/novnc:latest   "/app/entrypoint.sh"      *** ago      Up *** minutes   0.0.0.0:8080->8080/tcp   ros2-docker-dev-novnc-1

```

起動が確認できたら他のターミナルや**VScodeからアタッチ**[^10]することで開発・実行することが可能になります．

ターミナルからアタッチする時は，先ほど指定したコンテナ名に注意して以下のコマンドを実行します．
[^10]:[VSCodeでDockerコンテナにアタッチして開発 #React - Qiita](https://qiita.com/nonamenme/items/43243586c81cbbb9b08b)
```zsh
docker exec -it ros2_dev_container /bin/bash
#起動後，コンテナ内でターミナルが開始される
root@21cb948dd945:/# ls
bin  boot  dev  etc  home  lib  log  media  mnt  opt  proc  root  ros2_ws  ros_entrypoint.sh  run  sbin  srv  sys  tmp  usr  var
root@21cb948dd945:/# cd ros2_ws
root@21cb948dd945:/ros2_ws# ls
src
```
これで、ターミナル上で色々操作することができます。終了する場合は``ctr + D``です。
```
root@21cb948dd945:/#             　　 # ctr+D を押した。
exit
nkn4ryu@nkn4ryu-pro ~ % 　　　　　　　  # 外に出た
```

<details><summary>終了したいとき</summary>

compose upしたターミナルでctr + C を押します。コンテナの削除方法などは他のサイトを参考にしてください。
```
Gracefully stopping... (press Ctrl+C again to force)
[+] Stopping 2/2
 ✔ Container ros2_dev_container       Sto...                               10.1s 
 ✔ Container ros2-docker-dev-novnc-1  Stopped                               0.7s 
nkn4ryu@nkn4ryu-pro ros2-docker-dev % 
```
</details>


# ROSを動かしてみる

実際にコンテナにアタッチした状態で、ROSを動作させてみましょう。ROSの環境構築でよくやるexampleを回してみます。

https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html#try-some-examples

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665619/23a46149-93dc-3bfc-792d-23a0dff21b04.png)

左がtalker, 右がlistenerです。
両方とも実行すると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665619/78ace935-204f-58cc-8d34-962fefd21027.png)

きちんとpub/subできています！


# ブラウザ上でGUIを使う
ROSの動作確認も済んだので、今回のキモであるホストマシンのブラウザを経由したデスクトップ表示をやってみましょう。

Dockerが立ち上がった状態で、 http://localhost:8080/vnc.html
にアクセスします。
VNCクライアントが起動し、Dockerコンテナ内のデスクトップ画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665619/c6202832-fdc3-822c-1571-7764e3eee14e.png)

真ん中の``Connect`` をクリックすると、Xtermのみ立ち上がった状態のデスクトップ画面が表示されます。コンテナ内でVNCサーバが立ち上がり、GUIをストリーミングしているのをみているイメージです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665619/73912b96-f3e3-6c18-110e-7e7ebbe3d46d.png)


アタッチしたターミナルでrviz2を実行してみましょう。

```
~$ rviz2
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-ubuntu'
[INFO] [1737637590.009892540] [rviz2]: Stereo is NOT SUPPORTED
[INFO] [1737637590.009953748] [rviz2]: OpenGl version: 4.5 (GLSL 4.5)
[INFO] [1737637590.182024104] [rviz2]: Stereo is NOT SUPPORTED

```
ブラウザに戻ってみると、立ち上がったrvizのGUIが開いていることがわかります。
ここで操作することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665619/035345f6-c2bd-ce26-e046-768a1081574c.png)

---
ubuntu上で作業するほど快適とは言えませんが、macbook等を使って開発する際の最小限のGUIは提供されているので、適材適所で使うのが良いと思います。


# 謝辞
この取り組みは, GxP(グロースエクスパートナーズ)株式会社様のサポートを受けて実施しています. 貴重なアドバイスや, ロボットに必要な機材の支援をいただきました. 心より感謝申し上げます.

https://www.gxp.co.jp/

https://qiita.com/organizations/gxp


# 参考文献
[1] [ROS/ROS2のGUIをWebブラウザ経由でお手軽に試せるDockerfileを公開しました | Memoteki](https://memoteki.net/archives/2955#index_id2)
[2] [今回使ったスクリプトのGithubリンク](https://github.com/adeeb10abbas/ros2-docker-dev/tree/master)
[3] [Docker Desktopを使わずにMac上にDocker環境を構築【2025年版】 #colima - Qiita](https://qiita.com/Lightning7329/items/e2fd6045782230cebb61)