通信中间件 Fast DDS 基础概念简述与通信示例

2023-11-16

 

从事汽车软件开发,通信中间件绕不开,当前最火热的无非有 2 种:Some/IP 和 DDS。DDS 是一种分布式通信标准,有很多商业和开源的实现,Fast DDS 是其中的一种。它在 ROS2 中被应用,而 Apollo 中的 CyberRT 框架中也有它的身影。

讲 Fast DDS 之前先讲什么是 DDS。

1. 什么是 DDS ?

DDS 是 OMG 组织发布的一种中间件协议和 API 标准,它将系统的组件集成在一起,提供业务和任务关键型物联网 (IoT) 应用程序所需的低延迟数据连接、极高的可靠性和可扩展架构。

DDS(Data Distribution Service,数据分发服务) 是一种以数据为中心的通信协议,用于分布式软件应用程序通信。

它描述了支持 数据提供者(Data Providers)数据消费者(Data Consumers) 之间通信的通信应用程序编程接口 (API) 和通信语义。

要学习 DDS 就不能忽略它的模型:DCPS(以数据为中心的发布订阅模型)。

DCPS 有 3 个关键实体:

  1. publication entities: 定义消息生成对象及相关属性
  2. subscription entities:定义消息消费对象及相关属性
  3. configuration entities:定义传输相关的属性如 Topic 类型,通信的 QoS(服务质量)。

QoS 是一个非常重要的概念,DDS 使用 QoS 来定义 DDS 实体的行为特征。 QoS 由单独的 QoS 策略(源自 QoSPolicy 的类型的对象)组成。

2. 什么是 Fast-DDS?

DDS 是一套标准,它有很多实现,有商业的,也有开源的。

商业:RTI 开源: Cyclone DDS、Fast-DDS

所以,Fast DDS 是一种开源的 DDS 标准实现,它由 ePromise 公司发布并维护。

3. 什么是 DCPS?

先看看 Fast DDS 官方文档中的一张图。

在这里插入图片描述

DDS 是以数据为中心的通信模型,那么这个数据中心是什么呢?

我个人的理解是以 Topic 为代表的消息对象就是 DDS 中的数据中心。

通过 Topic 的纽带关系,可以将数据生成为数据消费对象连接起来,并且可以通过 QoS 执行通信服务质量策略。

在 DCPS 模型中,有 4 个基础的概念:

  1. Publisher:它是负责创建和配置其实现的 DataWriters 的 DCPS 实体。 DataWriter 是负责实际发布消息的实体。每个 DataWriter 都有一个分配的 Topic,在该 Topic 下发布消息。
  2. Subscriber:它负责接收在其订阅的 Topic下发布的数据。它为一个或多个 DataReader 对象提供服务,这些对象负责将新数据的可用性传达给应用程序。
  3. Topic(话题):它是绑定发布和订阅的实体。它在 DDS 域中是唯一的。通过TopicDescription,它允许发布和订阅数据类型的统一。
  4. Domain(领域):这是用于链接所有发布者和订阅者的概念,属于一个或多个应用程序,它们在不同主题下交换数据。这些参与域的单个应用程序称为 DomainParticipant。 DDS 域由域 ID 标识。 DomainParticipant 定义域 ID 以指定它所属的 DDS 域。具有不同 ID 的两个 DomainParticipants 不知道彼此在网络中的存在。因此,可以创建多个通信通道。这适用于涉及多个DDS应用程序的场景,它们各自的 DomainParticipants 相互通信,但这些应用程序不得干扰。 DomainParticipant 充当其他 DCPS 实体的容器,充当发布者、订阅者和主题实体的工厂,并在域中提供管理服务。

DDS 是一种通过信息,而 DCPS 是一个抽象的模型概念,实际上映射到具体的代码维度,则需要 DomainParticipants 作为容器去承载 Publisher、Subsriber、Topic 等等。

可以这样理解:

  1. Domain 是项目组
  2. Topic 是项目生产过程各类相关产出物,如需求文档、概要设计、产品方案、测试用例等
  3. DomainParticipant 代表项目中不同的参与组织如UI小组、产品小组、开发小组、测试小组等等
  4. Publisher 和 Subscriber 代表不同小组中对外输出文档和接受信息的窗口角色
  5. QoS 代表不同的文档在各个小组流转时,双方对于文件传输状态的质量要求

