Skip to content

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#

  1. Install rmw_zenoh

    sudo apt update && sudo apt install ros-humble-rmw-zenoh-cpp
    
  2. Set rmw_zenoh as the default RMW implementation

    Add the following line to your ~/.bashrc file:

    export RMW_IMPLEMENTATION=rmw_zenoh_cpp
    
  3. 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.

  1. 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
    
  2. 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
    
  3. 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.

  1. 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
    
  2. 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>
    
  3. 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>
    
  4. Rebuild your workspace (if necessary):

    source /opt/ros/humble/setup.bash
    colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
    
  5. 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.