Configure zenoh
Needs first: Pick and configure the RMW
Use this page when an image runs on the zenoh backend and you need to say where its router is: on this machine, on another host, or at the other end of a serial link.
A nano-ros zenoh image is a zenoh-pico client. It dials one router and
reaches every other node, nano-ros or ROS 2, through it. The router is the one
ROS 2 ships, rmw_zenohd from rmw_zenoh_cpp; nano-ros ships none of its
own. The image’s locator is the address it dials, and it is the only thing
a board needs to find the router.
Before you start
- A workspace with a zenoh image, such as the one from Run a talker.
- ROS 2 Humble with
ros-humble-rmw-zenoh-cpp, sourced in each terminal (source /opt/ros/humble/setup.bash). It providesrmw_zenohd.
Steps
-
See which locator the image dials.
--dry-runprints the run plan without running anything:nros run sensor_node --dry-runThe
[link]table is the image’s locator. The scaffold’s first image reaches the router over the board’s serial port:[link] kind = "serial" locator = "serial/UART_0#baudrate=115200" rmw = "zenoh"A host image (
board = "linux") that states no locator dials the zenoh default,tcp/127.0.0.1:7447. -
Point the image at a router over the network. Set
locatorin the image’s block ofsrc/sensor_node_bringup/system.toml. Inside QEMU’s user network, the host is10.0.2.2:[image.baremetal] board = "mps2-an385-baremetal" locator = "tcp/10.0.2.2:7447"Run it.
nros runsees that10.0.2.2is this host as the emulator reaches it, and startsrmw_zenohdon the matching local port first:nros run sensor_node --expect 'Publishing:'nros run: starting the zenoh router on tcp/127.0.0.1:7447 Publishing: 'Hello World: 1' nros run: matched after -
Use a router on another host instead. Name its address in the locator:
[image.baremetal] board = "mps2-an385-baremetal" locator = "tcp/192.168.50.1:7447"nros runstarts no router for an address that is not this machine’s, and says so:nros run: starting no router (tcp/192.168.50.1:7447 is not an address of this host, so its router runs elsewhere)On the other host, start the router. It reads no command-line arguments; its default configuration listens on port 7447:
source /opt/ros/humble/setup.bash ros2 run rmw_zenoh_cpp rmw_zenohd -
Reuse a router that is already running on this machine. Pass its locator to
--router, andnros runstarts nothing:nros run sensor_node --router tcp/127.0.0.1:7447nros run: starting no router (the router at tcp/127.0.0.1:7447) -
On a host image, change the locator at run time. A host image reads
NROS_LOCATORwhen it starts, and the variable wins over the locator baked fromsystem.toml. Its first log line says which one it used:NROS_LOCATOR=tcp/192.168.50.1:7447 nros run host_nodeboot config: domain 0 (baked), locator tcp/192.168.50.1:7447 (env), …An embedded image has no environment: its locator is fixed when it is built.
-
For more than one endpoint, TLS, or a user name and password, write the session’s own configuration file instead of a locator. Create
rmw/zenoh.json5besidesystem.toml. It is the same documentrmw_zenohreads fromZENOH_SESSION_CONFIG_URIon a ROS 2 host:// src/sensor_node_bringup/rmw/zenoh.json5 { mode: "client", connect: { endpoints: ["tcp/192.168.50.1:7447", "tcp/192.168.50.2:7447"] }, }Then delete the image’s
locatorline: the file is now the session’s wiring, andnros buildrefuses an image that states both. It also refuses a key zenoh-pico cannot take, and names the key, rather than dropping it. Because the file names routers elsewhere, run with--router none.
Client, not peer
zenoh defines a peer mode in which two devices talk with no router. nano-ros
does not build it: zenoh-pico is compiled without the multicast transport and
scouting that peer mode needs, to save flash. A session asked for peer mode,
by mode: "peer" in the file or NROS_SESSION_MODE=peer, refuses to open
and logs:
peer mode unsupported: shim built without multicast transport/scouting
Two nano-ros boards therefore talk through a router, as two rmw_zenoh_cpp
nodes do. This differs from the ROS 2 DDS backends, where nodes discover each
other directly; for that, use Cyclone DDS.
Downsample at the router
When a subscriber’s contract declares an arrival curve, nros configure
writes a router downsampling rule beside the resolved model.
nros router config --model <model> prints it as the
ZENOH_CONFIG_OVERRIDE entry rmw_zenohd reads (--format json5 prints the
rule file itself):
ZENOH_CONFIG_OVERRIDE="$(nros router config --model build/nros/models/<bringup>/<stem>.yaml)" rmw_zenohd
It fails when there is no rule: no subscriber declares an arrival curve, no
image links zenoh, or the model was never configured. nros router is a
command package (nros_zenoh_tools), not a built-in verb, so
nros help --all lists it and nros router config --help prints its flags.
Example
A talker in QEMU and a ROS 2 listener on the host, sharing one router that
nros run starts. The whole bringup:
# src/sensor_node_bringup/system.toml
[system]
name = "sensor_node"
rmw = "zenoh"
ros_edition = "humble"
domain_id = 0
[[component]]
pkg = "sensor_node"
class = "sensor_node::Talker"
name = "sensor_node"
[image.baremetal]
board = "mps2-an385-baremetal"
locator = "tcp/10.0.2.2:7447"
In one terminal:
source /opt/ros/humble/setup.bash
nros run sensor_node
In a second terminal:
source /opt/ros/humble/setup.bash
export RMW_IMPLEMENTATION=rmw_zenoh_cpp
ros2 topic echo /chatter std_msgs/msg/String --qos-reliability best_effort
data: 'Hello World: 3'
If it doesn’t work
nros runstops withno zenoh router: rmw_zenoh_cpp/rmw_zenohd was not found. Source ROS 2 in that terminal, installros-humble-rmw-zenoh-cpp, or setNROS_RMW_ZENOHDto thermw_zenohdbinary.the zenoh router exited on tcp/127.0.0.1:7447 … is the port taken?Another router already holds the port. Stop it, or reuse it with--router tcp/127.0.0.1:7447.- The board boots but nothing arrives. Check the locator with
--dry-run.10.0.2.2means the host only from inside QEMU’s user network; a board on a real network needs the router host’s real address. Both sides must use the samedomain_id, andros2 topic echoneeds--qos-reliability best_effortfor a best-effort talker. - A host image stops at start-up naming
NROS_LOCATOR.ZENOH_LOCATORandZENOH_MODEare retired names. UseNROS_LOCATORandNROS_SESSION_MODE.
See also
- Use a serial link: the
serial/locator and a router on a serial device. - Configure an image: the session file, per-image files and the keys it takes.
- Environment variables:
NROS_LOCATOR,NROS_SESSION_MODEand the TLS variables. - CLI reference: every
nros runflag. - Tune throughput and latency: zenoh-pico’s transmit path and buffers.
- How nano-ros differs from ROS 2.