eProsima Fast DDS getting started

系列文章目录



preface

fast dds官方文档缺乏对DDS整体的介绍,一上来就介绍各种细节,DDS的整体设计意图和用法隐匿与各种细节中,很容易让人一头雾水,不知其所云。该文章对DDS有一个整体的介绍,方便快速了解其概念。

https://www.eprosima.com/docs/fast-rtps/1.9.3/html/index.html

DDS全称是Data Distribution Service,这是一套通信协议和API标准,它提供了以数据为中心的连接服务,基于发布者-订阅者模型。这是一套中间件,它提供介于操作系统和应用程序之间的功能,使得组件之间可以互相通信。并且提供了低延迟,高可靠的通信以及可扩展的架构。

DDS本身是一套标准。由Object Management Group(简称OMG)维护。

OMG是一个开放性的非营利技术标准联盟,由许多大型IT公司组成:包括IBM,Apple Computer,Sun Microsystems等。

但OMG仅仅负责制定标准,而标准的实现则由其他服务提供商完成。

目前DDS的提供商包括下面这些:

  • Vortex OpenSplice
  • eProsima Fast RTPS
  • Hamersham
  • Company Summary Kongsberg Gallium
  • MilSOFT
  • Object Computing OpenDDS
  • Remedy IT
  • RTI
  • Twin Oaks Computing, Inc.

DDS与RTPS
在DDS规范中,有两个描述标准的基本文档:

  • DDS Specification:描述了以数据为中心的发布-订阅模型。该规范定义了API和通信语义(行为和服务质量),使消息从消息生产者有效地传递到匹配的消费者。DDS规范的目的可以概括为:“能够在正确的时间将正确的信息高效,可靠地传递到正确的位置”。
  • DDSI-RTPS:描述了RTPS(Real Time Publish Subscribe Protocol)协议。该协议通过UDP等不可靠的传输,实现最大努力(Best-Effort)和可靠的发布-订阅通信。RTPS是DDS实现的标准协议,它的目的和范围是确保基于不同DDS供应商的应用程序可以实现互操作。

在这里插入图片描述

Fast-RTPS 介绍
Fast-RTPS是eprosima对于RTPS的C++实现,这是一个免费开源软件,遵循Apache License 2.0。

eProsima Fast RTPS在性能,功能和对最新版本RTPS标准(RTPS 2.2)的遵守方面均处于领先地位。

Fast-RTPS具有以下优点:

  • 对于实时应用程序来说,可以在Best-Effort和可靠通信两种策略上进行配置。
  • 即插即用的连接性,使得网络的所有成员自动发现其他新的成员。
  • 模块化和可扩展性允许网络中设备不断增长。
  • 可配置的网络行为和可互换的传输层:为每个部署选择最佳协议和系统输入/输出通道组合。
  • 两个API层:一个简单易用的发布者-订阅者层和一个提供对RTPS协议内部更好控制的Writer-Reader层。

Fast-RTPS提供了两个层次的API:

  • Publisher-Subscriber层:RTPS上的简化抽象。
  • Writer-Reader层:对于RTPS端点的直接控制。
    在这里插入图片描述

对象与数据结构

下面是Fast-RTPS实现中的核心结构。

● Publish-Subscriber模块

RTPS标准的高层类型。

  • Domain:用来创建,管理和销毁Participants。
  • Participant:包括Publisher和Subscriber,并管理它们的配置。
    • ParticipantAttributes:创建Participant的配置参数。
    • ParticipantListener:可以让开发者实现Participant的回调函数。
  • Publisher:在Topic上发布数据的对象。
    • PublisherAttributes:创建Publisher的配置参数。
    • PublisherListener:可以让开发者实现Publisher的回调函数。
  • Subscriber:在Topic上接受数据的对象。
    • SubscriberAttributes:创建Subscriber的配置参数。
    • SubscriberListener:可以让开发者实现Subscriber的回调函数。

● RTPS模块

