Fast DDS 深入理解,吐血整理

1 介绍

1.1 DDS 概述

数据分发服务DDS(DataDistributionService)是OMG对象管理组织在HLA及CORBA等标准的基础上制定的新一代分布式实时通信中间件技术规范,DDS采用发布/订阅体系架构,强调以数据为中心,提供丰富的QoS服务质量策略,能保障数据进行实时、高效、灵活地分发,可满足各种分布式实时通信应用需求。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 通信分类

域与域通信

在这里插入图片描述

跨网络通信

在这里插入图片描述

2 要素

IDL(Interface Definition Language)

要声明结构化数据,必须使用 IDL 格式。IDL (接口定义语言)是一种规范语言,由OMG(对象管理组织)制定,它以与语言无关的方式描述接口,允许不同语言的软件组件之间进行通信。

IDL的全称是Interface Definition Language,即接口定义语言(有时也叫作接口描述语言)。因为RPC通常是跨进程、跨机器、跨系统和跨语言的,IDL是用来解决这个问题的,它与语言无关,借助编译器将它翻译成不同的编程语言。
Google开源的ProtoBuf中的“.proto”文件就是一种IDL文件。

IDL部分很多会用到 flex & bison。

  • protobuf 中底层有用flex & bison
  • opensplice DDS中底层有用flex & bison
  • RTI DDS中底层有用flex & bison
  • Fast DDS中底层有用flex & bison

在这里插入图片描述

详细介绍

OMG–IDL(Interface Definition Language)

拓展

序列化与反序列化深入理解
数据传输中,双方交互都需要对数据进行序列化和反序列化。也称为编码和解码。

RTPS

如下介绍,OMG组织定义的RTPS(Real Time Publish Subscribe Protocol),实时发布订阅协议。
Version: 2.5
OMG Document Number: formal/2022-04-01
Standard document URL: https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
在这里插入图片描述

缩写 含义 备注
CDR Common Data Representation 通用数据表示
DDS Data Distribution Service 数据分发服务
EDP Endpoint Discovery Protocol 端点发现协议
GUID Globally Unique Indentifier 全局唯一标识符
PDP Participant DiscoveryProtocol 参与者发现协议
PIM Platform Independent Model 平台独立模型
PSM Platform Specific Model 平台专用模型
RTPS Real-Time Publish-Subscribe 实时发布订阅
SEDP Simple Endpoint Discovery Protocol 简单端点发现协议
WLP Write Liveliness Protocol 写入者活跃性协议

详细介绍

OMG–RTPS(Real Time Publish Subscribe Protocol)

详细介绍–Discovery Module(发现模块)

发现协议的目的是允许每个 RTPS 参与者发现其他相关参与者及其端点。 一旦远程端点已经发现,实现可以相应地配置本地端点以建立通信。
DDS 规范同样依赖于使用发现机制来建立通信匹配的 DataWriters 和 DataReaders。 DDS 实现必须自动发现远程实体,无论是在他们加入和离开网络时。
RTPS 规范将发现协议拆分为两个独立的协议:(大型网络的基本发现协议。)

  • Participant Discovery Protocol(PDP)【参与者发现协议】
  • Endpoint Discovery Protocol(EDP)【端点发现协议】

为了互操作性,所有 RTPS 实现必须至少提供以下发现协议:(中小型网络的基本发现协议。)

  • Simple Participant Discovery Protocol (SPDP)
  • Simple Endpoint Discovery Protocol (SEDP)

每个RTPS StatelessWriter关联RTPS ReaderLocator对象。
每个RTPS StatefulWriter关联RTPS ReaderProxy对象。
每个RTPS StatefulReader关联RTPS WriterProxy对象。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

DDS(DataDistributionService)数据分发服务

DDS(DataDistributionService)是OMG对象管理组织在HLA及CORBA等标准的基础上制定的新一代分布式实时通信中间件技术规范,DDS采用发布/订阅体系架构,强调以数据为中心,提供丰富的QoS服务质量策略,能保障数据进行实时、高效、灵活地分发,可满足各种分布式实时通信应用需求。DDS信息分发中间件是一种轻便的、能够提供实时信息传送的中间件技术。

以数据为中心的模型,虚拟出全局数据空间的概念,各节点向该空间声明发布者或者订阅者的意图;
在这里插入图片描述

域(Domain):

这是用于链接所有发布者和订阅者的概念,属于一个或多个应用程序,它们在不同主题下交换数据。这些参与域的单个应用程序称为DomainParticipant。DDS域由域ID标识。DomainParticipant定义Domain ID以指定它所属的DDS域。具有不同ID的两个DomainParticipants不知道彼此在网络中的存在。因此,可以创建多个通信通道。这适用于涉及多个DDS应用程序的场景,它们各自的DomainParticipants相互通信,但这些应用程序不得干扰。DomainParticipant充当其他 DCPS实体的容器,充当发布者、订阅者和主题实体的工厂,并在域中提供管理服务。

主题(Topic):

它是将发布者的DataWriters与订阅者的DataReaders绑定的实体,在DDS域中是唯一的。它可在进程之间交换的数据的消息,数据表示为可以包含不同数据类型的结构,如整数,字符串等;

数据写入器(Data Writer):

它是负责发布消息的实体,用户在创建此实体时必须提供一个主题,该主题将是发布数据的主题;

数据读取器(Data Reader):

它是订阅主题以接收发布的实体,用户在创建此实体时必须提供订阅主题;

发布者(Publisher):

它是负责创建和配置其实现的DataWriters的DCPS实体。DataWriter是负责实际发布消息的实体。每个人都有一个分配的主题,在该主题下发布消息;

订阅者(Subscriber):

