Docker and ROS2 on NVIDIA Jetson Nano - HU-ICT-LAB/RobotWars GitHub Wiki

This page contains info on how to use Docker to run ROS2 images on an NVIDIA Jetson Nano. You should first initialize a Jetson Nano following the tutorial on the wiki page "Get started on using the NVIDIA Jetson Nano single board computer".

Sections

Docker framework

What is Docker?

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host.

These containers are not simple virtual environments simulating a whole operating system. Instead, containers run on your host machine and simulate the infrastructure of an operating system within the boundaries of a container. Therefore any files on the host machine can easily be accessed from a container.

Containers and Images

The terms Docker-container and Docker-image might be confusing when unfamiliar with the subject. I found that this article provided a good starting place. But to summarize, images can exist without containers, whereas a container needs to run an image to exist. Therefore, containers are dependent on images and use them to construct a run-time environment and run an application.

ROS2 image on Jetson Nano

Jetson containers

The containers we used to run ROS2 programs on a jetson were made by Dusty-nv and can be found in his repository.

He provides many containers, but you will want to use the latest version. At the time of writing, this is ros:foxy-ros-base-l4t-r32.6.1

The repository provides a script to run the image, but this won't work for the use-case of this project, as neither the robomaster library as well as the external files can be reached. Therefore a new Dockerfile and shell script should be created.

Dockerfile

A Dockerfile contains the building blocks to assemble a docker image. It will be used to extend the ROS2 Docker-images created by *Dust-nv with the robomaster python library.

  • Open a terminal in the desired directory and create a file named "Dockerfile".
  • Add the following line to create a layer from the 'dustynv/ros:foxy-ros-base-l4t-r32.6.1' image
# Create a layer from the 'dustynv/ros:foxy-ros-base-l4t-r32.6.1' image
FROM dustynv/ros:foxy-ros-base-l4t-r32.6.1

# Update the package information from al configured sources
RUN apt-get -y update

# Install python
RUN apt-get install -y python3

#Upgrade pip3
RUN sudo pip3 install --upgrade pip

# install the robomaster python-libary
RUN python3 -m pip install robomaster

Running the Docker image using a shellscript

  • Open a terminal in the same directory as the previously created Dockerfile and run the following command to build an image named "jetson/ros2_robomaster"
sudo docker build -t jetson/ros2_robomaster .
  • Create a .sh shellscript and add the following lines. When executed, the script will run the ROS2 image with the provided directory.
#!/usr/bin/env bash

#Store the name of the docker image to run
CONTAINER_IMAGE = "jetson/ros2_robomaster"
WS_DIRECTORY = "INSERT WORKSPACE DIRECTORY"

# Give docker root user X11 permissions
sudo xhost +si:localuser:root

# enable SSH X11 forwarding inside container (https://stackoverflow.com/q/48235040)
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
chmod 777 $XAUTH

# run the container (make sure to specify the WS_DIRECTORY with the absolute path of the directory on your machine you want to be able to access from the _/mnt_ folder inside the docker bash environment)
# The command below also passes the /dev/input/ directory containing the controller we used. Change this to the directory of your controller
# if it doesnt show up within the run image. Furthermore, the /dev/bus/usb/ passing is required in order to communicate 
# with the S1-robomaster when connected with USB. 
sudo docker run -i -t --privileged --runtime nvidia --rm --network host -e DISPLAY=$DISPLAY \
    -v /dev/bus/usb:/dev/bus/usb \
    -v /dev/input/:/dev/input/ \
    -v /tmp/.X11-unix/:/tmp/.X11-unix \
    -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH \
    -v $WS_DIRECTORY:/mnt \
    $CONTAINER_IMAGE

Running ROS2 and packages within the image

This section assumes you've created a package (or are using previously created packages) with internal nodes and configured the packages by altering their 'package.xml' and 'setup.py' files. If not, we strongly advise to follow these tutorials on the official ROS2 docs:

Bugs and Fixes

Docker newest upgrade issue

Description: We were halted by this problem after first initializing the jetson, which was unable to create new containers/images due to the error message:

docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: error adding seccomp filter rule for syscall

clone3: permission denied: unknown.

Fix: After a lot of searching we stumbled upon the following comment on this github issue. The fix is to downgrade Docker to a previous version.

No USB devices detected within Docker image

Description: You might come upon the problem that no USB devices can be accessed while testing packages and nodes within the Docker image using a controller/keyboard might. This is due to the fact that the Docker container is it's own little universe.

Fix: The fix is to add the USB addressed to the "docker run" command with the '--device' tag (The docker run command is called within the previously created .sh shellscript). Info can be found in the following thread

Sources

D. (2021). GitHub - dusty-nv/jetson-containers: Machine Learning Containers for NVIDIA Jetson and JetPack-L4T. GitHub. Retrieved 26 January 2022, from https://github.com/dusty-nv/jetson-containers

Docker - a way to give access to a host USB or serial device? (2014, June 15). Stack Overflow. Retrieved 26 January 2022, from https://stackoverflow.com/questions/24225647/docker-a-way-to-give-access-to-a-host-usb-or-serial-device

ROS 2 Documentation — ROS 2 Documentation: Foxy documentation. (2022). Docs.Ros.Org. Retrieved 26 January 2022, from https://docs.ros.org/en/foxy/index.htmlSimic,

S. (2021, September 13). Docker Image vs Container: The Major Differences. Knowledge Base by phoenixNAP. Retrieved 26 January 2022, from https://phoenixnap.com/kb/docker-image-vs-container#ftoc-heading-1

Related issues

Issues: #76, #124