FAST-DDS源码分析PDP(一)

news2025/5/19 6:38:38

准备开一个FAST-DDS源码分析系列,源码版本FAST-DDS 1.1.0版本。

FAST-DDS这种网络中间件是非常复杂的,所以前期先去分析每个类的作用是什么,然后在结合RTPS DOC,FAST-DDS DEMO,以及FAST-DDS的doc去串起来逻辑。

Builtin Discovery 模块

xxxProxyData 类负责在 RTPS 网络中「宣布(Announce)」与「发现(Discover)」参与者及其读写端点(DataReader/DataWriter)。它们在本地对象状态与网络 CDR 消息之间建立了双向映射,确保 QoS、Locator、GUID 等关键信息能被高效、可靠地交换。

类:
在这里插入图片描述

WriterProxyData

关键成员变量:

class WriterProxyData
GUID_t              m_guid;               // 发布者全局唯一 ID
LocatorList_t       m_unicastLocatorList; // 单播地址列表
LocatorList_t       m_multicastLocatorList;// 组播地址列表
InstanceHandle_t    m_key;                // Writer 实例句柄
WriterQos           m_qos;                // 完整 QoS 配置
ParameterList_t     m_parameterList;      // 临时参数列表
RemoteWriterAttributes m_remoteAtt;       // 转换后的远端属性

关键函数:
在这里插入图片描述

  • toParameterList()
    清空 m_parameterList,并依次创建 ParameterLocator_t、ParameterGuid_t、ParameterString_t、各类 QoS Policy(只包含 sendAlways 或 hasChanged)等,将它们推入 m_parameterList.m_parameters。
  • readFromCDRMessage(CDRMessage_t* msg)
    调用 ParameterList::readParameterListfromCDRMsg 填充 m_parameterList,再根据 Pid 将各参数拆回到本地成员(如从 PID_TOPIC_NAME 恢复 m_topicName、从 PID_LIVELINESS 恢复 m_qos.m_liveliness)。
  • toRemoteWriterAttributes()
    将本地数据(GUID、Locator、QoS)映射到 RemoteWriterAttributes,供 RTPSWriter 在发送数据时参考。

ReaderProxyData

与 WriterProxyData 对称,表示一个远端或本地的 DataReader(订阅者)。在初始化发现、数据交互阶段,要互报 Locator、期望的 Inline QoS、各类订阅策略等。

GUID_t              m_guid;
bool                m_expectsInlineQos;    // 是否在 DATA 消息中期待附带 QoS
LocatorList_t       m_unicastLocatorList;
LocatorList_t       m_multicastLocatorList;
InstanceHandle_t    m_key;
ReaderQos           m_qos;
ParameterList_t     m_parameterList;
RemoteReaderAttributes m_remoteAtt;

在这里插入图片描述

ParticipantProxyData

负责对等 Participant(节点)级别的宣布与发现,包括:

  1. SPDP(Simple Participant Discovery Protocol)消息的构建与解析。
  2. 管理 Builtin Endpoint 集(哪些内置读写端点应被广播/监听)。
  3. 维护租约计时器,监测远端 Participant 存活性。
  4. 汇总下属所有 ReaderProxyData 与 WriterProxyData 对象。
class ParticipantProxyData {
public:
    ParticipantProxyData();
    virtual ~ParticipantProxyData();

    // —— 协议与标识 —— 
    ProtocolVersion_t            m_protocolVersion;          // RTPS 协议版本
    VendorId_t                   m_VendorId;                 // 厂商 ID
    GUID_t                       m_guid;                     // 本地/远端 Participant GUID

    // —— QoS 与流量控制 —— 
    bool                         m_expectsInlineQos;         // 是否期望 inline QoS
    BuiltinEndpointSet_t         m_availableBuiltinEndpoints;// 本节点宣布的内置端点集合
    Duration_t                   m_leaseDuration;            // Participant 租约周期
    Count_t                      m_manualLivelinessCount;    // 手动存活声明计数

    // —— 网络定位 —— 
    LocatorList_t                m_metatrafficUnicastLocatorList;   // SPDP 单播列表
    LocatorList_t                m_metatrafficMulticastLocatorList; // SPDP 组播列表
    LocatorList_t                m_defaultUnicastLocatorList;       // 默认数据单播列表
    LocatorList_t                m_defaultMulticastLocatorList;     // 默认数据组播列表