RTPS的底层模型。包含下面几个子模块:

  • RTPS Common
    • CacheChange_t:描述Topic上的变更,存储在历史Cache中。
    • Data:Cache变化的负载。
    • Message:RTPS消息。
    • Header:RTPS协议的头信息。
    • Sub-Message Header:标识RTPS的订阅消息。
    • MessageReceiver:反序列化和处理接受到的RTPS消息。
    • RTPSMessageCreator:构建RTPS消息。
  • RTPS Domain
    • RTPSDomain:用来创建,管理和销毁底层的RTPSParticipants。
    • RTPSParticipant:包括Writer和Reader。
  • RTPS Reader
    • RTPSReader:读者的基类。
    • ReaderAttributes:包含RTPS读者的配置参数。
    • ReaderHistory:存储Topic变化的历史数据。
    • ReaderListener:读者的回调类型。
  • RTPS Writer
    • RTPSWriter:写者的基类。
    • WriterAttributes:包含RTPS写者的配置参数。
    • WriterHistory:存储写者的历史数据。

配置Attributes

上面的数据结构中看到了许多Attributes后缀的类名。这些类包含了对协议或者对象的配置参数,很多特性都需要设置这些属性来完成。
这些类的定义基本都位于下面三个文件夹中:
https://github.com/eProsima/Fast-DDS

  • include/fastrtps/attributes
  • include/fastrtps/rtps/attributes
  • include/fastdds/rtps/attributes

Fast RTPS支持非常多的配置参数,并且参数的结构常常是嵌套的。

通过代码去配置这些参数会产生很多啰嗦的代码,而且最大的问题在于:每次更改配置参数都需要重新编译。这个问题并非Fast RTPS才有,只要包含大量配置参数的软件都会这样的问题。通常的解决方法就是:提供文本格式的配置文件的方式来配置参数。因此对于Fast-RTPS来说,除了支持通过代码配置参数,它也支持通过XML文件的方式来进行配置。
Fast-RTPS支持的配置项,以及这些配置项说明和默认值都可以到这个链接中查看:XML profiles

Discovery

作为DDS的实现,Fast-RTPS提供了Publisher和Subscriber自动发现和匹配的功能。在实现上,这分为两个步骤来完成:

  • Participant Discovery Phase (PDP):在这个阶段,参与者互相通知彼此的存在。为了达到这个目的,每个参与者需要定时发送公告消息。公告消息通过约定的多播地址和端口发送(根据domain计算得到)。
  • Endpoint Discovery Phase (EDP):在这个阶段,Publisher和Subscriber互相确认。为此,参与者使用在PDP期间建立的通信通道,彼此共享有关其发布者和订阅者的信息。 该信息包含了Topic和数据类型。为了使两个端点匹配,它们的Topic和数据类型必须一致。 一旦发布者和订阅者匹配,他们就发送/接收数据了。

这两个阶段对应了两个独立的协议:

  • Simple Participant Discovery Protocol:指定参与者如何在网络中发现彼此。
  • Simple Endpoint Discovery Protocol:定义了已经互相发现的参与者交换信息的协议。

Fast-RTPS提供了四种发现机制:

  1. Simple:这是默认机制。它在PDP和EDP阶段均使用RTPS标准,因此可与任何其他DDS和RTPS实现兼容。
  2. Static:此机制在PDP阶段使用Simple Participant Discovery Protocol。如果所有发布者和订阅者的地址以及端口和主题信息是事先知道的,则允许跳过EDP阶段。
  3. Discovery Server: 这种发现机制使用集中式发现结构,由服务器充当发现机制的Hub。
  4. Manual:此机制仅与RTPSDomain层兼容。它禁用了PDP阶段,使用户可以使用其选择的任何外部元信息通道手动匹配和取消匹配RTPS参与者,读者和写者。

不同的发现机制具有一些共同的配置:

名称 描述 默认值
Ignore Participant flags 在必要的时候,可以选择忽略一些参与者。
例如:另一台主机上的,另一个进程的或者同一个进程的。 NO_FILTER
Lease Duration 指定远程参与者在多少时间内认为本地参与者还活着。 20s
Announcement Period 指定参与者的PDP公告消息的周期。 3s

more details: https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/discovery.html

传输控制

ast-RTPS实现了可插拔的传输架构,这意味着每一个参与者可以随时加入和退出。

