• Fast DDS之RTPS


    RTPS层实现了RTPS标准。DDS层概念映射关系如下:

    DDS LayerRTPS Layer
    DomainRTPSDomain
    DomainParticipantRTPSParticipant
    DataWriterRTPSWriter
    DataReaderRTPSReader

    RTPS层的四个实体:
    RTPSDomain:DDS domain在RTPS协议的扩展
    RTPSParticipant:包含所有的RTPS实体
    RTPSWriter:从DataWriterHistory 中读数据,传递给匹配的RTPSReaders
    RTPSReader:读取RTPSWriter 写入DataReaderHistory中的数据

    数据结构的定义

    GUID_t

    RTPSParticipant层的GUID_t全局唯一标识符)是由两部分组成的:GUIDPrefix_t和EntityId_t。

    GUIDPrefix_t是一个前缀,主要用于标识一个参与节点(Participant)。EntityId_t则用于标识该参与节点下的各种实体,比如发布者(Publisher)、订阅者(Subscriber)、主题(Topic)等。
    在Fast DDS中,GUID(全局唯一标识符)是一个全局唯一的标识,用来唯一地标识一个特定的DDS实体(如参与者、发布者、订阅者、数据写者、数据读者等)。GUID是RTPS协议的一部分,是由两部分组成:GUID前缀和实体ID。

    GUID前缀通常是由参与者(Participant)生成,并且所有由同一个参与者创建的实体(如发布者、订阅者、数据写者、数据读者等)都将共享相同的GUID前缀。实体ID则是用来在同一个参与者下唯一地标识一个实体。

    GUID的主要作用是在DDS网络中唯一地标识一个实体,以便进行消息路由和数据交换。例如,当一个数据写者发布一个消息时,它会包含该写者的GUID,这样接收到消息的读者就知道这个消息是由哪个写者发送的。同样,当一个读者请求一个特定的数据时,它也会包含请求的写者的GUID,这样DDS网络就知道应该将请求路由到哪个写者。
    因此,GUID_t的主要作用是在DDS系统中唯一地标识一个实体。这样,无论实体在何处,或在哪个参与节点上,都可以通过它的GUID_t准确找到。这对于在分布式环境中进行有效的通信和数据交换是非常重要的。

    ChangeKind_t

    在Fast DDS中,ChangeKind_t是一个枚举类型,用于表示CacheChange_t数据实例的状态更改类型。它有以下四种可能的值:

    • ALIVE - 表示数据实例是活跃的,即它还在生成新的数据。
    • NOT_ALIVE_DISPOSED - 表示数据实例已被销毁。在这种情况下,Fast DDS不会再为此实例生成任何新的数据。
    • NOT_ALIVE_UNREGISTERED - 表示数据实例已被注销。这意味着实例可能在未来重新注册并生成新的数据。
    • NOT_ALIVE_DISPOSED_UNREGISTERED - 表示数据实例已被销毁并注销。在这种情况下,实例将不会再生成任何新的数据。

    Fast DDS使用ChangeKind_t来跟踪数据实例的状态,并据此决定如何处理实例生成的数据。例如,如果一个实例的状态被标记为NOT_ALIVE_DISPOSED,那么Fast DDS就会停止接收或处理此实例生成的任何新数据。

    CacheChange_t

    CacheChange_t是一个结构体,它用于存储与数据相关的所有信息,包括数据的实例、序列号、时间戳、数据类型等。这个结构体通常用于表示在数据发布者和订阅者之间传输的数据。
    CacheChange_t的主要成员包括:

    • instanceHandle:一个句柄,用于唯一标识与此更改关联的数据实例。
    • sequenceNumber:序列号,用于标识此更改在数据实例历史中的位置。
    • sourceTimestamp:源时间戳,表示数据实例产生此更改的时间。
    • writerGUID:datawriter的GUID,表示产生此更改的数据发布者。
    • kind:一个ChangeKind_t值,表示此更改的类型(例如,数据实例是否处于活动状态,是否已被销毁等)。
    • serializedPayload:一个SerializedPayload_t对象,包含实际的序列化数据。

    Fast DDS使用CacheChange_t来跟踪和管理数据更改,确保数据的一致性和正确传输。

    InstanceHandle_t

    InstanceHandle_t是一个特殊的句柄类型,用于唯一标识数据实例。InstanceHandle_t通常用于以下场景:

    • 在读取或取样数据时,用于表示那个特定的数据实例正在被操作。
    • 在发布数据时,用于指示正在更新哪个数据实例。
    • 在使用DataReaderlookup_instance方法时,用于返回与给定数据样本对应的实例句柄。
      因此,InstanceHandle_t为处理和管理数据实例提供了一种有效的方式。

    SequenceNumber_t

    SequenceNumber_t用于表示消息的序列号。序列号是用来标识和排序消息的,确保消息的顺序和完整性。
    在分布式系统中,消息可能因为网络延迟或者其他原因而达到的顺序和发送的顺序不一致。通过在每个消息上附加一个序列号,接收方就可以根据序列号重新对消息进行排序,确保消息按照发送的顺序被处理。同时,序列号也可以用来检测是否有消息丢失。例如,如果接收方收到了序列号为1和3的消息,但没有收到序列号为2的消息,那么接收方就知道有一个消息丢失了。

    总的来说,SequenceNumber_t在Fast DDS中用于确保消息的顺序和完整性,是实现可靠通信的一个重要工具。

    HistoryAttributes

    用于指定WriterHistory 或 ReaderHistory的属性,包含以下属性:
    MemoryManagementPolicy_t memoryPolicy; 内存管理策略
    uint32_t payloadMaxSize 最大负载,默认值为500
    int32_t initialReservedCaches; 初始缓存,默认值为500
    int32_t maximumReservedCaches 最大缓存
    int32_t extraReservedCaches; 需要保存的额外的缓存

    RTPSParticipantAttributes

    这个类用于配置RTPSParticipantImpl的数据,有以下内容:
    LocatorList_t defaultUnicastLocatorList 单播地址,默认端口是从7411开始
    BuiltinAttributes builtin 内置协议如服务发现,保活等协议的属性配置

    ParticipantProxyData

    服务发现的对端的信息都存储在ParticipantProxyData中。这个实例在发现过程中被创建,然后填充发现后的信息后,加入到PDP的参与者列表(ResourceLimitedVector participant_proxies_)中。participant_proxies_的第一个成员是其所在的ParticipantProxyData数据。具体有以下数据成员:

    ProtocolVersion_t m_protocolVersion; 协议版本,当前版本?
    GUID_t m_guid; participant的guid
    VendorId_t m_VendorId; 供应商 id,fastdds的id为?
    bool m_expectsInlineQos;
    BuiltinEndpointSet_t m_availableBuiltinEndpoints; //!Available builtin endpoints
    RemoteLocatorList metatraffic_locators; //!Metatraffic locators
    RemoteLocatorList default_locators; //!Default locators
    Count_t m_manualLivelinessCount; //!Manual liveliness count
    string_255 m_participantName; //!Participant name
    InstanceHandle_t m_key;
    Duration_t m_leaseDuration;
    #if HAVE_SECURITY
    //!
    IdentityToken identity_token_;
    //!
    PermissionsToken permissions_token_;
    //!
    security::ParticipantSecurityAttributesMask security_attributes_;
    //!
    security::PluginParticipantSecurityAttributesMask plugin_security_attributes_;
    #endif // if HAVE_SECURITY
    //!
    bool isAlive;
    //!
    ParameterPropertyList_t m_properties;
    //!
    UserDataQosPolicy m_userData;
    //!
    TimedEvent* lease_duration_event;
    //!
    bool should_check_lease_duration;
    //!
    ProxyHashTable* m_readers = nullptr;
    //!
    ProxyHashTable* m_writers = nullptr;

    RTPS的使用

    RTPS层实体有以下:

    1. RTPSDomain
    2. RTPSParticipant:包含RTPS层其他实体
    3. RTPSWriter:从DataWriterHistory中读数据并发送给和他匹配的所有的RTPSReaders
    4. RTPSReader:接收从RTPSWriter发送的消息并写入DataReaderHistory

    RTPS层RTPSParticipant的创建时序如下:
    在这里插入图片描述
    RTPSWriter的创建过程:
    在这里插入图片描述
    和文档中使用 RTPSDomain::createRTPSWriter() 创建有差异?

    使用History发送和接收数据
    History相关类图如下: 在这里插入图片描述

    配置Readers和Writers

    设置数据持久化属性:

    • VOLATILE:数据发送后即丢失。如果一个新的reader被发现并匹配后,message发送到第n条,此时新的reader从第n+1条开始接收
    • TRANSIENT_LOCAL:writer保存了k条已发送的messages,新的reader加入进来后此时消息已经发送n条了,新的reader从第n-k条开始接收
    • TRANSIENT:数据一直保存,及时writer被销毁和重新创建,或者app crash。

    配置History

    通过HistoryAttributes配置History

    使用自定义PayloadPool

  • 相关阅读:
    突破限制, 访问其它 Go package 中的私有函数
    vue+Select+Tree实现单选 默认选中全部
    【机器学习】李宏毅——Flow-based Generative Models
    ZC-CLS381RGB颜色识别+8x8点阵指示(完)
    C++并发编程
    小文智能GPT助手介绍
    基于json文件创建后端模拟接口
    2022届秋招Java岗高频面试题盘点,老司机也未必全会,真的太卷了
    苹果+甲基化=切开不变色
    VUE——验证码倒计时
  • 原文地址:https://blog.csdn.net/u010378559/article/details/133751982