From de9698e7fa4f0e165833da5424b76698aaa286b8 Mon Sep 17 00:00:00 2001 From: Leonardo Cencetti <37414873+leocencetti@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:00:58 +0100 Subject: [PATCH] zenoh: Add support for ROS2 Humble and earlier (#26619) * Add support for hash-less Zenoh topic key expressions - Add kConfig option ZENOH_KEY_TYPE_HASH to toggle the inclusion - Update topic and liveliness generators * chore: Update Zenoh kConfig param description and help message * docs(zenoh): Document Zenoh configuration for Humble * docs: Clarify PX4 ROS2 Interface library compatibility --- docs/en/middleware/zenoh.md | 17 +++++++++++++++- docs/en/ros2/px4_ros2_interface_lib.md | 4 ++++ src/modules/zenoh/Kconfig | 7 +++++++ src/modules/zenoh/zenoh.cpp | 27 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/en/middleware/zenoh.md b/docs/en/middleware/zenoh.md index bfee1e79f1..a152e0edf7 100644 --- a/docs/en/middleware/zenoh.md +++ b/docs/en/middleware/zenoh.md @@ -48,6 +48,11 @@ ros2 run rmw_zenoh_cpp rmw_zenohd For more information about the Zenoh Router see the [rmw_zenoh](https://github.com/ros2/rmw_zenoh?tab=readme-ov-file#start-the-zenoh-router) documentation. +::: note +From ROS 2 Jazzy onward, `rmw_zenoh` topic key expressions include the message type hash (RIHS01, as defined in REP-2016). This prevents interoperability with ROS 2 Humble and earlier. +For more information about key expressions, refer to the [rmw_zenoh design documentation](https://github.com/ros2/rmw_zenoh/blob/jazzy/docs/design.md#topic-and-service-name-mapping-to-zenoh-key-expressions). +::: + ## PX4 Zenoh-Pico Node Setup ### PX4 Firmware @@ -78,6 +83,12 @@ You can check if Zenoh is present at runtime by using QGroundControl to [find th If present, the module is installed. ::: +::: warning +Interoperability with ROS 2 Humble and earlier requires setting `CONFIG_ZENOH_KEY_TYPE_HASH=n` to disable the +inclusion of the message type hash (RIHS01, as defined in REP-2016) in the Zenoh key expression. +Note that this will break compatibility with ROS 2 Jazzy and later. +::: + ### Enable Zenoh on PX4 Startup Set the [ZENOH_ENABLE](../advanced_config/parameter_reference.md#ZENOH_ENABLE) parameter to `1` to enable Zenoh on PX4 startup. @@ -93,7 +104,7 @@ If you're using a different IP for the Zenoh daemon, run the following command ( zenoh config net client tcp/10.41.10.1:7447#iface=eth0 ``` -Note that for the simulation target with Zeroh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. +Note that for the simulation target with Zenoh (`px4_sitl_zenoh`) you won't need to make any changes because the default IP address of the Zenoh daemon is set to `localhost`. :::warning Any changes to the network configuration require a PX4 system reboot to take effect. @@ -198,3 +209,7 @@ Subscription count: 0 The [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md) works out of the box with Zenoh as a transport backend. This means you can publish and subscribe to PX4 topics over Zenoh without changing your ROS 2 nodes or dealing with DDS configuration. For setup details and supported message types, refer to the [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md). + +::: info +The PX4 ROS 2 Interface Library is not compatible with ROS 2 Humble and earlier, as it requires the message type hash (RIHS01, as defined in REP-2016) to be included in the Zenoh key expression. +::: diff --git a/docs/en/ros2/px4_ros2_interface_lib.md b/docs/en/ros2/px4_ros2_interface_lib.md index d695ab7f21..c304684f82 100644 --- a/docs/en/ros2/px4_ros2_interface_lib.md +++ b/docs/en/ros2/px4_ros2_interface_lib.md @@ -6,6 +6,10 @@ At the time of writing, parts of the PX4 ROS 2 Interface Library are experimental, and hence subject to change. ::: +:::info +When using `rmw_zenoh`, the PX4 ROS 2 Interface Library requires ROS 2 Jazzy or later, and is not compatible with ROS 2 Humble or earlier. +::: + The [PX4 ROS 2 Interface Library](https://github.com/Auterion/px4-ros2-interface-lib) is a C++ library (with Python bindings) that simplifies controlling and interacting with PX4 from ROS 2. The library provides three high-level interfaces for developers: diff --git a/src/modules/zenoh/Kconfig b/src/modules/zenoh/Kconfig index ae050c6ad8..8408d08092 100644 --- a/src/modules/zenoh/Kconfig +++ b/src/modules/zenoh/Kconfig @@ -35,6 +35,13 @@ if MODULES_ZENOH Uses the Zenoh matching feature to check whether a publisher has subscribers. If so, only then publish the data. This is still experimental + config ZENOH_KEY_TYPE_HASH + bool "Include the type hash in Zenoh key expression" + default y + ---help--- + Uses the message type hash (RIHS01, as defined in REP-2016) in the Zenoh key + expression (supported by ROS2 Jazzy and later). + Set to false to use in ROS2 Humble and earlier. # Choose exactly one item choice ZENOH_PUBSUB_SELECTION diff --git a/src/modules/zenoh/zenoh.cpp b/src/modules/zenoh/zenoh.cpp index 2b3f82e06e..c10659a160 100644 --- a/src/modules/zenoh/zenoh.cpp +++ b/src/modules/zenoh/zenoh.cpp @@ -115,6 +115,8 @@ int ZENOH::generate_rmw_zenoh_topic_keyexpr(const char *topic, const uint8_t *ri if (type_name) { strncpy(type, type_name, TOPIC_INFO_SIZE); toCamelCase(type); // Convert uORB type to camel case + +#ifdef CONFIG_ZENOH_KEY_TYPE_HASH return snprintf(keyexpr, KEYEXPR_SIZE, "%" PRId32 "%s/" KEYEXPR_MSG_NAME "%s_/RIHS01_" "%02x%02x%02x%02x%02x%02x%02x%02x" @@ -131,6 +133,11 @@ int ZENOH::generate_rmw_zenoh_topic_keyexpr(const char *topic, const uint8_t *ri rihs_hash[24], rihs_hash[25], rihs_hash[26], rihs_hash[27], rihs_hash[28], rihs_hash[29], rihs_hash[30], rihs_hash[31] ); +#else + return snprintf(keyexpr, KEYEXPR_SIZE, "%" PRId32 "%s/" + KEYEXPR_MSG_NAME "%s_/TypeHashNotSupported", + _zenoh_domain_id.get(), topic, type); +#endif } return -1; @@ -155,6 +162,7 @@ int ZENOH::generate_rmw_zenoh_topic_liveliness_keyexpr(const z_id_t *id, const c str++; } +#ifdef CONFIG_ZENOH_KEY_TYPE_HASH return snprintf(keyexpr, KEYEXPR_SIZE, "@ros2_lv/%" PRId32 "/" "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/" @@ -184,6 +192,25 @@ int ZENOH::generate_rmw_zenoh_topic_liveliness_keyexpr(const z_id_t *id, const c rihs_hash[24], rihs_hash[25], rihs_hash[26], rihs_hash[27], rihs_hash[28], rihs_hash[29], rihs_hash[30], rihs_hash[31] ); +#else + return snprintf(keyexpr, KEYEXPR_SIZE, + "@ros2_lv/%" PRId32 "/" + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/" + "0/11/%s/%%/%%/px4_%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/%s/" + KEYEXPR_MSG_NAME "%s_/TypeHashNotSupported" + "/::,7:,:,:,,", + _zenoh_domain_id.get(), + id->id[0], id->id[1], id->id[2], id->id[3], id->id[4], id->id[5], id->id[6], + id->id[7], id->id[8], id->id[9], id->id[10], id->id[11], id->id[12], id->id[13], + id->id[14], id->id[15], + entity_str, + _px4_guid[0], _px4_guid[1], _px4_guid[2], _px4_guid[3], + _px4_guid[4], _px4_guid[5], _px4_guid[6], _px4_guid[7], + _px4_guid[8], _px4_guid[9], _px4_guid[10], _px4_guid[11], + _px4_guid[12], _px4_guid[13], _px4_guid[14], _px4_guid[15], + topic_lv, type_camel_case + ); +#endif } int ZENOH::setupSession()