Zenn
🦾

Isaac SimをDockerでインストールする

2025/04/12に公開

環境について

Dockerでisaac simをインストールします。
nvidia公式で配布されているnvcr.io/nvidia/isaac-sim:4.5.0というイメージがありますが、以下2点が理由で別のベースイメージを使用します。

  • Isaac Sim WebRTC Streaming ClientというVNCのようなかたちで操作しなければならない
  • cudaバージョン等を自分で指定したものを使いたい

色々なインストール方法があるのですが、isaac labとしてはpip installの方法が紹介されているので、このやり方をベースとします。
Pythonのパッケージ管理はuvで、venv仮想環境上にisaac simをインストールします。
isaac simのインストール自体にはROSやcudaは必要ないはずですが、isaac labやpytorch等を用いたライブラリを後々使用したいので入れています。

  • OS: Ubuntu 22.04
  • GPU: Geforce RTX 3080 (10GB)
  • GPU driver: 570.133.07
  • Dockerベースイメージ: nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04
  • isaac sim: 4.5.0
  • ROS: ROS2 humble

先にやっておくこと

GPUのdriverインストール

GPUのdriverをインストールします。
apt経由でもいいのですが、個人的にあまり上手くいったためしがないので.runファイル経由でインストールしました。
driver手動検索のページ

sudo sh NVIDIA-Linux-x86_64-570.133.07.run

だいたいよしなにYesを選択しておけば問題ないのですが、途中でUEFIのセキュアブートの箇所で引っ掛かります。
私の環境はWindows11とのデュアルブートとなっております。
Windows11は10からの移行時にUEFIを要求されてました。
そのため、Windows11とのデュアルブートをしている方は確実にこれが要求されるかと思います。
以下ページを参考にさせていただき、公開鍵を作ります。
参考: UEFI のセキュアブート機にNVIDIAのドライバを入れる話

そして、rebootする前に以下を実行してパスワードを設定します。
********の箇所はtabで候補が出ると思います。

sudo mokutil --import /usr/share/nvidia/nvidia-modsign-crt-********.der

その後再起動するのですが、いつものubuntuの起動画面の前に1枚別の画面が挟まります。
一番上は普通に起動する選択肢ですが、私の場合は2つ目にenrollする選択肢が出たのでそちらを選びます。
そして、先ほど入力したパスワードをいれます。

この時点で、nvidia-smiが通ると思います。

Docker関係のインストール

まずは公式ドキュメントの通り、dockerをインストールします。
以下はそのコピペです。

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt remove $pkg; done

sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

さらに、nvidia-container-toolkitをインストールします。以下はそのコピペです。

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
  && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update
sudo apt install -y nvidia-container-toolkit
		
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Docker環境をつくる

Dockerイメージをビルドする

Docker composeを使用します。

ディレクトリ構成は好みですが、私は以下のようなかたちで作っていることが多いです。

.
├── docker
|   ├── cpu
|   |   └── Dockerfile
|   ├── gpu
|   |   └── Dockerfile
|   ├── compose.yaml
|   ├── entrypoint.sh
|   └── .env
└── src

まずは、Docker内でローカルユーザをつくるために.envファイルをつくります。
以下のようにして現在ホスト側でログインしているユーザの情報をそのまま使います。手打ちしてもよいです。

echo UID=$(id -u) > .env
echo GID=$(id -g) >> .env
echo USERNAME=$(whoami) >> .env

.envはこうなります。

.env
UID=1000
GID=1000
USERNAME=<usernameを書く>

次にcompose.yamlファイルを作成します。
docker-compose.yaml時代の書き方とかが混ざっていたり、port等は必要がないものがある気がしますが、気にしない方向でいきます。

compose.yaml
services:
  gpu:
    build:
      context: ../
      dockerfile: docker/gpu/Dockerfile
      args:
        - UID=${UID}
        - GID=${GID}
        - USERNAME=${USERNAME}
    env_file:
      - .env
    image: <イメージ名を入力する>
    command: /bin/bash
    ports:
      - 8000:8000
    working_dir: /home/${USERNAME}
    tty: true
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
      - /home/${USERNAME}/.Xauthority:/root/.Xauthority
    runtime: nvidia
    environment:
      NVIDIA_VISIBLE_DEVICES: all
      NVIDIA_DRIVER_CAPABILITIES: all
      DISPLAY: $DISPLAY
      QT_X11_NO_MITSHM: 1
    privileged: true
    shm_size: '16gb'
    network_mode: "host"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

恐らくポイントとしてあげられるのが以下項目で、これがないとDockerコンテナ内のnvidia-smiでGPUを見つけられていても、vulkaninfoで見つけられない場合があります。

compose.yamlの一部
    runtime: nvidia
    environment:
      NVIDIA_VISIBLE_DEVICES: all
      NVIDIA_DRIVER_CAPABILITIES: all

ないと下記のようなエラーが出てきます。

