アプリケーションコンテナの構築 - AWS RoboMaker

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

アプリケーションコンテナの構築

AWS RoboMaker でシミュレーションジョブを送信するには、アプリケーションコンテナの構築、コンテナの AWS RoboMaker アプリケーションへのリンク、コンテナを使用したシミュレーションジョブの送信、という 3 つのステップがあります。このセクションでは、Docker for AWS RoboMaker を使用してアプリケーションコンテナを構築する方法について説明します。hello-world のサンプルアプリケーションを使用して、ROS ベースのサンプルロボットとシミュレーションアプリケーションコンテナの構築に必要な手順を紹介します。このページでは、コンテナをローカルでテストする方法についても説明します。

ROS を使用していない場合は、AWS RoboMaker での GPU とコンテナサポートを使用した高忠実度シミュレーションの実行方法を説明したブログ記事をご覧ください。

前提条件

始める前に、開発環境に必要な依存関係があることを確認してください。Docker、AWS CLI、VCS インポートツールがマシンにインストールされている必要があります。

sudo pip3 install vcstool

以下の権限を含む IAM ロールの AWS アカウントも必要です。

  • IAM ロールの作成

  • AWS RoboMaker リソース(シミュレーションジョブ、ロボット、シミュレーションアプリケーション)の作成

  • Amazon ECR リポジトリの作成とアップロード

最後に、アカウント番号を控え、シミュレーションを実行するリージョンを選択します。AWS RoboMaker は、AWS RoboMaker エンドポイントとクォータ に記載されているリージョンでサポートされています。

ROS ワークスペースからのアプリケーションコンテナの構築

AWS RoboMaker シミュレーションは、シミュレーションアプリケーションとオプションのロボットアプリケーションで構成されます。これらのアプリケーションはそれぞれ名前とコンテナイメージで定義されます。このセクションでは、シミュレーションアプリケーションとロボットアプリケーションの両方のコンテナイメージを構築する方法を紹介します。次の例では、両方のアプリケーションが 1 つのワークスペース内で構築されています。以下のアプローチは、どの ROS プロジェクトにも簡単に一般化できます。

まず、hello world リポジトリをクローンしてソースをインポートします。

git clone https://github.com/aws-robotics/aws-robomaker-sample-application-helloworld.git helloworld cd helloworld vcs import robot_ws < robot_ws/.rosinstall vcs import simulation_ws < simulation_ws/.rosinstall

次に、helloworld ディレクトリで Dockerfile という名前の新しいファイルを作成します。以下の内容をコピーして貼り付けます。

# ======== ROS/Colcon Dockerfile ======== # This sample Dockerfile will build a Docker image for AWS RoboMaker # in any ROS workspace where all of the dependencies are managed by rosdep. # # Adapt the file below to include your additional dependencies/configuration # outside of rosdep. # ======================================= # ==== Arguments ==== # Override the below arguments to match your application configuration. # =================== # ROS Distribution (ex: melodic, foxy, etc.) ARG ROS_DISTRO=melodic # Application Name (ex: helloworld) ARG APP_NAME=robomaker_app # Path to workspace directory on the host (ex: ./robot_ws) ARG LOCAL_WS_DIR=workspace # User to create and use (default: robomaker) ARG USERNAME=robomaker # The gazebo version to use if applicable (ex: gazebo-9, gazebo-11) ARG GAZEBO_VERSION=gazebo-9 # Where to store the built application in the runtime image. ARG IMAGE_WS_DIR=/home/$USERNAME/workspace # ======== ROS Build Stages ======== # ${ROS_DISTRO}-ros-base # -> ros-robomaker-base # -> ros-robomaker-application-base # -> ros-robomaker-build-stage # -> ros-robomaker-app-runtime-image # ================================== # ==== ROS Base Image ============ # If running in production, you may choose to build the ROS base image # from the source instruction-set to prevent impact from upstream changes. # ARG UBUNTU_DISTRO=focal # FROM public.ecr.aws/lts/ubuntu:${UBUNTU_DISTRO} as ros-base # Instruction for each ROS release maintained by OSRF can be found here: # https://github.com/osrf/docker_images # ================================== # ==== Build Stage with AWS RoboMaker Dependencies ==== # This stage creates the robomaker user and installs dependencies required # to run applications in RoboMaker. # ================================== FROM public.ecr.aws/docker/library/ros:${ROS_DISTRO}-ros-base AS ros-robomaker-base ARG USERNAME ARG IMAGE_WS_DIR RUN apt-get clean RUN apt-get update && apt-get install -y \ lsb \ unzip \ wget \ curl \ xterm \ python3-colcon-common-extensions \ devilspie \ xfce4-terminal RUN groupadd $USERNAME && \ useradd -ms /bin/bash -g $USERNAME $USERNAME && \ sh -c 'echo "$USERNAME ALL=(root) NOPASSWD:ALL" >> /etc/sudoers' USER $USERNAME WORKDIR /home/$USERNAME RUN mkdir -p $IMAGE_WS_DIR # ==== ROS Application Base ==== # This section installs exec dependencies for your ROS application. # Note: Make sure you have defined 'exec' and 'build' dependencies correctly # in your package.xml files. # ======================================== FROM ros-robomaker-base as ros-robomaker-application-base ARG LOCAL_WS_DIR ARG IMAGE_WS_DIR ARG ROS_DISTRO ARG USERNAME WORKDIR $IMAGE_WS_DIR COPY --chown=$USERNAME:$USERNAME $LOCAL_WS_DIR/src $IMAGE_WS_DIR/src RUN sudo apt update && \ rosdep update && \ rosdep fix-permissions # Note: This will install all dependencies. # You could further optimize this by only defining the exec dependencies. # Then, install the build dependencies in the build image. RUN rosdep install --from-paths src --ignore-src -r -y # ==== ROS Workspace Build Stage ==== # In this stage, we will install copy source files, install build dependencies # and run a build. # =================================== FROM ros-robomaker-application-base AS ros-robomaker-build-stage LABEL build_step="${APP_NAME}Workspace_Build" ARG APP_NAME ARG LOCAL_WS_DIR ARG IMAGE_WS_DIR RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ colcon build \ --install-base $IMAGE_WS_DIR/$APP_NAME # ==== ROS Robot Runtime Image ==== # In the final stage, we will copy the staged install directory to the runtime # image. # ================================= FROM ros-robomaker-application-base AS ros-robomaker-app-runtime-image ARG APP_NAME ARG USERNAME ARG GAZEBO_VERSION ENV USERNAME=$USERNAME ENV APP_NAME=$APP_NAME ENV GAZEBO_VERSION=$GAZEBO_VERSION RUN rm -rf $IMAGE_WS_DIR/src COPY --from=ros-robomaker-build-stage $IMAGE_WS_DIR/$APP_NAME $IMAGE_WS_DIR/$APP_NAME # Add the application source file to the entrypoint. WORKDIR / COPY entrypoint.sh /entrypoint.sh RUN sudo chmod +x /entrypoint.sh && \ sudo chown -R $USERNAME /entrypoint.sh && \ sudo chown -R $USERNAME $IMAGE_WS_DIR/$APP_NAME ENTRYPOINT ["/entrypoint.sh"]

