环境:
$ uname -a
Linux didi-Precision-3630-Tower 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

DDS

eProsima Fast DDS

eProsima Fast DDS是 DDS(数据分发服务)规范的 C++ 实现,该规范由对象管理组 (OMG)定义。eProsima Fast DDS库提供应用程序编程接口 (API) 和通信协议,用于部署以数据为中心的发布者 - 订阅者 (DCPS) 模型,目的是在实时系统之间建立高效可靠的信息分发。 eProsima 快速 DDS在资源处理方面是可预测的、可扩展的、灵活的和高效的。为了满足这些要求,它使用类型化接口并依赖于多对多分布式网络范式,该范式巧妙地允许通信的发布方和订阅方分离。

eProsima Fast DDS包括:

  • DDS API实现。
  • Fast DDS-Gen,一种用于将类型化接口与中间件实现桥接的生成工具。
  • 底层RTPS有线协议实现。

支持协议:

  • Data Distribution Service (DDS) 1.4版规范定义
  • DDSI-RTPS™ DDS 互操作性有线协议2.5,该协议通过 TCP/UDP/IP 等传输提供发布者-订阅者通信,并保证不同 DDS 实现之间的兼容性。

FastDDS安装

FastDDS提供了三种安装方式,分别是bin、Source、docker image 3 种方式。

推荐使用bin安装方式,FastDDS的bin安装方式实际也是源码编译安装。

在官网填写信息后,选择bin安装方式,进入下载界面(该链接不需要填写信息!),下载安装包eProsima Fast DDS 2.8.1 - Linux (32 & 64)

在这里插入图片描述

该安装包有install.sh脚本,install.sh会自动apt安装各种依赖,然后进入src目录下,分别从源码构建foonathan_memory_vendor、fastcdr、fastrtps、fastddsgen。
在这里插入图片描述

  • foonathan_memory_vendor,一个 STL 兼容的 C++ 内存分配器 库。
  • fastcdr,一个根据 CDR 标准进行数据序列化的 C++ 库。
  • fastrtps,eProsima Fast DDS库的核心库。
  • fastddsgen,一个使用 IDL 文件中定义的数据类型生成源代码的 Java 应用程序。

如果这些组件中的任何一个不需要,可以简单地重命名或从src 目录中删除。

开始

注意编译需要CMake3.11以上的版本,安装编译需要时间比较久,大概15分钟(8代i7编译)。

下载该安装包后,解压缩至新建文件夹并安装

mkdir fastdds2.8.1
tar -zxvf eProsima_Fast-DDS-v2.8.1-Linux.tgz -C fastdds2.8.1/
cd fastdds2.8.1/
sudo ./install.sh

注意,如果要测试FastDDS中的examples,需要在install.sh脚本脚本中打开该选项,默认为OFF。

在这里插入图片描述
install.sh脚本首先安装各种依赖,包括git、build-essential、cmake、libssl-dev、libasio-dev、libtinyxml2-dev、openjdk-8-jre-headless。
在这里插入图片描述
接着install.sh脚本编译安装foonathan_memory_vendor。
在这里插入图片描述
然后install.sh脚本编译安装fastcdr。
在这里插入图片描述
随后install.sh脚本编译安装fastrtps(Fast DDS)。
在这里插入图片描述
最后install.sh脚本拷贝fastddsgen二进制文件到系统目录中。

在这里插入图片描述

测试

IDL文件生成接口文件

git clone https://github.com/wanghuohuo0716/fastdds_helloworld.git
cd fastdds_helloworld
mkdir -p include/idl_generate/
cd idl/
fastddsgen -d ./../include/idl_generate/  HelloWorld.idl# -d选项指示生成的头文件保存目录

编译FastDDS的程序

根据IDL文件生成接口文件后,同一个终端内接着编译FastDDS程序。

cd ..
mkdir build && cd build
cmake .. 
make

运行Publisher和Subscriber

cd build/
./DDSHelloWorldPublisher
cd build/
./DDSHelloWorldSubscriber

可以看到终端输出

添加环境变量

如果上面步骤可以正常执行,不需要再手动添加环境变量了。

当使用eProsima Fast DDS运行应用程序实例时,它必须与安装包的库链接,可以临时添加环境变量

export LD_LIBRARY_PATH=/usr/local/lib/

也可以永久添加

echo ‘export LD_LIBRARY_PATH=/usr/local/lib/’ >> ~/.bashrc

卸载

该安装包同样提供/uninstall.sh卸载脚本,直接执行该脚本即可:

cd fastddss2.8.1
sudo ./uninstall.sh

注意:如果任何其他组件已经以某种其他方式安装在系统中,它们也将被删除。为避免这种情况,请在执行之前编辑./uninstall.sh脚本。

编写IDL文件

定义IDL数据类型

创建IDL文件

cd idl && touch HelloWorld.idl

定义 HelloWorld 数据类型,它有两个元素:

  • 类型为uint32_t的index
  • 类型为std::string 的message
struct HelloWorld
{
    unsigned long index;
    string message;
};

生成定义数据类型的源代码

接着利用fastdds的工具fastddsgen,生成在 C++中实现此数据类型的源代码,在idl/ 目录运行以下命令:

fastddsgen -d ./../include/idl_generate/ HelloWorld.idl

其中-d选项指定生成源代码存放的目录路径./../include/idl_generate/。

fastddsgen是一个Java应用程序(已经在前述安装步骤中成功安装),用来解析idl文件,生成数据类型定义的的源代码。

生成类型源码解析

fastddsgen工具会为HelloWorld.idl文件生成四个文件,分别是

  • HelloWorld.h
  • HelloWorld.cxx
  • HelloWorldPubSubTypes.h
  • HelloWorldPubSubTypes.cxx

其中HelloWorld.h,HelloWorld.cxx中会根据idl文件中定义的结构体生成对应的类,即 类型定义:

class HelloWorld
{
public:
    ****
private:
    uint32_t m_index;
    std::string m_message;
};

其中HelloWorldPubSubTypes.h,HelloWorldPubSubTypes.cxx文件在定义HelloWorld类的基础上添加了一些了对HelloWorld 类型的序列化和反序列化代码:

#include "HelloWorld.h"

class HelloWorldPubSubType : public eprosima::fastdds::dds::TopicDataType
{
public:

    typedef HelloWorld type;

    eProsima_user_DllExport HelloWorldPubSubType();
    eProsima_user_DllExport virtual ~HelloWorldPubSubType() override;
    ***
    unsigned char* m_keyBuffer;
};

Publisher代码

参考

https://www.jianshu.com/p/b9eb5dd9559f#%E4%B8%80fastdds%E5%92%8Cfast-rtps%E5%8C%BA%E5%88%AB

更多推荐