在这里插入图片描述

最后说明一下,如何理解 QoS 呢?

你可以联想到,假如你是写代码的,产品经理传递文件给你时的方法和需要你反馈的时效,以及测试人员传递文档给你要求的时效是不一样的。

当然,这里只是类比,为了帮助大家加深理解,真正的 DDS 不一定这样。

4. 什么是 RTPS ?

RTPS 是 Real-Time Publish Subscribe 的缩写,它是 DDS 的通信中间件,是发布-订阅模式,通信能力强大,支持 UDP/IP、TCP 及共享内存。

RTPS 是 DDS 通信的根基,它内部有一样重要的概念:

  • Domain
  • RTPSParticipant
  • Topic
  • Attributes
  • Change
  • History
  • RTPSWriter
  • RTPSReader

RTPS 中定义了一个 Domain 的概念,它定义了一个单独的通信平面。几个域可以同时独立地共存。一个域包含任意数量的 RTPSParticipant,即能够发送和接收数据的元素。

RTPSParticipants 使用 EndPoint 进行通信:

  • RTPSWriter:能够发送数据的 EndPoint 端点。
  • RTPSReader:能够接收数据的 EndPoint 端点。

RTPSParticipant 可以有任意数量的写入器和读取器端点。

在这里插入图片描述

Topic 定义和标记正在交换的数据。主题不属于特定 DomainParticipant。DomainParticipant 通过 RTPSWriters 对 Topic 发布的数据进行更改,并通过 RTPSReaders 接收与其订阅的 Topic 相关的数据。

在 Fast DDS 中最基础的通信单元称为 Change,它表示在 Topic 下写入的数据的更新。 RTPSReaders/RTPSWriters 在其 History 中注册这些 Change,History 是一种用作最近更改缓存的数据结构。

在 eProsima Fast DDS 的默认配置中,当您通过 RTPSWriter 端点发布更改时,会在后台执行以下步骤:

  1. Change 将添加到 RTPSWriter 的 History 中。
  2. RTPSWriter 将 Change 发送到它知道的任何 RTPSReaders。
  3. 接收到数据后,RTPSReaders 用新的 Change 更新他们的 History。

Fast DDS 支持多种配置,允许更改 RTPSWriters/RTPSReaders 的行为。修改 RTPS 实体的默认配置意味着 RTPSWriters 和 RTPSReaders 之间的数据交换流发生变化。此外,通过选择服务质量 (QoS) 策略,您可以通过多种方式影响这些历史缓存的管理方式,但通信循环保持不变。

5. Fast DDS 和 RTPS 关系?

前文说过 RTPS 是 DDS 的基础,实际上完整的 Fast DDS 架构分为 4 层:

  • Application Layer
  • FAST DDS Layer
  • RTPS Layer
  • Tranport Layer

在这里插入图片描述

Application 指的是采用 Fast DDS API 的各类应用。

DDS Layer 主要定义一个系统中不同的 Domain,在同一个 Domain 下 Topic 按规则通信。

Fast RTPS 是通信协调层,是下层 Transport 的抽象。

Transport 层处理底层 UDP、TCP、SHM(共享内存)。

6. 一个简单的 Fast DDS 示例

要使用 Fast DDS 首先需要安装它,有 bin、Source、docker image 3 种方式,但 bin 和 docker image 需要到官网预留个人信息才能下载,所以,我们可以考虑源码下载。

要下载 3 份源码:

  • vendor
  • fast cdr
  • fast dds

我选择的是在 ubuntu 下用 cmake 方式编译。

可以参考这个地址:DDS安装

当然,还要下载编译 Fast DDS Gen,它是一个工具,能够将 IDL 文件转换成 C++ 代码。

现在考虑写一个最基础的 DDS 应用。

我们首先需要知道一个最小的 DDS 应该包含什么。

  • 消息.IDL
  • 数据发布器对应的.cpp
  • 数据接收器对应的.cpp
  • CMakeLists.txt

消息数据通过 IDL 文件定义。

IDL 功能很强大,定义了基础数据类型、数组、窗器、map、枚举、注解等等。[3]