先ほど作成した Dockerfile は、Docker イメージを構築するために使用される命令セットです。Dockerfile のコメントを読んで何が構築されるのかを理解し、必要に応じて変更してください。開発を容易にするため、DockerfileOpen Source Robotics Foundation (OSRF) が管理する ROS の公式 Docker イメージに基づいています。ただし、本番環境で実行する場合は、アップストリームの変更による影響を防ぐために、GitHub の OSRF ソース命令セットを使用して ROS のベースイメージをビルドすることもできます。

次に、entrypoint.sh という名前の新しいファイルを作成します。

#!/bin/bash set -e source "/home/$USERNAME/workspace/$APP_NAME/setup.bash" if [[ -f "/usr/share/$GAZEBO_VERSION/setup.sh" ]] then source /usr/share/$GAZEBO_VERSION/setup.sh fi printenv exec "${@:1}"

ENTRYPOINT ファイルは Docker コンテナの生成時に実行される実行ファイルです。ROS ワークスペースのソースにエントリポイントを使用しているため、AWS RoboMaker で簡単に roslaunch のコマンドを実行できます。この ENTRYPOINT ファイルに、独自の環境設定ステップを追加することもできます。

Dockerfile では、マルチステージビルドと Docker BuildKit との統合キャッシュを使用します。マルチステージビルドでは個別のビルドステップによるワークフローが可能なため、ビルドの依存関係やソースコードはランタイムイメージにコピーされません。このため Docker イメージのサイズが小さくなり、パフォーマンスが向上します。キャッシュ操作は、以前にビルドされたファイルを保存することで、その後のビルドを加速します。

次のコマンドを使用してロボットアプリケーションをビルドします。

DOCKER_BUILDKIT=1 docker build . \ --build-arg ROS_DISTRO=melodic \ --build-arg LOCAL_WS_DIR=./robot_ws \ --build-arg APP_NAME=helloworld-robot-app \ -t robomaker-helloworld-robot-app

ロボットアプリケーションをビルドしたら、次のようにシミュレーションアプリケーションをビルドできます。

DOCKER_BUILDKIT=1 docker build . \ --build-arg GAZEBO_VERSION=gazebo-9 \ --build-arg ROS_DISTRO=melodic \ --build-arg LOCAL_WS_DIR=./simulation_ws \ --build-arg APP_NAME=helloworld-sim-app \ -t robomaker-helloworld-sim-app

docker images コマンドを実行して Docker イメージが正常にビルドされたことを確認します。出力は次のようになります。

Administrator:~/environment/helloworld (ros1) $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE robomaker-helloworld-sim-app latest 5cb08816b6b3 6 minutes ago 2.8GB robomaker-helloworld-robot-app latest b5f6f755feec 10 minutes ago 2.79GB

これで、Docker イメージが正常にビルドされました。これらをアップロードしてで使用する前に、AWS RoboMaker を使ってローカルでテストすることをおすすめします。次のセクションは、これを行う方法を示しています。

コンテナのテスト

次のコマンドを使用すると、ローカル開発環境でアプリケーションを実行できます。

ロボットアプリケーションを起動します。

docker run -it -v /tmp/.X11-unix/:/tmp/.X11-unix/ \ -u robomaker -e ROBOMAKER_GAZEBO_MASTER_URI=http://localhost:5555 \ -e ROBOMAKER_ROS_MASTER_URI=http://localhost:11311 \ robomaker-helloworld-robot-app:latest roslaunch hello_world_robot rotate.launch

シミュレーションアプリケーションを起動します。

docker run -it -v /tmp/.X11-unix/:/tmp/.X11-unix/ \ -u robomaker -e ROBOMAKER_GAZEBO_MASTER_URI=http://localhost:5555 \ -e ROBOMAKER_ROS_MASTER_URI=http://localhost:11311 \ robomaker-helloworld-sim-app:latest roslaunch hello_world_simulation empty_world.launch

コンテナが正常に機能していることを確認したら、アプリケーションコンテナを Amazon ECR に公開して、シミュレーションジョブを送信することができます。