モチベーション
ROS 2 Humbleのように、JetPackで入れられるl4tのベースとなるUbuntuのバージョンでは対応できないバージョンのROS 2を活用する際には、構築済みの環境を使用する方が楽です。一方で、Nvidiaが提供しているSBCのJetsonでは、通常のUbuntuイメージだとGPUがうまく動作しないことがあり、例えば、ホストマシンではubuntu:20.04で動かしていたものは、nvcr.io/nvidia/l4t-baseを使用する必要があります。そのため、Jetsonとホストマシンでは別のイメージをベースとするDockerfileが必要になるので、管理が煩雑になるという問題がありました。本稿では、Dockerfileとイメージをビルドする際のシェルスクリプトを工夫することで、共通のDockerfileで環境構築することを目指します。
この記事でできること
- 共通のDockerfileを用いてJetsonとホストマシンでほぼ同じDockerイメージを構築できる
- ついでに、コンテナ起動時にGPUの有無をチェックすることで、GPUのないホストマシンでもコンテナを立ち上げられる
検証環境
- ホストマシンOS: Ubutnu 24.04LTS
- Jetson: Jetson AGX Xavier(l4t:R35.4.1)
Dockerfileの書き換え
作成したDockerfileの先頭部分を以下に示します。
ARG TARGET="general"
FROM ros:humble AS image_general
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics
# check your jetpack version with "cat /etc/nv_tegra_release" in Jetson terminal.
FROM dustynv/ros:humble-desktop-l4t-r35.4.1 AS image_jetson
FROM image_${TARGET}
#以下で必要なパッケージのインストール
はじめに、ホストマシンかJetsonかを識別するための引数TARGETを定義します。
その後に、ホストマシン用のベースイメージとして、ros:humbleを、Jetson用のベースイメージとしてはdustynv/ros:humble-desktop-l4t-r35.4.1を使用しています。コメントにもあるように、/etc/nv_tegra_releaseの内容を確認して使用するl4tのバージョンを合わせておくと良いと思います。
[参考] Jetson AGX Orin でROS 2 Humbleを動かす
イメージビルド用シェルスクリプト
イメージをビルドする際に使用するシェルスクリプトの内容を以下に示します。
#!/bin/bash
if uname -r | grep tegra; then
BUILD_JETSON="--build-arg TARGET=jetson"
fi
docker build --build-arg NUM_THREADS=8 ${BUILD_JETSON} --rm -t hogehoge-image .
unameコマンドで表示される情報に"tegra"の文字列が含まれているかで、Jetsonであるかを判定しています。
"hogehoge-image"は必要に応じて変更してください。
コンテナ立ち上げ用シェルスクリプト
コンテナを立ち上げる際に使用するシェルスクリプトの内容を以下に示します。
#!/bin/bash
xhost +local:
if type nvidia-container-runtime >/dev/null 2>&1; then
GPU_OPT="--gpus all"
fi
docker run -it --rm ${GPU_OPT} --net host \
--privileged -v /dev/bus/usb:/dev/bus/usb \
--env="DISPLAY" \
-v $HOME/.Xauthority:/root/.Xauthority:rw \
-v /tmp/.X11-unix:/tmp/.X11-unix \
--workdir="/root/colcon_ws" \
--volume="$(pwd)/../colcon_ws:/root/colcon_ws" \
hogehoge-image:latest
使用しているDockerがGPUに対応しているかを判定するために、"nvidia-container-runtime"コマンドが存在するかを使用しています。"nvidia-smi"で判定する場合だと、Jetsonではうまく動作しなかったのでこのコマンドを使用しています。
このシェルスクリプトでは、Dockerfileやシェルスクリプトの格納されているディレクトリのひとつ上に"colcon_ws"が存在することを前提としているので、適宜変更してください。
イメージビルド用シェルスクリプト内の"hogehoge-image"を変更していた場合には、忘れずにこちらにも反映させてください。
まとめ
本稿では、Jetsonとホストマシンで共通のDockerfileを使用する方法として、Dockerfileの引数を活用する方法についてまとめました。今回の投稿は、新しいロボットを作るたびに書き方を忘れてしまう自分のための備忘録的なものとなっています。参考になれば幸いです。