每个协议文件都可包含import, items, protocols三项,但并非必须,解析时也按照前面顺序依次解析。
import|导入其他协议文件
json数组,填写需要引入的其他json协议文件,示例:
{"import": ["example_utils.json","example_setting.json"]}
items
items当中每一项由名称-内容构成,经过解析,将注入当前协议集合的公共项库中,可在解析protocols时通过import关键字调用,用于在同一个item存在于多个协议时提高重用性。
name
表示该项名称,对应自定义脚本函数scripts中args
的from_frame_data参数项,同时,如需要生成波形,波形名称中也会含有name,因此需要保持唯一。
data_type
支持多种数值类型,用 data_type 表示,基础类型包括
uint8_t uint16_t uint24_t uint32_t uint64_tint8_t int16_t int24_t int32_t int64_tfloat double
而为了节省字节占用,通常会将浮点型乘以倍数后以整形传输,例如 float 类型数据 ,需要以单字节int8_t传输,可根据实际情况乘以一定倍率,这里假设100,则有对应关系如下
- 用户端:int8_t=[float,double]*100
- 上位机:double=int8_t/100
协议定义中上位机端表示,也即int8_t/100
如果是数组,则可在末尾直接添加数组标识,如int8_t/100[3]
bytes
用于表示当前项占用的字节数,用于无法确定长度的item类型,如frame_tail,reserved等
type
frame_header
协议固定帧头,用以协议数据检测,必须作为block中首项存在,示例:
{"use": "frame_header","hex": "55 04"}
frame_length
仅变长协议需要,且必须为帧头后一项
{"use": "frame_length","data_type": "uint16_t"}
frame_tail
协议帧尾,用于协议数据校验,非必须项,目前支持如下校验方式
固定值校验,仅对帧尾进行固定值比对,相同则校验通过。
{"use": "frame_tail","check_type": "fixed","hex": "ee"}
和校验,对帧尾之前所有数据累加求和,sum类型为
bytes对应长度的无符号整形,sum相等则校验通过。{"use": "frame_tail","check_type": "sum","bytes": 1}
循环冗余校验(CRC),类似和校验,仅计算方式替换为CRC
{"use": "frame_tail","check_type": "crc","polynomial": "0x5503","initial_value": "0x5503","final_xor": "0x5503","reflect_input": true,"reflect_output": true}
异或校验(BCC),类似和校验,仅计算方式替换为BCC
{"use": "frame_tail","check_type": "bcc"}
reserved
保留字节,作为协议中暂时不用部分的占用符
{"use": "reserved","bytes": 11,"placeholder": "0xff"}
其中,
placeholder表示当前保留字节填充字符(适用于write类型协议),若为空则默认填充0x00。flag
用于表示标志项,支持位域,对于可写协议,将根据标志项生成对应下拉框控件,对于可读协议,将根据接收到的值显示对应标志项。
{"use": "flag","bit_field": [{"bits": 2,"name": "mode","elements": ["write","read","restart=3"]},{"bits": 2},{"bits": 1,"name": " led","elements": ["off","on"]}]}
其中,name为空表示此项为保留位,bits表示占用比特,elements可单独指定枚举值,如上面
restart=3,未指定则顺延,规则同C语言枚举。value
表示常规数值项,
read协议将生成只读文本控件,write协议将生成可编辑单行文本控件,若数据类型为数组,则将生成数组大小对应的资源数量,其中资源名称命名方式q_i,如这里为q_0,q_1,q_2,q_3。{"name": "q","use": "value","data_type": "float[4]"}
line
表示需要使用波形显示的数据项,除波形资源外,还将生成
value对应全部资源。{"name": "eop","use": "line","data_type": "uint8_t/100"}
position
表示需要显示三维位置的数据项,除三维位置资源外,还将生成二维位置,
line相应资源,注意,数据类型必须为长度为3的数组。{"name": "pos","use": "position","data_type": "int24_t/1000[3]"}
attitude
表示需要显示物体3D姿态的数据项,除姿态资源外,还将生成
line相应资源,注意,数据类型必须为长度为3的数组。{"name": "angle","use": "attitude","data_type": "int16_t/100[3]"}
position_attitude
表示需要同时显示3D位置和姿态的数据项,不同于单纯
position,此项生成的3D资源中,模型将同时绘制位置及姿态角,2D资源中将额外位置航向角。{"name": "pose","use": "position_attitude","position": {"data_type": "int24_t/1000[3]"},"attitude": {"data_type": "int16_t/100[3]"}}
hex_array
表示16进制变长数组,对于
read协议,将生成对应多行只读控件,16进制显示,对于write协议,将生成对应可编辑多行控件。{"name": "dt","use": "hex_array","length": {"data_type": "uint16_t"}}
block_with_id
同一帧协议,但根据
block+id不同,数据分别归属于不同组,例如可用于多激光测距传感器TOFSense级联情况下数据输出协议帧。{"use": "block_with_id","block_id": {"data_type":"uint8_t"},"block": [{"use":"value","data_type":"uint32_t","name":"systemTime"},{"use":"line","data_type":"uint24_t/1000","name":"dis"},......]}
group
同一帧协议中,拥有多个block,block之间根据
block_id区分,block个数通过block_count计算,可用于室内高精度实时定位系统 LinkTrack 的Node系列变长协议,用以显示多个节点位置信息或距离信息等。{"use": "group","block_count": {"data_type": "uint8_t"},"block_id": {"import": "LtBlockRoleId"},"block": [{"import": "LtDis"},{"import": "LtFpRssi"},......]}
内存分布:
block_count+[block_id+block]+…+[block_id+block]protocols|协议
name
mode
协议模式,均从上位机角度描述,分为如下三种
read表示只读协议,上位机仅从收到的数据中提取并解析该协议write表示只写协议,上位机仅根据协议生成对应控件,用户可修改控件生成新的协议帧数据,用于下发-
minimum_length
表示协议帧最小字节数,对定长协议而言,表示全部字节数,用于校验目的,若格式定义错误导致实际解析的协议最小长度不等于用户输入的
minimum_length,加载协议时将报错提醒。block
json数组,按先后顺序定义了整个协议格式,可通过
import调用items中的公共项,也可直接编写单项,具体项定义规则参考前面itemsscripts
可通过JavaScript语法定义多个数据处理函数,处理来自当前所属协议的实时数据以及用户自定义的数据,并将函数输出结果通过本软件支持的可视化方式呈现出来,同时也支持console输出,用户可在脚本函数中自定义打印内容,内容将在软件的日志信息中实时显示,用户可用脚本定义自己的数据处理算法,如常见数据滤波算法(示例中提供了中值滤波,滑动窗口滤波,求取标准差等函数),或者做数据检查,日志提醒输出等。
"scripts": {"global_properties": ["length"],"import": ["example_script.js"],"items": [{"name": "pos_processed","args": {"from_frame_data": ["pos_0","pos_1","pos_2"],"from_user_input": ["z_offset"],"from_global_properties": ["length"]},"outputs": ["x","y","z"],"function": "positionFilter","use": "position"},{"name": "angle_0","args": {"from_frame_data": ["angle_0"],"from_user_input": ["min","max"]},"function": "checkRange"}]}
其中
global_properties表示当前分组下所有脚本函数均可使用的全局属性,软件将自动生成对应的控件供用户编辑属性,如用于定义多个滤波函数的数据长度import用于引入JavaScript文件,后续function即从引入的文件中查找items表示脚本的集合name表示脚本名称,将用于定义资源名称args表示将会传入脚本函数的参数集合,不需要类型无需填写,按顺序传入function参数列表from_frame_data从实时协议帧中获取数据from_user_input软件将为每个脚本单独生成各自的参数控件,可实时改变参数from_global_properties从前面的global_properties中获取参数
- function 表示脚本函数,简单函数可直接行内编辑,但没有语法检查,推荐在JavaScript文件中编辑,倘若在前面import的文件中无法找到函数,则尝试直接解析函数,若解析失败则会报错。
