Using micro-ROS on the Raspberry Pi Pico

 Running micro-ROS on Raspberry Pi Pico

In this post, we'll look at how the Raspberry Pi Pico can communicate with a ROS2 graph natively via micro-ROS. In VSCode, we'll create a project, build it, and upload it to the microcontroller. As a result, we'll presume you're comfortable with ROS2 development using VSCode.

Running micro-ROS on Raspberry Pi Pico

Running ROS2 on RP2040 microcontrollers.

The Raspberry Pi Pico with RP2040 chip is totally open-hardware and created by the Pi's developers. At only $4, it is extraordinarily inexpensive, as is typical of the Pi foundation.

The board's specifications, the distinctions between a microprocessor and a microcontroller, the 101 on how to get started, and what the Pi Pico can accomplish are all outside the scope of this article. But, whether you're familiar with microcontrollers or not, I strongly advise you to have a look for yourself.

micro-ROS

Microcontrollers have long been treated as second-class citizens in the ROS (1) world. They can't communicate with the ROS graph directly, therefore developers must rely on libraries like rosserial. However, ROS2 is a completely new universe, and things are evolving all the time.

> micro-ROS instals ROS 2 on microcontrollers, allowing them to participate in the ROS 2 ecosystem as first-class citizens.

The micro-ROS project is led by huge industry names like Bosch, eProsima, Fiware Foundation, and a slew of partners and collaborators, including Amazon and Canonical, as well as the OFERA H2020 project.

Running micro-ROS on Raspberry Pi Pico
Image Credit: Jeremie Deray

So, what exactly is it? It's simply a thin wrapper (see its design paper) on top of DDS for eXtremely Resource Constrained Environments (DDS-XRCE) that runs on a real-time OS and allows microcontrollers to communicate with a ROS2 graph (the standard talker/listener) using an optimised subset of the DDS protocol. It's a mouthful. It uses a ‘bridged' communication architecture with the ‘micro-ROS Agent‘ as a ‘broker.' The agent is responsible for bridging the gap between the ROS2 graph and one or more micro-ROS devices.

More information, including how it compares/differs from rosserial, may be found on the micro-ROS website (see here and here).

So, now that we've explained a few terminology, let's get started with the official micro-ROS on Raspberry Pi Pico example available on github, step by step. Note that I'm using Ubuntu 20.04 with the VSCode snap for this lesson.

If you haven't yet upgraded to Ubuntu 20.04, you might want to consider utilising an LXD container. To get started setting up the container, refer to our earlier piece ‘ROS Development with LXC.'

Dependencies are being installed.

Let's begin by installing the required prerequisites.

sudo apt install build-essential cmake gcc-arm-none-eabi libnewlib-arm-none-eabi doxygen git python3

Obtaining the Information

We'll now establish a workspace and gather all of the necessary information.
mkdir -p ~/micro_ros_ws/src
cd ~/micro_ros_ws/src
git clone --recurse-submodules https://github.com/raspberrypi/pico-sdk.git
git clone https://github.com/micro-ROS/micro_ros_raspberrypi_pico_sdk.git
The Pi Pico SDK, offered by the Pi Foundation, is the initial repository. The second includes a precompiled micro-ROS stack as well as a hello-world-style example.

Installing VSCode

Let's open the example in VSCode and configure it. You'll need two VSCode additions to follow along, both of which are ubiquitous in C++ programming. For VSCode, these extensions are the C++ extension and the CMake tools. After installing them, we'll create a CMake tools configuration file and specify a variable to tell our project where to look for the Pi Pico SDK.

Use Code:

cd ~/micro_ros_ws/src/micro_ros_raspberrypi_pico_sdk
mkdir .vscode
touch .vscode/settings.json
Use your preferred editor to open the newly produced file.
vi .vscode/settings.json
plus the following,
{
    "cmake.configureEnvironment": {
       "PICO_SDK_PATH": "/home/$USER/micro_ros_ws/src/pico-sdk",
    },
}
This is an environment variable that is only supplied to CMake during the configuration process. For further information, see the CMake-Tools manual.

Let's get started on the project, shall we?
code .
We must choose the suitable ‘kit' before executing the CMake configuration and creating it (maybe VSCode has already asked you to do so). Search for CMake: (ctrl+shift+p) in the palette. Scanning for Kits, followed by CMake: Select a Kit and ensure that the compiler we installed earlier, GCC for arm-non-eabi, is selected.

We're all prepared; now it's time to set an example! Return to the palette and choose CMake: Build.

So, let's take a quick look at what the example does. To orchestrate everything, it creates a node named pico node, then a publisher that publishes a std msgs/msg/int32.h message on the subject pico publisher, a repeating timer, and an executor. The executor rotates every 0.1 second. The timer, however, will only have the publisher post a message and increase the message data by one per second.

Uploading to a Raspberry Pi Pico

You should notice a new build folder in your project view if everything went well during compilation. The file that we need now upload to the Pi Pico is titled pico micro ros example.uf2 and can be found in this folder.

Simply connect the board to a computer via USB connection while pushing the little white button labelled BOOTSEL to upload it. The Pi Pico will then mount as a flash drive, allowing us to copy/paste the.uf2 file with ease. Go to a computer terminal and type,

cp build/pico_micro_ros_example.uf2 /media/$USER/RPI-RP2
After the file has been copied, the board will reboot and begin running the example.

Micro-ros-agent installation

Micro-ROS features a bridged communication architecture, as we saw in the introduction. As a result, we must construct that bridge. Fortunately, the development team has already created it and makes it available as a Snap or a Docker image. We'll utilise the former in this case.

Snap is already pre-installed and ready to use if you're running Ubuntu 16.04 or later. If you're using a different operating system, you may either instal snap or use the Docker image. Type, to instal the micro-ros-agent snap.

sudo snap install micro-ros-agent
We'll need to tweak a few things after installing it because we're utilising a serial connection. We must first enable the hotplug functionality.
sudo snap set core experimental.hotplug=true
and then restart the snap demon for it to take effect
sudo systemctl restart snapd
Execute after ensuring that the Pi Pico is plugged in.
$ snap interface serial-port
name:    serial-port
summary: allows accessing a specific serial port
plugs:
  - micro-ros-agent
slots:
  - snapd:pico (allows accessing a specific serial port)
The micro-ros-agent snap features a serial connector, while a pico slot appears out of nowhere. We should probably link them together based on semantics. To do so, sprint.
snap connect micro-ros-agent:serial-port snapd:pico
We're now ready to put our example into action.

We'll start the micro-ros-agent with the Pi Pico connected via USB as follows:

micro-ros-agent serial --dev /dev/ttyACM0 baudrate=115200
Wait a few seconds for the LED on the Pi Pico to turn on, signalling that the main loop is operating. If it does not light up after a few lengthy seconds (count up to 10 mississippi), you may need to disconnect and reinstall the board. The example's initialization procedure is missing a few error checks... Could one of your first projects be to improve that?

As a result, the LED should now be brilliant green. That's OK. What do you think is cooler? It's installed on your host PC and it's up and running.
$ source /opt/ros/dashing/setup.bash
$ ros2 topic echo /pico_publisher
data: 41
---
data: 42
---
Then hit
$ ros2 node list
/pico_node
demonstrates that the Raspberry Pi Pico's micro-ROS node is visible to ROS2 on the host system. Now Enjoy!

Author Credit: Jeremie Deray