RTPS协议之Messages Module


我们承担ROS,FastDDS,C++,cmake等技术的项目开发和专业指导和培训,有10年+相关工作经验,质量有保证,如有需要请私信联系。

Type定义

TypePurpose
ProtocolId_t
SubmessageFlagsub msg flag
SubmessageKind枚举值用于标识是什么类型的sub msg,有这些:DATA, GAP, HEARTBEAT, ACKNACK, PAD, INFO_TS, INFO_REPLY, INFO_DST, INFO_SRC, DATA_FRAG, NACK_FRAG, HEARTBEAT_FRAG
Time_t时间戳,至少到ns,TIME_ZERO,TIME_INVALID TIME_INFINITE
Count_t保存递增的计数,用于识别重复消息
ParameterId_t用于在参数列表中唯一标识参数的类型。主要在Discovery中广泛使用,主要用于定义QoS参数。一些被保留用于协议定义的参数,另一些可以用于供应商定义的参数。
FragmentNumber_t用于保存帧序号?
GroupDigest_t用于保存唯一标识属于同一参与者的一组实体的摘要值的类型。

RTPS消息结构

RTPS message structure

RTPS协议发送的每一条消息都有一个固定的长度。这个长度不是由RTPS协议明确发送的,而是作为传输底层的一部分,RTPS消息是通过这种方式发送的。在面向数据包的传输(例如UDP/IP)的情况下,消息的长度已经由传输头部提供。面向流的传输(例如TCP)则需要在消息前面插入长度,以便识别RTPS消息的边界

RTPS消息头

RTPS Header
消息头标识这条消息属于RTPS协议,标识了协议版本和供应商,具体包含以下内容:

字段类型含义抓包中对应的字段
protocolProtocolId_t表示这个rtps消息Magic: RTPS
versionProtocolVersion_t标识rtps协议的版本号Protocol version: 2.2
vendorIdVendorId_tRTPS协议实现的供应商标识vendorID: 01.15(eProsima - Fast-RTPS)
guidPrefixGuidPrefix_tGUIDs中使用的默认的prefix?TODO要确认
  • guidPrefix定义了一个默认前缀,可以用来重构消息中包含的子消息的全局唯一标识符(GUIDs)。guidPrefix允许子消息只包含GUID的EntityId部分,因此可以避免在每个GUID上重复相同的前缀,从而节省空间。

子消息结构

每个RTPS消息都是由一个或多个子消息组成。
Structure of the RTPS Message Header
所有的子消息都是由 一个SubmessageHeader+0个或多个消息元素 组成。子消息头部用于标识子消息的种类和该子消息内的可选元素。

子消息头结构:

字段类型含义
submessageIdSubmessageKind标识了Submessage.的消息类型,消息类型在下面列出
flagsSubmessageFlag[8]标识用于编码子消息的字节顺序,子消息中的可选元素的存在,并可能修改子消息的解释。有8个可能的标志。第一个标志(索引0)标识用于编码子消息的字节顺序。其余的标志会根据子消息的种类有不同的解释,并分别为每个子消息进行描述。
submessageLengthushort表示子消息的长度。由于RTPS消息由子消息的连结组成,所以子消息的长度可用于跳转到下一个子消息。

submessageLength:表示Submessage的长度,如果submessageLength> 0,有以下两种情况:

  • 从子消息内容的开始到下一个子消息头的开始的长度(如果该子消息不是消息中的最后一个子消息)。
  • 或者它是剩余的消息长度(如果子消息是消息中的最后一个子消息)。解读消息的解析器可以区分这两种情况,因为它知道消息的总长度。

如果子消息长度等于0,那么子消息就是消息中的最后一个子消息,并且会延伸到消息的结束。这使得发送大于64k的子消息成为可能(这是可以存储在submessageLength字段中的最大长度),只要它们是消息中的最后一个子消息。

RTPS消息接收者

一个消息中的子消息的解释和含义可能取决于该消息中之前的子消息。因此,消息的接收者必须维护同一消息中先前反序列化的子消息的状态。这种状态被建模为每次处理新消息时复位的RTPS接收器的状态,并为每个子消息的解释提供上下文。
 RTPS Receiver

对每一条新的message,Receiver的状态按下表列出的内容被重置和初始化。对应Fast DDS中的MessageReceiver