它是 DCPS实体,负责接收在其订阅的主题下发布的数据。它为一个或多个DataReader对象提供服务,这些对象负责将新数据的可用性传达给应用程序;

3 组件

eProsima Fast DDS-Gen

eProsima Fast DDS-Gen是一个 Java 应用程序,它使用 IDL(接口定义语言)文件中定义的数据类型生成eProsima Fast DDS源代码。
eProsima Fast DDS-Gen生成的源代码使用Fast CDR,这是一个提供数据序列化和编码机制的 C++11 库。因此,正如RTPS 标准中所述,发送数据时,它们会使用相应的通用数据表示 (CDR) 进行序列化和编码。CDR 传输语法是代理间传输的低级表示,从 OMG IDL 数据类型映射到字节流。

foonathan_memory_vendor

an STL compatible C++ memory allocator library.

fastcdr

a C++ library for data serialization according to the CDR standard (Section 10.2.1.2 OMG CDR).

fastrtps

the core library of eProsima Fast DDS library.

4 架构

DDS模型架构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主要功能类

在这里插入图片描述

Domain类图

在这里插入图片描述

Publisher类图

在这里插入图片描述

Subscriber类图

在这里插入图片描述

Topic类图

在这里插入图片描述

5 示例介绍

FastDDS 示例介绍

helloworld.idl

struct HelloWorld
{
    
    
    unsigned long index;
    string message;
};

在FastDDS中,unsigned long是一种无符号整数类型,通常用于表示非负整数。在DDS中,unsigned long常用于表示时间戳、状态代码等数值。

fastddsgen 生成文件

HelloWorld
├── CMakeLists.txt
├── HelloWorld.cxx		// 由 idl 生成, HelloWorld 类型定义
├── HelloWorld.h
├── HelloWorld.idl		// idl 文件, payload
├── HelloWorld_main.cpp
├── HelloWorldPublisher.cpp		// 发布服务器
├── HelloWorldPublisher.h
├── HelloWorldPubSubTypes.cxx	// 由 idl 生成, 序列化和反序列化代码
├── HelloWorldPubSubTypes.h
├── HelloWorldSubscriber.cpp	// 订阅服务器
└── HelloWorldSubscriber.h

序列化,反序列化

在这里插入图片描述

HelloWorld.h、HelloWorld.cxx 【类型定义,序列化反序列化(CDR<->Data)】

在这里插入图片描述

序列化反序列化,消息类型都必须继承自 eprosima::fastcdr::Cdr 类。

// 使用 CDR 将 HelloWorld 结构体序列化为二进制数据
void HelloWorld::serialize(
        eprosima::fastcdr::Cdr& scdr) const
{
    
    

    scdr << m_index;
    scdr << m_message.c_str();

}
// 使用 CDR 将二进制数据反序列化为 HelloWorld 结构体
void HelloWorld::deserialize(
        eprosima::fastcdr::Cdr& dcdr)
{
    
    

    dcdr >> m_index;
    dcdr >> m_message;
}

helloworldPubSubTypes.h & helloworldPubSubTypes.cxx 【序列化反序列化 (buffer<->CDR<->Data)】

在这里插入图片描述

helloworldPublisher.h & helloworldPublisher.cxx

在这里插入图片描述

eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Publisher* publisher_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataWriter* writer_;
eprosima::fastdds::dds::TypeSupport type_;
  • DomainParticipant:充当所有其他实体对象的容器,并充当发布者、订阅者和主题对象的工厂。
  • Publisher:是负责创建 DataWriter的对象。
  • DataWriter:允许应用程序设置要在给定主题下发布的数据的值。
  • TypeSupport:为participant提供序列化、反序列化和获取特定数据类型的key的函数。

helloworldSubscriber.h & helloworldSubscriber.cxx

在这里插入图片描述

eprosima::fastdds::dds::DomainParticipant* participant_;
eprosima::fastdds::dds::Subscriber* subscriber_;
eprosima::fastdds::dds::Topic* topic_;
eprosima::fastdds::dds::DataReader* reader_;
eprosima::fastdds::dds::TypeSupport type_;
  • DomainParticipant:充当所有其他实体对象的容器,并充当发布者、订阅者和主题对象的工厂。
  • Subscriber:是负责创建 DataReader 的对象。
  • DataReader:它是负责实际接收数据的对象。
  • TypeSupport:为participant提供序列化、反序列化和获取特定数据类型的key的函数。

发布消息步骤:

  1. 创建要发布数据的 idl ,并通过 fast-gen 生成对应的数据结构,并生成该数据结构序列化的类
  2. 通过 DomainParticipantFactory 创建 participant ,参数为 domain id 和 qos
  3. 将 participant 注册到 type ,该类型提供 helloworld 的序列化支持
  4. 通过 participant 创建 publisher ,用于发布数据
  5. PubListener 继承于 DataWriterListener ,用于给发布者注册消息通知函数。DDS 通过服务发现,将消息最终给到应用
  6. publisher 创建 writer ,用于最终的消息发布

在线安装 & 调试

机器人开发–Fast DDS

源码编译 & 调试

FastDDS 编译(x86、arm)

零拷贝问题

机器人开发–DDS数据分发服务

参考

1、机器人开发–Fast DDS
2、OMG–IDL(Interface Definition Language)
3、FastDDS 示例介绍
4、FastDDS 编译(x86、arm)
5、序列化与反序列化深入理解
6、OMG–RTPS(Real Time Publish Subscribe Protocol)
7、机器人开发–DDS数据分发服务
8、OMG–DDS(Data Distribution Service)

猜你喜欢

转载自blog.csdn.net/qq_38880380/article/details/135131544
dds
今日推荐