每个协议文件都可包含import, items, protocols三项,但并非必须,解析时也按照前面顺序依次解析。

import|导入其他协议文件

json数组,填写需要引入的其他json协议文件,示例:

  1. {
  2. "import": [
  3. "example_utils.json",
  4. "example_setting.json"
  5. ]
  6. }

items

items当中每一项由名称-内容构成,经过解析,将注入当前协议集合的公共项库中,可在解析protocols时通过import关键字调用,用于在同一个item存在于多个协议时提高重用性。

name

表示该项名称,对应自定义脚本函数scriptsargs
from_frame_data参数项,同时,如需要生成波形,波形名称中也会含有name,因此需要保持唯一。

data_type

支持多种数值类型,用 data_type 表示,基础类型包括

  1. uint8_t uint16_t uint24_t uint32_t uint64_t
  2. int8_t int16_t int24_t int32_t int64_t
  3. float double

而为了节省字节占用,通常会将浮点型乘以倍数后以整形传输,例如 float 类型数据 ,需要以单字节int8_t传输,可根据实际情况乘以一定倍率,这里假设100,则有对应关系如下

  • 用户端:int8_t=[float,double]*100
  • 上位机:double=int8_t/100

协议定义中上位机端表示,也即int8_t/100
如果是数组,则可在末尾直接添加数组标识,如int8_t/100[3]

bytes

用于表示当前项占用的字节数,用于无法确定长度的item类型,如frame_tailreserved

type

表示item类型,使用不同类型item组合出目标协议格式

frame_header

协议固定帧头,用以协议数据检测,必须作为block中首项存在,示例:

  1. {
  2. "use": "frame_header",
  3. "hex": "55 04"
  4. }

frame_length

仅变长协议需要,且必须为帧头后一项

  1. {
  2. "use": "frame_length",
  3. "data_type": "uint16_t"
  4. }

frame_tail

