Skip to content

Zenoh Router

A ROS2 Jazzy container running a rmw_zenoh router.

Why aren't we using the default FastDDS?

Because of a technical limitation of the network setup at the DFKI, the robot and the computing machine are in seperate subnets. This causes some issues, because FastDDS assumes everything runs on the same subnet and only advertises on that same subnet. It might be possible to make cross-networking possible using ROS_STATIC_PEERS, but in our case, there were too many issues.

Also, since we are using Docker for deploying our software, hostmode was required to make automatic discovery of the ROS nodes. But that made FastDDS assume, that all software runs on the same machine, while it didn't, so we needed to disable "shared memory" manually and that caused more configuration issues.

That's why we chose to use Zenoh as a replacement for FastDDS.

How does it work?

Make sure to install rmw-$ROS_DISTRO-rmw-zenoh-cpp in your container or device, where your ROS nodes reside. Substitute $ROS_DISTRO with your own ROS distribution like jazzy.

In order to use Zenoh, you need to start up the compose.yml in this repository. After starting the router, every ROS node on the same device as the router can add the following lines in the compose:

services:
  ${service-name}:
    environment:
      ROS_AUTOMATIC_DISCOVERY_RANGE: OFF # Disable automatic discovery
      RMW_IMPLEMENTATION: rmw_zenoh_cpp # Force ROS2 to use zenoh as RMW
      ZENOH_ROUTER_CHECK_ATTEMPTS: 0 # Indefinitely wait for zenoh router
      ZENOH_CONFIG_OVERRIDE: mode="client";connect/endpoints=["tcp/host.docker.internal:7447"]
    extra_hosts:
      - "host.docker.internal:host-gateway"

After adding them in, local ROS nodes will automatically discover all other nodes connected to the Zenoh router.

If you need to connect any other device to the network, you need to configure the compose.yml file and add the other devices' IP to the config file. This means that you need to specify every other devices' IPs in the router config, so they can discover each other.

Example (DEVICE1):

services:
  zenoh_router:
    environment:
      ZENOH_CONFIG_OVERRIDE: >-
        connect/endpoints=["tcp/${DEVICE2_IP}:7447","tcp/${DEVICE3_IP}:7447"]
Example (DEVICE2):

services:
  zenoh_router:
    environment:
      ZENOH_CONFIG_OVERRIDE: >-
        connect/endpoints=["tcp/${DEVICE1_IP}:7447","tcp/${DEVICE3_IP}:7447"]

Example (DEVICE3):

services:
  zenoh_router:
    environment:
      ZENOH_CONFIG_OVERRIDE: >-
        connect/endpoints=["tcp/${DEVICE1_IP}:7447","tcp/${DEVICE2_IP}:7447"]

With this configuration, every ROS node can discover every other ROS node inside the configured Zenoh network. Make sure to restart the container, after editing the config file.