pixiとDocker Desktop on Macで始めるmacOSにおけるROS 2開発環境構築

## はじめに

一昔前であればmacOSでROS 2開発環境構築する時、ソースビルドによりインストールされていました。以下に参考記事を示します。

- https://docs.ros.org/en/humble/Installation/Alternatives/macOS-Development-Setup.html
- https://qiita.com/TakanoTaiga/items/f67217ce60a81799a663
- https://ar-ray.hatenablog.com/entry/2023/12/24/115051
- https://www.docswell.com/s/dandelion1124/KM1PJL-2024-02-13-093736

ただし、この方法は必要なROS 2パッケージをソースビルドする必要があり、パッケージ管理システムの恩恵を受けることができないため、開発環境構築が煩雑となっていました。

そのような混沌とした状況の中、高瀬先生より「pixiというパッケージ管理システムを使うとmacOSでROS 2開発環境構築が簡単にできる」という情報が共有されました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">なにもわかってないですが pixi というのがいいらしいという本質情報が飛び交っております <a href="https://twitter.com/hashtag/macOS%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8BROS2?src=hash&amp;ref_src=twsrc%5Etfw">#macOSで始めるROS2</a> <a href="https://t.co/x7qE6c0nC0">https://t.co/x7qE6c0nC0</a> <a href="https://t.co/oQZux9ZkBx">pic.twitter.com/oQZux9ZkBx</a></p>&mdash; Hideki Takase (@takasehideki) <a href="https://twitter.com/takasehideki/status/1849041186612265346?ref_src=twsrc%5Etfw">October 23, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

従来よりDocker Desktop on MacでROS 2開発環境を作る方法もあったのでそれぞれの長所、短所を列挙します。

- pixi
  - 長所：ネイティブにROS 2をインストールできる
  - 短所：現状、rosdepをサポートしていない（<https://pixi.sh/v0.32.0/tutorials/ros2/#what-happens-with-rosdep>参照）
- Dockerコンテナ
  - 長所：UbuntuにおけるROS 2開発環境構築手順を踏襲できる（aptでパッケージをインストールできる、rosdepで依存関係解決できるなど）
  - 短所：センサデバイス、GUI、macOS固有のアクセラレータ利用に制限がある

上記のことからわかるようにそれぞれ一長一短あることがわかります。本記事ではpixiとDockerコンテナのROS 2環境を連携させることでそれぞれの不満点を補うことができるような方法を紹介します。

## 動作確認環境

今回動作確認に用いた開発環境は以下の通りです。

- MacBook Air (15インチ, M3, 2024)
- macOS Sonoma 14.4
- Docker Desktop on Mac 4.39.0
- pixi 0.42.1

## 前準備

### Docker Desktop on Macインストール

<https://docs.docker.com/desktop/setup/install/mac-install/>を参照してDocker Desktop on Macをインストールします。また、Docker Desktop設定画面にて`Resources`-`Network`で`Enable host networking`にチェックを入れます。

### Dockerコンテナ起動

以下のコマンドを実行してROS 2 HumbleのDockerコンテナを起動します。

```bash
docker run --rm -it \
           --net=host \
           --ipc=host \
           ros:humble-base \
           bash
```

また、今回、Fast DDSを使います。Fast DDSはデフォルトで共有メモリを介して通信を行うことがあるため、docker runのオプションに`--ipc=host`を付与します。このあたりの挙動が気になる方は<https://qiita.com/dandelion1124/items/9c0a9c16956bb8fb9065>を参照ください。

:::note info
pixiでROS 2 HumbleをインストールするとデフォルトのDDSはCyclone DDSとなっています。ただし、現状のpixiではCyclone DDSの場合にDockerコンテナと疎通できない問題（<https://github.com/prefix-dev/pixi/issues/2979>）があったため、今回、Fast DDSを使っています。
:::

### pixiインストール

以下のコマンドを実行してpixiをインストールします。

```bash
curl -fsSL https://pixi.sh/install.sh | bash
```

### pixiプロジェクト作成

以下のコマンドを実行してpixiプロジェクトを作成します。

```bash
pixi init my_ros2_project -c robostack-staging -c conda-forge
```

### パッケージインストール

以下のコマンドを実行して`ros-humble-desktop`をインストールします。

```bash
cd my_ros2_project
pixi add ros-humble-desktop
```

### pixiプロジェクト設定

my_ros2_project以下にある`pixi.toml`に以下の記述を追記し、環境変数を設定できるようにします。

```toml
[activation]
scripts = ["activate.sh"]
```

また、my_ros2_project以下に`activate.sh`を作成し、以下の記述を追記します。

```bash
export ROS_LOCALHOST_ONLY=0
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
```

## 動作確認

### pub

pixi上で以下のコマンドを実行します。

```bash
pixi run ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
```

### sub

Dockerコンテナで以下のコマンドを実行します。

```bash
ros2 topic echo /turtle1/cmd_vel
```

## 連携例

具体的なpixi、Dockerコンテナ連携例を以下に示します。

- pixi：RViz2
  - RViz2はGUIアプリケーション、画面描画にハードウェアアクセラレーションの恩恵が受けられる
- Dockerコンテナ：Gazebo Ignition、navigation2
  - Gazebo Ignitionはheadlessで動かす
  - Gazebo Ignition、navigation2および依存パッケージはapt、rosdepの恩恵が受けられる

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">macOS上のDockerコンテナ（ROS 2 Jazzy）でGazebo Ignition、navigation2を動かしてpixi上でRViz2を動かす。 <a href="https://t.co/LRus9a016u">pic.twitter.com/LRus9a016u</a></p>&mdash; dandelion (@dandelion1124) <a href="https://twitter.com/dandelion1124/status/1898683936919990610?ref_src=twsrc%5Etfw">March 9, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに

本記事ではpixiとDockerコンテナのROS 2環境を連携させることでそれぞれの開発環境での不満点を補うことでができるような方法を紹介しました。これらの情報を参考にしながら

- pixi：センサデバイス、GUI、macOS固有のアクセラレータ利用するパッケージ
- Dockerコンテナ：それ以外のパッケージ

と言うような使い分けをすることで、pixi、Dockerコンテナ単体での不満点を補完することができるようになります。そのため、これまでよりmacOS上でROS 2を使ったアプリケーション開発がやりやすくなるでしょう。

## 参考記事

- https://pixi.sh/latest/tutorials/ros2/
- https://zenn.dev/yahooshiken/articles/getting-started-ros2-with-pixish
- https://www.docswell.com/s/zibaanyan/KWWRYD-2024-12-28-113147