fastddsgen 可以将其转换成 c++ 数据结构体。

在这里插入图片描述

通过 fastddsgen 可以转换成 C++ 类。

在这里插入图片描述

现在我们可以编写一个简单的 IDL

在这里插入图片描述

然后可以通过 fastddsgen 快速生成代码。

在这里插入图片描述

最终会自动产生好几个代码文件。

在这里插入图片描述

FrankTestDDS.idl 被转换成 FrankTestDDS.cxx 和它应对的 .h 文件。

其它的 FrankTestDDSPubSubMain 之类是 fastddsgen 自动生成的,用于实现发布和订阅演示代码。

我们先观察 CMakeLists.txt。

在这里插入图片描述

我们可以发现,整个工程依赖于 fastcdr 和 fastrtps 两个库,之后,代表消息数据经 idl 转换后的 FrankTestDDS.cxx 被编译成库的形式。

这样后面编译的 FrankTestDDS 这个可执行文件就可以链接消息库,保证了应用代码和消息的解耦。 现在我要试验 FastDDS 的发布-订阅功能。我在生成的 FrankTestDDSPublisher.cxx 中添加了一些代码。

在这里插入图片描述

st 是我们的消息体,我将其中的 msg 赋值。

同时,我还得修改 FrankTestSubscriber.cxx 的代码。

在这里插入图片描述

现在,我们可以编译代码并尝试运行了。

mkdir build
cd build
cmake ..
make

然后,分别在两个终端中运行 publisher 和 subscriber

./FrankTestDDS publisher
./FrankTestDDS subscriber

在这里插入图片描述

我们可以看到,通信正常,这也说明我们可以开始通过 fast dds 干活了。

至于高阶内容,需要结合业务实际需求了,比如大量传输摄像头图片、点云数据、控制命令等等。我们得处理好相应的数据结构转换和 QOS 定义。这个在本文中就不展开了。

参考
https://www.dds-foundation.org/what-is-dds-3/
https://fast-dds.docs.eprosima.com/en/latest/fastdds/getting_started/definitions.html
https://www.omg.org/spec/IDL/4.2/PDF

 


来源:https://blog.csdn.net/briblue/article/details/124081170

                              ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

推荐阅读

【1】jetson nano开发使用的基础详细分享

【2】Linux开发coredump文件分析实战分享

【3】CPU中的程序是怎么运行起来的 必读

【4】cartographer环境建立以及建图测试

【5】设计模式之简单工厂模式、工厂模式、抽象工厂模式的对比

