Utilize Docker containers to quickly set up and begin ROS 2 development.
Many native tools in the ROS ecosystem are only supported on Linux, often making robotics development on other operating systems difficult and tedious. To solve this developer friction, many roboticists have turned to container platforms like Docker to help them work cross-platform.
In this tutorial, we'll cover how you can quickly get up and running with ROS 2 on your macOS computer – all with the help of Docker containers.
Docker is a container platform that allows you to run an instance of an operating system on top of a host. It can empower teams to develop robots with unique operating system requirements, regardless of their own system specs, or to work with ROS distributions that are not supported on the host operating system.
A Docker image essentially packages software into standardized units for reproducible development and deployment. It's a lightweight, standalone, executable piece of software that includes everything needed to run an application – all the code, runtime, system tools, system libraries and settings.
Once you've installed Docker on your macOS machine, you can browse Docker Hub for available ROS images. Download (pull) your desired image (in this case, ROS 2 Jazzy) from Docker Hub:
$ docker pull ros:jazzy-ros-core
language-bash
Verify that you've downloaded the correct image:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ros jazzy-ros-core cbe7e6024f69 8 weeks ago 505MB
language-bash
Before we run any commands, we need to customize the image by installing a few more packages. To do so, create a file named Dockerfile
in an empty directory with the following contents:
FROM ros:jazzy-ros-core
RUN apt-get update && apt-get install -y \
ros-jazzy-demo-nodes-cpp \
ros-jazzy-foxglove-bridge \
ros-jazzy-tf2-ros
language-dockerfile
In a new terminal, run the following command to build the image and tag it with the name rosdemo
:
$ docker build -t rosdemo .
language-bash
The -t
option tags the new image with the name rosdemo
. The .
represents the build context, which is the current folder.
You can now start your ROS 2 container:
$ docker run --rm -it rosdemo bash
language-bash
The --rm
flag will remove this container after it exits (to save disk space), and the -it
option will open an interactive terminal.
Inside your docker container, publish a /chatter
topic:
root@396119f9e9ce:/# ros2 run demo_nodes_cpp talker
language-bash
In another terminal, start a new docker container and verify you can see the message being published. This time, instead of running Docker with bash
we're going to run the ros2
command directly:
$ docker run --rm -it rosdemo ros2 topic echo /chatter
language-bash
Your output should look similar to the following. Keep in mind that both containers are fully isolated, and are talking to each other over Docker's internal network.
Next, let's verify our ROS messages by visualizing them in Foxglove.
To be able to connect Foxglove to the container, you must publish the port 8765 on the Docker server with the -p 8765:8765
option when running the new container. Start a third docker container, this time launching the Foxglove ROS Bridge:
docker run --rm -it -p 8765:8765 rosdemo ros2 launch foxglove_bridge foxglove_bridge_launch.xml
language-bash
To make things more interesting, let's also publish a simple transform:
$ docker run --rm -it rosdemo ros2 run tf2_ros static_transform_publisher --x 0 --y 1 --z 1 --roll 0 --pitch 0 --yaw 0 --frame-id base_link --child-frame-id sensor
language-bash
Now, open your Foxglove desktop app, initiate a Foxglove WebSocket connection with the default URL. You can also use the following direct link:
https://app.foxglove.dev/~/view?ds=foxglove-websocket&ds.url=ws%3A%2F%2Flocalhost%3A8765
Add a Raw Messages panel and subscribe to the /chatter
topic to verify that it shows the message "hello":
You've now successfully run ROS 2 in a Docker container, and connected it to Foxglove to visualize that data.
With Docker containers, you can seamlessly continue development across different platforms – regardless of your robotics framework's constraints.
Reach out to us directly in our Discord community to ask questions or request a topic for the next tutorial.