协议帧尾,用于协议数据校验,非必须项,目前支持如下校验方式

  • 固定值校验,仅对帧尾进行固定值比对,相同则校验通过。

    1. {
    2. "use": "frame_tail",
    3. "check_type": "fixed",
    4. "hex": "ee"
    5. }
  • 和校验,对帧尾之前所有数据累加求和,sum类型为bytes对应长度的无符号整形,sum相等则校验通过。

    1. {
    2. "use": "frame_tail",
    3. "check_type": "sum",
    4. "bytes": 1
    5. }
  • 循环冗余校验(CRC),类似和校验,仅计算方式替换为CRC

    1. {
    2. "use": "frame_tail",
    3. "check_type": "crc",
    4. "polynomial": "0x5503",
    5. "initial_value": "0x5503",
    6. "final_xor": "0x5503",
    7. "reflect_input": true,
    8. "reflect_output": true
    9. }
  • 异或校验(BCC),类似和校验,仅计算方式替换为BCC

    1. {
    2. "use": "frame_tail",
    3. "check_type": "bcc"
    4. }

    reserved

    保留字节,作为协议中暂时不用部分的占用符

    1. {
    2. "use": "reserved",
    3. "bytes": 11,
    4. "placeholder": "0xff"
    5. }

    其中,placeholder表示当前保留字节填充字符(适用于write类型协议),若为空则默认填充0x00。

    flag

    用于表示标志项,支持位域,对于可写协议,将根据标志项生成对应下拉框控件,对于可读协议,将根据接收到的值显示对应标志项。

    1. {
    2. "use": "flag",
    3. "bit_field": [
    4. {
    5. "bits": 2,
    6. "name": "mode",
    7. "elements": [
    8. "write",
    9. "read",
    10. "restart=3"
    11. ]
    12. },
    13. {
    14. "bits": 2
    15. },
    16. {
    17. "bits": 1,
    18. "name": " led",
    19. "elements": [
    20. "off",
    21. "on"
    22. ]
    23. }
    24. ]
    25. }

    其中,name为空表示此项为保留位,bits表示占用比特,elements可单独指定枚举值,如上面restart=3,未指定则顺延,规则同C语言枚举。

    value

    表示常规数值项,read协议将生成只读文本控件,write协议将生成可编辑单行文本控件,若数据类型为数组,则将生成数组大小对应的资源数量,其中资源名称命名方式q_i,如这里为q_0,q_1,q_2,q_3。

    1. {
    2. "name": "q",
    3. "use": "value",
    4. "data_type": "float[4]"
    5. }

    line

    表示需要使用波形显示的数据项,除波形资源外,还将生成value对应全部资源。

    1. {
    2. "name": "eop",
    3. "use": "line",
    4. "data_type": "uint8_t/100"
    5. }

    position

    表示需要显示三维位置的数据项,除三维位置资源外,还将生成二维位置,line相应资源,注意,数据类型必须为长度为3的数组。

    1. {
    2. "name": "pos",
    3. "use": "position",
    4. "data_type": "int24_t/1000[3]"
    5. }

    attitude

    表示需要显示物体3D姿态的数据项,除姿态资源外,还将生成line相应资源,注意,数据类型必须为长度为3的数组。

    1. {
    2. "name": "angle",
    3. "use": "attitude",
    4. "data_type": "int16_t/100[3]"
    5. }

    position_attitude

    表示需要同时显示3D位置和姿态的数据项,不同于单纯position,此项生成的3D资源中,模型将同时绘制位置及姿态角,2D资源中将额外位置航向角。

    1. {
    2. "name": "pose",
    3. "use": "position_attitude",
    4. "position": {
    5. "data_type": "int24_t/1000[3]"
    6. },
    7. "attitude": {
    8. "data_type": "int16_t/100[3]"
    9. }
    10. }

    内存分布:position+attitude

    hex_array

    表示16进制变长数组,对于read协议,将生成对应多行只读控件,16进制显示,对于write协议,将生成对应可编辑多行控件。

    1. {
    2. "name": "dt",
    3. "use": "hex_array",
    4. "length": {
    5. "data_type": "uint16_t"
    6. }
    7. }

    内存分布:length+data

    block_with_id

    同一帧协议,但根据block+id不同,数据分别归属于不同组,例如可用于多激光测距传感器TOFSense级联情况下数据输出协议帧。

    1. {
    2. "use": "block_with_id",
    3. "block_id": {
    4. "data_type":"uint8_t"
    5. },
    6. "block": [
    7. {
    8. "use":"value",
    9. "data_type":"uint32_t",
    10. "name":"systemTime"
    11. },
    12. {
    13. "use":"line",
    14. "data_type":"uint24_t/1000",
    15. "name":"dis"
    16. },
    17. ......
    18. ]
    19. }

    内存分布:block_id+block

    group

    同一帧协议中,拥有多个block,block之间根据block_id区分,block个数通过block_count计算,可用于室内高精度实时定位系统 LinkTrack 的Node系列变长协议,用以显示多个节点位置信息或距离信息等。

    1. {
    2. "use": "group",
    3. "block_count": {
    4. "data_type": "uint8_t"
    5. },
    6. "block_id": {
    7. "import": "LtBlockRoleId"
    8. },
    9. "block": [
    10. {
    11. "import": "LtDis"
    12. },
    13. {
    14. "import": "LtFpRssi"
    15. },
    16. ......
    17. ]
    18. }

    内存分布:block_count+[block_id+block]+…+[block_id+block]

    protocols|协议

    json数组,可定义多个不同协议

    name

    协议名称需要保持唯一

    mode

    协议模式,均从上位机角度描述,分为如下三种

  • read 表示只读协议,上位机仅从收到的数据中提取并解析该协议

  • write 表示只写协议,上位机仅根据协议生成对应控件,用户可修改控件生成新的协议帧数据,用于下发
  • read_write 表示可读可写协议,含括上面两种

    minimum_length

    表示协议帧最小字节数,对定长协议而言,表示全部字节数,用于校验目的,若格式定义错误导致实际解析的协议最小长度不等于用户输入的minimum_length,加载协议时将报错提醒。

    block

    json数组,按先后顺序定义了整个协议格式,可通过import调用items中的公共项,也可直接编写单项,具体项定义规则参考前面items

    scripts

    可通过JavaScript语法定义多个数据处理函数,处理来自当前所属协议的实时数据以及用户自定义的数据,并将函数输出结果通过本软件支持的可视化方式呈现出来,同时也支持console输出,用户可在脚本函数中自定义打印内容,内容将在软件的日志信息中实时显示,用户可用脚本定义自己的数据处理算法,如常见数据滤波算法(示例中提供了中值滤波,滑动窗口滤波,求取标准差等函数),或者做数据检查,日志提醒输出等。

    1. "scripts": {
    2. "global_properties": [
    3. "length"
    4. ],
    5. "import": ["example_script.js"],
    6. "items": [
    7. {
    8. "name": "pos_processed",
    9. "args": {
    10. "from_frame_data": [
    11. "pos_0",
    12. "pos_1",
    13. "pos_2"
    14. ],
    15. "from_user_input": [
    16. "z_offset"
    17. ],
    18. "from_global_properties": [
    19. "length"
    20. ]
    21. },
    22. "outputs": [
    23. "x","y","z"
    24. ],
    25. "function": "positionFilter",
    26. "use": "position"
    27. },
    28. {
    29. "name": "angle_0",
    30. "args": {
    31. "from_frame_data": [
    32. "angle_0"
    33. ],
    34. "from_user_input": [
    35. "min","max"
    36. ]
    37. },
    38. "function": "checkRange"
    39. }
    40. ]
    41. }

    其中

  • global_properties表示当前分组下所有脚本函数均可使用的全局属性,软件将自动生成对应的控件供用户编辑属性,如用于定义多个滤波函数的数据长度

  • import用于引入JavaScript文件,后续function即从引入的文件中查找
  • items表示脚本的集合
    • name表示脚本名称,将用于定义资源名称
    • args表示将会传入脚本函数的参数集合,不需要类型无需填写,按顺序传入function参数列表
      • from_frame_data 从实时协议帧中获取数据
      • from_user_input 软件将为每个脚本单独生成各自的参数控件,可实时改变参数
      • from_global_properties 从前面的global_properties中获取参数
  • function 表示脚本函数,简单函数可直接行内编辑,但没有语法检查,推荐在JavaScript文件中编辑,倘若在前面import的文件中无法找到函数,则尝试直接解析函数,若解析失败则会报错。