Skip to main content

Connecting ROS 2 Nodes with the ROS_STATIC_PEERS env

info
  • Level: 🌴 easy
  • Compatible ROS distributions: ROS 2 Jazzy
  • Compatible RMW implementations: rmw_cyclonedds_cpp

To connect your ROS 2 nodes over the Internet, the simplest method is to set the ROS_STATIC_PEERS environment variable before running your nodes. On each host, provide a semicolon-separated list of the peers' hostnames or addresses.

To use IPv6 addresses with ROS_STATIC_PEERS, you need to enable this mode in Cyclone DDS by creating the following file:

/var/tmp/cyclonedds.xml
<?xml version="1.0" encoding="UTF-8" ?>
<CycloneDDS xmlns="https://cdds.io/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://cdds.io/config https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd">
<Domain>
<General>
<Interfaces>
<NetworkInterface name="hnet0"/>
</Interfaces>
<AllowMulticast>false</AllowMulticast>
<FragmentSize>1194B</FragmentSize><!-- default: 1344 B minus Husarnet metadata (~150 B) -->
<Transport>udp6</Transport>
</General>
</Domain>
</CycloneDDS>

Examples

Below is a demonstration using a talker-listener ROS 2 demo. Assume that talker-host and listener-host are Husarnet hostnames of the two devices in the same Husarnet group:

Host Setup

Execute the following commands in the terminal:

joe@talker-host
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///var/tmp/cyclonedds.xml # enable IPv6 in Cyclone DDS
export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST #optional: thanks to this env, you make sure all remote traffic goes through Husarnet
export ROS_STATIC_PEERS=talker-host;listener-host
# or with IPv6 addresses
# export ROS_STATIC_PEERS=fc94:a67f:2b47:756c:6e1c:7c05:7361:7378;fc94:6260:26e:e057:9bc:8786:4f8a:c7a6

ros2 run demo_nodes_cpp talker

Docker Setup

Create the following two files in the same directory:

Dockerfile
FROM ros:jazzy-ros-core

RUN apt update && apt install -y \
ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \
ros-${ROS_DISTRO}-demo-nodes-cpp && \
rm -rf /var/lib/apt/lists/*
compose.yaml
name: ${CHATTER_ROLE:-talker}

services:
chatter:
build: .
network_mode: host
volumes:
- /var/tmp/cyclonedds.xml:/var/tmp/cyclonedds.xml
environment:
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
- CYCLONEDDS_URI=file:///var/tmp/cyclonedds.xml # enable IPv6 in Cyclone DDS
- ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST #optional: thanks to this env, you make sure all remote traffic goes through Husarnet
- ROS_STATIC_PEERS=talker-host;listener-host
command: ros2 run demo_nodes_cpp ${CHATTER_ROLE:-talker}

Perform this action on both the talker-host and listener-host. Then, execute the following commands:

joe@talker-host
CHATTER_ROLE=talker docker compose up --build --force-recreate
tip

You can also run the Docker-based demo on the same host, by running Husarnet within the container:

👉 See the full ros-static-peers example here.