How to set up TurtleBot3 in minutes with snaps (2/2)

Welcome to part two of our TurtleBot3 set up, namely the turtlebot3c project. In part one, we rearranged the launch files and configuration files of the TurtleBot3 so that we have four entry points to our robot’s functionalities. One per application in our snap. Now it is time to build the snap so that it can be installed and run on the onboard computer.

Prerequisites

We will be creating a snap in this blog post, and we will assume that you understand the basics of how those work. If you need a refresher, you’ll find the details of creating a snap for your ROS application in this brief tutorial, as well as part 5 of the mini-series of posts entitled ‘Your first robot’. You may also find the documentation for the snapcraft Catkin plugin helpful. Finally, make sure to have read part one as we explain how and why we set up the TurtleBot3 launch files the way they are.

Deploying on the TurtleBot3

The TurtleBot3 onboard computer is a RaspberryPi 3b+, an ARM architecture. This essentially means that one cannot simply build a snap on a beefy desktop (likely x86 architecture) and copy it on the Pi3 as it resolves into an architecture incompatibility. And where would be the fun in doing that, it would be too simple. We will investigate our options hereafter.

Snapping directly on the Raspberry Pi

Snapcraftis a tool for developers to package their programs in the snap format. By default, it uses multipass to isolate the build process. However, multipass is not available for ARM platforms, so we will use LXD instead. And you are one lucky reader because since this work started, snapcraft support for LXD containers on ARM platforms has improved a lot. So much so that building a snap on the Pi3, in a LXD container, boils down to a single command,

snapcraft --use-lxd

Easy, right?
But let us take a step back and detail a little more how we get there.

Setting up the workspace

First, let’s create our ROS workspace on the Pi3. You can either use your own or use the following commands to clone the turtlebot3c project. In a terminal, open an SSH connection to the Pi3 and clone the following packages:

mkdir -p ~/tb3c_ws/src & cd ~/tb3c_ws/src
git clone https://github.com/ROBOTIS-GIT/turtlebot3 --branch melodic-devel
git clone https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git --branch melodic-devel
git clone https://github.com/canonical/turtlebot3c

Setting up snapcraft on the Raspberry Pi

Whether you are using Ubuntu 18.04 or Raspbian, chances are we have to either install or update your snapcraft version. To do so, the following steps should work regardless of the distro in use (note that they should be fairly similar on other Linux distro).

First we will install snapd:

sudo apt update
sudo apt install snapd

Next we’ll install the snapcraft snap:

sudo snap install snapcraft

At the time of writing, the version of snapcraft installed by the above command is not recent enough for our use case since we require some bugfixes that landed in version 4.0. You can verify your current version with snapcraft --version. If it is any lower than 4.0, update it as follows,

sudo snap refresh snapcraft --channel=latest/candidate

The turtlebot3c snap configuration file

Now that the ROS workspace and packaging process are ready, the next step is to write the snapcraft configuration file for the snap. We will skip many of the details of the snapcraft.yaml (see the prerequisites if you need the details), and simply highlight below the different apps and how they map to the reorganisation work we did in part one of this post.

apps:

  core:
    daemon: simple
    command: roslaunch turtlebot3c_bringup turtlebot3c_bringup.launch

  teleop:
    daemon: simple
    command: roslaunch turtlebot3c_teleop turtlebot3c_teleop.launch

  mapping:
   command: rosrun turtlebot3c_2dnav mapping_manager

  navigation:
   command: roslaunch turtlebot3c_2dnav turtlebot3c_navigation.launch

Although this is not a complete configuration file, there are still a few important features to note. First, you may have noticed that two of our apps are actually daemons. It means that both are automatically launched when the robot is turned on; one can start working with it right away! 

It is all about the small details

The second noticeable thing happening here is that the ‘mapping’ app actually starts an unknown ‘mapping_manager’ node. Behind the pompous name actually lies a simple Python script whose main purpose is to launch the mapping and tear it down. But that’s not its only task. Before shutting down mapping, it also automatically saves the map to a predefined directory so that you, the user, don’t have to do it. Furthermore, the navigation app also loads the map from this predefined directory so that you, the user, don’t have to worry about it. Simple things that make the user experience so much better.

But how does that manager work? Well, without getting too deep in the details (although you can read the script), we rely on the roslaunch Python API which allows us to easily launch and stop ROS nodes given a launch file. It is very similar to calling the launch file directly from the terminal. However, when the user hits ctrl+c to stop the mapping, our script also calls the map_saver node to save to map before tearing the mapping down. The map is saved in $SNAP_USER_DATA/.tb3c/maps/<date><time>/ where $SNAP_USER_DATA is the root directory for user data in snaps (find out more about snaps environment variables) and <date><time> is the date and time at which the map is saved. In order for the navigation stack to find the latest map always at the same path, a softlink is create from $SNAP_USER_DATA/.tb3c/maps/<date><time>/ as $SNAP_USER_DATA/.tb3c/maps/config/.

You can find the complete snapcraft configuration file for the turtlebot3c project online. Mind that it sets up the ROS workspace using a rosinstall file. If you wish to use it with the local workspace we have set up earlier, simply delete the line referring to the rosinstall file.

Time to package!

Alright, now that we are fully set up, let’s hit that enter button shall we?

cd ~/tb3c_ws
snapcraft --use-lxd

Snapcraft will pull a LXD container, update it, pull all the necessary ROS dependencies, build your workspace, install it and finalise the snap. This can be long. In the meantime let us discuss how to speed this process up by sending the workload to the cloud.

Snapping remotely

One may ask,