    // —— 标识与属性 —— 
    InstanceHandle_t             m_key;                      // Participant 实例句柄
    std::string                  m_participantName;          // Participant 名称
    std::vector<octet>           m_userData;                 // userData QoS
    ParameterPropertyList_t      m_properties;               // 属性列表

    // —— 状态与并发 —— 
    bool                         isAlive;                    // 存活标志
    bool                         m_hasChanged;               // 数据是否变更(影响 toParameterList)
    boost::recursive_mutex*      mp_mutex;                   // 保护 readers/writers 容器


bool ParticipantProxyData::initializeData(RTPSParticipantImpl* part, PDPSimple* pdp)
{
    // 1) 从本地 ParticipantImpl 获取租约时长、VendorId、默认 Locator
    this->m_leaseDuration = part->getAttributes().builtin.leaseDuration;
    set_VendorId_eProsima(this->m_VendorId);

    // 2) 根据配置,设置 availableBuiltinEndpoints 掩码
    this->m_availableBuiltinEndpoints |= DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER;
    ...
    // 3) 复制 Locator 列表
    this->m_defaultUnicastLocatorList = part->getAttributes().defaultUnicastLocatorList;
    ...
    // 4) 保存 Participant 名称与 GUID、InstanceHandle
    this->m_participantName = part->getAttributes().getName();
    this->m_guid = part->getGuid();
    for (i < 16) { copy into m_key }
    // 5) 从 PDPSimple(SPDP 组件)拷贝 metatraffic Locator
    this->m_metatrafficMulticastLocatorList = pdp->mp_builtin->m_metatrafficMulticastLocatorList;
    ...
    return true;
}

将本地 RTPSParticipantImpl 上的租约时长、GUID、Locator、ParticipantName、UserData 等信息拷贝进来,同时根据配置设置需要 Announce/Detect 的内置端点位掩码,并复制 SPDP 使用的 metatraffic Locator。

bool ParticipantProxyData::toParameterList()
{
    if (m_hasChanged)
    {
        // 清理并重置 QoSList
        m_QosList.allQos.resetList();
        m_QosList.inlineQos.resetList();

        // 依次 addQos:协议版本、VendorID、EXPECTS_INLINE_QOS、GUID
        valid &= QosList::addQos(&m_QosList, PID_PROTOCOL_VERSION, this->m_protocolVersion);
        valid &= QosList::addQos(&m_QosList, PID_VENDORID, this->m_VendorId);
        if (m_expectsInlineQos)
            valid &= QosList::addQos(&m_QosList, PID_EXPECTS_INLINE_QOS, m_expectsInlineQos);
        valid &= QosList::addQos(&m_QosList, PID_PARTICIPANT_GUID, this->m_guid);

        // 添加所有 Locator 列表、租约时长、BuiltinEndpointSet、ParticipantName、UserData、Properties
        for each Locator in m_metatrafficMulticastLocatorList:
            valid &= QosList::addQos(&m_QosList, PID_METATRAFFIC_MULTICAST_LOCATOR, locator);
        ...
        valid &= QosList::addQos(&m_QosList, PID_PARTICIPANT_LEASE_DURATION, this->m_leaseDuration);
        valid &= QosList::addQos(&m_QosList, PID_BUILTIN_ENDPOINT_SET, this->m_availableBuiltinEndpoints);
        valid &= QosList::addQos(&m_QosList, PID_ENTITY_NAME, this->m_participantName);
        if (!m_userData.empty())
            valid &= QosList::addQos(&m_QosList, PID_USER_DATA, this->m_userData);
        if (!m_properties.empty())
            valid &= QosList::addQos(&m_QosList, PID_PROPERTY_LIST, this->m_properties);

        // 最后根据 endianess 调用 CDR 序列化
        valid &= ParameterList::updateCDRMsg(&m_QosList.allQos, LITTLEEND);

        if (valid) m_hasChanged = false;
        return valid;
    }
    return true;
}

当 m_hasChanged == true 时,将协议版本、VendorID、GUID、Locator 列表、租约时长、BuiltinEndpointSet、ParticipantName、UserData、Properties 等,按照 RTPS ParameterList 规范打包到 m_QosList.allQos 中,并调用 CDR 序列化。打包成功后将 m_hasChanged 清零。

bool ParticipantProxyData::readFromCDRMessage(CDRMessage_t* msg)
{
    if (ParameterList::readParameterListfromCDRMsg(msg, &m_QosList.allQos, NULL) > 0)
    {
        for (auto* p : m_QosList.allQos.m_parameters)
        {
            switch (p->Pid)
            {
                case PID_KEY_HASH:
                    // 从 key 恢复 GUID
                case PID_PROTOCOL_VERSION:
                    // 兼容性校验
                case PID_VENDORID:
                    // VendorId 拷贝
                case PID_EXPECTS_INLINE_QOS:
                    m_expectsInlineQos = ((ParameterBool_t*)p)->value;
                    break;
                case PID_METATRAFFIC_MULTICAST_LOCATOR:
                    m_metatrafficMulticastLocatorList.push_back(((ParameterLocator_t*)p)->locator);
                    break;
                ...
                case PID_ENTITY_NAME:
                    m_participantName = std::string(((ParameterString_t*)p)->getName());
                    break;
                case PID_PROPERTY_LIST:
                    m_properties = *((ParameterPropertyList_t*)p);
                    break;
                case PID_USER_DATA:
                    m_userData = ((UserDataQosPolicy*)p)->getDataVec();
                    break;
                default: break;
            }
        }
        return true;
    }
    return false;
}

