DDS(数据分发服务)是一种专为分布式实时系统设计的高性能通信中间件。下面我将通过一个具体的实例,展示如何使用 Fast DDS​ (一个流行的开源DDS实现) 来创建发布者和订阅者,并涵盖从环境搭建到代码运行的完整流程。

为了帮助您快速建立整体概念,下图概括了 DDS 的核心通信模型(DCPS)及其实例中各个组件的协作关系。

flowchart TD
    A[发布者应用程序] -->|创建| B[Publisher]
    A -->|创建| C[DataWriter]
    D[订阅者应用程序] -->|创建| E[Subscriber]
    D -->|创建| F[DataReader]
    
    B -->|管理| C
    E -->|管理| F
    
    C -->|写入数据| G[HelloWorld Topic]
    F -->|读取数据| G
    
    G -->|基于| H[Msg.id<br/>Msg.message]
    
    I[DomainParticipant] -->|发现并匹配| J[DomainParticipant]
    
    B -->|隶属于| I
    E -->|隶属于| J
    
    subgraph K [DDS全局数据空间]
        I
        J
        G
    end

上图的逻辑在实例中体现为:发布者和订阅者作为DomainParticipant加入同一个域(例如ID为0的域),并通过名为HelloWorldTopicTopic进行数据连接。DataWriterDataReader分别负责数据的写入和读取,并通过DDS内置的自动发现机制建立通信。

CMake版本升级:

# 卸载旧版本
sudo apt remove --purge cmake

# 安装依赖
sudo apt update
sudo apt install -y software-properties-common lsb-release

# 下载 Kitware 的 GPG 密钥
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null

# 添加 Kitware 仓库
echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/kitware.list

# 更新并安装最新 CMake
sudo apt update
sudo apt install -y cmake

# 验证安装
cmake --version

第一步:环境搭建与Fast DDS安装

在开始编写代码前,需要先安装Fast DDS及其依赖库。以Ubuntu系统为例,具体操作如下表所示:

步骤

命令/操作

说明

1. 安装依赖

sudo apt update && sudo apt install -y cmake g++ libssl-dev libasio-dev libtinyxml2-dev git

获取编译工具和必要的库文件。

2. 安装FastCDR

git clone https://github.com/eProsima/Fast-CDR.git
cd Fast-CDR && mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
sudo make install

Fast DDS依赖的序列化库。

3. 安装Foonathan Memory

git clone https://github.com/eProsima/foonathan_memory_vendor.git
cd foonathan_memory_vendor && mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
sudo make install

Fast DDS依赖的内存管理库。

4. 安装Fast DDS

git clone https://github.com/eProsima/Fast-DDS.git
cd Fast-DDS && mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
sudo make install

编译并安装核心的Fast DDS库。

5. 验证安装

执行sudo ldconfig更新动态链接库后,可以尝试编译官方示例(如HelloWorldExample)。

确保头文件和库链接正确。

提示:如果在cmake阶段遇到类似“Asio版本过低”的错误,可能需要手动升级Asio库。 在Windows系统上,过程类似,但通常使用Visual Studio的开发者命令提示符和CMake GUI进行编译,并需确保环境变量设置正确。

第二步:编写DDS应用程序代码

安装好环境后,就可以编写DDS应用程序了。一个典型的DDS应用包含三个部分:数据定义发布者订阅者

1. 定义数据类型(IDL文件)

首先,我们需要定义一个在进程间传输的数据结构。这通常使用接口定义语言(IDL)​ 完成。

// HelloWorld.idl
module HelloWorld {
    struct Msg {
        long id;
        string message;
    };
};

使用Fast DDS提供的代码生成工具,可以将这个IDL文件转换成C++代码:

# fastddsgen HelloWorld.idl
//本文章使用的是以下命令,可以生成一个完整的使用示例文件
fastddsgen -example CMake HelloWorld.idl

如果fastddsgen命令不存在,需要安装Fast DDS Gen,编译完的fastddsgen在Fast-DDS-Gen/scripts路径下:

~$ cd fastdds-workspace
~/fastdds-workspace$ sudo apt install openjdk-17-jdk
~/fastdds-workspace$ git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git
~/fastdds-workspace$ cd Fast-DDS-Gen
~/fastdds-workspace/Fast-DDS-Gen$ ./gradlew assemble

此命令会生成 以下文件,其中包含了用于序列化和反序列化的C++类。

第三步:编译与运行
编译

使用CMake来管理编译过程是最佳实践。

编译命令:

mkdir build && cd build
cmake ..
make -j$(nproc)

这个示例只编译出一个可执行文件HelloWorld,这个程序包含了发布者和订阅者的功能。

运行
  1. 在一个终端启动订阅者,它将开始监听数据:

    ./HelloWorld subscriber # 运行为订阅者

  2. 在另一个终端启动发布者,它将开始发送数据:

    ./HelloWorld publisher  # 运行为发布者

    如果一切正常,你将在订阅者终端看到接收到的消息。这就是DDS自动发现机制在起作用:发布者和订阅者无需知道彼此的地址,只要在同一个域内,订阅同一主题,就能自动建立连接。

第四步:核心概念与进阶应用

理解服务质量(QoS)

DDS的强大之处在于其丰富的QoS策略,你可以像下面这样配置它们,以满足不同的可靠性需求:

// 配置一个可靠的、持久化的DataWriter
DataWriterQos writer_qos;
writer_qos.reliability().kind = RELIABLE_RELIABILITY_QOS; // 确保数据送达
writer_qos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS; // 新订阅者能获取最后一条消息
writer_qos.history().kind = KEEP_LAST_HISTORY_QOS; // 保留最后N条历史记录
writer_qos.history().depth = 10;
DataWriter* reliable_writer = publisher->create_datawriter(topic, writer_qos);
分布式仿真中的应用

在分布式仿真中,DDS的这些特性至关重要:

  • 实时性:极低的延迟和确定性延迟保证,满足仿真系统苛刻的时序要求。

  • 可扩展性:去中心化的架构允许轻松添加新的仿真节点(如新的传感器、控制器模型)。

  • 可靠性:通过QoS确保关键控制指令和状态更新绝不丢失。

  • 互操作性:DDS是一个开放标准,不同厂商开发的仿真组件可以通过DDS进行通信。

总结与建议

这个实例展示了DDS通信的核心流程。DDS通过其以数据为中心的架构丰富的QoS策略去中心化的自动发现机制,为构建复杂、可靠、实时的分布式仿真系统提供了坚实基础。

如果想进一步探索,可以从这几个方面入手:

  • 深入QoS:尝试不同的QoS策略组合,观察其对数据传输行为的影响。

  • 使用XML配置:将QoS等配置外置到XML文件中,使应用更灵活。

  • 性能测试:利用perftest等工具测试DDS在不同网络条件下的吞吐量和延迟。

Logo

更多推荐