[Error] [gpu.foundation.plugin] No device could be created. Some known system issues:
- The driver is not installed properly and requires a clean re-install.
- Your GPUs do not support RayTracing: DXR or Vulkan ray_tracing, or hardware is excluded due to performance.
- The driver cannot enumerate any GPU: driver, display, TCC mode or a docker issue. For Vulkan, test it with Vulkaninfo tool from Vulkan SDK, instead of nvidia-smi.
- For Ubuntu, it requires server-xorg-core 1.20.7+ and a display to work without --no-window.
- For Linux dockers, the setup is not complete. Install the latest driver, xServer and NVIDIA container runtime.

Dockerfileはこんな感じです。
isaac sim側のインストールだとなぜかエラーが出たので、isaac lab側のインストールの方法を参考にしています。
(恐らく、pytorchをあらかじめインストールしておく必要があったのだと思います)

ちょこちょことUSERを切り替えて、isaac sim使用時をローカルユーザとなるようにしています。
一応isaacsim実行時に引数を指定することでrootでも実行できるようなのですが、ローカルユーザ使用が前提となっているようなのでこのようにしています。
rootのままuv pip install ~~~してしまうと、rootユーザでコンテナに入らないと実行できなくなります。

Dockerfile
ARG BASE_IMAGE=nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04
FROM $BASE_IMAGE

ARG UID
ARG GID
ARG USERNAME

USER root
SHELL ["/bin/bash", "-c"]

ENV TZ=Asia/Tokyo

RUN export DEBIAN_FRONTEND=noninactive \
    && apt-get update && apt-get install -y --no-install-recommends \
        tzdata \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN apt-get update && apt-get install -y --no-install-recommends \
        apt-transport-https \
        build-essential \
        bzip2 \
        ca-certificates \
        curl \
        ffmpeg \
        g++ \
        git \
        gnupg \
        graphviz \
        locales \
        libgl1-mesa-dev \
        libusb-1.0-0-dev \
        lsb-release \
        net-tools \
        openssh-client \
        software-properties-common \
        sudo \
        unzip \
        vim \
        wget \
        xorg-dev \
        zip \
        emacs \
        python3-dev \
        python3-setuptools \
        python3-pip \
        python3-venv \
        vulkan-tools \
        usbutils \
        x11-apps \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN groupadd -g ${GID} ${USERNAME} && useradd -u ${UID} -g ${GID} -s /bin/bash -m ${USERNAME}
WORKDIR /home/$USERNAME/ws

# ROS2
ENV ROS_DISTRO=humble
RUN locale-gen ja_JP ja_JP.UTF-8 \
    && update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
RUN add-apt-repository universe \
    && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null \
    && apt-get update && apt-get install -y \
        ros-$ROS_DISTRO-desktop \
        ros-dev-tools \
        ros-$ROS_DISTRO-xacro \
        ros-$ROS_DISTRO-joint-state-publisher \
        ros-$ROS_DISTRO-joint-state-publisher-gui \
        ros-$ROS_DISTRO-moveit \
        python3-rosdep \
        python3-colcon-common-extensions \
        python3-colcon-mixin \
        python3-vcstool \
        python3-argcomplete \
        # for isaacsim bridge
        ros-$ROS_DISTRO-vision-msgs \
        ros-$ROS_DISTRO-ackermann-msgs \
        python3-rosinstall \
        python3-rosinstall-generator \
        python3-wstool \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && rosdep init \
    && rosdep update

# uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /home/$USERNAME/

USER $USERNAME
RUN mkdir isaacsim \
    && cd isaacsim \
    && uv venv --python 3.10 \
    && source .venv/bin/activate \
    && uv pip install --upgrade pip \
    && uv pip install torch==2.5.1 torchvision==0.20.1 --index-url https://download.pytorch.org/whl/cu124 \
    && uv pip install 'isaacsim[all,extscache]==4.5.0' --extra-index-url https://pypi.nvidia.com

USER root
RUN source /opt/ros/$ROS_DISTRO/setup.bash --extend \
    && cd ws \
    && git clone https://github.com/isaac-sim/IsaacSim-ros_workspaces.git \
    && cd IsaacSim-ros_workspaces/humble_ws \
    && rosdep update && apt-get update \
    && rosdep install -i --from-path src --rosdistro humble -y \
    && colcon build

# entrypoint
COPY docker/entrypoint.sh ./ws/entrypoint.sh
RUN chmod +x ./ws/entrypoint.sh

USER $USERNAME

ENTRYPOINT ["./ws/entrypoint.sh"]

enrtypoint.shはこんな感じです。
現状はROSのためだけにあります。

entrypoint.sh
#!/bin/bash
set -e

source /opt/ros/$ROS_DISTRO/setup.bash --extend
source /home/$USERNAME/ws/IsaacSim-ros_workspaces/humble_ws/install/setup.bash --extend

exec "$@"

