当前位置: 首页 > news >正文

详解高性能中间件Iceoryx在ROS2中的使用

文章目录

  • 0. 概述
  • 1. 系统架构对比
    • 1.1 移除 Master 节点
    • 1.2 引入 DDS 系统
    • 1.3 跨平台支持
  • 2. DDS 系统的引入
    • 2.1 RMW 概述
    • 2.2 QoS(质量服务策略)
    • 2.3 ROS2去中心化节点注册和订阅
  • 3. ROS2安装与配置
    • 3.1 一键安装
    • 3.2 官网教程
  • 4. [ROS2 底层切换 Iceoryx 官方实现](https://github.com/ros2/rmw_iceoryx/blob/iron/README.md)
    • 4.1 安装
    • 4.2 使用 rmw_iceoryx_cpp
    • 4.3 零拷贝传输
  • 5. 不同负载下的Iceoryx、cycloneDDS和FastDDS延迟对比
    • 5.1 进程间延迟
    • 5.2 进程内延迟
    • 5.3 对比总结

0. 概述

本文将概述ROS2相比ROS中间件的改进和优势,重点推荐Iceoryx

1. 系统架构对比

系统架构对比图

1.1 移除 Master 节点

  • ROS1:依赖 roscore 作为 Master 节点,Master 节点崩溃会导致系统无法订阅和发布。
  • ROS2:不再依赖 roscore,避免了 Master 节点崩溃导致的系统风险。

1.2 引入 DDS 系统

  • ROS1:使用 TCP/UDP 进行通信,存在延迟、数据丢失和无法加密的问题。
  • ROS2:基于 Data Distribution Service(DDS)的通信架构,提高了网络安全性和实时性。

1.3 跨平台支持

  • ROS1:跨平台支持较弱。
  • ROS2:提供了更好的跨平台兼容性,支持多种操作系统和硬件架构。

2. DDS 系统的引入

DDS 系统图

2.1 RMW 概述

不同厂商可以根据需要实现不同的 DDS 系统,如 OpenSplice 和 FastRTPS。为了统一不同 DDS 厂商的接口,ROS2 设计了 ROS Middleware(RMW)接口,使得各 DDS 厂商能够编写适配接口,将自家 DDS 系统移植到 ROS2 中。

ROS2 的核心概念与 ROS1 基本类似,但在架构上进行了优化,提供了更好的性能和灵活性。RMW 是构建 ROS 所需的原始中间件最小功能集,包括 Initialization and Shutdown、Nodes、Publisher、Subscription、Service Client、Service Server 等功能。

核心概念图

2.2 QoS(质量服务策略)

在开发过程中,需要关注 DDS 的 QoS 特性,它可以通过指定所需的网络传输质量来满足通信需求。

ros2 topic echo /example_topic --qos-reliability reliable

切换不同的 DDS 系统只需安装相应的包,并通过设置环境变量即可:

export RMW_IMPLEMENTATION=rmw_fastrtps_cpp

2.3 ROS2去中心化节点注册和订阅

在ROS 2中,注册和订阅的机制是由节点自身以及底层的通信中间件(如Fast-RTPS)共同负责的。以下步骤描述了注册和订阅的过程:

  • 节点启动:当一个ROS2节点启动时,它会初始化并与底层通信中间件建立连接。这个过程包括创建节点上下文、设置QoS(Quality of Service)策略等。

  • 创建发布者和订阅者:节点通过调用ROS2 API创建发布者和订阅者。发布者用于向特定的话题发送消息,而订阅者则用于接收特定话题的消息。

  • 发布者和订阅者的注册

    • 当节点创建发布者时,它会向通信中间件注册这个发布者,表明它将在这个话题上发布消息。
    • 当节点创建订阅者时,它同样会向通信中间件注册,声明它对某个话题感兴趣并希望接收相关消息。
  • 发现机制:通信中间件负责维护一个关于网络上所有活动节点、话题、服务和动作的动态目录。当节点注册了发布者或订阅者后,通信中间件会广播这些信息,以便其他节点能够发现它们。

  • 匹配过程:一旦一个订阅者注册,通信中间件会查找与之匹配的发布者。匹配基于话题名称和消息类型,以及任何附加的QoS策略。如果找到匹配项,中间件将建立一个直接的连接,允许发布者和订阅者之间直接通信,而无需通过中心节点。

  • 通信:匹配成功后,发布者和订阅者之间可以直接交换数据。发布者发送消息,而订阅者接收消息。这一过程是去中心化的,意味着数据流经由直接的点对点连接,提高了效率和可靠性。

ROS2的这种设计允许节点在不需要中心协调的情况下自主发现和通信,这极大地增强了系统的灵活性、可扩展性和鲁棒性。同时,DDS的QoS机制允许用户根据应用需求调整消息的传输特性,比如可靠性、持久性、历史记录等,从而满足不同的实时性和数据完整性要求。

3. ROS2安装与配置

3.1 一键安装

提供简易的一键安装脚本,支持多个版本的 ROS2 安装。

wget http://fishros.com/install -O fishros && . fishros
# 支持 noetic(ROS1), foxy(ROS2), galactic(ROS2), rolling(ROS2), iron(ROS2), humble(ROS2)

3.2 官网教程

链接到 ROS2 的官方安装教程,为用户提供详细的安装指导。

https://docs.ros.org/

4. ROS2 底层切换 Iceoryx 官方实现

4.1 安装

以下步骤展示了如何安装 Iceoryx 的 RMW 实现。安装 rmw_iceoryx 非常简单,因为 Iceoryx 已包含在 ros2.repos 中。所有提供的包都可以使用 colcon 构建,因此你可以轻松地在 ROS 2 工作区内构建 rmw_iceoryxrmw_iceoryx 使用 rosidl_typesupport_introspection,这允许在现有的 ROS 2 工作区或 Debian 安装基础上构建 iceoryx,因为不需要再次构建 ROS 2 消息。

要在最新的 ROS 版本的 ROS 2 工作区中安装 rmw_iceoryx,请执行以下步骤:

mkdir -p ~/iceoryx_ws/src
cd $_
# LATEST_ROS_VERSION 可以是例如 iron
git clone --branch LATEST_ROS_VERSION https://github.com/ros2/rmw_iceoryx.git

有关替代安装说明和 iceoryx 内部详细信息,请参阅 iceoryx 的 GitHub 仓库。

rmw_iceoryx 与 ROS 2 从 Eloquent 版本开始兼容。假设你已正确安装 ROS 2,可以使用 colcon 编译 iceoryx 工作区:

cd ~/iceoryx_ws/
source /opt/ros/LATEST_ROS_VERSION/setup.bash  # 或者 source 你自己的 ROS 2 工作区
rosdep update
rosdep install --from-paths src --ignore-src --rosdistro LATEST_ROS_VERSION -y
colcon build
# 或者使用更多选项
colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF

就是这样!你已经安装了 iceoryx,现在可以开始使用了。

4.2 使用 rmw_iceoryx_cpp

Iceoryx 基于共享内存,并具有一个名为 RouDi 的共享内存管理应用。启动守护进程:

./iceoryx_ws/install/iceoryx_posh/bin/iox-roudi

然后指定 RMW 实现并运行 ROS 2 示例节点:

source ~/iceoryx_ws/install/setup.bash
RMW_IMPLEMENTATION=rmw_iceoryx_cpp ros2 run demo_nodes_cpp talker

在另一个终端中订阅 talker

source ~/iceoryx_ws/install/setup.bash
RMW_IMPLEMENTATION=rmw_iceoryx_cpp ros2 run demo_nodes_cpp listener

4.3 零拷贝传输

基本的零拷贝工作流程如下:

在这里插入图片描述

  1. loan_message():发布者请求借用一条消息。
  2. publish():发布者填写数据并发布消息。
  3. take_loaned_message():订阅者获取消息。
  4. return_loaned_message():订阅者回调完成后,消息返回中间件。

示例代码:

auto pod_pub_ = node->create_publisher<std_msgs::msg::Float64>("/float", 1);
auto pod_loaned_msg = pod_pub_->borrow_loaned_message();
pod_loaned_msg.get().data = 123.456f;
pod_pub_->publish(std::move(pod_loaned_msg));

在这里插入图片描述

5. 不同负载下的Iceoryx、cycloneDDS和FastDDS延迟对比

该对比数据展示了三种中间件解决方案(IceoryxcycloneDDSFastDDS)的延迟性能。延迟单位为微秒(us),测试负载范围从1KB到64MB。

5.1 进程间延迟

负载IceoryxcycloneDDSFastDDS
1KB2.47.353.95
2KB2.47.883.85
4KB2.47.413.98
8KB2.49.474.42
16KB2.411.975.22
32KB2.414.406.35
64KB2.420.868.72
128KB2.439.2910.11
256KB2.477.9023.06
512KB2.4238.3544.66
1MB2.4836.6489.74
2MB2.4984.68264.61
4MB2.42809.75526.03
8MBNA4874.371895.88
16MBNA8881.515112.93
32MBNA55535.9511998.55
64MBNA120856.5843563.32

5.2 进程内延迟

负载IceoryxcycloneDDSFastDDS
1KB1.5-1.22
2KB1.5-1.73
4KB1.5-1.82
8KB1.5-1.94
16KB1.5-2.34
32KB1.5-3.39
64KB1.5-4.45
128KB1.5-8.26
256KB1.5-23.09
512KB1.5-48.59
1MB1.5-103.26
2MB1.5-360.16
4MB1.5-687.45
8MBNA-1189.07
16MBNA-1951.29
32MBNA-3874.46
64MBNA-7967.83

5.3 对比总结

  • Iceoryx在处理不同负载的进程间通信时,始终保持在2.4微秒的低稳定延迟,这显示了其在处理各种负载时的高效性。在进程内通信方面,其延迟更低,仅为1.5微秒。
  • cycloneDDS随着负载的增加,延迟逐渐增加,特别是在512KB以上,延迟显著增加,在64MB负载时达到120856.58微秒。
  • FastDDS的延迟性能优于cycloneDDS,但仍高于Iceoryx,负载增大时,特别是在4MB以上,延迟显著增加。

综上所述,Iceoryx在小到中等负载的进程间和进程内通信中表现最为高效。而cycloneDDS和FastDDS虽然具有一定的处理能力,但在大数据传输时存在延迟瓶颈。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【大模型从入门到精通13】openAI API 构建和评估大型语言模型(LLM)应用1
  • Chapter 30 多态
  • 解密 Coretime:Polkadot 区块链资源分配的新革命
  • LVS实验的三模式总结
  • “绿色积分引领新风尚:‘我店‘平台重塑消费市场格局“
  • SpringBoot 自动装配原理
  • 五,搭建环境:辅助功能
  • 亚信安慧入选2024信创产业白皮书,AntDB荣获数据库卓越品牌
  • 云计算实训24——python基本环境搭建、变量和数据类型、数据集合、py脚本
  • Win11+docker+gpu+vscode+pytorch配置
  • LeetCode——3131.找出与数组相加的整数I
  • Base64在线解码工具
  • three.js 模型高亮效果实现说明(结合react)
  • Java基础之文件字节流
  • OpenCV 读取 MP4 视频
  • [译] React v16.8: 含有Hooks的版本
  • Angular 2 DI - IoC DI - 1
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • js 实现textarea输入字数提示
  • leetcode-27. Remove Element
  • PHP面试之三:MySQL数据库
  • Python进阶细节
  • Rancher如何对接Ceph-RBD块存储
  • React系列之 Redux 架构模式
  • Redis学习笔记 - pipline(流水线、管道)
  • tensorflow学习笔记3——MNIST应用篇
  • Terraform入门 - 1. 安装Terraform
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何在 Tornado 中实现 Middleware
  • 使用权重正则化较少模型过拟合
  • 微信支付JSAPI,实测!终极方案
  • 学习JavaScript数据结构与算法 — 树
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 优化 Vue 项目编译文件大小
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • Mac 上flink的安装与启动
  • 从如何停掉 Promise 链说起
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $$$$GB2312-80区位编码表$$$$
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (12)Linux 常见的三种进程状态
  • (JS基础)String 类型
  • (Note)C++中的继承方式
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (转)母版页和相对路径
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .bat批处理(六):替换字符串中匹配的子串
  • .Net Core 中间件与过滤器
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET连接MongoDB数据库实例教程