Latest News / October ‘25 / BrightDrive Joins The Autoware Foundation!

Agnocast: A True Zero-Copy Publish/Subscribe IPC

Author: ADMIN
Agnocast: A True Zero-Copy Publish/Subscribe IPC

For Autoware, Inter-Process Communication (IPC) has been an important topic. Autoware is a ROS 2–based application, in which nodes—the smallest functional units—communicate with each other via publish/subscribe, collectively realizing autonomous driving. When nodes run in different processes, ROS 2 message communication incurs multiple copies, including serialization and deserialization. Autoware has avoided this overhead by using ComponentContainer, which hosts the nodes within the same process. From a fault isolation perspective, however, it is preferable to place each node in a separate process. Therefore, we need ROS 2–compatible middleware with true zero-copy IPC, i.e., eliminating all copies including serialization and deserialization.

Production-level middleware such as Iceoryx (and Iceoryx2) supports true zero-copy IPC, but only for messages with static size, and thus cannot be adopted in Autoware. Autoware extensively uses unsized message types (e.g., message types containing C++’s std::vector) as part of its design goal to handle multiple use cases within a single codebase. Even at the conceptual level (e.g., in academic papers), no ROS 2–compatible middleware has ever existed that supports true zero-copy IPC for arbitrary ROS 2 messages. True zero-copy IPC for unsized messages was proposed in TZC [IROS ‘19] and LOT [IROS ‘21], but they only support runtime-resizable arrays specialized for TZC/LOT, not arbitrary ROS 2 messages with properties like std::vector.

To address this problem, we invented a new IPC technique and developed a new ROS 2–compatible middleware, Agnocast. With minimal code changes to existing ROS 2 applications, Agnocast enables true zero-copy IPC for arbitrary ROS 2 message types. In this blog post, we introduce Agnocast and its integration into Autoware.

Agnocast GitHub repository: GitHub – tier4/agnocast: True Zero Copy Communication Middleware for Unsized ROS 2 Message Types. 


How to Use Agnocast

Agnocast coexists with the ROS 2 stack without requiring changes to ROS 2, and is unaffected by changes to the RMW implementation.

To introduce Agnocast, the following changes and operations are necessary:

  1. Installation of dependencies
  2. Insertion of the kernel module
  3. Modifications to ROS 2 app’s source code
  4. Modifications to launch files

See details in the Agnocast GitHub repository README.

1. Installation of dependencies

To use Agnocast, two packages must be installed in addition to the client library: a library loaded via LD_PRELOAD for hooking heap allocations (agnocast-heaphook), and a kernel module (agnocast-kmod). Both are distributed through TIER IV’s PPA as of August 2025, with the latest version being v2.1.2.

Shell
sudo add-apt-repository ppa:t4-system-software/agnocast
sudo apt update
sudo apt install agnocast-heaphook-v2.1.2 agnocast-kmod-v2.1.2

Next, install the client library agnocastlib. As of August 2025, it is only available as a source build, but it will soon be distributed through the ROS build farm.

Shell
git clone --branch 2.1.2 --depth 1 https://github.com/tier4/agnocast.git
source /opt/ros/humble/setup.bash
rosdep install -y --from-paths src --ignore-src --rosdistro $ROS_DISTRO
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release
source install/setup.bash

2. Insertion of the kernel module

Load the installed kernel module. You may also configure systemd to automatically load it at system startup.

Shell
sudo modprobe agnocast

3. Modifications to ROS 2 app’s source code

Only the smart pointer type that wraps the message type and the publish/subscribe functions need to be modified. Agnocast provides a smart pointer, agnocast::ipc_shared_ptr, which manages the lifetime of message objects transferred between processes. The only required change for publisher and subscriber functions is to change their namespace from rclcpp to agnocast.

4. Modifications to launch files

In the launch file, environment variables such as LD_PRELOAD need to be set so that agnocast-heaphook is applied to processes participating in Agnocast communication. Additionally, for ComposableNode, the Agnocast-specific executor must be specified in the launch file.


New IPC Technology behind Agnocast

The production-grade Agnocast (tier4/agnocast) has been developed based on a paper of new IPC technology and its prototype. The paper, titled “ROS 2 Agnocast: Supporting Unsized Message Types for True Zero-Copy Publish/Subscribe IPC” was accepted by IEEE ISORC 2025. If you are interested in more details, we encourage you to read the paper.

The new IPC technology behind Agnocast is primarily based on two elements: memory mapping that allows data structures containing pointers to be shared across processes, and a smart pointer that manages metadata such as reference counts within the kernel module.

For processes participating in Agnocast communication, all heap allocations and deallocations are intercepted via LD_PRELOAD and redirected to a specified virtual address range. This address range is mapped to shared memory. Subscribers map the publisher’s heap region as read-only at the same offset in their own virtual address space.

In this shared address range, raw pointers remain valid across processes (if they do not point outside the shared memory region), thereby enabling true zero-copy IPC in Agnocast. For details on why such a drastic approach is necessary, please refer to the paper mentioned above.

As explained above, an Agnocast-specific smart pointer type (agnocast::ipc_shared_ptr) is provided for wrapping ROS 2 messages. While normal smart pointer types (e.g., std::shared_ptr) have their own data structures (e.g., reference counts) in the user-space address space, the Agnocast-specific smart pointer maintains them within the kernel module (agnocast-kmod).

This is necessary because updates to cross-process metadata must be transactional—either fully succeed or roll back—without leaving an inconsistent state. For simplicity of implementation, Agnocast adopts the former approach by implementing metadata operations as kernel module system calls, ensuring that updates are completed regardless of the timing of process termination.

Because the objects may be referenced by multiple processes, their lifetime management—that is, the logic for determining when to free them—differs from that of ordinary smart pointers. The kernel module also monitors process exits to ensure that the data structures remain valid, even if a process terminates unexpectedly.


Integration into Autoware

As of August 2025, Agnocast has already been integrated into autonomous bus projects at TIER IV. The introduction of Agnocast has resolved the challenge of combining efficient IPC for large sensor data with fault isolation for safety.

Agnocast is being introduced not only into internal projects at TIER IV but also into the open-source Autoware project. The initial integration targets are as follows:

Since Agnocast is still in an experimental stage, its integration can be enabled or disabled at build time using the environment variable ENABLE_AGNOCAST. For details, please refer to the autoware_agnocast_wrapper README.


Interested in learning more? A talk on Agnocast will be given at ROSCon 2025! We will also soon publish detailed documentation of Agnocast. Integration into Autoware is currently being discussed in the discussion in the awf/autoware repository.