本公众号全部原创干货已整理成一个目录,回复[ 资源 ]即可获得。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通信中间件 Fast DDS 基础概念简述与通信示例 的相关文章

  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 进程名称长度的最大允许限制是多少?

    进程名称允许的最大长度是多少 我正在读取进程名称 proc pid stat文件 我想知道我需要的最大缓冲区 我很确定有一个可配置的限制 但就是找不到它在哪里 根据man 2 prctl http man7 org linux man pa
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • touch命令在一个目录下创建多个文件(不同名称)

    我想制作一个在 bash 中创建目录和文件结构的脚本 我尝试过这样的事情 mkdir p 1 2 touch 1 2 a b c a b c 应该是在一个命令或其他命令中创建的文件 但由于某种原因 结构是这样的 current folder
  • 如何使用AWK脚本检查表的所有列数据类型? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在这里 我正在检查表中第一列的数据类型 但我想知道AWK中表的所有列数据类型 我尝试过 但只能获得一列数据类型 例如 Column 1
  • 停止服务时单元陷入故障状态(状态=143)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的问题 我有 CentOS 和 java 进程在上面运行 Java进程是通过启动 停止脚本来操作的 它也创建了 java 实例的 p
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • 每个进程每个线程的时间量

    我有一个关于 Windows 和 Linux 中进程和线程的时间量子的问题 我知道操作系统通常为每个线程提供固定的时间量 我知道时间量根据前台或后台线程而变化 也可能根据进程的优先级而变化 每个进程有固定的时间量吗 例如 如果操作系统为每个
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • 无需 cron 在后台发送邮件

    我想知道是否有一种方法可以运行 PHP 循环 以便在后台向订阅者发送几百封电子邮件 我的目标是格式化新闻通讯 单击发送 然后关闭浏览器或更改页面 当然 发送电子邮件的实际过程将在后台运行 不会因浏览器关闭而中断 我知道这可以通过 cron
  • Linux shell 脚本中的 while 循环超时

    这工作正常 无限循环 while TRUE do printf done 我在尝试着timeout this while loop与timeout命令 所有这些都不起作用 timeout 5 while TRUE do printf don
  • 让 MongoDB 在 Linux 上监听远程连接

    我已在 Windows 本地计算机上 上成功安装 MongoDB 作为服务 但现在我想将 MongoDb 移动到单独的服务器 所以我将 tarball 解压到网络上的虚拟服务器 运行 Linux 当我从本地计算机使用 PuTTY 连接到服务
  • 归档文件系统或格式

    我正在寻找一种文件类型来存储已退役系统的档案 目前 我们主要使用 tar gz 但从 200GB tar gz 存档中查找并提取几个文件是很麻烦的 因为 tar gz 不支持任何类型的随机访问读取规定 在你明白之前 使用 FUSE 安装 t
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • diff 文件仅比较每行的前 n 个字符

    我有2个文件 我们将它们称为 md5s1 txt 和 md5s2 txt 两者都包含a的输出 find type f print0 xargs 0 md5sum sort gt md5s txt 不同目录下的命令 许多文件被重命名 但内容保
  • 在 Linux 上的 Python 中使用受密码保护的 Excel 工作表

    问题很简单 我每周都会收到一堆受密码保护的 Excel 文件 我必须解析它们并使用 Python 将某些部分写入新文件 我得到了文件的密码 当在 Windows 上完成此操作时 处理起来很简单 我只需导入 win32com 并使用 clie
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte

