Zenoh settings for ROS 2 and Autoware#
Autoware uses CycloneDDS as its default communication middleware, but it's also compatible with other protocols like Zenoh. The ROS community has selected Zenoh as a promising new middleware alternative due to its key advantages:
- Internet Communication: Unlike DDS, which is limited to a local area network (LAN), Zenoh can seamlessly communicate with the cloud, eliminating the need for a separate bridge.
- Namespace Support: Zenoh allows for the use of namespaces for each vehicle. This feature simplifies managing multiple vehicles and isolating network traffic.
- Non-Multicast Support: Zenoh functions in non-multicast environments like 5G, a key limitation for DDS.
- Reduced Discovery Overhead: Zenoh significantly reduces discovery packet overhead, a known issue with DDS in wireless environments.
- Superior Performance: A study has shown that Zenoh generally outperforms other protocols such as DDS, MQTT, and Kafka.
The following sections provide a step-by-step tutorial for running Autoware with Zenoh. Please note that a workaround patch is currently required to enable Zenoh in Autoware. This patch may not be compatible with the Autoware main branch.
Install rmw_zenoh#
-
Install rmw_zenoh
sudo apt update && sudo apt install ros-humble-rmw-zenoh-cpp
-
Set rmw_zenoh as the default RMW implementation
Add the following line to your
~/.bashrc
file:export RMW_IMPLEMENTATION=rmw_zenoh_cpp
-
Reload your shell configuration (or open a new terminal):
source ~/.bashrc
For more details, see the rmw_zenoh repository.
Avoid the GuardCondition Use-After-Free Issue with Zenoh#
When running Autoware with Zenoh, a modification to behavior_planning.launch.xml
is required to avoid a GuardCondition use-after-free issue in ROS 2 Humble’s multi-threaded executor. This issue is fixed in ROS 2 Rolling (2025.04+) but not backported.
There are two options to avoid this issue:
Option 1: Use the Patched Package#
You can use our patched tier4_planning_launch
package directly.
This package already runs behavior_path_planner
in a single-threaded node container, so no manual modification is needed.
-
Clone
evshary/tier4_planning_launch
and move to the directory:- Note that the version should match the one in autoware_universe.
mkdir -p ~/tier4_planning_launch_ws/src cd ~/tier4_planning_launch_ws/src # Switch to the version you are using in autoware_universe, for example, 0.45.0. git clone https://github.com/evshary/tier4_planning_launch.git -b 0.45.0
-
Build the workspace:
source <YOUR-AUTOWARE-DIR>/install/setup.bash cd ~/tier4_planning_launch_ws colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
-
Launch Autoware with Zenoh:
Start the Zenoh router:
# terminal 1 ros2 run rmw_zenoh_cpp rmw_zenohd
Launch Autoware with the
tier4_planning_launch
overlay applied:# terminal 2 source ~/tier4_planning_launch_ws/install/setup.bash ros2 launch autoware_launch autoware.launch.xml ...
Option 2: Manually Patch the Launch File#
If you are using a version of Autoware that is not compatible with our tier4_planning_launch
, you need to manually patch behavior_planning.launch.xml
to run autoware_behavior_path_planner
in a separate single-threaded container.
-
Open the launch file:
vim <YOUR-AUTOWARE-DIR>/src/universe/autoware_universe/launch/tier4_planning_launch/launch/scenario_planning/lane_driving/behavior_planning/behavior_planning.launch.xml
-
Find the block for
autoware_behavior_path_planner
:<load_composable_node target="/planning/scenario_planning/lane_driving/behavior_planning/behavior_planning_container"> <composable_node pkg="autoware_behavior_path_planner" plugin="autoware::behavior_path_planner::BehaviorPathPlannerNode" name="behavior_path_planner" namespace=""> ... </composable_node> </load_composable_node>
-
Modify opening and closing tags and add the
thread_num
param to ensure single-threaded execution:<!-- <load_composable_node target="/planning/scenario_planning/lane_driving/behavior_planning/behavior_planning_container"> --> <node_container pkg="rclcpp_components" exec="$(var container_type)" name="behavior_planning_container2" namespace="" args="" output="both"> <composable_node pkg="autoware_behavior_path_planner" plugin="autoware::behavior_path_planner::BehaviorPathPlannerNode" name="behavior_path_planner" namespace=""> ... </composable_node> <param name="thread_num" value="1"/> <!-- </load_composable_node> --> </node_container>
-
Rebuild your workspace (if necessary):
source /opt/ros/humble/setup.bash colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
-
Launch modified Autoware with rmw_zenoh
Start the Zenoh router
# terminal 1 ros2 run rmw_zenoh_cpp rmw_zenohd
Launch modified Autoware
# terminal 2 source <YOUR-AUTOWARE-DIR>/install/setup.bash ros2 launch autoware_launch autoware.launch.xml ...
Logging#
Zenoh is implemented in Rust and uses a logging library configurable via the RUST_LOG
environment variable.
You can specify different levels (such as info
, debug
, or trace
) for more or less verbosity.
Example#
Start the Zenoh router with debug logs enabled:
export RUST_LOG=zenoh=debug
ros2 run rmw_zenoh_cpp rmw_zenohd
Or launch autoware with info log in a single command:
RUST_LOG=zenoh=info ros2 launch autoware_launch autoware.launch.xml ...
For more information, see the rmw_zenoh logging section.