在传输上,Fast-RTPS支持以下五种传输方式:
UDPv4
UDPv6
TCPv4
TCPv6
SHM(Shared Memory
默认的,当Participant创建时,会自动的配置两个传输通道:
SHM:用来与同一个机器上的参与者通信。
UDPv4:同来与跨机器的参与者通信。

开发者可以改变这个默认行为,通过C++接口或者XML配置文件都可以。

SHM要求所有参与者位于同一个系统上,它是借助了操作系统提供的共享内存机制实现。共享内存的好处是:支持大数据传输,减少了数据拷贝,并且也减少系统负载。因此通常情况下,使用SHM会获得更好的性能。使用SHM时,可以配置共享内存的大小。

网络通信包含了非常多的参数需要配置,例如:Buffer大小,端口号,超时时间等等。框架本身为参数设置了默认值,大部分情况下开发者不用调整它们。但是知道这些默认值是什么,在一些情况下可能会对分析问题有所帮助。

与UDP不同,TCP传输是面向连接的,因此,Fast-RTPS必须在发送RTPS消息之前建立TCP连接。TCP传输可以具有两种行为:充当TCP服务器或充当TCP客户端。服务器打开一个TCP端口以侦听传入的连接,然后客户端尝试连接到服务器。服务器和客户端的概念独立于RTPS概念,例如:Publisher,Subscriber,Reader或Writer。它们中的任何一个都可以用作TCP服务器或TCP客户端,因为这些实体仅用于建立TCP连接,而RTPS协议可以在该TCP连接上工作。

如果要使用TCP传输,开发者需要做更多的配置。



前言

eProsima Fast DDS是DDS规范的C++实现,DDS是由OMG定义的一种协议。eProsima Fast DDS 库提供应用程序编程接口 (API) 和通信协议 部署 以数据为中心的发布者-订阅者 (DCPS) 模型,旨在建立高效可靠的信息在实时系统之间分配。eProsima Fast DDS 在资源处理方面具有可预测性、可扩展性、灵活性和高效性。 为了满足这些要求,它利用了类型化接口和多对多的铰链 分布式网络范式,巧妙地允许将通信的发布者和订阅者端分开。eProsima Fast DDS 包括:

  1. DDS API实现
  2. Fast DDS-Gen,一种用于桥接类型化接口与中间件的生成工具 实现
  3. 底层RTPS有限协议实现

DDS采用的通信模式是多对多的单向数据交换,其中应用 生成数据,将其发布到属于使用数据的应用程序的订阅者的本地缓存。 信息流由QOS策略管理,QOS由交换数据的实体建立。DDS通讯只能发生在DDS Domain内,不能夸Domain。
在这里插入图片描述
RTPS Wire Protocol
在传输层之上的协议,传输层可以是TCP/UDP/IP


0、安装

https://www.eprosima.com/index.php/downloads-all

https://fast-dds.docs.eprosima.com/en/latest/index.html

cmake安装相关

做用 用法 备注
CMAKE_INSTALL_PREFIX 指定make intall安装路径 cmake … -DCMAKE_INSTALL_PREFIX=<path/to/install>
CMAKE_C_COMPILER 指定C编译器 set(CMAKE_C_COMPILER </path/gcc> 在project之前
CMAKE_CXX_COMPILER 指定C++编译器 set(CMAKE_CXX_COMPILER </path/g++> 在project之前
指定全局编译选项 add_compile_options(-O2 -g)

include

源码安装:

  • A foonathan_memory_vendor, an STL compatible C++ memory allocator library.
  • B fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.
  • C fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.
  • D tinyxml2
  • E asio
  • F openssl
  • G fastrtps, the core library of eProsima Fast DDS library.

最终目标是安装:https://github.com/eProsima/Fast-DDS
在thirdparty目录下也有第三方依赖

- A foonathan_memory_vendor

https://github.com/eProsima/foonathan_memory_vendor
编译该项目时需要下载:https://github.com/foonathan/memory.git。将该项目手动下载并修改foonathan_memory_vendor的CMakeLists.txt文件中的:

externalproject_add(foo_mem-ext
GIT_REPOSITORY https://github.com/foonathan/memory.git
GIT_TAG v0.7-3
TIMEOUT 600
# Avoid the update (git pull) and so the recompilation of foonathan_memory library each time.
UPDATE_COMMAND ""
CMAKE_ARGS
  -DFOONATHAN_MEMORY_BUILD_EXAMPLES=${BUILD_MEMORY_EXAMPLES}
  -DFOONATHAN_MEMORY_BUILD_TESTS=${BUILD_MEMORY_TESTS}
  -DFOONATHAN_MEMORY_BUILD_TOOLS=${BUILD_MEMORY_TOOLS}
  -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/foo_mem_ext_prj_install
  ${extra_cmake_args}
  -Wno-dev
  ${PATCH_COMMAND_STR}
)
修改为:
externalproject_add(foo_mem-ext
SOURCE_DIR <dir/memory-main>
# Avoid the update (git pull) and so the recompilation of foonathan_memory library each time.
UPDATE_COMMAND ""
CMAKE_ARGS
  -DFOONATHAN_MEMORY_BUILD_EXAMPLES=${BUILD_MEMORY_EXAMPLES}
  -DFOONATHAN_MEMORY_BUILD_TESTS=${BUILD_MEMORY_TESTS}
  -DFOONATHAN_MEMORY_BUILD_TOOLS=${BUILD_MEMORY_TOOLS}
  -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/foo_mem_ext_prj_install
  ${extra_cmake_args}
  -Wno-dev
  ${PATCH_COMMAND_STR}
)

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- C fastcdr

https://github.com/eProsima/Fast-CDR

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- D tinyxml2

https://github.com/leethomason/tinyxml2

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- E asio

Asio是一个用于网络和低级I/O编程的跨平台C++库,它使用现代C++方法为开发人员提供了一个一致的异步模型。
asio只有头文件,不需要编译

https://think-async.com/Asio/
https://think-async.com/Asio/Repository.html
https://github.com/chriskohlhoff/asio/

- F openssl

https://github.com/janbar/openssl-cmake
如果需要动态库则需要将crypto/CMakeLists.txt的add_library(crypto ${LIBSRC} ${OBJECTS_SRC})添加SHARED;ssl/CMakeLists.txt的add_library(ssl ${LIBSRC})添加SHARED

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- G fastrtps

libfastrtps.so是最后一个库,安装完后fastdds就可以使用了。
https://github.com/eProsima/Fast-DDS
在其thirdparty目录下有一些第三方库,部分文件在编译时cmake会自动找到,下面解决编译时报错等问题。

修改CMakeLists.txt,添加include_directories(openssl/include/path asio/include/path)
大约在249行,在eprosima_find_package(fastcdr REQUIRED)之前添加cmake package搜罗路径:

# 将fastcdr, tinyxml2, foonathan_memory的位置添加进find_package的搜罗路径
set(CMAKE_PREFIX_PATH "<installpath/lib/cmake/fastcdr>;<lib/cmake/tinyxml2>;<lib/foonathan_memory/cmake>")
# 根据上面编译时的路径,编译fastrtps是应该找到对应的cmake package了

另外,Asio和Boost.Asio是可同时存在的,虽然它们功能一样但namespace和宏名等有差异,因此是不冲突的,modules/FindAsio.cmake文件line:35中使用的是ASIO_VERSION,boost.asio的宏为BOOST_ASIO_VERSION

由于openssl在安装后没有cmake文件,因此不能通过find_package找到openssl。需要在编译时指定动态库:在target_link_libraries中添加库文件的绝对路径即可
<fastdds_root_dir>/cpp/CMakeLists.txt:line:460后添加target_link_directories(${PROJECT_NAME} PUBLIC <openssl/lib_dir>); line:517添加<xx/lib/libssl.so> <xx/lib/libcrypto.so>注释掉关于OpenSSL的行


编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

一、C++ publisher、subscriber应用

什么是DDS

Data Distribution Service(DDS)是一个以数据为中心的通讯协议,它用于进程之间的通讯。它描述了通讯APIs和通讯双方的通讯语义。
Since it is a Data-Centric Publish Subscribe (DCPS) model, 三个关键点:

  1. 发布实体:生成数据并定义其格式、属性等
  2. 接收实体:数据接接收方
  3. 配置实体:定义信息类型,作为topics传输,创建publishersubscriber和QOS属性,确保实体的正确表现

DDS 使用 QoS 来定义 DDS 实体的行为特征。QoS 由单独的 QoS 策略组成

DCPS概念模型

在DCPS模型中,为通信应用系统的开发定义了四个基本要素。

  • 发布者。它是 DCPS 实体,负责创建和配置它实现的 DataWriter。 DataWriter 是负责消息实际发布的实体。 每个主题都将有一个分配的主题,在该主题下发布消息。
  • 订阅者。 它是DCPS实体,负责接收在其订阅的主题下发布的数据。 它提供一个或多个 DataReader 对象,这些对象负责传达新数据的可用性 到应用程序。
  • 主题。 它是绑定发布者和订阅者的实体。 它在 DDS 域中是唯一的。 通过 TopicDescription,它允许出版物和订阅的数据类型的统一性。

在这里插入图片描述

RTPS

RPTS 协议,开发为 支持DDS应用,是一个发布-订阅通信中间件 通过尽力而为的传输,例如 UDP/IP。此外,Fast DDS 还支持 TCP 和 共享内存 (SHM) 传输。
它旨在支持单播和组播通信。
在 RTPS 的顶部,继承自 DDS,可以找到域,它定义了一个单独的通信平面。 多个域可以独立地同时共存。 域包含任意数量的 RTPSParticipants,即能够发送和接收数据的元素。 为此,RTPSParticipants 使用其终结点:
RTPSWriter:能够发送数据的端点。
RTPSReader:能够接收数据的端点。
在这里插入图片描述

C++ 发布者订阅者应用

DDS是以数据为中心的通讯中间件,它实现了DCPS模型。该模型基于发布者、订阅者模式。这些实体通过主题进行通信,主题是绑定两个 DDS 实体的元素。发布者在主题下产生信息,订阅者通过相同的主题接收信息。

  1. 创建应用程序空间
  2. 依赖库
    Fast DDS 和 Fast CDR
    如果是二进制安装,头文件在/usr/include/fastrtps/ /usr/include/fastcdr/;库文件在/usr/lib/
  3. 配置CMake工程
cmake_minimum_required(VERSION 3.20)

project(DDSHelloWorld)

# Find requirements
if(NOT fastcdr_FOUND)
    find_package(fastcdr 2 REQUIRED)
endif()

if(NOT fastrtps_FOUND)
    find_package(fastrtps 2.12 REQUIRED)
endif()

# Set C++11
include(CheckCXXCompilerFlag)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR
        CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11)
    if(SUPPORTS_CXX11)
        add_compile_options(-std=c++11)
    else()
        message(FATAL_ERROR "Compiler doesn't support C++11")
    endif()
endif()

message(STATUS "Configuring HelloWorld publisher/subscriber example...")
file(GLOB DDS_HELLOWORLD_SOURCES_CXX "src/*.cxx")
  1. build the topic data type
    eProsima Fast DDS-Gen是一个生成源码的Java应用,它使用Interface Description Language(IDL)文件定义的数据类型。它有两个功能:
    1. 为topic生成C++定义
    2. 用topic数据生成功能案例
cd src && touch HelloWorld.idl

HelloWorld.idl文件中定义的 topic C++定义

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

然后通过eProsima Fast DDS-Gen工具生成C++11代码:

<path/to/Fast DDS-Gen>/scripts/fastddsgen HelloWorld.idl

这将生成:
在这里插入图片描述


总结

https://fast-dds.docs.eprosima.com/en/latest/02-formalia/titlepage.html

https://paul.pub/dds-and-fastrtps/

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 01:04:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 01:04:05       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 01:04:05       58 阅读
  4. Python语言-面向对象

    2024-07-15 01:04:05       69 阅读

热门阅读

  1. React@16.x(58)Redux@4.x(7)- 实现 combineReducers

    2024-07-15 01:04:05       21 阅读
  2. springsecurity01

    2024-07-15 01:04:05       15 阅读
  3. this指向解析

    2024-07-15 01:04:05       22 阅读
  4. AI究竟是在帮助开发者还是取代他们?

    2024-07-15 01:04:05       20 阅读
  5. C语言 判断素数

    2024-07-15 01:04:05       19 阅读
  6. ios CCRectangleBlock.m

    2024-07-15 01:04:05       17 阅读
  7. Spring之常见注解

    2024-07-15 01:04:05       19 阅读
  8. Golang 后端面经

    2024-07-15 01:04:05       21 阅读
  9. 印度标普基金关门,继续套利美元债LOF

    2024-07-15 01:04:05       20 阅读
  10. 基于深度学习的点云平滑

    2024-07-15 01:04:05       19 阅读
  11. 【网络编程】poll函数

    2024-07-15 01:04:05       18 阅读
  12. 19. 删除链表的倒数第 N 个结点

    2024-07-15 01:04:05       16 阅读