Home » Blog » Using ROS with Docker in macOS
Using ROS with Docker in macOS
— Created: Xiaoke, 2017/06/05 13:41 CST
— Last modified: Xiaoke, 2017/06/07 21:00 CST
I am a beginner of both Docker and ROS, thus techinques listed in this article may not be the optimal or even correct ones. Contents will be continuously examined and updated.
ROS Installation in macOS
The latest LTS (long time support) version of ROS Kinetic Kame can be installed on macOS by following the official instructions. Despite a long troubleshooting list, unexpected errors about GUI packages (rqt) and Qt still occurred in my compliation of the recommended Desktop Install. The Bare Bones ROS-Comm installation turned out to be pretty smooth, but I was still obssessed with using graphics in ROS. Docker seemed to be a good choice in this circumstance.
Docker Installation in macOS
Docker for mac can be downloaded and installed from the Docker store.
Start ROS in Docker
Public docker images are managed by the so-called Docker Registry, and ROS images could be found in the OSRF respository on Docker Hub. A simple command
docker pull osrf/ros:kinetic-desktop
can easily download or “pull” the image of the Kinetic Desktop ROS. The download may take some time depending on the network speed. Note that the osrf/ros
in the command refers to the name of the repository, and the kinetic-desktop
after the colon is the tag or “branch”. A list of tags in the osrf/ros repository can be found here .
After pulling the osrf/ros:kinetic-desktop image, we can run it by
docker run -it --rm --name roscore osrf/ros:kinetic-desktop
A terminal will appear because of the '-it' option. This command actually creates a “container” called roscore due to the '–name roscore' option. The other option '–rm' tells docker that this container will be removed after it stops. Otherwise, it will be always there until we explicitly delete it by
docker rm roscore
In order to use ROS, we need to execute the roscore
program first to start a master, a parameter server and a logging node. We can achieve this by executing the following code in the above terminal
./ros_entrypoint.sh ip=$(hostname -I) export ROS_IP=$ip roscore
After running roscore, the terminal won't accept any further commands, we could use docker exec
to execute a command (e.g. bash) in the roscore container
docker exec -it roscore bash
The Talker-Listener Tutorial
After starting roscore
, we can test a simple talker-listener example. First, start a listener by
docker run -it --name listener --rm osrf/ros:kinetic-desktop
then within the terminal, execute the following code
./ros_entrypoint.sh ip=$(hostname -I) export ROS_IP=$ip export ROS_MASTER_URI=http://172.17.0.2:11311 echo $ROS_IP echo $ROS_MASTER_URI rosrun rospy_tutorials listener.py
A listener program is waiting for incoming messages, but there won't be anything happening at the moment. Next we start a talker by
docker run -it --name talker --rm osrf/ros:kinetic-desktop
and within the terminal, execute the following code
./ros_entrypoint.sh ip=$(hostname -I) export ROS_IP=$ip export ROS_MASTER_URI=http://172.17.0.2:11311 echo $ROS_IP echo $ROS_MASTER_URI rosrun rospy_tutorials talker.py
Then we can see messages are displayed in both the talker and the listener terminals.
Graphics setup
Download and install XQuartz . Then use the following code to start a ros container.
ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}') echo $ip xhost + $ip docker run -it --rm --name turtlesim -e DISPLAY=$ip:0 -v /tmp/.X11-unix:/tmp/.X11-unix:rw osrf/ros:kinetic-desktop
We can run the turtlesim tutorial in this terminal by
rosrun turtlesim turtlesim_node
then, open another terminal without the display settings and execute
rosrun turtlesim turtle_teleop_key
Network with Non-Docker Nodes
The ROS nodes within docker has their own network defaultly bridged to the host machine. We can make docker containers to share the same IP address with the host machine by a '–net=host' option, as
docker run -it --net=host --rm --name roscore -v /tmp/.X11-unix:/tmp/.X11-unix:rw osrf/ros:kinetic-desktop
However, docker in macOS itself runs inside a virtual machine. The above setting merely shares the same address with the virtual machine rather than the actual host. A temperary workaround is to use port mapping as
docker run -it -p 11311:11311 --name roscore --rm -v /tmp/.X11-unix:/tmp/.X11-unix:rw osrf/ros:kinetic-desktop
Then we can run roscore
in this container, and other nodes within the same local network can connect to this ROS master.