目录
我们承担ROS,FastDDS,C++,cmake等技术的项目开发和专业指导和培训,有10年+相关工作经验,质量有保证,如有需要请私信联系。
本文主要依据RTPS官方文档,翻译RTPS协议,并加入个人理解和例证说明。
术语
CDR:Common Data Representation
DDS:Data Distribution Service
EDP:Endpoint Discovery Protocol
GUID:Globally Unique Indentifier
PDP:Participant Discovery Protocol
PIM:Platform Independent Model
PSM:Platform Specific Model
RTPS:Real-Time Publish-Subscribe
SEDP:Simple Endpoint Discovery Protocol
介绍
DDS规范依赖于使用发现机制来建立匹配的DataWriters和DataReaders之间的通信。DDS实现必须自动发现远程实体的存在,无论它们是加入还是离开网络。这些发现信息可以通过DDS内置主题使用户可以访问。
RTPS标准将服务发现分为两部分:
- Participant Discovery Protocol
- Endpoint Discovery Protocol
PDP规定了Participants如何在网络中互相发现,一旦完成两个Participants的发现,就开始使用EDP交换它们所包含的端点信息。除了这层关系之外,这两种协议可以被认为是独立的。
实现上可以支持多种PDPs和EDPs,这个由供应商决定。所有的RTPS实现必须至少要提供Simple Discovery 协议:
- Simple Participant Discovery Protocol (SPDP)
- Simple Endpoint Discovery Protocol (SEDP)
两者都是基本的发现协议,足以满足小到中等规模的网络。针对更大网络的额外的PDP和EDP可能会被添加到规范的未来版本中。
最后,发现协议的角色是提供有关发现的远程端点的信息。参与者如何使用此信息配置其本地端点取决于RTPS协议的实际实现,并不是发现协议规范的一部分。比如,获取到的关于远程终端点的信息允许实现以下进行配置:
- RTPS ReaderLocator对象关联每个RTPS StatelessWriter;
- RTPS ReaderProxy对象关联每个RTPS StatefulWriter;
- RTPS WriterProxy对象关联每个RTPS StatefulReader;
Discovery Endpoints
DDS规范中指定了使用DDS的DataWriters和DataReaders以及预先定义的topic和Qos来进行服务发现。
有四个预定义的Topic:“DCPSParticipant,” “DCPSSubscription,” “DCPSPublication,” and “DCPSTopic.”。和这些topic关联的DataTypes也由DDS规范指定,主要包含实体的Qos。
对于每个built-in的topic,存在一个对应的built-in的DDS的DataWriter/DataReader。这些built-in DataWriter用于向其他网络中公告participant的Qos和它包含的DDS实体(DataWriters, DataReaders, Topics),同样,内置的DataReader从远程participant收集这些信息,然后由DDS Entity实现识别和匹配远端的Entities。内置的DataReaders充当常规的DDS DataReaders,用户也可以通过DDS API访问它们。(为什么需要访问它们)
RTPS层简单发现协议(SPDP和SEDP)采取的方法类似于内置实体的概念。RTPS将每个内置的DDS DataWriter或DataReader映射到与之关联的内置RTPS端点。这些内置端点充当常规的写入和读取端点,并提供了使用行为模块中定义的常规RTPS协议在参与者之间交换所需的发现信息的方法。
SPDP主要关注参与者如何发现彼此,它将DDS的内置实体映射到“DCPSParticipant”的topic。SEDP则指定如何交换有关本地topic、DataWriters和DataReaders的发现信息,它将DDS的内置实体映射到“DCPSSubscription”,“DCPSPublication”和“DCPSTopic”的topics。
SPDP
PDP的目的是发现网络上其他参与者的存在及其属性。participant可以支持多个PDP,但是为了实现互操作性,所有实现都必须至少支持简单的参与者发现协议。
对于每个Participant,SPDP创建两个RTPS built-in Endpoints: SPDPbuiltinParticipantWriter
和 SPDPbuiltinParticipantReader
.(对应于Fast DDS就是SimplePDPEndpoints类的两个数据成员BuiltinWriter和BuiltinReader)
SPDPbuiltinParticipantWriter
使用RTPS的best-effort 的StatelessWriter
(这意味着它尝试发送数据,但不能保证所有数据都会成功传输给所有的读者。此外,它不跟踪读者是否已经接收到数据)SPDPbuiltinParticipantWriter
的HistoryCache中只包含一个类型为SPDPdiscoveredParticipantData
(对应于Fast DDS的数据类型是ParticipantProxyData)的数据对象。这个数据对象的值来源于参与者(Participant)的属性。如果这些属性发生变化,这个数据对象就会被替换掉。
SPDPbuiltinParticipantWriter定期向预配置的locators列表发送此数据对象,以宣告participants在网络上的存在。这是通过定期调用StatelessWriter :: unsent_changes_reset
来实现的,这会导致StatelessWriter
重新发送其HistoryCache
中的所有的cachechange到所有locators。 SPDPbuiltinParticipantWriter
发送SPDPdiscoveredParticipantData
的周期速率默认为PSM指定的值。此周期应小于SPDPdiscoveredParticipantData
中指定的leaseDuration。
预配置的locators列表可能包括单播和多播的locators。端口号由每个PSM定义。这些locators只表示网络中可能存在的远程参与者,实际上并不需要参与者存在。通过定期发送SPDPdiscoveredParticipantData
,参与者可以按任意顺序加入网络。
SPDPbuiltinParticipantReader
接收来自远程参与者的SPDPdiscoveredParticipantData
公告。其中包含的信息包括远程参与者支持的EDP端点发现协议。然后使用适当的端点发现协议与远程参与者交换端点信息。
实现方可以通过对接收到的来自之前未知参与者的数据对象的响应中发送额外的SPDPdiscoveredParticipantData
,以尽量减少任何启动延迟,但这种行为是可选的。实现方也可以让用户选择是否要用新发现的参与者的新的locators自动扩展预配置的locators列表。这能够启用非对称locator列表。这最后两项功能是可选的,并不是实现互操作性所必需的。——实现
SPDPdiscoveredParticipantData
SPDPdiscoveredParticipantData用于定义SPDP阶段要交换的data。
---------------------类图 P116
从类图中可以看到,SPDPdiscoveredParticipantData继承了ParticipantProxy,因此包含了所有配置发现的Particiapnt的信息;也继承了ParticipantBuiltinTopicData,它提供了DDS built-in DataReader所需要的信息
SPDPdiscoveredParticipantData的属性:
attribute | type | meaning |
---|---|---|
domainId | DomainId | DDS domainId |
domainTag | string | DDS domainTag |
protocolVersion | ProtocolVersion_t | RTPS protocol version |
guidPrefix | GuidPrefix_t | |
vendorId | VendorId_t | 供应商id |
expectsInlineQos | ||
metatrafficUnicastLocatorList | ||
metatrafficMulticastLocatorList | ||
defaultUnicastLocatorList | ||
defaultMulticastLocator List | ||
availableBuiltinEndpoints | ||
leaseDuration | ||
manualLivelinessCount | ||
builtinEndpointQos |
SPDP中使用的EndPoints
---------- 图P 118
SPDP Endpoints的EntityID:
ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER
SPDPbuiltinParticipantWriter
SPDP Writer属性如下:
attribute | type | value |
---|---|---|
unicastLocatorList | Locator_t[*] | |
multicastLocatorList | Locator_t[*] | |
reliabilityLevel | ReliabilityKind_t | |
topicKind | TopicKind_t | |
resendPeriod | Duration_t | |
readerLocators | ReaderLocator[*] |
SPDPbuiltinParticipantReader
SPDP Reader属性如下:
attribute | type | value |
---|---|---|
unicastLocatorList | Locator_t[*] | |
multicastLocatorList | Locator_t[*] | |
reliabilityLevel | ReliabilityKind_t | |
topicKind | TopicKind_t |
SPDPbuiltinParticipantReader的HistoryCache中包含了所有活跃的participants的信息,key用来识别每个不同的participant(通过participant GUID)。
每当SPDPbuiltinParticipantReader接收到关于participant的信息时,SPDP会检查HistoryCache,寻找一个与participant GUID匹配的key的内容。如果没有找到匹配的key的条目,就会以参与者的GUID为key添加新的条目。
SPDP会周期性检查SPDPbuiltinParticipantReader的historycache,寻找旧的条目,这些条目被定义为那些超过leaseDuration没有收到消息的条目。然后删除它们。
物理端口
预先配置的locators中必须使用以下端口:
Port | Locators configured using this port |
---|---|
SPDP_WELL_KNOWN_UNICAST_PORT | entries in SPDPbuiltinParticipantReader.unicastLocatorList,unicast entries in SPDPbuiltinParticipantWriter.readerLocators |
SPDP_WELL_KNOWN_MULTICAST_PORT | entries in SPDPbuiltinParticipantReader.multicastLocatorList,multicast entries in SPDPbuiltinParticipantWriter.readerLocators |
SEDP
SEDP定义了两个participants之间为了互相发现彼此Writer and Reader端点而交换信息的协议。Participant可以支持多种EDPs协议,必须要支持SEDP。
类似于SPDP,SEDP也使用预先定义的built-in Endpoints。使用预定义的内置端点意味着一旦参与者知道了另一参与者的存在,它就可以假定远程参与者提供的内置端点的存在,并与本地匹配的内置端点建立联系。
用于在内置端点之间通信的协议与用于应用定义端点的协议相同。因此,通过读取内置的reader端点,协议虚拟机可以发现属于任何远程参与者的DDS实体的存在和QoS。类似地,通过写入内置的writer端点,participant可以告知其他participant本地DDS实体的存在和QoS。
因此,SEDP中内置主题的使用将整个发现协议的范围缩小到确定系统中存在哪些参与者以及与这些参与者的内置端点对应的ReaderProxy和WriterProxy对象的属性值。一旦知道这些信息,其他所有事情都是从将RTPS协议应用于内置RTPS读取器和写入器之间的通信中产生的。
SEDP中built-in Endpoints的使用
SEDP将映射DDS built-in Entities topic:“DCPSSubscription,” “DCPSPublication,” and “DCPSTopic”。根据DDS标准,这些Entities的reliability QoS是reliable,因此SEDP将映射每个的built-in DDS DataWriter和DataReader到对应的relibale的RTPS Writer and Reader Endpoints中。
SEDP中对built-in Endpoints的要求
就其余的内置端点而言,参与者只需要提供用于匹配本地和远程端点的内置端点。例如,如果DDS参与者只包含DDS DataWriters,那么唯一需要的RTPS内置端点就是SEDPbuiltinPublicationsWriter和SEDPbuiltinSubscriptionsReader。在这种情况下,SEDPbuiltinPublicationsReader和SEDPbuiltinSubscriptionsWriter内置端点没有任何作用。
Data Types
定义了DiscoveredWriterData, DiscoveredReaderData, 和DiscoveredTopicData关联到RTPS内置的实体“DCPSPublication,” “DCPSSubscription,” and “DCPSTopic”这三个topic中。
关联到每个RTPS built-in Endpoint的data type包含了所有信息。基于这个原因, DiscoveredReaderData 扩展了DDS定义的 DDS::SubscriptionBuiltinTopicData, DiscoveredWriterData 扩展了DDS::PublicationBuiltinTopicData, DiscoveredTopicData 扩展了
DDS::TopicBuiltinTopicData.
图P 122