灵感来源于凌翔大神,膜拜。。。(摆脱通信双方必须时刻保持协议格式完全一致)
kv:key-value键值对
kv消息对外呈现为字符数组(字符串),可通过网络等其他方式进行传输,消息的发送方和接收方采用同一套配置(预定义大量键值),对字符串进行解析,从而获取各个变量值。
举例:定义距离、方位、俯仰的键值分别为1、2、3;
如果通过解析字符串,获得
{
1:50;
2:25;
}
则表示距离为50,方位为25。
键值对
键值对格式中包含的要素有键值、有效数据长度和有效数据,如图
由内部数据转换成键值对,并转换成字符数组的过程,成为序列化(借鉴 google protobuf 术语),序列化后的字符数组按“键值 + 有效长度 + 有效数据”组成;从字符数组中获取有效数据的过程称为反序列化,为序列化的逆过程。
“键值 + 有效长度”是公用解析头,同时,一个键值对(key-value对、kv对)只包含一个数据。
域
键值对(key-value对、kv对)是kv消息模块的最小数据单元,只包含一个数据,无法表示类似{ 距离、方位、俯仰……}等信息。定义“域”为kv对的组合来表达多组kv对,如图:
上述示意图无法获取键值对数量,同时表达该域所表达的含义,为解决以上问题,“域”的格式改进为
域的键值表示字符数组的含义,其有效长度则表示本“域”的有效数据范围,即包含多少kv对。
由于域格式和键值对格式的头部是公用的,域的键值和键值对的键值需要有明确的区分。当检测到为域键值,则需要继续往下(下一层级)解析;当检测到为键值对的键值,则解析完当前数据后中止这一层级的解析(已解析到最小数据单元)。
基于同一个数据中不会存在相同的变量,域中的键值对的键值是不可以重复的,插入同一个键值(key),则会覆盖上一次的赋值,等同于基本数据类型与结构体的概念。
在程序设计中会涉及到结构体嵌套的场景,以雷达数据处理中的数据点迹包为例,一个点迹包中会包含多组点迹,每组点迹又包含多组信息(r、a、e、vd、snr、ad等),同时点迹包中需要指定有效的点迹数量信息,因此扩展域格式2,如图所示:
域内部自嵌套,域的键值可以重复。以点迹包为例,点迹1、2……分别对应(子)域1、2……,键值对1对应有效点迹数量。
注意:其实点迹包中的键值对1(有效点迹数量)可以不需要,通过对(子)域的解析,能获得点迹数量。由于自嵌套的逻辑,可以无限嵌套下去,因此建议对模块设计增加最大嵌套层数的限制,同时使用这套逻辑的时候,尽量注意,不要嵌套太多。
消息
消息是对域的补充。域适用的场景主要为同一个进程内部,相当于结构体互传,使用域可以使各个模块提供统一的对外接口。域也可以跨进程传递数据,如在使用udp进行end-to-end网络传输,数据经过其他媒介传输,可能会造成数据损坏,通常情况下会增加一些保护措施,比如同步字头、校验和、同步字尾等。
将上述保护措施应用到域格式中,形成(kv)消息,如图:
同步字头、校验和、同步字尾都是可选的,也可设计自定义的保护措施。
最终,kv消息的格式为
附:程序中应用不多,内部只应用在BITE上,主要针对独立线程工作的模块,生成kv域对象,在雷达模块中解析,转对外接口;同时,生成kv消息,送配套的调试软件。