ビルドするときはdockerのディレクトリに移動してビルドします。

$ cd docker/
sudo docker compose build gpu

Dockerコンテナをrunする

実行するときは以下のようなかたちです。

sudo docker compose run --rm -u <usernameを書く> gpu

コンテナ内で以下をするとisaac simが実行できると思います。
実行後、GUIはすぐに立ち上がるのですが、諸々ロードするのに結構時間がかかり、GUI画面から応答待ちのダイアログが表示されるので待ちます。

cd isaacsim
source .venv/bin/activate
isaacsim

ROS2チュートリアルを実行してみる

基本的には公式のTurtlebotのチュートリアルに沿って実行します。

この前提となるROS and ROS 2 Installationについては、既にROS2:humbleと関連パッケージはDockerfile内でもう入っており、恐らくROS2 BridgeはONになっているはずなのでスキップします。
(Cyclone DDSを使う場合は戻ってくる必要があります)

コンテナをrunして、

sudo docker compose run --rm -u <usernameを書く> gpu

まず適当な場所に移動して、turtlebot3のrepositoryをcloneしておきます。

git clone -b humble-devel https://github.com/ROBOTIS-GIT/turtlebot3.git turtlebot3

そしてisaacsimを立ち上げます。

cd isaacsim
source .venv/bin/activate
isaacsim

ここからチュートリアルに沿っていきます。
isaacsimのGUI画面の、下のIsaac Sim AssetsタブからEnvironments->SIMPLE_ROOM->simple_roomを選択してロードします。
滑り台みたいなテーブル?が置いてあるシンプルな部屋がロードされたと思います。

File->Importから、先ほど別ターミナルでcloneしたTurtlebot3をインポートします。
場所は(cloneした場所)/turtlebot3/turtlebot3_description/urdf/turtlebot3_burger.urdfです。
インポートするときに、Linksの部分だけチュートリアルの画像と違うので、Static BaseからMoveable Baseに変更にしておきます。

インポートしたTurtlebot3はテーブル?の上に乗ってしまうので、右サイドバーのturtlebot3_burgerをクリックして表示される矢印をドラッグし、適当に床面の近くに移動させます。
後に使うPlayボタンを押すと勝手に下に落ちるので、ちょっと床から浮かせておくくらいでいいそうです。

右サイドバーのturtlebot3_burger->joints->wheel_left_jointとwheel_right_jointをクリックし、その下に表示される諸々のPropertyの中からDumpingとStiffnessを探します。
そして両方ともDampingを10000000.0、Stiffnessを0.0としておきます。  
isaac_install_right_area.png

そして、次のチュートリアルページを見ながらWindow->Graph Editors->Action Graphからグラフを作ります。今回はコツコツ写経をしました。
その中のMake Arrayはデフォルトは1入力ですが、右のPropertyからArray Sizeを手入力で変えるかプラスボタンを押して2入力とします。

グラフができた後は、各ノードをクリックして右サイドバーに表示されるPropertyに対して、以下を変更します。

  • ROS2 Subscribe Twist Node: topic nameに/cmd_velを入力します
  • Differential Controllerのノードで以下のようにPropertyを変更します
    • Max Angular Speed: 1.0
    • Max Linear Speed: 0.22
    • Wheel Distance: 0.16
    • Wheel Radius: 0.025
  • Articulation Controller: targetPrimでturtlebot3_burger->base_footprintを選択する
    isaac_install_target_prim.png
  • Constant Tokenのそれぞれのノードで以下のようにPropertyを変更します
    • Value: wheel_left_joint
    • Value: wheel_right_joint

上記が終われば、左側にある三角の再生マークのplayボタンをクリックすると動作可能の状態になります。
何らか失敗していると鬼のようなエラーと警告の嵐になるかと思いますので、直しましょう。

別ターミナルを立ち上げて、同じコンテナにexecで入ります。

sudo docker compose exec -u <usernameを書く> gpu bash

entrypoint.shを読み込んでないので中身に相当するものを読み込みます。
(source entrypoint.shでもよいです)

source /opt/ros/$ROS_DISTRO/setup.bash --extend
source /home/$USERNAME/ws/IsaacSim-ros_workspaces/humble_ws/install/setup.bash --extend

別ターミナルから以下を実行すると、壁にぶつかるまでTurtlebot3が直進します。

ros2 topic pub /cmd_vel geometry_msgs/Twist "{'linear': {'x': 0.2, 'y': 0.0, 'z': 0.0}, 'angular': {'x': 0.0, 'y': 0.0, 'z': 0.0}}"

壁にぶつかってもタイヤは動き続けます。
止めるには以下を実行します。

ros2 topic pub /cmd_vel geometry_msgs/Twist "{'linear': {'x': 0.0, 'y': 0.0, 'z': 0.0}, 'angular': {'x': 0.0, 'y': 0.0, 'z': 0.0}}"

Discussion

ログインするとコメントできます