Zephyr Emulator
In this tutorial, you’ll learn the use of micro-ROS with a Zephyr RTOS emulator (also known as Native POSIX) by testing a Ping Pong application.
Installing ROS 2 and the micro-ROS build system
First of all, install ROS 2 Humble Hawksbill on your Ubuntu 22.04 LTS computer. To do so from binaries, via Debian packages, follow the instructions detailed here.
TIP: Alternatively, you can use a docker container with a fresh ROS 2 Humble installation. The one that serves the purpose is the container run by the command:
docker run -it --net=host -v /dev:/dev --privileged ros:humble
Once you have a ROS 2 installation in the computer, follow these steps to install the micro-ROS build system:
# Source the ROS 2 installation
source /opt/ros/$ROS_DISTRO/setup.bash
# Create a workspace and download the micro-ROS tools
mkdir microros_ws
cd microros_ws
git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup
# Update dependencies using rosdep
sudo apt update && rosdep update
rosdep install --from-paths src --ignore-src -y
# Install pip
sudo apt-get install python3-pip
# Build micro-ROS tools and source them
colcon build
source install/local_setup.bash
These instructions will setup a workspace with a ready-to-use micro-ROS build system. This build system is in charge of downloading the required cross-compilation tools and building the apps for the required platforms.
The build system’s workflow is a four-step procedure:
- Create step: This step is in charge of downloading all the required code repositories and cross-compilation toolchains for the specific hardware platform. Among these repositories, it will also download a collection of ready to use micro-ROS apps.
- Configure step: In this step, the user can select which app is going to be cross-compiled by the toolchain. Some other options, such as transport, agent’s IP address/port (for UDP transport) or device ID (for serial connections) will be also selected in this step.
- Build step: Here is where the cross-compilation takes place and the platform-specific binaries are generated.
- Flash step: The binaries generated in the previous step are flashed onto the hardware platform memory, in order to allow the execution of the micro-ROS app. Further information about micro-ROS build system can be found here.
Creating a new firmware workspace
Once the build system is installed, let’s create a firmware workspace that targets all the required code and tools:
# Create step
ros2 run micro_ros_setup create_firmware_ws.sh zephyr host
Once the command is executed, a folder named firmware
must be present in your workspace.
This step is in charge, among other things, of downloading a set of micro-ROS apps for the specific platform you are
addressing.
In the case of Zephyr, these are located at firmware/zephyr_apps/apps
.
Each app is represented by a folder containing the following files:
src/main.c
: This file contains the logic of the application.app-colcon.meta
: This file contains the micro-ROS app specific colcon configuration. Detailed info on how to configure the RMW via this file can be found here.CMakeLists.txt
: This is the CMake file containing the script to compile the application.<transport>.conf
: This is a Zephyr specific and transport-dependent app configuration file.<transport>
can beserial
,serial-usb
andhost-udp
.
For the user to create its custom application, a folder <my_app>
will need to be registered in this location,
containing the four files just described.
Configuring the firmware
The configuration step will set up the main micro-ROS options and select the desired application. It can be executed with the following command:
# Configure step
ros2 run micro_ros_setup configure_firmware.sh [APP] [OPTIONS]
The options available for this configuration step are:
--transport
or-t
:udp
,serial
or any hardware-specific transport label--dev
or-d
: agent string descriptor in a serial-like transport--ip
or-i
: agent IP in a network-like transport--port
or-p
: agent port in a network-like transport
In this tutorial, we will use a UDP transport that looks for the agent on the port UDP/8888 at localhost, and focus on
the out-of-the-box ping_pong
application located at firmware/zephyr_apps/apps/ping_pong
.
To execute this application with the chosen transport, run the configuration command above by specifying the [APP]
and [OPTIONS]
parameters as below:
# Configure step
ros2 run micro_ros_setup configure_firmware.sh ping_pong --transport udp --ip 127.0.0.1 --port 8888
You can check the complete content of the ping_pong
app
here.
This example showcases a micro-ROS node with two publisher-subscriber pairs associated with a ping
and a pong
topics, respectively.
The node sends a ping
package with a unique identifier, using a ping
publisher.
If the ping
subscriber receives a ping
from an external node, the pong
publisher responds to the incoming ping
with a pong
. To test that this logic is correctly functioning, we implement communication with a ROS 2 node that:
- Listens to the topics published by the
ping
subscriber. - Publishes a
fake_ping
package, that is received by the micro-ROSping
subscriber. As a consequence, thepong
publisher on the micro-ROS application will publish apong
, to signal that it received thefake_ping
correctly.
The diagram below clarifies the communication flow between these entities:
The contents of the Zephyr app specific files can be found here: main.c, app-colcon.meta, CMakeLists.txt and host-udp.conf. A thorough review of these files is illustrative of how to create a micro-ROS app in this RTOS.
Building the firmware
When the configuring step ends, just build the firmware:
# Build step
ros2 run micro_ros_setup build_firmware.sh
Now you have a Zephyr + micro-ROS app ready to run on your own computer. Notice that in this case, the steps of flashing the firmware and running the micro-ROS app go together.
Creating the micro-ROS agent
The micro-ROS app is now ready to be connected to a micro-ROS agent to start talking with the rest of the ROS 2 world. To do that, let’s first of all create a micro-ROS agent:
# Download micro-ROS-Agent packages
ros2 run micro_ros_setup create_agent_ws.sh
Now, let’s build the agent packages and, when this is done, source the installation:
# Build step
ros2 run micro_ros_setup build_agent.sh
source install/local_setup.bash
Running the micro-ROS app
At this point, you have both the client and the agent correctly installed in your host machine.
To give micro-ROS access to the ROS 2 dataspace, run the agent:
# Run a micro-ROS agent
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888
Flashing the firmware
Finally, in order to run the micro-ROS node inside of the Zephyr RTOS emulator, open a new command shell and execute the flash step by means of the flashing command:
source /opt/ros/$ROS_DISTRO/setup.bash
source install/local_setup.bash
# Flash/run step
ros2 run micro_ros_setup flash_firmware.sh
Testing the micro-ROS app
Now, we want to check that everything is working.
Open a new command line. We are going to listen to the ping
topic
with ROS 2 to check whether the micro-ROS Ping Pong node is correctly publishing the expected pings:
source /opt/ros/$ROS_DISTRO/setup.bash
# Subscribe to micro-ROS ping topic
ros2 topic echo /microROS/ping
You should see the topic messages published by the Ping Pong node every 5 seconds:
user@user:~$ ros2 topic echo /microROS/ping
stamp:
sec: 20
nanosec: 867000000
frame_id: '1344887256_1085377743'
---
stamp:
sec: 25
nanosec: 942000000
frame_id: '730417256_1085377743'
---
At this point, we know that our app is publishing pings. Let’s check if it also answers to someone else’s pings. If this works, it’ll publish a pong.
So, first of all, let’s subscribe with ROS 2 to the pong
topic from a new shell
(notice that initially we don’t expect to receive any pong, since none has been sent yet):
source /opt/ros/$ROS_DISTRO/setup.bash
# Subscribe to micro-ROS pong topic
ros2 topic echo /microROS/pong
And now, let’s publish a fake_ping
with ROS 2 from yet another command line:
source /opt/ros/$ROS_DISTRO/setup.bash
# Send a fake ping
ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}'
Now, we should see this fake_ping
in the ping
subscriber console,
along with the micro-ROS pings:
user@user:~$ ros2 topic echo /microROS/ping
stamp:
sec: 0
nanosec: 0
frame_id: fake_ping
---
stamp:
sec: 305
nanosec: 973000000
frame_id: '451230256_1085377743'
---
stamp:
sec: 310
nanosec: 957000000
frame_id: '2084670932_1085377743'
---
Also, we expect that, because of having received the fake_ping
, the micro-ROS node will answer with a pong
:
user@user:~$ ros2 run micro_ros_demos_rcl ping_pong
Ping send seq 1706097268_1085377743
Ping send seq 181171802_1085377743
Ping send seq 1385567526_1085377743
Ping send seq 926583793_1085377743
Ping send seq 1831510138_1085377743
Ping received with seq fake_ping. Answering.
Ping send seq 1508705084_1085377743
Ping send seq 1702133625_1085377743
Ping send seq 176104820_1085377743
As a consequence, in the pong
subscriber console,
we should see the micro-ROS app answer to our fake_ping
:
user@user:~$ ros2 topic echo /microROS/pong
stamp:
sec: 0
nanosec: 0
frame_id: fake_ping
---
Multiple Ping Pong nodes
One of the advantages of having an emulator is that you don’t need to buy a bunch of hardware in order to test some multi-node micro-ROS apps. So, with the same micro-ROS agent of the last section, let’s open four different command lines and run the following on each:
cd microros_ws
# This is an alternative way of executing the Zephyr emulator
./firmware/build/zephyr/zephyr.exe
As soon as all micro-ROS node are up and connected to the micro-ROS agent you will see them interacting:
user@user:~$ ./firmware/build/zephyr/zephyr.exe
*** Booting Zephyr OS build zephyr-v2.2.0-492-gc73cb85b4ae9 ***
Ping send seq 1711620172_1742614911 <---- This micro-ROS node sends a ping with ping ID "1711620172" and node ID "1742614911"
Pong for seq 1711620172_1742614911 (1) <---- The first mate pongs my ping
Pong for seq 1711620172_1742614911 (2) <---- The second mate pongs my ping
Pong for seq 1711620172_1742614911 (3) <---- The third mate pongs my ping
Ping received with seq 1845948271_546591567. Answering. <---- A ping is received from a mate identified as "546591567", let's pong it.
Ping received with seq 232977719_1681483056. Answering. <---- A ping is received from a mate identified as "1681483056", let's pong it.
Ping received with seq 1134264528_1107823050. Answering. <---- A ping is received from a mate identified as "1107823050", let's pong it.
Ping send seq 324239260_1742614911
Pong for seq 324239260_1742614911 (1)
Pong for seq 324239260_1742614911 (2)
Pong for seq 324239260_1742614911 (3)
Ping received with seq 1435780593_546591567. Answering.
Ping received with seq 2034268578_1681483056. Answering.
TIP: use the help flag to discover some Zephyr emulation features ./firmware/build/zephyr/zephyr.exe -h
- Previous
- Next