This is how it goes. You create a piece of code, maybe it’s a ROS Node or a ReactJS application and you pass the package over to a friend. It’s simple build the application and start to use it. Not so fast. Something’s wrong, the version of Python you were using has changed, or the Point Cloud Library has been updated. Well, the next few hours will be trying to match up your package to your friend’s system or vice versa. What if there was a way to ensure packages run the same on various different computers? A sort of container that can be passed around? There is! It’s called Docker
Let’s get started!
Assuming you are using Ubuntu. First go ahead and install Docker from Docker Hub
$ sudo apt-get remove docker docker-engine docker.io containerd runc
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb_release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo docker run hello-world
Now you’re all set. Once the hello-world container runs, Docker is installed in your system. Yes, it’s that easy. There are a couple of commands that are useful for Docker. Check out this cheat sheet for more.
Let’s try to set up Docker with ROS. So there a number of easier alternatives such as this ROS image or this SLAM Toolbox image. So yes Docker is pretty flexible, you can get an Ubuntu image, or a ROS image which builds on top of the Ubuntu image or a ROS package image itself which builds on top of both ROS and Ubuntu.
Let’s try to build our own ROS package image in our case. Run the following command to pull a docker image:
$ sudo docker pull ubuntu
Then start the docker container by running:
$ sudo docker run -it ubuntu bash
The -it commands allows commands written in your terminal to be transferred to the Docker container and the output of the Docker container to be written to your terminal. The bash commands prevents the container from starting and dying immediately. You can try to play around with this Docker container but you will find that most things are not set up. Let’s set them up
$ apt-get update
$ apt-get install lsb-release -y
$ apt-get install net-tools -y
$ apt-get install iputils-ping -y
$ apt-get install gnupg -y
$ apt-get install curl -y
$ apt install python-catkin-tools -y
Notice that sudo is not needed anymore because within the Docker container you are running in “root”. Now that all the dependencies are sufficiently installed, we can install ROS and the ROS package. Let’s go with SLAM Toolbox for now.
$ sh -c ‘echo “deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main” > /etc/apt/sources.list.d/ros-latest.list’
$ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | apt-key add —$ apt-get update
$ apt install ros-noetic-desktop-full
$ mkdir -p /catkin_ws/src && cd /catkin_ws
$ catkin build
$ cd src && git clone https://github.com/SteveMacenski/slam_toolbox.git
$ source /opt/ros/noetic/setup.bash
$ rosdep update
$ rosdep install -y -r --from-paths src --ignore-src --rosdistro=noetic -y
$ catkin build
Now you have both ROS and the ROS package successfully installed. Try running roscore to see if everything is installed properly. If all is good proceed to finish up by setting up your environment. Let’s assume your docker is communicating with a ROS MASTER on the same device. For example, if you have a Turtlebot3 with an onboard PC running docker it is possible for the ROS package within docker to communciate with the ROS packages and ROS MASTER running natively on the onboard PC
$ echo “source /opt/ros/noetic/setup.bash” >> ~/.bashrc
$ echo “source /catkin_ws/devel/setup.bash” >> ~/.bashrc
$ echo “export ROS_MASTER_URI=http://172.17.0.1:11311" >> ~/.bashrc
$ echo “export ROS_IP=172.17.0.2” >> ~/.bashrc
$ echo “220.127.116.11 turtlebot” >> /etc/hosts
Take note that the ROS MASTER URI on the host device is always 172.17.0.1. There will be dual IP addresses, in our case the secondary IP address is 18.104.22.168. This can be checked using the command:
The name turtlebot is the name of the PC. This is not the username. In the terminal below for example, the name of the PC is linux-desktop and the username is mark. The name in /etc/hosts should be the name of the PC not the username!
Voila! You’re all set to running your docker container with ROS capability. In order to exit the container type “exit”.
In order to go back into this container do:
$ sudo docker ps -a
This will show you all the closed containers. Restart the name of the previously closed container. So in the image shown below, the name of the previously closed container is “jolly_lewin”.
The commands to restart and attach to the container are:
$ sudo docker restart jolly_lewin
$ sudo docker attach jolly_lewin
There you have it. A quick guide to creating Docker containers with some element of ROS and Ubuntu mixed into them. In the next lesson, we will cover ways to create an entire container as we have done here using a Dockerfile. Stay Tuned!