Fast DDS,全称 Fast Data Distribution Service,是一种开源的、高性能的数据分发服务,它实现了实时数据通信的标准DDS(Data Distribution Service)规范。Fast DDS 的设计旨在提供快速、可靠的数据传输,适用于实时系统和分布式应用。GitHub地址:https://github.com/eProsima/Fast-DDS?tab=readme-ov-file
关键特性:
高性能:Fast DDS 采用了优化的数据传输机制和网络协议栈,以实现高效的数据传输和低延迟。
可扩展性:Fast DDS 支持灵活的配置选项,可以根据应用需求调整和优化性能。
可靠性:Fast DDS 提供了数据传输的可靠性保证机制,包括数据重传、确认机制等,以确保数据的可靠传输。
安全性:Fast DDS 支持数据加密、身份验证等安全功能,保护数据传输的安全性和隐私性。
开源:Fast DDS 是开源项目,采用 Apache 许可证,任何人都可以免费使用和修改。
RTPS
RTPS
是 “Real-Time Publish-Subscribe Protocol” 的缩写,它是一种用于实时数据通信的协议,通常用于实时系统中,例如工业控制、医疗设备、航空航天等领域,以实现设备之间的实时数据交换和通信。
RTPS 基于发布-订阅模型,其中数据生产者(发布者)将数据发布到网络上,而数据消费者(订阅者)则订阅并接收感兴趣的数据。RTPS 允许实时数据的快速传输,并提供了一些机制来确保数据的可靠性、实时性和安全性。
案例
假设有一个机器人控制系统,在这个系统中,Fast DDS作为通信框架,而RTPS则是其底层协议之一,用于实现实时数据分发和通信。
这个机器人控制系统,包括多个机器人和一个中央控制器。机器人需要不断地向控制器发送状态信息(比如位置、速度、传感器数据等),同时控制器也需要向机器人发送控制指令(比如移动、停止、执行任务等)。这种实时的双向通信需要一种高效、可靠的通信机制,这时就可以使用Fast DDS作为通信框架,并利用RTPS作为其底层协议。
Fast DDS可以用于在机器人和控制器之间建立一个DDS数据域(DDS Domain),其中机器人和控制器分别作为数据域中的参与者(Participants)。机器人将自己的状态信息发布到数据域中的特定主题(Topic),而控制器则订阅这些主题以获取机器人的状态信息。同时,控制器也可以向特定的主题发布控制指令,而机器人则订阅这些主题以接收控制指令。
在这个过程中,Fast DDS使用RTPS协议来实现机器人和控制器之间的实时数据传输。RTPS协议提供了高性能、可靠的数据传输机制,保证了数据的及时性和可靠性。这样,通过将RTPS应用于Fast DDS,可以实现机器人控制系统中实时数据的高效传输和通信。以下是一个简单的示例代码:
#include <iostream>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/topic/Topic.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/SampleInfo.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastrtps/Domain.h>
#include <fastrtps/utils/eClock.h>
using namespace eprosima::fastdds::dds;
// 定义机器人状态的消息类型
struct RobotStatus
{
int id;
double position_x;
double position_y;
double velocity;
};
// 定义控制指令的消息类型
struct ControlCommand
{
int id;
double target_position_x;
double target_position_y;
};
// 机器人状态消息的订阅者回调函数
void robot_status_callback(const RobotStatus& status, const SampleInfo_t& info)
{
if (info.valid_data) {
std::cout << "Received robot status - ID: " << status.id << ", Position: (" << status.position_x << ", " << status.position_y << "), Velocity: " << status.velocity << std::endl;
}
}
int main()
{
// 初始化Fast DDS域
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0);
// 创建机器人状态主题
Topic* robot_status_topic = participant->create_topic("RobotStatus", "RobotStatusType", TOPIC_QOS_DEFAULT);
// 创建机器人状态订阅者
Subscriber* robot_status_subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
DataReader* robot_status_reader = robot_status_subscriber->create_datareader(robot_status_topic, DATA_READER_QOS_DEFAULT, &robot_status_callback);
// 创建控制指令主题
Topic* control_command_topic = participant->create_topic("ControlCommand", "ControlCommandType", TOPIC_QOS_DEFAULT);
// 创建控制指令发布者
Publisher* control_command_publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
DataWriter* control_command_writer = control_command_publisher->create_datawriter(control_command_topic, DATA_WRITER_QOS_DEFAULT);
// 发布机器人状态
RobotStatus robot_status;
robot_status.id = 1;
robot_status.position_x = 0.0;
robot_status.position_y = 0.0;
robot_status.velocity = 0.0;
control_command_writer->write(&robot_status);
// 发布控制指令
ControlCommand control_command;
control_command.id = 1;
control_command.target_position_x = 10.0;
control_command.target_position_y = 5.0;
control_command_writer->write(&control_command);
// 等待一段时间
std::this_thread::sleep_for(std::chrono::seconds(1));
// 清理资源
participant->delete_datawriter(control_command_writer);
participant->delete_publisher(control_command_publisher);
participant->delete_topic(control_command_topic);
participant->delete_datareader(robot_status_reader);
participant->delete_subscriber(robot_status_subscriber);
participant->delete_topic(robot_status_topic);
DomainParticipantFactory::get_instance()->delete_participant(participant);
return 0;
}