When you want to start using ROS (Robot Operating System) it might be a good practice to install it in an closed environment to prevent conflicts with other packages and add more flexibility to the complex dependency structure. There are multiple ways on how to approach this idea. For example you could create a VM running Ubuntu and use it exclusively for ROS development or you can create a Docker Container for the ROS system. When I was looking for possible solutions I came accross a video from the user celebrateubuntu who showed how to install ROS using LXD. LXD containers are a super convenient way to set up containerized linux machines. In the following lines I want to describe the process on how to install ROS using a LXD container.
I am using an Ubuntu based machine. If you are using a different OS you might need to refer to the LXD docs. First step is to install LXD using snap.
snap install lxd
Next you need to configure the installation. Make sure to run this as root.
sudo lxd init
To interact with LXD you need to have root privileges or be part of the lxd group. You can add yourself to the lxd group for the current terminal session using the command newgrp lxd.
Now that we have all the tools we need, we can start with the setup. In theory you can start an instance right now using the following command. (Yes, now its called lxc instead of lxd)
lxc launch ubuntu:20.04 my_instance
However we need some more configuration to get all the features we want. Creating a profile will help us when we want to setup multiple instances with different ROS versions. A profile acts like blueprint for the instance where we can define some useful setting. Create a profile called ros and edit it using the following command.
lxc profile create ros
lxc profile edit ros
Let’s have a look at the lines we will add to the profile. Under config you will need to add the following parameters. Please don’t just copy paste those settings because you might need to adjust them for your machine.
config:
environment.DISPLAY: :1 ### Defines a variable for the X Windows display
raw.idmap: both 1000 1000 ### Maps your host id to the container host id.
### If your id differs, you need to change the first number to your id.
user.user-data: | ### Define commands that are run on initiation of the container.
### We add the ros1 and ros 2 repositorys to the system.
#cloud-config
runcmd:
- apt-key adv --fetch-keys https://raw.githubusercontent.com/ros/rosdistro/master/ros.key
- apt-add-repository http://packages.ros.org/ros2/ubuntu
- apt-add-repository http://packages.ros.org/ros/ubuntu
Let’s move on to the devices section. Here we can add components to pass through to the container. In our case we will add the display, network and filestorage component.
The X1 device is used for X-Windows. Check if the directory existst on your machine if it has an other name (for example X0) then you need to use X0 instead of X1. In this case you also have to change environment.DISPLAY under config to the corresponding number.
X1:
path: /tmp/.X11-unix/X1
source: /tmp/.X11-unix/X1
type: disk
The eth0 device will bridge your network to the container. Use a command like ifconfig to find your network adapter name and add it under the parent node.
eth0:
name: eth0
nictype: macvlan
parent: wlxb06ebfa49658
type: nic
Last but not least we will connect to our file storage. Just use the default storage pool.
root:
path: /
pool: default
type: disk
Now your profile should look similar to this.
### This is a YAML representation of the profile.
### Any line starting with a '# will be ignored.
###
### A profile consists of a set of configuration items followed by a set of
### devices.
###
### An example would look like:
### name: onenic
### config:
### raw.lxc: lxc.aa_profile=unconfined
### devices:
### eth0:
### nictype: bridged
### parent: lxdbr0
### type: nic
###
### Note that the name is shown but cannot be changed
config:
environment.DISPLAY: :1
raw.idmap: both 1000 1000
user.user-data: |
#cloud-config
runcmd:
- ¨apt-key adv --fetch-keys https://raw.githubusercontent.com/ros/rosdistro/master/ros.key¨
- ¨apt-add-repository http://packages.ros.org/ros2/ubuntu¨
- ¨apt-add-repository http://packages.ros.org/ros/ubuntu¨
description: ROS
devices:
X1:
path: /tmp/.X11-unix/X1
source: /tmp/.X11-unix/X1
type: disk
eth0:
name: eth0
nictype: macvlan
parent: wlxb06ebfa49658
type: nic
gpu:
type: gpu
root:
path: /
pool: default
type: disk
name: ros
used_by:
- /1.0/instances/rosfoxy
Now that we succesfully added a profile for our container we just need to create it using the following command.
#lxc launch -p [profile_name] ubuntu:20.04 [container_name]
lxc launch -p ros ubuntu:20.04 rosfoxy
The container is now created and we can access it with the following command.
lxc exec rosfoxy -- su --login ubuntu
If there are no errors we can go ahead and install ROS.
sudo apt install ros-foxy-desktop
Congratulation. You can now use the container like your usual linux environment without complications when experimenting with different versions. Just create a new container and you are good to go.