随机推荐

  • COCO数据集解析生成语义分割mask

    COCO数据集解析生成语义分割mask 通过coco数据集的标注文件 instances train2014 json instances val2014 json 生成语义分割mask存在不同类别区域重叠问题 导致重叠部分像素的数值超出
  • linux的PAM认证和shadow文件中密码的加密方式

    它是一种统一的认证方案 PAM 让您能随时改变您的认证方法以及需求 并且不需要重新编译任何代码就封装了所有本地认证方法 具体见 PAM 网站 对于 PAM 您只需要做 对您的密码采用不同于 DES 的加密方式 让它们面对暴力解码 brute
  • “自顶向下,逐步求精“的方法简介

    自顶向下 逐步求精 的方法思路代表了生活中大多数事情的处理方法 它的奥妙之处在于将繁杂棘手的事务进行分解 逐部列条 化为最简易单调的子任务然后进行求解 如图即是一个很典型的逐步分解的问题模型 对于一件既定的事务 先进行总体性的了解即定出整个
  • halcon 中 select_shape 算子 相关特征参数

    求Region指定特征值 region features Regions Features Value 根据特征值选择区域 select shape Regions SelectedRegions Features Operation Mi
  • 安卓初学——界面按钮响应

    安卓学习 采用onClickListener监听器 界面按钮响应 一 定义监听 绑定组件 二 通过匿名内部类 把组件和事件绑定 三 采用view 对象调用onClick 四 在当前Activity实现监听接口 一 定义监听 绑定组件 自定义
  • VMware安装后打开就蓝屏

    VMware虚拟机开机蓝屏 追风 80 人赞同了该文章 目录 收起 一 查看主板上的虚拟化技术支持是否开启 二 开启虚拟机平台 如果在新建的虚拟机安装好后一点开机出现蓝屏 反复重装并且确定了新建虚拟机没有出错的情况下考虑是否是虚拟化没有开启
  • MobaXterm的下载安装

    下载地址 MobaXterm Xserver with SSH telnet RDP VNC and X11 Home Edition 进入页面后 点击绿色的方框下载 下载后得到一个压缩包 解压后可以看到有两个文件 点击 msi进行安装 选
  • Json Object转Model, Model、DataTable转Json Object (Jayrock技巧)

    本文假定读者有一定的Ext 控件的使用经验 看过Ext EditGridPanel实现效果的朋友会很惊讶 一个Grid就能实现所有增删改查功能 在展示给客户看时 让你的表现得很风骚 而他们又怎么知道 我们在调试js时 是多么痛苦 如何在js
  • PyTorch基础练习-task5(PyTorch实现L1,L2正则化以及Dropout)

    PyTorch基础练习 task5 一 Dropout原理 二 用代码实现正则化 L1和L2 2 1 L1实现 2 2 L2实现 三 PyTorch中实现dropout 一 Dropout原理 在前向传播的时候 让某个神经元的激活值以一定的
  • android edittext 输入完成监听,EditText输入监听

    EditText输入监听 原创 6710766562015 05 13 13 34 38著作权 文章分类 android开发 阅读数 548 著作权归作者所有 来自51CTO博客作者671076656的原创作品 如需转载 请注明出处 否则将
  • 关于idea 生成war 包放入tomcat的路径访问问题

    目录 1 打包成war 2 关于war 和war exploded 3 在idea中使用tomcat启动 4 把war包放在指定的tomcat下启动 1 打包成war 点击右上角project structure或者左上角File proj
  • leetcode刷题(不邻接植花、电话号码的字母组合、统计共同度过的日子数、节点与其祖先之间的最大差值、分隔数组以得到最大和、二进制求和、x的平方根、最小偶倍数)

    目录 1 不邻接植花 2 电话号码的字母组合 3 统计共同度过的日子数 4 节点与其祖先之间的最大差值 5 分隔数组以得到最大和 6 二进制求和 7 x的平方根 8 最小偶倍数 1 不邻接植花 2 电话号码的字母组合 class Solut
  • LeetCode——二叉树

    二叉树 二叉树概念和性质 104 二叉树的的最大深度 递归 98 验证二叉搜索树 中序遍历 101 对称二叉树 代码比较精巧 不好理解 102 二叉树的层序遍历 中等 参考题解 自己码的代码 108 将有序数组转换为二叉搜索树 递归 剑指
  • 如何写好Java程序呢

    如何写出更好的Java代码 05 22 2014 Java是最流行的编程语言之一 但似乎并没有人喜欢使用它 好吧 实际上Java是一门还不错的编程语言 由于最近Java 8发布了 我决定来编辑一个如何能更好地使用Java的列表 这里面包括一
  • windows基本命令 --快速打开文件夹

    通过 cmd 命令行进入指定目录后如果想查看该目录下的文件需要输入 dir 命令 很不方便 我们可以在 cmd 下打开文件夹图形界面 explorer path 例子 1 打开当前目录 explorer 2 打开上级目录 explorer
  • RocketMQ占用内存过大的解决方法

    目录 一 问题描述 二 解决方法 1 runserver sh 修改 2 runbroker sh 修改 一 问题描述 RocketMQ 启动后 一下子把内存撑爆了 二 解决方法 修改启动参数 分别对 bin 目录下的 runserver
  • jenkins拉取项目提示 ‘parent.relativePath‘ points at wrong local POM

    环境说明 为一台无法连接外网的linux服务器 问题描述 安装了jenkins拉取项目 提示ERROR Failed to parse POMs org apache maven project ProjectBuildingExcepti
  • 【C++】卡常技巧

    1 若乘上一个2的倍数的数值 可改用左移运算符 例1 x x 2 或 x 2 改成 x x lt lt 1 或 x lt lt 1 log22 1 例2 x x 32 或 x 32 改成 x x lt lt 5 或 x lt lt 5 lo
  • 3DMAX渲染完卡住不动该怎么办?

    有很多种原因都可能会导致3DMAX卡死 需要一个一个排查 1 3DMAX和系统语言不兼容 可以把电脑语音设置兼容点上 2 3dmax内存分配不足 把动态内存限制设置到1W以上或是直接设置为0 无限制 3 软件运行错误 可以尝试重置下vray
  • 通信中间件 Fast DDS 基础概念简述与通信示例

    从事汽车软件开发 通信中间件绕不开 当前最火热的无非有 2 种 Some IP 和 DDS DDS 是一种分布式通信标准 有很多商业和开源的实现 Fast DDS 是其中的一种 它在 ROS2 中被应用 而 Apollo 中的 CyberR