But are there no alternatives to building my snap on the Pi3? It is a nice board but not super powerful…

Fear not for we have options! And we will overview hereafter two of them that allow you to easily build your snap remotely, in the cloud.

Remote build

Remote build is a snapcraft feature which allows anyone to build a snap for multiple architectures on remote servers using Launchpad. To use it, you will need to create an account on Launchpad and set up an SSH key. Furthermore, it is important to note that using this feature will upload your project on Launchpad where it will be publicly available. If this is fine by you, after creating your account, you can send the workload to the cloud as follows,

snapcraft remote-build --launchpad-user <username> --build-on=<Pi3-arch>

where <username> is obviously your username on Launchpad and <Pi3-arch> is the architecture type of the Pi3. Note that it may be different whether you use Ubuntu Server (32 or 64 bit) or Raspbian (32 bit). To find out the architecture simply issue the command,

dpkg --print-architecture

snapcraft.io/build

This second option is probably the most interesting for Open Source project developers. It allows you to hook up your GitHub repository to snapcraft.io/build, and automatically builds your snap on commit pushes and publishes it to the snapstore. It couldn’t be easier! Find a quick start guide here.

After iterating the snap a couple times on the Pi3, we used this solution to speed up the process and automatically build the snap for all plausible architectures!

Installing the snap

Ding, ding, ding. The snap packaging process just finished and our snap is ready for installation. Let us finish the Turtlebot3 set up.

If you built locally or using the remote-build option, you’ll use the following command:

sudo snap install --dangerous turtlebot3c.1_<Pi3-arch>.snap

Note the --dangerous flag. When a snap comes from a trusted place (e.g. the store) it comes along with signatures that prove that it is what it claims to be and that it’s created by who it claims created it. However, in our case, since we’re installing the snap from disk instead of from the store, we don’t have any of those signatures and need to use --dangerous to say that, for this situation, it’s okay. Generally this is not something you should need to do outside of developing a snap.

If, however, you have used snapcraft.io/build, use the following command,

sudo snap install --edge <your snap name>

Using the turtlebot3c

The TurtleBot3 is set up, let the fun begin! Upon installation, the snap should start its daemons automatically, both the core and the teleop apps. Therefore we should be able to visualise the turtlebot3c in Rviz. In a terminal on your desktop, set the ROS master IP to point to the robot and open Rviz,

export ROS_MASTER_URI=http://<TURTLEBOT3-IP>:11311
rosrun rviz rviz

In Rviz, try adding for instance the TF visualisation or the laser scan one.

Next let us try to drive the robot. In a new terminal, export again the ROS master IP and open a keyboard-based teleoperation node, namely the key_teleop. But remember, as we have seen in part one, we also have to tell the mux node that we want it to forward the control command from the key_teleop node:

export ROS_MASTER_URI=http://<TURTLEBOT3-IP>:11311
rosservice call /mux/select "topic: 'key_vel'"
rosrun key_teleop key_teleop

Isn’t it easy? Driving the robot around using the keyboard’s arrow keys?!

mapping

Let’s get to the really interesting bit, autonomous navigation. And we will start by building a map. To do so, keep the teleoperation terminal open on your desktop and open a new terminal on the Pi3 and enter,

turtlebot3c.mapping

This command starts the whole mapping stack. All we have to do is to drive the robot around, trying to cover as well as possible the entire environment. Once done, simply terminate the mapping with ctrl+c. As mentioned before, the map is automatically saved on the robot.

navigation

With our environment mapped, it is time to let go. That is, to let our turtlebot3c go all by itself around the place. First, we have to tell the mux node that we want it to forward commands from the navigation stack:

rosservice call /mux/select "topic: 'nav_vel'"

Again we will keep the visualisation open on our desktop and enter the following command on the Pi3,

turtlebot3c.navigation

From the Rviz window, set the robot initial position. It is now ready for its first autonomous walk. Well, autonomous drive. Set a goal through Rviz and watch it move around! If you aren’t sure how to do that, heads over to the Navigation tutorials on the ROS wiki for a quick overview.

The TurtleBot3 navigating autonomously

Wrap up

In this series, we discussed the thought process and the different technologies involved in making a snap for a whole robotic system. While we didn’t dive too deeply into the details of each and every step, I hope I have provided you with enough insights, information and links to get you started packaging your own robot. As for me, the main objective of this work is complete: cutting hours of installation process to barely minutes, replacing tonnes of terminal commands by a consistent and secure way to repeatedly set up my TurtleBot3.

The snap is already available in the snapstore in case you want to try it right now. To install it, open a SSH connection in a terminal to the Pi3 and type,

sudo snap install turtlebot3c

This project is, again, completely open source. Please feel free to log an issue if you have any questions, or see any improvements that can be made. Have fun!



Talk to us today

Interested in running Ubuntu in your organisation?

Newsletter signup

Select topics you’re
interested in

In submitting this form, I confirm that I have read and agree to Canonical’s Privacy Notice and Privacy Policy.

Are you building a robot on top of Ubuntu and looking for a partner? Talk to us!

Contact Us

Related posts

Exploring ROS 2 Kubernetes configurations

Kubernetes and robotics make a great match. However, as we have seen, robots running ROS 2 can be tricky to set up on Kubernetes. This blog series has...

Distribute ROS 2 across machines with MicroK8s

Introduction Our simple ROS 2 talker and listener setup runs well on a single Kubernetes node, now let’s distribute it out across multiple computers. This...

Popular snaps per distro (2020 edition)

Back in mid-2019, we wrote a blog post detailing and comparing the most popular snaps across multiple distributions – Arch Linux, CentOS, Debian, Fedora,...