============= Isaac ROS Dev ============= Isaac ROS Dev is a container-based workflow to enable production robotics by building your ROS workspace in a consistent, reproducible environment and then being able to deploy the resulting build products as a single, hermetic artifact to run on robot. Development Environment ======================= The Isaac ROS development environment is run within a Docker container on the target platform using the script :ir_repo:`run_dev.sh `. After you've setup your ROS workspace on your machine with your packages, third party packages, and one or many Isaac ROS packages, you can use this script to launch a Docker container that contains all the system libraries and dependencies to build. ``run_dev.sh`` sets up a development environment containing ROS 2 and key versions of NVIDIA frameworks prepared for both x86_64 and Jetson. This script prepares a Docker image with a supported configuration for the host machine and delivers you into a bash prompt running inside the container. From here, you are ready to execute ROS 2 build/run commands with your host workspace files, which are mounted into the container and available to edit both on the host and in the container. Note: If you run this script again while it is running, it will attach a new shell to the same running container. .. code:: bash $PATH_TO_ISAAC_ROS_COMMON/scripts/run_dev.sh -d $PATH_TO_ROS_WORKSPACE For a complete description of arguments for ``run_dev.sh``, see :ref:`here `. Image keys ---------- ``run_dev.sh`` prepares a base Docker image and mounts your target workspace into the running container. The base Docker image itself is assembled by the :ir_repo:`build_image_layers.sh ` script which parses a period-delimited string called an image key. The image key specifies an order of matching Dockerfiles to be built as layers in sequence and fed into the next. ``build_image_layers.sh`` matches corresponding Dockerfiles to the image key. For example, an image key of ``first.second.third`` could match {``Dockerfile.first``, ``Dockerfile.second``, ``Dockerfile.third``}, where ``run_dev.sh`` will build the image for ``Dockerfile.first``, then use that image as the base image while building ``Dockerfile.second``, and so on. The file matching looks for the largest subsequence, so ``first.second.third`` could also match {``Dockerfile.first.second``, ``Dockerfile.third``} depending on which files exist in the search paths. .. _configuring-run-dev: Configuring ``run_dev.sh`` -------------------------- Using this pattern, you can add your own layers on top of the base images provided in Isaac ROS to set up your environment your way, such as installing additional packages to use. If you write a file with the name ``.isaac_ros_common-config`` in your home directory, you can configure the development environment. The following keys configured in ``.isaac_ros_common-config`` can let you specify your own image key and paths to your own Dockerfiles for ``run_dev.sh`` to use. An example ``.isaac_ros_common-config`` file: .. code:: bash CONFIG_IMAGE_KEY=ros2_humble.mine CONFIG_DOCKER_SEARCH_DIRS=(../ros_ws/src/isaac_ros_common/docker ../lib/src/gxf/docker) CONFIG_CONTAINER_NAME_SUFFIX=mysuffix BASE_DOCKER_REGISTRY_NAMES=("nvcr.io/isaac/ros" "some.other/image/name") For example, if you had the following directory structure: .. code:: console ~/.isaac_ros_common-config workspaces/isaac_ros-dev workspaces/isaac_ros-dev/ros_ws workspaces/isaac_ros-dev/ros_ws/mystuff workspaces/isaac_ros-dev/ros_ws/mystuff/Dockerfile.mine workspaces/isaac_ros-dev/ros_ws/mystuff/myfile.txt where ``Dockerfile.mine`` is your own custom image layer, using its host directory for the Docker build context: .. code:: dockerfile ARG BASE_IMAGE FROM ${BASE_IMAGE} ... steps ... COPY myfile.txt /myfile.txt ... more steps ... You could then extend the base image launched as a container by ``run_dev.sh`` as follows. ``~/.isaac_ros_common-config`` .. code:: vim CONFIG_IMAGE_KEY="ros2_humble.mine" CONFIG_DOCKER_SEARCH_DIRS=(workspaces/isaac_ros-dev/ros_ws/mystuff) This configures the image key to match with ``mine`` included and specifies where to look first for Dockerfiles (``workspaces/isaac_ros-dev/ros_ws/mystuff)``) before checking the default location. Prebuilt images --------------- As part of the build image preparation when invoking ``run_dev.sh``, Dockerfiles will be matched to the target image key. After the Dockerfiles have been determined, ``build_image_layers.sh`` will then check the remote Docker registry for an image that matches the hash of the matched Dockerfiles. If one exists, it will pull it down and use that image rather than try to build the image locally. If you do change the contents of any Dockerfiles, you may change the hash and cause ``build_image_layers.sh`` to build the Docker images locally again. NVIDIA provides prebuilt Docker images for standard image key ``aarch64.ros2_humble`` and ``x86_64.ros2_humble` on NVCR (NVIDIA Container Registry) for your convenience. If your local copies of ``Dockerfile.x86_64``, ``Dockerfile.aarch64``, and ``Dockerfile.ros2_humble`` match the hashed contents of these prebuilt images, ``run_dev.sh`` will find and download them to build on rather than start from scratch. For a complete description of arguments for ``build_image_layers.sh``, see :ref:`here `. The following keys configured in ``.isaac_ros_common-config`` let you determine which remote registries will be checked. An example ``.isaac_ros_common-config`` file: .. code:: bash CONFIG_IMAGE_KEY=ros2_humble.mine CONFIG_DOCKER_SEARCH_DIRS=(../ros_ws/src/isaac_ros_common/docker ../lib/src/gxf/docker) CONFIG_CONTAINER_NAME_SUFFIX=mysuffix BASE_DOCKER_REGISTRY_NAMES=("nvcr.io/isaac/ros" "some.other/image/name") Offline dev environment ----------------------- If you have already built your base image before and you want ``run_dev.sh`` to not try to rebuild the base image and perform any operations that could require internet connectivity, you can use the ``-b/--skip_image_build`` argument to run offline. Deployment ========== After you've built your ROS workspace, you will have one of two products: A) Debians built from `bloom-generate `__ or B) ROS workspace ``install/`` directory. The ``docker_deploy.sh`` script let's you package these build products into a runnable Docker image to deploy to your robot. Using ``docker_deploy.sh`` -------------------------- Once you have your built ROS workspace and/or set of Debians to install, the ``docker_deploy.sh`` script packages the ROS workspace directory, other directories, tarballs, and/or Debians to install onto a base image. You can also configure a launch file to run by default each time the container is started. The base image can be specified as an image key for your own custom production environment that will be built with ``build_image_layers.sh``. There are more options for you to customize how the final build image will be assembled with your build products. For a complete description of arguments for ``docker_deploy.sh``, see :ref:`here `. .. code:: console $PATH_TO_ISAAC_ROS_COMMON/scripts/docker_deploy.sh \ --base_image_key "aarch64.ros2_humble" \ --custom_apt_source "deb https://mycool-apt-get-server.com/ros-debian-local focal main" \ --install_debians "mydebian01,libnvvpi3,tensorrt" \ --include_dir /workspaces/isaac_ros-dev/tests \ --include_dir /home/admin/scripts:/home/admin/scripts \ --ros_ws /workspaces/isaac_ros-dev/ros_ws \ --launch_package "isaac_ros_image_proc" \ --launch_file "isaac_ros_image_flip.launch.py" \ --name "my_docker_registry.io/myimage" In this example, a Docker image named ``my_docker_registry.io/myimage`` will be built by configuring one custom ``apt`` sources, installing three Debians packages, and packaging two host directories and a ROS workspace at ``/workspaces/isaac_ros-dev/ros_ws`` on top of a base image built using the key ``aarch64.ros2_humble``. Finally, a launch file and its package were configured to run by default when the container is launched. You can then push this image to your remote Docker registry ``my_docker.registry.io`` and run the image as follows. .. code:: console docker run --rm -it --gpus all my_docker_registry.io/myimage This will launch the container and run ``isaac_ros_image_flip.launch.py`` by default.