name初始值
sourceVersionPROTOCOLVERSION
sourceVendorIdVENDORID_UNKNOWN
sourceGuidPrefixGUIDPREFIX_UNKNOWN
destGuidPrefix接收消息的participant的guid prefix
UnicastReplyLocatorList
multicastReplyLocatorList
haveTimestampFalse
timestampTIME_INVALID
messageLength

Message Receiver必须遵守以下规则:

  1. 如果Submessage的消息头不能被读取,则其他消息体无效
  2. submessageLength为下一个Submessage的起始位置,或指示子消息扩展到消息的结束。如果这个字段是无效的,那么这条消息无效。
  3. 具有未知SubmessageId的子消息必须被忽略,并且必须要解析继续下一个子消息。也就是说,不在SubmessageKind范围内的消息id必须要被忽略。未知vendorId的供应商的SubmessageIds也必须被忽略,并且必须解析继续到下一个子消息。
  4. Submessage的接收者应忽略未知的flag。RTPS2.4的实现跳过了所有被标记为“X”的flags
  5. 一个有效的submessageLength字段必须要被用于发小下一条Submessage, 即使Submessage有明确的id
  6. 一个已知但无效的子消息会使消息的其余部分失效。

子消息何时被视为无效,接收到有效的头部和/或子消息,对于接收者有两个影响::

  • 它可以改变接收者的状态;这个状态影响了消息中后续子消息的解释方式。RTPS Submessages部分会讨论每个子消息如何改变状态。在此协议版本中,只有Header和子消息InfoSourceInfoReplyInfoDestinationInfoTimestamp改变了接收者的状态。
  • 它可以影响消息的目标Endpoint的行为,这适用于基本的RTPS消息:DataDataFragHeartBeatAckNackGap, HeartbeatFrag, NackFrag.

RTPS SubmessageElements

每个RTPS消息包含可变数量的RTPS子消息。每个RTPS子消息反过来又是由一组预定义的原子构建块构成,这些构建块被称为SubmessageElements(子消息元素)。RTPS 2.4定义了以下子消息元素:GuidPrefix, EntityId, SequenceNumber, SequenceNumberSet, FragmentNumber, FragmentNumberSet, VendorId, ProtocolVersion, LocatorList, Timestamp, Count, SerializedData, ParameterListGroupDigest
RTPS SubmessageElements

  • GuidPrefix和EntityId:GUID_t的组成部分
  • VendorId:供应商id
  • ProtocolVersion:协议版本
  • SequenceNumber:64位带符号的整数,值的范围为:-2^63 <= N <= 2^63-1,
  • SequenceNumberSet:SequenceNumberSet被限制在小于256的一个区间内,换句话说,一个有效的SequenceNumberSet必须要校验:
maximum(SequenceNumberSet) - minimum(SequenceNumberSet) < 256
minimum(SequenceNumberSet) >= 1

SequenceNumberSet子元素可以用于选择性地请求重新发送一组序列号。SequenceNumberSet子元素的结构:

字段类型含义
baseSequenceNumber_t集合中的第一个数据
setSequenceNumber_t[*]一个连续的集合,每个都会校验:base <= element(set) <= base+255
  • FragmentNumber:32位无符号整数,用于Submessage标识一个分片序列化的特定的分片。
  • FragmentNumberSet
  • Timestamp:时间
  1. ParameterList
  2. Count
  • LocatorList:locators的列表
字段类型含义
valueLocator_t[*]locators的列表
  • SerializedData:SerializedData包含数据对象值的序列化表示。RTPS协议不会解释序列化的数据流,因此这个数据流是无法直接能看懂的。
字段类型含义
valueoctet[*]序列化的数据流
  • SerializedDataFragment:分片的数据流。和上面一样,rtps协议不会解释数据流,所以这个数据流是晦涩难懂的
字段类型含义
valueoctet[*]序列化的数据流
  • GroupDigest:GroupDigest用于以紧凑的方式传递一组EntityId_t。
字段类型含义
valueGroupDigest_t序列化的数据流

RTPS Header

每一条 RTPS Message必须以一个 Header开头.
目的:Header必须指定这条消息属于RTPS协议,RTPS协议的版本
内容:
有效性:

RTPS Submessages

RTPS协议定义了不同类型的Submessages。划分为两类:Entity-Submessages和Interpreer-Submessages。Entity-Submessages的目标是RTPS Entity;Interpreer-Submessages修改RTPS Receiver的状态,并提供有助于处理后续实体子消息的上下文。
Entity Submessages是:

  • Data:包含application的Data对象的信息,Data Submessages由Writers发送给Readers。
  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值