  1. 使用 ParameterList::readParameterListfromCDRMsg 解析 SPDP 收到的 CDR,填充 m_QosList.allQos.m_parameters。
  2. 按 Pid 分支,将参数恢复到相应字段。
  3. 对 PID_PROTOCOL_VERSION 进行向前兼容性校验:若远端版本过低则直接返回 false,弃用该 Participant。

本地信息采集 → initializeData
打包广播 → toParameterList
接收解析 → readFromCDRMessage
动态刷新 → updateData
生命周期管理 → 构造/析构、clear/copy


在 SPDP(Participant 简单发现协议)公告中,最关键的参数标识(ParameterId,PID)及其作用包括:

  • PID_PROTOCOL_VERSION
    表示 RTPS 协议版本,用于不同实现间的向前兼容性检测。
  • PID_VENDORID
    标识产品/厂商(如 eProsima),在多厂商环境中可用于隔离或兼容性判断。
  • PID_PARTICIPANT_GUID
    发布者自身的全局唯一标识(GUID),远端节点通过它区分不同 Participant。
  • PID_EXPECTS_INLINE_QOS
    指示该 Participant 是否在后续 DATA 消息中期望附带 QoS 信息(Inline QoS),影响后续的样本发送方式。
  • PID_METATRAFFIC_UNICAST_LOCATOR / PID_METATRAFFIC_MULTICAST_LOCATOR
    SPDP 协议使用的“元流量”单播/组播地址列表,告知远端如何向本地 Participant 发送发现消息。
  • PID_DEFAULT_UNICAST_LOCATOR / PID_DEFAULT_MULTICAST_LOCATOR
    普通数据流量(非发现)的默认单播/组播地址,后续 SEDP 或数据传输会用到。
  • PID_PARTICIPANT_LEASE_DURATION
    租约时长(Liveliness Lease Duration),指明多长时间没收到续约就认为该 Participant 已失效。
  • PID_BUILTIN_ENDPOINT_SET
    位掩码,说明本地 Participant 要 Announce/Detect 哪些内置端点(如 PublicationAnnouncer、SubscriptionDetector 等)。
  • PID_ENTITY_NAME
    Participant 的可读名称(EntityName),便于日志、调试和监控时识别节点。
  • PID_USER_DATA
    用户自定义二进制数据,可用于传递应用层特定的元信息或身份验证令牌。
  • PID_PROPERTY_LIST
    键-值属性列表(Property List),支持扩展静态 EDP、配置注入或其他高级用例。

这些 PID 在 ParticipantProxyData::toParameterList() 中依次被打包进 SPDP 消息,在 readFromCDRMessage() 中被解析恢复,构成了 Participant 级别发现协议的核心。它们保证了节点身份、版本兼容、地址可达性、存活检测和可扩展性的完整传递。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python打卡day29@浙大疏锦行

知识点回顾 类的装饰器装饰器思想的进一步理解&#xff1a;外部修改、动态类方法的定义&#xff1a;内部定义和外部定义 作业&#xff1a;复习类和函数的知识点&#xff0c;写下自己过去29天的学习心得&#xff0c;如对函数和类的理解&#xff0c;对python这门工具的理解等&…

【数据结构】2-3-1单链表的定义

数据结构知识点合集 知识点 单链表存储结构 优点&#xff1a;不要求大片连续空间&#xff0c;改变容量方便&#xff1b;缺点&#xff1a;不可随机存取&#xff0c;要耗费一定空间存放指针 /*单链表节点定义*/ typedef struct LNode{ElemType data;struct LNode *next; }LNo…

贝塞尔曲线原理

文章目录 一、 低阶贝塞尔曲线1.一阶贝塞尔曲线2. 二阶贝塞尔曲线3. 三阶贝塞尔曲线 一、 低阶贝塞尔曲线 1.一阶贝塞尔曲线 如下图所示&#xff0c; P 0 ​ P_0​ P0​​, P 1 ​ P_1​ P1​​ 是平面中的两点&#xff0c;则 B ( t ) B ( t ) B(t) 代表平面中的一段线段。…

3D个人简历网站 4.小岛

1.模型素材 在Sketchfab上下载狐狸岛模型&#xff0c;然后转换为素材资源asset&#xff0c;嫌麻烦直接在网盘链接下载素材&#xff0c; Fox’s islandshttps://sketchfab.com/3d-models/foxs-islands-163b68e09fcc47618450150be7785907https://gltf.pmnd.rs/ 素材夸克网盘&a…

创建型:原型模式

目录 1、核心思想 2、实现方式 2.1 基本结构 2.2 代码示例&#xff08;Java&#xff09; 3、适用场景 4、new与clone实际场景建议 1、核心思想 目的&#xff1a;通过复制&#xff08;克隆&#xff09;现有对象来创建新对象&#xff0c;而不是通过new关键字实例化。对于那…

Tapered Off-Policy REINFORCE_ 如何为LLM实现稳定高效的策略优化?

Tapered Off-Policy REINFORCE: 如何为LLM实现稳定高效的策略优化&#xff1f; 在大语言模型&#xff08;LLM&#xff09;的微调领域&#xff0c;强化学习&#xff08;RL&#xff09;正成为提升复杂任务性能的核心方法。本文聚焦于一篇突破性论文&#xff0c;其提出的Tapered …

[Java实战]Spring Boot整合Elasticsearch(二十六)

[Java实战]Spring Boot整合Elasticsearch&#xff08;二十六&#xff09; 摘要&#xff1a;本文通过完整的实战演示&#xff0c;详细讲解如何在Spring Boot项目中整合Elasticsearch&#xff0c;实现数据的存储、检索和复杂查询功能。包含版本适配方案、Spring Data Elasticsea…

图像分割(1)U-net

一、整体结构 虽然说是几年前的产品&#xff0c;但是现在还在用&#xff0c;因为深度学习很多时候越是简单的网络用起来效果越好&#xff0c;而且一般是目标比较小的时候产生的分割问题。u-net的优势就是网络结构简单&#xff0c;适合小目标分割&#xff0c;所以一直用到现在&a…

2025抓包工具Reqable手机抓包HTTPS亲测简单好用-快速跑通

前言 自安卓7.0高版本系统不在信任用户证书&#xff0c;https抓包方式市面查找方法太过复杂手机要root等&#xff0c;前置条件要求太高太复杂&#xff0c;看的头痛&#xff0c;今天一台电脑按步骤操作完即可抓包https,给大家搞定抓包https问题。支持直接编辑修改请求参…

使用 Auto-Keras 进行自动化机器学习

使用 Auto-Keras 进行自动化机器学习 了解自动化机器学习以及如何使用 auto-keras 完成它。如今&#xff0c;机器学习并不是一个非常罕见的术语&#xff0c;因为像 DataCamp、Coursera、Udacity 等组织一直在努力提高他们的效率和灵活性&#xff0c;以便将机器学习的教育带给普…

简单使用Slidev和PPTist

简单使用Slidev和PPTist 1 简介 前端PPT制作有很多优秀的工具包&#xff0c;例如&#xff1a;Slidev、revealjs、PPTist等&#xff0c;Slidev对Markdown格式支持较好&#xff0c;适合与大模型结合使用&#xff0c;选哟二次封装&#xff1b;revealjs适合做数据切换&#xff0c…

RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试,踩坑介绍

视频讲解&#xff1a; RISC-V 开发板 MUSE Pi Pro V2D图像加速器测试&#xff0c;踩坑介绍 今天测试下V2D&#xff0c;这是K1特有的硬件级别的2D图像加速器&#xff0c;参考如下文档&#xff0c;但文档中描述的部分有不少问题&#xff0c;后面会讲下 https://bianbu-linux.spa…

c++多线程debug

debug demo 命令行查看 ps -eLf|grep cam_det //查看当前运行的轻量级进程 ps -aux | grep 执行文件 //查看当前运行的进程 ps -aL | grep 执行文件 //查看当前运行的轻量级进程 pstree -p 主线程ID //查看主线程和新线程的关系 查看线程栈结构 pstack 线程ID 步骤&…

如何畅通需求收集渠道,获取用户反馈?

要畅通需求收集渠道、有效获取用户反馈&#xff0c;核心在于多样化反馈入口、闭环反馈机制、用户分层管理、反馈数据结构化分析等四个方面。其中&#xff0c;多样化反馈入口至关重要&#xff0c;不同用户有不同的沟通偏好&#xff0c;只有覆盖多个反馈路径&#xff0c;才能捕捉…

设备预测性维护的停机时间革命:中讯烛龙如何用AI重构工业设备管理范式

在工业4.0的智能化浪潮中&#xff0c;非计划停机每年吞噬企业3%-8%的产值。中讯烛龙预测性维护系统通过多模态感知矩阵分布式智能体的创新架构&#xff0c;实现设备健康管理的范式跃迁&#xff0c;帮助制造企业将停机时间压缩70%以上。本文将深度解析技术实现路径与行业级实践方…

Python数据分析三剑客:NumPy、Pandas与Matplotlib安装指南与实战入门

Python数据分析三剑客&#xff1a;NumPy、Pandas与Matplotlib安装指南与实战入门 1. 引言 Python数据分析生态&#xff1a;NumPy、Pandas、Matplotlib是数据科学领域的核心工具链。适用场景&#xff1a;数值计算、数据处理、可视化分析&#xff08;如金融分析、机器学习、科研…

Spring-Beans的生命周期的介绍

目录 1、Spring核心组件 2、Bean组件 2.1、Bean的定义 2.2、Bean的生命周期 1、实例化 2、属性填充 3、初始化 4、销毁 2.3、Bean的执行时间 2.4、Bean的作用域 3、常见问题解决方案 4、与Java对象区别 前言 关于bean的生命周期&#xff0c;如下所示&#xff1a; …

Android 自定义悬浮拖动吸附按钮

一个悬浮的拨打电话按钮&#xff0c;使用CardViewImageView可能会出现适配问题&#xff0c;也就是图片显示不全&#xff0c;出现这种问题&#xff0c;就直接替换控件了&#xff0c;因为上述的组合控件没有FloatingActionButton使用方便&#xff0c;还可以有拖动和吸附效果不是更…

一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting

一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting 文章目录 一种开源的高斯泼溅实现库——gsplat: An Open-Source Library for Gaussian Splatting摘要Abstract1. 基本思想1.1 设计1.2 特点 2. Nerfstudio&Splatfacto2.1 Nerfstudio2.…

ARM A64 STR指令

ARM A64 STR指令 1 STR (immediate)1.1 Post-index1.1.1 32-bit variant1.1.2 64-bit variant 1.2 Pre-index1.2.1 32-bit variant1.2.2 64-bit variant 1.3 Unsigned offset1.3.1 32-bit variant1.3.2 64-bit variant 1.4 Assembler symbols 2 STR (register)2.1 32-bit varia…