【ROS2实战笔记-8】Agnocast:ROS 2跨进程零拷贝的工程实现与取舍

news2026/5/24 12:44:35
“零拷贝”在ROS 2语境下是一个经常被讨论的概念。许多开发者听说过Fast DDS的共享内存、Iceoryx或者Node Composition但对于它们之间真正的差异、各自的边界条件以及为什么需要一个叫Agnocast的新方案未必有一个清晰的认知。本文从Autoware在自动驾驶场景中的真实需求出发梳理ROS 2跨进程零拷贝通信的技术演进、核心难题以及Agnocast给出的工程答案。一、为什么需要跨进程零拷贝ROS 2的节点既可以放在同一个进程中运行也可以放在不同进程中。两者各有代价。放在同一进程ComponentContainer可以实现真正的零拷贝通信因为数据在进程内通过共享指针传递没有序列化/反序列化。但这种方式的代价是故障隔离能力的丧失任何一个节点崩溃整个进程都会退出进而导致系统完全失效。放在不同进程则相反故障隔离性好但每次跨进程通信都要经过序列化、DDS传输、反序列化等多个拷贝步骤。在Autoware这样的自动驾驶系统中节点数量众多功能覆盖定位、感知、规划、控制等多个环节。把每个节点放在独立进程中从工程健壮性角度看是正确选择。但这样一来跨进程通信的开销就成了不得不面对的问题。论文中给出的背景是Autoware大量使用unsized message types例如包含std::vector的消息类型以此实现在同一套代码库中适配多种传感器和不同使用场景的需求。而当时已有的实用级零拷贝中间件如Iceoryx只支持静态大小的消息无法满足这一需求。二、“零拷贝”的不同层次“零拷贝”这个词在ROS 2社区中存在不同程度的理解区分清楚非常重要层级实现方式适用场景局限进程内零拷贝ComponentContainer shared_ptr同一进程内的多个节点故障隔离差DDS共享内存Fast DDS SHM Loaned Messages跨进程静态大小或POD类型对复杂消息类型支持有限独立零拷贝中间件Iceoryx跨进程硬实时场景仅支持静态大小消息应用层零拷贝方案TZC / LOT跨进程支持动态数组非通用ROS 2消息格式Agnocast共享内存 POSIX mq LD_PRELOAD跨进程任意ROS 2消息类型目前仅支持Linux CROS 2标准层在rmw_fastrtps中提供了Loaned Messages机制。应用程序可以从RMW实现中借用消息内存从而消除ROS 2应用层与RMW实现之间的拷贝。但实现零拷贝消息交付需要同时启用Fast DDS Data Sharing机制并正确使用Loaned Messages API。这一套机制的局限在于它对消息类型有约束对开发者也有额外要求。三、Agnocast的设计目标三个“必须满足”Agnocast的论文列出了三个必须满足的要求这也是它与现有方案的区分点。第一支持所有ROS 2消息类型包括unsized类型。包含std::vector的动态数组是ROS 2消息中的常见结构但给零拷贝带来了根本性的困难——动态数组的大小在编译时未知内存布局不固定无法像静态结构那样预先分配共享内存区域。Iceoryx无法满足这一点因为它只支持静态大小的消息。第二对现有应用程序代码的修改尽可能小。Agnocast不能要求开发者重写整个节点必须能在保持原有ROS 2 API接口的前提下替换底层通信机制。第三选择性实现零拷贝。这意味着在同一个系统中某些节点之间的通信使用零拷贝其他节点尤其是跨主机的节点仍走传统的DDS路径。不能因为引入了零拷贝就破坏原有的分布式通信能力。四、Agnocast的工作原理从内核模块到LD_PRELOADAgnocast的架构比一般的ROS 2中间件要复杂因为它没有直接复用现有的RMW层而是在RMW之外另建了一套通信路径。整体包含以下三个核心组件。agnocast-kmod内核模块负责管理共享内存区域的分配和访问控制。所有发布者和订阅者共享的内存区域由这个内核模块统一管理。内核模块的介入意味着对系统内核的修改或额外加载这是Agnocast与纯用户态方案如普通DDS共享内存的一个关键区别。agnocast-heaphook这是一个通过LD_PRELOAD加载的库用于拦截堆内存分配。它的作用是在节点申请内存分配ROS 2消息时将分配操作重定向到Agnocast管理的共享内存区域而不是普通的堆。这种技术手段使得消息数据从一开始就落在共享内存中避免了后续的数据拷贝。agnocastlib客户端库提供与rclcpp兼容的API。应用程序代码中原本使用rclcpp::Node的地方可以替换为agnocast::Node其余的逻辑基本保持不变。在通信机制方面Agnocast使用POSIX消息队列作为跨进程的通知机制。当一个发布者写完共享内存中的数据后它通过消息队列向所有订阅者发送通知订阅者收到通知后直接从共享内存中读取数据。Agnocast需要增大系统对消息队列的限制。fs.mqueue.msg_max的默认值通常不足以支持它的运行官方推荐将此值设置为256以上。每个订阅者会对应一个消息队列因此在大规模系统中消息队列的总数可能超过系统默认限制通常为256需要额外调整。五、关键问题如何支持unsized消息类型Agnocast最核心的技术贡献在于对unsized消息类型即包含变长数组的消息的支持。这是Iceoryx做不到的也是它与TZC、LOT等学术方案的本质区别。unsized消息的难点在于共享内存是固定大小的区域而std::vector的内容可以在运行时动态增长。当vector扩容时原来的内存地址可能失效。Agnocast的处理思路是分离存储消息的元数据固定大小的部分和动态数据vector的实际内容分开存放。动态数据区本身也是在共享内存中分配的但通过一个间接层来管理使得vector扩容时只需要重新分配动态数据区而不影响消息的固定头部的内存地址。这种分离存储的设计使得Agnocast可以支持任意嵌套的unsized类型——例如一个消息中包含一个vectorvector中的元素本身又包含另一个vector。论文中提到Agnocast通过启发式地拦截堆分配来实现对动态内存的管理确保所有相关数据都落在共享内存区域。六、性能数据16%的平均响应时间改善Agnocast的性能评估在Autoware的真实点云预处理流水线上进行。点云是自动驾驶系统中数据量最大、频率最高的消息类型之一也是最适合零拷贝优化的场景。论文中的数据表明在点云预处理模块中Agnocast实现了16%的平均响应时间改善和25%的最坏情况响应时间改善。这个数值需要放在具体上下文中理解点云预处理是一个计算密集的环节通信开销只是整体耗时的一部分。16%的改善意味着通信部分在优化前可能占了相当可观的比例。Agnocast的另一个关键特性是通信开销与消息大小无关——无论消息是1KB还是10MB跨进程通信的额外开销保持恒定。这一点与传统的基于序列化的DDS通信形成鲜明对比后者的延迟通常随消息大小线性增长。七、Agnocast与Autoware的集成方式Agnocast不是对ROS 2的替换而是在其旁边运行的一个库。它与ROS 2栈共存且不受RMW实现变化的影响。在Autoware中集成Agnocast并不是开箱即用的。官方提供了autoware_agnocast_wrapper包通过包装宏和智能指针类型来将Agnocast集成到各个话题中。集成方式分为两种节点包装Node Wrapper通过agnocast_wrapper::Node类可以在运行时根据ENABLE_AGNOCAST环境变量透明地切换底层实现是rclcpp::Node还是agnocast::Node。这种方式的优点是对已有代码的影响最小节点内部逻辑完全不用改动。但需要额外注意目前Timercreate_wall_timer, create_timer还未被完全支持将在后续版本中补全。组件容器支持对于使用ComponentContainer的节点Agnocast提供了专门的executor支持。agnocast_components包提供CMake工具用于将ROS 2组件节点注册到Agnocast executor中。autoware_agnocast_wrapper包的设计保证了向后兼容性默认构建命令不启用Agnocast只有设置ENABLE_AGNOCAST1环境变量后才会进行包含Agnocast集成的构建。八、局限性目前还不能做什么Agnocast的局限性与它的设计选择同样值得关注。**仅支持C**。Agnocast的API与rclcpp兼容对rclpyPython客户端没有官方支持。Python本身的GIL和内存管理机制使其难以实现同样的零拷贝效果因此短期内可能不会出现Agnocast的Python绑定。服务Service和客户端Client尚未正式支持。官方文档中明确标注警告Agnocast service/client尚未得到官方支持API可能在将来发生变化。这意味着当前版本的Agnocast只适用于纯发布-订阅publish-subscribe通信模式。仅支持Linux。由于依赖内核模块和POSIX消息队列Agnocast目前只能在Linux上运行。对macOS或Windows的支持不在当前路线图中。需要源码构建。截至2026年初Agnocast的ROS包尚未从ROS build farm分发用户需要从源码克隆并构建。官方推荐克隆特定版本标签如2.3.1以保证稳定性。节点间通信优先级无差异。Agnocast当前的调度策略对所有节点一视同仁。在一个有实时性要求的系统中不同节点的关键程度不同缺乏优先级区分可能影响系统在资源紧张时的表现。九、与其他方案的横向比较方案支持unsized类型对现有代码的侵入性故障隔离额外依赖Fast DDS SHM Loan有限支持低好需要DDS配置Iceoryx不支持中好需要独立中间件Node Composition支持低差无TZC有限支持中好需要修改消息定义Agnocast支持中低好内核模块 POSIX mqSIMSensor-in-Memory是一个值得单独讨论的竞争方案。它同样实现了共享内存传输但与Agnocast的设计思路不同SIM将传感器数据保留在原生内存布局中如cv::Mat、PCL使用无锁双缓冲区只需四行代码即可集成。在Jetson Orin Nano上的测试中SIM相比FastRTPS和Zenoh等ROS 2零拷贝传输方式降低了最高98%的数据传输延迟。与Agnocast相比SIM的优势在于对特定数据类型的高度优化和极简的集成成本但Agnocast的优势在于对任意ROS 2消息类型的通用支持。十、配置与调试的冷门细节消息队列参数。Agnocast对POSIX消息队列的依赖意味着系统级的参数调优至关重要。fs.mqueue.msg_max控制每个队列的最大消息数默认值通常只有10而Agnocast推荐256。如果未调整在高频消息场景下可能出现消息丢失或阻塞。fs.mqueue.queues_max控制系统级最大消息队列数。每个订阅者对应一个消息队列在节点数量较多的大规模系统中默认值256可能不够用。内核模块的兼容性。Agnocast的内核模块在Linux内核5.x和6.x系列上均可运行但不同内核版本之间的模块可能不兼容。在同一台机器上升级内核后需要重新编译并加载内核模块。LD_PRELOAD的潜在冲突。Agnocast的heap hook通过LD_PRELOAD机制加载。如果系统中同时有其他依赖LD_PRELOAD的调试或监控工具如valgrind、某些性能分析器可能会与Agnocast产生冲突。这种情况下要么先禁用其他工具要么调整加载顺序。环境感知的零拷贝切换。Agnocast的节点包装实现了一种有趣的能力同一个二进制程序可以通过环境变量在零拷贝和标准ROS 2通信之间切换。这对于在生产环境中进行A/B测试或灰度发布非常有用。具体实现中ENABLE_AGNOCAST1环境变量控制这一开关没有该变量时系统完全退回到标准ROS 2行为。结语Agnocast的出现填补了ROS 2生态中“对任意消息类型的跨进程零拷贝”这一空白。它不是对DDS的替代而是在DDS之外为对延迟敏感的大数据传输提供了一条专用通道。它的设计体现了一个清晰的取舍通过增加系统复杂度内核模块、LD_PRELOAD、消息队列配置换取对通用消息类型的零拷贝能力和跨节点通信的选择性启用。对于大多数ROS 2应用标准的DDS通信已经足够。但当节点数量增加、消息尺寸变大、响应时间要求变严格时Agnocast提供了一个经过工程验证的优化路径。目前它在Autoware中的集成效果已经证明这种取舍在自动驾驶这类实时性要求极高的场景中是值得的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2541005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…