This is the fifth (and final) blog post in this series about ROS production. In the previous post we created a gadget snap to allow confined access to the Turtlebot. In this post, we’re going to put all the pieces from this series together and create an Ubuntu Core image with our ROS snap preinstalled, ready to send to the factory for production.
If you download one of the generic Ubuntu Core images for a reference device and run snap list on it immediately, you’ll see three snaps installed: a core snap, a kernel snap, and a gadget snap.
Every Ubuntu Core image consists of at least these three snaps. In my case, since I’m using an Intel NUC, I see core, pc-kernel and pc-amd64-gadget. You may recognize that last one from part 3, because it’s the gadget we started with when creating our custom one.
We want to create an Ubuntu Core image that uses our custom gadget, and includes our ROS snap so that as soon as the device boots for the first time, the robot starts moving.
Alright, let’s get started! Remember that this is also a video series: feel free to watch the video version of this post:
Step 1: Request interface auto-connection
As soon as the device boots for the first time, we want the Turtlebot to begin moving. In order for this to happen, the ROS snap needs access to the Turtlebot at boot. We added the correct slot to our gadget and plug to our app, but this interface isn’t automatically connected, which means at boot, the ROS snap doesn’t actually have the appropriate permission to access the Turtlebot. This works okay for testing purposes, but to actually have a production image, we need this interface automatically connected. Eventually this will be automated, but currently it’s a manual process. You have to:
Put the ROS snap in the store (which we did in part 3).
Put the gadget snap in the store (which we did in part 4).
Create a new topic in the Snapcraft forum requesting that the kobuki interface (or whatever you called it) be automatically connected between these two snaps. This is done via an assertion on the gadget in the store.
Step 2: Install required tools
Ubuntu Core will verify that the image it’s booting actually came from you. In order for that to happen, you need to create a signing key and register it with the store. You need Snapcraft and Snapd to generate, register, and use the signing key, and you need Ubuntu Image to actually create the image. You already have most of this from following the rest of the series, but for completeness:
$ sudo apt install snapcraft snapd ubuntu-image
Step 3: Create and register your signing key
Now let’s create a signing key:
$ snapcraft create-key my-key-name
Check that everything worked and your key is ready:
Now register your new key with the store to associate it with your account:
$ snapcraft register-key
Registering key ...
Done. The key "my-key-name" (Qjdfp<snip>H4CROy) may be used to sign your assertions.
Step 4: Define the model
In order to create an Ubuntu Core image, we need to create what’s called the “model definition.” The “model” in question is your device. The definition is simply a JSON document that answers the questions “what is this device, who created it, and what software is running on it?” The model definition and assertion I created are available for reference.
Create a file named turtlebot-model.json and make it look something like this:
We specify that this is targeting Ubuntu Core series 16, name the model “turtlebot-demo” (you can use whatever you wish), specify the architecture for this model as well as the kernel snap to use (these would change if your arch wasn’t amd64). Note that we’re using the kernel maintained and supported by Canonical here. The gadget field needs to contain the name of your gadget snap. The authority-id and brand-id need to be the account ID from your store account. The timestamp needs to be the output of
$ date -Iseconds --utc
Finally, the required-snaps is a list of snaps to be preinstalled on this image. In our case, that’s the name of the ROS snap we created in part 3.
Step 5: Create the model assertion
Now that we have a model definition, we need to use our key to sign it, thereby turning it into what’s called a “model assertion”:
$ cat turtlebot-model.json | snap sign -k my-key-name > turtlebot.model
You need a passphrase to unlock the secret key for
4096-bit RSA key, ID 0B79B865, created 2016-01-01
After giving your passphrase, a turtlebot.model file is created containing the assertion.
Step 6: Create the image
The assertion we just created is all we need for ubuntu-image to actually put the image together (note that the image I created is available for download, for both amd64 and the DragonBoard):
This will pull down the various components of the image (gadget, kernel, core, and any additional snaps from required-snaps) from the stable channel, and create an Ubuntu Core image out of them. Well, what if the gadget (or other) snap is your own, and isn’t available in the store yet? The assertion doesn’t change, but you can provide local snaps to satisfy the snap names specified in the assertion with the –extra-snaps parameter. For example, say your gadget snap isn’t available in the store; you could use the local one with:
We already mentioned the downsides to this, but it’s worth mentioning again: installing local snaps like this will prevent those snaps from updating, and will also prevent the serial-port interface from auto-connecting.
Once ubuntu-image completes successfully, you’ll have an Ubuntu Core image ready to flash to your device!
Once the image boots (assuming the Turtlebot is connected and powered on), the Turtlebot will begin moving. Congratulations, you’re done!
Step 7a: Connect interfaces if necessary
If you were unable to follow Step 1, then the Turtlebot probably didn’t begin moving for you once you powered the device on. This is due to the lack of interface auto-connection. To work around that, go through the first boot wizard as discussed on the flashing directions, SSH into the device, and run:
Now you should see the Turtlebot start moving as expected. This is persistent across reboots.
At this point, we’ve taken a ROS prototype running on classic Ubuntu all the way to a production-ready Ubuntu Core image with the ROS prototype preinstalled and running on boot. Every component of this image will automatically update, including your ROS snap. Admittedly there are a few rough edges, but I hope this shows you how powerful snaps and Ubuntu Core can be.
Hopefully you managed to follow along successfully, but if you ran into issues, here’s the reference material for this series:
Turtlebot demo ROS snap
Note that this is published as turtlebot-demo-kyrofa in the store for all supported architectures (stable channel)