Unverified Commit 3a2909a1 authored by AutonomousHansen's avatar AutonomousHansen Committed by GitHub

Creates a tutorial example on using Docker (#281)

# Description

Adds tutorial for using Orbit Docker image at 00_sim/docker.rst, also
adds the corresponding script.

Fixes #229 (partially)

## Type of change

- New feature (non-breaking change which adds functionality)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent 3f04d18d
...@@ -50,6 +50,7 @@ For more information about the framework, please refer to the `paper <https://ar ...@@ -50,6 +50,7 @@ For more information about the framework, please refer to the `paper <https://ar
source/tutorials/00_sim/empty source/tutorials/00_sim/empty
source/tutorials/00_sim/prims source/tutorials/00_sim/prims
source/tutorials/00_sim/docker
source/tutorials/01_assets/articulation source/tutorials/01_assets/articulation
source/tutorials/01_assets/rigid_object source/tutorials/01_assets/rigid_object
source/tutorials/02_scene/scene source/tutorials/02_scene/scene
......
...@@ -88,10 +88,10 @@ Running the Container ...@@ -88,10 +88,10 @@ Running the Container
.. note:: .. note::
The docker container copies all the files from the repository into the container at the The docker container copies all the files from the repository into the container at the
location ``/workspace/orbit``. This means that any changes made to the files in the container will not location ``/workspace/orbit`` at build time. This means that any changes made to the files in the container would not
be reflected in the repository. normally be reflected in the repository after the image has been built, i.e. after ``./container.sh start`` is run.
To deal with this, we mount the following directories in the Orbit repository into the container For a faster development cycle, we mount the following directories in the Orbit repository into the container
so that you can edit their files from the host machine: so that you can edit their files from the host machine:
* ``source``: This is the directory that contains the Orbit source code. * ``source``: This is the directory that contains the Orbit source code.
...@@ -109,7 +109,7 @@ The script ``container.sh`` wraps around three basic ``docker-compose`` commands ...@@ -109,7 +109,7 @@ The script ``container.sh`` wraps around three basic ``docker-compose`` commands
container instances. container instances.
4. ``stop``: This brings down the container and removes it. 4. ``stop``: This brings down the container and removes it.
Following shows how to launch the container in a detached state and enter it: The following shows how to launch the container in a detached state and enter it:
.. code:: bash .. code:: bash
...@@ -130,7 +130,7 @@ directories to the ``docker/artifacts`` directory. This is useful for copying th ...@@ -130,7 +130,7 @@ directories to the ``docker/artifacts`` directory. This is useful for copying th
.. code:: bash .. code:: bash
# Copy the logs and docs/_build directories to the docker/artifacts directory # Copy the logs, data_storage and docs/_build directories to the docker/artifacts directory
./docker/container.sh copy ./docker/container.sh copy
To stop the container, you can use the following command: To stop the container, you can use the following command:
......
Using Orbit with Docker
=======================
In this tutorial, we will learn how to use the Orbit Docker container for development. For a detailed
description of the Docker setup, including installation and obtaining access to an Isaac Sim
image, please reference the :doc:`Docker Setup page </source/setup/docker>`. For a description
of Docker in general, please refer to `their official documentation <https://docs.docker.com/get-started/overview/>`_.
From the root of the ``orbit`` repository, the ``docker`` directory contains all the Docker relevant files. These include the three files (**Dockerfile**, **docker-compose.yaml**, **.env**)
which are used by Docker, and an additional script that we use to interface with them, **container.sh**. In this tutorial, we will learn
how to use the latter to build an image, run an experiment, and extract the outputs.
Building the Container
~~~~~~~~~~~~~~~~~~~~~~
To build the Orbit container from the root of the Orbit repository, we will run the following:
.. code-block:: console
./docker/container.sh start
The terminal will first pull the base IsaacSim image, build the Orbit image's additional layers on top of it, and run the Orbit container.
This should take several minutes upon the first build but will be shorter in subsequent runs as Docker's caching prevents repeated work.
If we run the command ``docker container ls`` on the terminal, the output will list the containers that are running on the system. If everything has been set up correctly, a container with the ``NAME`` **orbit** should appear, similar to below:
.. code-block:: console
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
483d1d5e2def orbit "bash" 30 seconds ago Up 30 seconds orbit
Now that the container is up and running, we can enter it from our terminal.
.. code-block:: console
./docker/container.sh enter
On entering the Orbit container, we are in the terminal as the superuser, ``root``. This environment contains a copy of the
Orbit repository, but also has access to the directories and libraries of Isaac Sim. We can run experiments from this environment
using a few convenient aliases that have been put into the ``root`` **.bashrc**. For instance, we have made the **orbit.sh** script
usable from anywhere by typing ``orbit``.
Additionally in the container, we have `bind mounted`_ the ``orbit/source`` directory from the
host machine. This means that if we modify files under this directory from an editor on the host machine, the changes are
reflected immediately within the container without requiring us to rebuild the Docker image.
We will now run a sample script from within the container to demonstrate how to extract artifacts
from the Orbit Docker container.
The Code
~~~~~~~~
The tutorial corresponds to the ``docker.py`` script in the ``orbit/source/standalone/tutorials/00_sim`` directory.
.. dropdown:: :fa:`eye,mr-1` Code for ``docker.py``
.. literalinclude:: ../../../../source/standalone/tutorials/00_sim/docker.py
:language: python
:emphasize-lines: 46-55, 72-79
:linenos:
The Code Explained
~~~~~~~~~~~~~~~~~~
The Orbit Docker container has several `volumes`_ to facilitate persistent storage between the host computer and the
container. Once such `volume`_ is the ``/workspace/orbit/logs`` directory.
The ``docker.py`` script designates this directory as the location to which a ``log.txt`` should be written:
.. literalinclude:: ../../../../source/standalone/tutorials/00_sim/docker.py
:language: python
:start-at: # Specify that the logs must be in logs/docker_tutorial
:end-at: print(f"[INFO] Logging experiment to directory: {log_dir_path}")
As the comments note, :func:`os.path.abspath()` will prepend ``/workspace/orbit`` because in
the Docker container all python execution is done through ``/workspace/orbit/orbit.sh``.
The output will be a file, ``log.txt``, with the ``sim_time`` written on a newline at every simulation step:
.. literalinclude:: ../../../../source/standalone/tutorials/00_sim/docker.py
:language: python
:start-at: # Prepare to count sim_time
:end-at: sim_time += sim_dt
Executing the Script
~~~~~~~~~~~~~~~~~~~~
We will execute the script to produce a log, adding a ``--headless`` flag to our execution to prevent a GUI:
.. code-block:: bash
orbit -p source/standalone/tutorials/00_sim/docker.py --headless
Now ``log.txt`` will have been produced at ``/workspace/orbit/logs/docker_tutorial``. If we exit the container
by typing ``exit``, we will return to ``orbit/docker`` in our host terminal environment. We can then enter
the following command to retrieve our logs from the Docker container and put them on our host machine:
.. code-block:: console
./container.sh copy
We will see a terminal readout reporting the artifacts we have retrieved from the container. If we navigate to ``/orbit/docker/artifacts/logs/docker_tutorial``,
we will see a copy of the ``log.txt`` file which was produced by the script above.
Each of the directories under ``artifacts`` corresponds to Docker `volumes`_ mapped to directories
within the container and the ``container.sh copy`` command copies them from those `volumes`_ to these directories.
We could return to the Orbit Docker terminal environment by running ``container.sh enter`` again,
but we have retrieved our logs and wish to go inspect them. We can stop the Orbit Docker container with the following command:
.. code-block:: console
./container.sh stop
This will bring down the Docker Orbit container. The image will persist and remain available for further use, as will
the contents of any `volumes`_. If we wish to free up the disk space taken by the image, (~20.1GB), and do not mind repeating
the build process when we next run ``./container.sh start``, we may enter the following command to delete the **orbit** image:
.. code-block:: console
docker image rm orbit
A subsequent run of `docker image ls` will show that the image tagged **orbit** is now gone. We can repeat the process for the
underlying NVIDIA container if we wish to free up more space. If a more powerful method of freeing resources from Docker is desired,
please consult the documentation for the `docker prune`_ commands.
.. _volumes: https://docs.docker.com/storage/volumes/
.. _volume: https://docs.docker.com/storage/volumes/
.. _bind mounted: https://docs.docker.com/storage/bind-mounts/
.. _docker prune: https://docs.docker.com/config/pruning/
# Copyright (c) 2022-2023, The ORBIT Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
"""
This script demonstrates how to generate outputs in the Orbit Docker such that
they are easily retrievable.
.. code-block:: bash
# Usage
./orbit.sh -p source/standalone/tutorials/00_sim/docker.py
"""
from __future__ import annotations
"""Launch Isaac Sim Simulator first."""
import argparse
import os
from omni.isaac.orbit.app import AppLauncher
# create argparser
parser = argparse.ArgumentParser(description="Tutorial on using Orbit with Docker")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args()
# launch omniverse app
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
"""Rest everything follows."""
import traceback
import carb
from omni.isaac.orbit.sim import SimulationCfg, SimulationContext
def main():
"""Main function."""
# Specify that the logs must be in logs/docker_tutorial
log_dir_path = os.path.join("logs", "docker_tutorial")
# In the container, the absolute path will be
# /workspace/orbit/logs/docker_tutorial, because
# all python execution is done through /workspace/orbit/orbit.sh
# and the calling process' path will be /workspace/orbit
log_dir_path = os.path.abspath(log_dir_path)
if not os.path.isdir(log_dir_path):
os.mkdir(log_dir_path)
print(f"[INFO] Logging experiment to directory: {log_dir_path}")
# Initialize the simulation context
sim_cfg = SimulationCfg(dt=0.01, substeps=1)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# Play the simulator
sim.reset()
# Now we are ready!
print("[INFO]: Setup complete...")
# Prepare to count sim_time
sim_dt = sim.get_physics_dt()
sim_time = 0.0
# Open logging file
with open(os.path.join(log_dir_path, "log.txt"), "w") as log_file:
# Simulate physics
while simulation_app.is_running():
log_file.write(f"{sim_time}" + "\n")
# perform step
sim.step()
sim_time += sim_dt
if __name__ == "__main__":
try:
# run the main execution
main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment