About Singularity

We are using Singularity to execute applications on the robots. With the provided image, you can test your code locally with simulation in the exact same environment as will be present on the real robot.

The image we provide contains all dependencies to get started with the robot. If you want to use additional libraries in your own code, you can extend the image accordingly.

Install Singularity

Note that Singularity only runs on Linux. It may work with a virtual machine but it is recommended to use a computer with a native Linux installation (we are testing with Ubuntu but other distributions should also be fine).

We are using Singularity version 3.7.4. To simplify the installation, we provide a pre-built Debian package:



SHA256: 1a2b0a8c6d510518cbc28b82e01fadbaec99175b70c23b7814c45ebc0cad1f13

After downloading you can install it with the following command:

$ sudo apt install ./singularity-container_3.7.4-1.deb

You may also be able to install Singularity from the official package repositories of your Linux distribution, however, the version you get this way may not be up-to-date. Slightly older version are probably fine, but we cannot guarantee compatibility for those.

If none of the above works for you, you can install it from source. For this see the official installation instructions.

Download the Real Robot Challenge Image

You can directly pull the image from the Singularity cloud library:

$ singularity pull library://felix.widmaier/rrc/rrc2021:latest

The image uses Ubuntu 20.04 and has all dependencies of the robot software and the simulation already installed. For most of the libraries we use the default version provided through the official Ubuntu repositories. To explore the image and to check which libraries and which versions exactly are installed, you can open a shell inside the container, see Open a Shell in the Image.

Using the Singularity Image

This is a brief introduction to the basic usage of the Singularity image. For more information, see the official documentation.

Singularity is a tool to run applications in isolated images (also often called “containers”), similar to the more widely known Docker. We use it as it is an easy way to provide you with a well-defined environment that contains the proper versions of all dependencies, independent of what you have installed locally on your system. This ensures that the applications will run in the same way on different machines.


By default, Singularity is not fully isolated. For example the whole home directly is bound into the container at run time. This can impair reproducibility. See Ensure Isolation from the Host System on how to make it more isolated.

Run a Command using the Singularity Image

You can run commands inside the Singularity image. They will have access to everything installed in the image and will be more or less isolated from your host system (see Ensure Isolation from the Host System).

$ singularity run rrc2021.sif python3 path/to/some/script.py

To give a more concrete example, the following runs the simulation with a demo script, moving the robot to random positions (the --nv flag is only needed if you are using Nvidia drivers, otherwise you have to remove it, see Running GUI-Applications in Singularity):

$ singularity run --nv rrc2021.sif ros2 run trifinger_simulation demo_trifinger_platform.py


If the image file is marked as executable, you can also drop singularity run and directly execute the file. However, this way you cannot pass additional arguments like --nv to Singularity.

Open a Shell in the Image

With the command above, you can only run a single command inside the image environment. If you want to run multiple commands in a row, preserving the environment, you open a shell in the container:

$ singularity shell path/to/rrc2021.sif

Once inside the container, run the following commands:

Singularity> source /setup.bash

This is mostly needed set up the ROS environment, so the TriFinger-related software packages are found. Now you can again run commands like the demo script (you may need to pass --nv to singularity shell, see Running GUI-Applications in Singularity):

Singularity> ros2 run trifinger_simulation demo_trifinger_platform.py

Ensure Isolation from the Host System

By default Singularity is not completely isolated from the host system. If run without arguments, it automatically binds the full home directory of the user, the /tmp directory and a few system directories into the image.

While this is usually very convenient, it can cause some trouble. For example, Python may find packages that are installed in your home which may be conflicting with versions installed in the container. Further it can impair reproducability, as your code may unintentionally use some package from your home directory which are not available when executed on a different machine. To avoid these problems, you can run Singularity with the following command, to be more isolated:

$ singularity shell --cleanenv --no-home -B path/to/workspace path/to/rrc2021.sif
  • --cleanenv: Do not export all environment variables from the host into the image. Since the environment variable DISPLAY needs to be set in order to run graphical applications, it is still exported into the image by setting SINGULARITYENV_DISPLAY in the first line.

  • --no-home: Do not bind the full home directory. Other directories like /tmp are still bound. You may use --contain to exclude those as well.

  • -B path/to/workspace: Explicitly bind your workspace, so it is accessible in the container. You can list multiple directories separated by commas.

For more information, please refer to the official documentation of Singularity.

Running GUI-Applications in Singularity

When running applications that use GPU-based rendering (e.g. the pyBullet visualisation) on a computer with Nvidia drivers, you may need to add the –nv flag when running Singularity.

$ singularity run --nv rrc2021.sif <command>


$ singularity shell --nv rrc2021.sif

See the Singularity documentation on GPU Support for more information.

Build and Run Code in Singularity

When developing your code using Singularity, you need to build and run it inside the container.

An easy way to do this is to create a workspace on your computer and then open the image in “shell” mode, binding the workspace into the container so it can be accessed/modifed from there.

Set up the Workspace

The workspace should have the following structure:

└── src
    └── my_package

To get started with example package:

$ mkdir -p workspace/src
$ cd workspace/src
$ git clone https://github.com/rr-learning/rrc_example_package.git

Open a shell using the Singularity image, binding the workspace into it:

$ export SINGULARITYENV_DISPLAY=$DISPLAY  # only needed for graphical applications
$ singularity shell -e --no-home -B path/to/workspace path/to/rrc2021.sif

If you want to run graphical applications (like pyBullet’s visualisation) on a machine using Nvidia drivers, you need to add --nv to the list of arguments, see Running GUI-Applications in Singularity.

Once inside the container, run the following commands to set up the environment and build the workspace:

Singularity> source /setup.bash
Singularity> cd path/to/workspace
Singularity> colcon build
Singularity> source install/local_setup.bash

Now you can execute your code inside the container. For example, to run the simulation demos of the example package:

Singularity> ros2 run rrc_example_package sim_move_up_and_down


Singularity> ros2 run rrc_example_package sim_trajectory_example_with_gym

Some things to keep in mind:

  • You need to run colcon build again, after making modifications in the code.

  • colcon build always needs to be run from the workspace’s root directory (the one containing the src directory).

  • I you add custom scripts and want them to be executable with ros2 run, you need to add them as entry_points in the setup.py (see the existing examples there).

Add Custom Dependencies to the Container

The image we provide already includes everything needed to run the robot and the simulation. However, you may need additional libraries to use them in our own code, which are not yet present. In this case, you can create your own image which is based on our standard image but extends it with your additional dependencies.

Note that you don’t need to add your own code for the challenge to the image as this will be provided separately. So you only need to create a custom image if you want to install dependencies that are not yet available in the default image.

Create the Custom Image

To extend the image, create definition file like the following:

# Use the rrc2021 image as base
Bootstrap: library
From: felix.widmaier/rrc/rrc2021:latest

# alternatively to the above, you can specify the path to a local image:
# Bootstrap: localimage
# From: ./rrc2021.sif

    # Put commands to install additional dependencies here.
    # Make sure everything runs automatically without human input (e.g. add
    # `-y` to automatically say "yes" below).
    apt-get install -y package_name

See the official Documentation for Definition Files for all options in the definition file.

Assuming you called your definition file user_image.def, use the following command to build the image:

$ singularity build --fakeroot user_image.sif path/to/user_image.def


To ensure that your custom image is compatible with our setup for executing the code, always use the official image as base and avoid overwriting existing libraries or applications with different versions.

Upload the Custom Image

To use your custom image on the robot (stages 1 and 2), you will need to upload it and update your configuration. See Configuration.