Docker Desktop for Macを利用してROS開発環境を作ってみる(on M1 MBA)

はじめに

今回、M1 MBA上でDockerを使用してROSノードのコンパイルをできる環境を作ってみようと思います。どうもDockerは各種概念や操作感がややこしくて個人的には良いイメージがないのですが、軽量なLinuxサブシステムとして使えるなら、と思い今回挑戦してみました。

Dockerはイメージからコンテナ(実体)を作成しそこにログインして利用するような世界観ですが、コンテナは一度起動するとオプションを変えるために再起動が必要で、その際にコンテナ内で行った変更を保存するのが面倒だったりします。このため、VMwareやVirtualBox、Parallelsのような感覚で使おうとするととても使いにくいということに気づきます。

このため、DockerはDocker流の使い方をする必要があります。これは、まずDockerfileを作成し、それをもとにイメージをビルド、ファイルはディレクトリマウントにより外部に保存し、コンテナは使い捨てにするような使い方です。

私自身難しい使い方はわかっていないのですが、今回ROSノードを最低限コンパイルでき、WSLのようなサブシステムとして簡単に使えることを目指して作ってみました。

手順

まずはイメージをビルドするためのプロジェクトディレクトリを作成します。

mkdir ros2_dev
cd ros2_dev
vi Dockerfile

Dockerfileには以下のような内容を記述します。今回はMacのホームディレクトリを直接マウントすることにしました。当然Linuxでの変更が直接反映されるため、注意は必要です。

Dockerfile

FROM ros:foxy
ENV USER your_user_name
ENV PASS your_test_password
RUN apt update
RUN apt install -y vim tmux ros-foxy-example-interfaces
RUN useradd -s /bin/bash ${USER}
RUN gpasswd -a ${USER} sudo
RUN echo "${USER}:${PASS}" | chpasswd
ENTRYPOINT su - ${USER}

イメージをビルドします。

docker build -t ros2_dev_image .

コンテナの起動は以下のようなコマンドとしました。 X11転送もできるようにオプションを付加してみましたが、なぜかできたりできなかったりで安定しない状態です。これは今後調査の必要がありそうです。

docker run \
    -it \
    --name dev_ros2 \
    -e DISPLAY=$(hostname):0 \
    -v ~/.Xauthority:/root/.Xauthority \
    -v /Users/${USER}:/home/${USER} \
    ros2_dev_image

Dockerfileを変更して再ビルドするときには、上記ビルドコマンドを再実行すると、自動的に差分ビルドをしてくれるようです。 新しいコンテナを立ち上げるためには、一旦古いコンテナを削除する必要があります。私はコマンド覚えられないのでDocker DesktopのGUIから行ってしまいました。

Dockerfileから直接シェルの環境変数を取り込もうとしましたが、できないようです。また、Dockerfile内で環境変数と呼んでいるものは環境のそれとは違うとのことです。(こういうところなんですよね。。)

ros2のサンプルをcloneして実行してみます。一つapt installも必要でした。

cd
mkdir colcon_ws/src/
cd colcon_ws/src
git clone https://github.com/ros2/examples
cd ..
sudo apt install ros-foxy-example-interfaces
colcon build

別な端末を開いて、コンテナに接続したい場合は以下のようにします。この方法で、.bashrcが実行されることは確認しました。

docker exec -it -u your_user_name dev_ros2 bash

端末を2つ開いて上記方法でそれぞれコンテナに接続します。 それぞれで以下を実行します。

ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
ros2 run examples_rclcpp_minimal_publisher publisher_member_function

Hello, world!が送受信できていたら成功です。

おわりに

ひとまず、Docker自体を動かすまでにUbuntuの場合結構苦労した記憶がありますが、Macはそこらへんは楽ですね。

ですが、新しいシェルでコンテナに接続するといった誰もが行いたいような操作についても調べ物やtry&errorが必要であったり、やはり専業の方以外にはおすすめしづらいツールだという印象は変わりませんでした。