Adapter 生成器指南
适配程序(Adapter)生成器是一个快速生成 Adapter 程序的工具。只需在图形化界面中简单配置参数,便可快速创建相应的 Adapter 程序,然后在此基础上进行二次开发,实现标准接口无法满足的复杂功能。
生成Adapter工程
在菜单栏依次单击 机器人与通信 > 适配程序(Adapter)生成器,弹出适配程序(Adapter)生成器窗口。
注意
在 适配程序(Adapter)生成器 窗口中进行配置时,请保持方案处于打开状态,以便正常保存 Adapter 工程。
配置“基础设置”
在基础设置 窗口,进行以下配置:
配置项
说明
Adapter工程名称
指定 Adapter 工程名称。工程名称是由字母、数字或下划线组成的字符串(不能以数字作为起始字符)。
通信对象
RVS-Vision。仅需配置 RVS-Vision 的输入与输出。
通信协议
TCP/IP
通信格式
指定通信传输的数据格式,目前仅支持 ASCII 文本形式。若需使用 HEX 二进制格式,需在后端 Adapter 代码中将通信模式设置为
hex(参见示例:二进制协议)。服务类型
指定 Adapter 工程作为 TCP/IP 通信的服务端或客户端。
服务端监听外部连接,客户端主动连接外部设备。默认作为服务端。平移单位
mm(毫米,默认)和 m(米)
旋转单位
°(角度,默认)和 rad(弧度)
旋转方式
旋转方式通常选择 欧拉角 即可。使用欧拉角时,必须与机器人控制器的旋转顺序一致。根据机器人类型,选择对应的格式:
Z-Y'-X''(ZYX_ROTATED):ABB / EPSON / ESTUN / KUKA / NACHIX-Y-Z(XYZ_STATIC):AUBO / DENSO / DOBOT / DELTA / EFORT / ELITE / FANUC / FLEXIV / FR / HANS / HYUNDAI / JAKA / MELFA / ROKAE / SIASUN / STEP / TM / YASKAWAZ-Y'-Z''(ZYZ_ROTATED):COMAU / DOOSAN / KAWASAKI / QJARX-Y'-Z''(XYZ_ROTATED):STAUBLI / TURINur_rot:UR
浮点小数位数
指定数据的小数位数。默认为 4,可选范围为 1~20。
字符串分割符
指定数据间的分割字符。默认为英文逗号,常用分割符有英文逗号、分号和空格。
字符串终止符
指定指令的结束字符。默认为\r,常用终止符有\n、\r、\r\n。
添加首尾字符
指定整条指令的首尾字符。勾选后需要输入首尾字符,默认为空字符。例如,指令为“p,1\r”,若首字符使用“<”,尾字符使用“>”,则整条指令将表示为“<p,1>\r”。具体用法可参考示例:带帧前后缀的 ASCII 协议。
备注
欧拉角格式配置错误会导致姿态方向不正确。配置前应确认机器人控制器采用静态轴还是旋转轴,以及具体轴顺序。
完成上述配置后,单击 下一页,进入 RVS-Vision输入 窗口。
配置“RVS-Vision输入”
在 RVS-Vision输入 窗口,设置机器人或上位机发送给 RVS-Vision 的指令格式。具体配置项包括 拍照指令 、设置RVS-Vision步骤参数 和 从RVS-Vision获取机器人名称。
拍照指令
设置 RVS-Vision 的拍照指令。
备注
该指令主要用于触发 RVS-Vision 工程运行。除此之外,该指令还可以根据需求设置以下功能:
如果 RVS-Vision 工程存在参数配方,该指令支持切换参数配方。
如果相机的安装方式为 Eye In Hand,或者 RVS-Vision 工程存在“路径规划”步骤,该指令支持将机器人拍照位姿传入 RVS-Vision 工程。
请根据以下说明配置 拍照指令。
表格说明
名称:整条指令中各部分的名称。
参数值:各部分名称所对应的具体值。
位置:各部分在整条指令中所处的起始位置,从 1 开始排序,一个分隔符表示一个位置结束。
长度:各部分占用的字段数(字段指使用 字符串分隔符 隔开的数据)。
位置 与 长度 之间的关系:下一个参数的起始位置 = 上一个参数的起始位置 + 上一个参数的长度。
名称
参数值
位置
长度
指令码
触发 RVS-Vision 工程运行的指令码,默认为 p,可修改。
固定为 1
固定为 1
工程编号
RVS-Vision 工程编号,为正整数。
固定为 2
固定为 1
配方编号(可选)
RVS-Vision 工程中参数配方的编号,为正整数。
可设置
固定为 1
机器人拍照位姿(可选)
如果相机安装方式为 Eye In Hand,该指令将把机器人拍照位姿传入 RVS-Vision 工程。该参数可设置为 JPs 或 "JPs+法兰位姿"。
可设置
若旋转方式选择 欧拉角:
- 位姿形式为 JPs,则固定为 6
- 位姿形式为 "JPs+法兰位姿",则固定为 12
- 位姿形式为 JPs,则固定为 6
- 位姿形式为 "JPs+法兰位姿",则固定为 13
备注
每个字段都有位置和长度。位置从 1 开始,命令码通常位于第 1 个字段。各字段占用区间不得重叠,可以按协议要求保留空位。
ASCII 示例:
p,1,2,0.0,10.0,20.0,30.0,40.0,50.0\r
该示例可解释为:
p:指令码1:工程编号2:配方编号后续 6 个数:机器人关节角。
如果选择“JPs+法兰位姿”,位姿字段至少包含 12 个数:前 6 个为关节角,后续数据为法兰位置和旋转。具体长度由所选旋转方式决定。
单击 参数值、位置、长度 三列中高亮显示的单元格,可根据需求修改其值。
注意
修改时,需注意以下事项:
对于不同指令,指令码需保证唯一。
不同参数所占的字段位置切勿重叠。例如,机器人拍照位姿的位置为3,长度为12。如果配方编号的位置为4,长度为1,此时机器人拍照位姿的第二个字段位置与配方编号的位置重叠。如果配方编号的位置大于或等于15,则机器人拍照位姿与配方编号的位置将不存在重叠。
若各参数所对应的位置之间存在空缺,则空缺位置默认使用0填充。在预览时,空缺位置显示为 预留位置,对应的值为0。例如,配方编号的位置为3,长度为1,机器人拍照位姿的位置为6,长度为12,则位置4和5空缺。若将机器人拍照位姿的位置修改为4,便可消除该空缺位置。建议通过修改位置,消除不必要的空缺位置。
完成上述配置后,单击 预览,将根据配置项生成相应的指令示例。
小技巧
在 指令预览 窗口,将鼠标的光标悬浮到字段名称上,字段名称及对应的数据将高亮显示。
设置RVS-Vision步骤参数(可选)
若无法使用参数配方对步骤参数进行预设置,或者需要根据外部信息对步骤参数进行设置,则勾选 设置RVS-Vision步骤参数,从而配置“设置RVS-Vision步骤参数”指令。
配置前请确认:
工作流和步骤选择正确。
属性路径与目标参数一致。
字段位置和字段长度符合外部协议。
外部值的数据类型能转换为目标属性类型。
参数修改发生在工作流执行之前。
选择是否勾选 与拍照指令合并。
备注
与拍照指令合并 是指将设置 RVS-Vision 步骤参数的指令合并到拍照指令中,即在拍照指令的基础上追加步骤参数字段。
设置RVS-Vision步骤参数 指令可以与拍照指令合并成一条指令,也可以单独作为一条指令(此时需在调用拍照指令之前被调用)。两种方式适用场景如下:
独立指令适合先设置多个参数,随后再触发拍照的控制流程。
合并指令适合一个报文完成参数更新和拍照触发。
勾选:下列表格中的配置项将复用拍照指令中的设置,直接执行第二步即可。
不勾选:请根据下表单独配置"设置 RVS-Vision 步骤参数"指令。
名称
参数值
位置
长度
指令码
设置 RVS-Vision 步骤参数的指令码,默认为 s,可修改。
固定为 1
固定为 1
工程编号
RVS-Vision 工程编号,为正整数。
固定为 2
固定为 1
配方编号(可选)
RVS-Vision 工程中参数配方的编号,为正整数。
可设置
固定为 1
选择步骤参数。
单击 选择步骤参数,在弹出的窗口中,根据以下操作选择步骤参数:
a. 选择方案中的某个工程,用于显示将要设置的步骤及对应的参数名称。
b. 在 选择步骤 选项下,选择需设置的步骤。
c. 在 步骤参数 选项下,展开勾选步骤的参数名称。
d. 单击 确定。
备注
若勾选 设置RVS-Vision步骤参数,则必须选择步骤参数,否则将出现报错提示。
步骤和参数可选择多个。
若步骤参数值的数据类型为布尔,则使用1表示true,0表示false。
单击 参数值、位置、长度 三列中高亮显示的单元格,可根据需求修改其值。
注意
修改时,需注意以下事项:
不同参数所占的字段位置切勿存在重叠。
若各参数所对应的位置之间存在空缺,则空缺位置默认使用0填充。建议通过修改位置,消除不必要的空缺位置。
完成上述配置后,单击 预览,将根据配置项生成相应的指令示例。
参见
独立指令与合并指令的完整配置,可参考示例:独立设置视觉步骤参数。
从RVS-Vision获取机器人名称(可选)
单击 获取,输入框中将会显示 机器人通信配置 中选择的机器人名称。
获取的机器人名称将用于注册机器人服务。在 机器人通信配置 界面,选择的机器人选项不同,此处获取的对应机器人名称也会有所不同。
机器人选项
机器人名称
品牌机器人
具体机器人名称及型号
其他机器人
RobotType1
不使用机器人
未发现机器人
完成上述配置后,单击 下一页,进入 RVS-Vision输出 窗口。
配置“RVS-Vision输出”
在 RVS-Vision输出 窗口,设置 RVS-Vision 返回给机器人或上位机的数据格式。具体配置项包括 位姿数据、物体标签 和 其他输出。
根据 RVS-Vision 工程的“视觉输出”步骤确定相应配置项。
"输出"步骤端口类型
端口名称
配置项
适用场景
预定义(视觉结果)
poses
位姿数据(视觉点数据)
获取目标物体的位姿
预定义(视觉结果)
poses、labels
位姿数据(视觉点数据)、物体标签
获取目标物体的位姿、标签
自定义
自定义端口名称
其他输出
获取自定义的数据,例如,获取OCR文字、VIN码、测量结果等
选择是否勾选 位姿数据(默认:勾选)。
若选择配置 视觉点数据,参考下表进行配置。
注意
若 基础设置 中旋转方式选择四元数,则输出的每个位姿占据 7 个字段。
配置项
说明
数量
可设置项:1个、固定值(需手动填写)、所有。
- 1:RVS-Vision 输出 N 个视觉点,但 Adapter 只返回第一个视觉点。
- 固定值M:RVS-Vision 输出 N 个视觉点,但 Adapter 只返回前 M 个视觉点。
- 所有:RVS-Vision 输出 N 个视觉点,Adapter 返回 N 个视觉点。
发送的位姿个数
RVS-Vision 返回的数据中将携带本次返回的位姿个数,位姿个数位于位姿数据前面。
将物体位姿转为机器人位姿
自动将 RVS-Vision 识别结果的位姿绕 X 轴旋转 180°(使其 Z 轴朝下),机器人便可直接移动到该位姿进行抓取。
选择是否勾选 物体标签。物体标签为“视觉输出”步骤的 labels 端口数据。
选择是否配置 其他输出。单击 +,可配置多个端口。
注意
自定义端口数据的列表大小应与标签或位姿的列表大小保持一致。
配置项
说明
端口名称
“视觉输出”步骤的自定义端口名称。
数据类型
可设置项:Stringlist、Numberlist、Size3DList。
完成上述配置后,单击 预览,将根据配置项生成相应的指令示例。确认无误后,单击 下一页,进入下一配置界面。
备注
典型 ASCII 成功响应如下:
1,2,100.0000,20.0000,500.0000,180.0000,0.0000,90.0000,...\r
其中第一个字段为外部状态码,第二个字段为位姿数量,后续字段为按配置格式展开的位姿数据。实际字段顺序以生成器中的指令预览为准。
配置“状态码设置”
在 状态码设置 窗口,为指令处理的各种结果设置对应的状态码。
Adapter 生成器默认支持以下状态码:
状态
默认外部状态码
成功
1
非法指令
2
工程未加载
3
无点云
4
无结果
5
路径规划失败
6
步骤参数无效
7
超时
8
其他错误
9
小技巧
你可根据需求增加或减少状态码。
减少状态码:将不同的状态码对应的值设置成相同数值。例如,将“非法指令”、“工程未加载”都设置成 2。
增加状态码:修改 Adapter 代码中的状态码映射(
status_code_map.py或自定义 Assembler)。具体方法参见 Adapter 编程指南:内部错误码。
完成上述配置后,单击 保存并生成。在弹出的确认窗口中,单击 是,保存所有配置。
注意
保存前,应逐项检查输入与输出预览:
字段顺序、位置和长度是否正确;
命令码是否与外部程序一致;
ASCII 分隔符、结束符和前后缀是否正确;
长度单位、旋转单位和欧拉角格式是否正确;
状态码是否与外部程序一致。
保存配置后,系统会写入 Adapter 配置并生成 Python 代码。生成目录主要包含:
<Adapter 配置目录>/ ├── configurational_adapter.json ├── generated/ │ ├── __init__.py │ ├── header_parser.py │ ├── parser_trigger.py │ ├── parser_setprop.py # 配置独立步骤参数指令时生成 │ ├── assembler.py │ ├── status_code_map.py │ └── register.py └── .vscode/ └── launch.json
备注
generated/中的文件会在重新保存配置时被覆盖,不应直接修改。需要改变常规字段时,请修改生成器配置后重新生成;确需扩展生成逻辑时,应修改生成器模板或创建独立的自定义协议包。参见
完整的配置与联调流程,可参考示例:机器人触发视觉并获取抓取位姿。
部署Adapter工程
完成 Adapter 生成器配置后,按照以下步骤部署 Adapter 工程。
联调Adapter工程
配置网络
如果 Adapter 作为 TCP 服务端:
将监听地址设置为本机网卡地址,或使用
0.0.0.0监听全部网卡;端口不能被其他程序占用;
外部设备应主动连接 Adapter 所在工控机的 IP 和端口。
如果 Adapter 作为 TCP 客户端:
将主机地址设置为外部设备的 IP;
确认外部设备已启动 TCP 服务;
连接断开后,Adapter 会按配置的重连间隔尝试重新连接。
发送测试指令
建议先使用网络调试工具验证协议,再连接机器人或 PLC。
测试顺序如下:
启动并加载需要运行的视觉工程;
启动 Adapter;
建立 TCP 连接;
发送一条字段最少的合法指令;
确认 Adapter 日志识别到正确的命令码;
确认视觉工作流被执行;
对照响应预览检查状态码和数据字段;
再增加配方、机器人位姿和步骤参数等可选字段。
TCP 是字节流协议。当前通信层把每次
read()得到的数据直接交给协议层处理,并未按结束符自动缓存和拆帧。因此联调时应让外部设备一次发送一条完整请求,并等待响应后再发送下一条。对于可能出现拆包、粘包、单帧超过接收缓冲区或高频连续发送的正式协议,应在通信层增加按定长、长度字段或结束符缓存分帧的实现,再投入现场使用。
示例:机器人触发视觉并获取抓取位姿
本节通过一个完整样例说明如何从需求定义、生成器配置一直完成报文联调。样例目标如下:
Adapter 作为 TCP 服务端,监听
50000端口;机器人发送 ASCII 指令;
一条指令中包含工程编号、配方编号和 6 个关节角;
Adapter 切换配方、写入机器人位姿、执行视觉工作流;
Adapter 返回状态码、位姿数量、抓取位姿和物体标签;
字段使用逗号分隔,报文以
\r结束;长度单位为毫米,旋转单位为度,输出姿态为
ZYX_STATIC欧拉角;浮点数保留 3 位小数。
先定义通信协议
在打开生成器前,应先与机器人程序开发者确认协议字段。不要一边配置一边临时决定字段,否则机器人端和 Adapter 端很容易出现位置不一致。
拍照请求字段表:
位置 |
字段 |
类型 |
长度 |
示例 |
说明 |
|---|---|---|---|---|---|
1 |
|
字符串 |
1 |
|
拍照触发命令码。 |
2 |
|
无符号整数 |
1 |
|
视觉工程编号。 |
3 |
|
无符号整数 |
1 |
|
需要切换到的配方编号。 |
4~9 |
|
浮点数组 |
6 |
|
机器人六轴关节角。 |
完整请求:
P,1,2,0,10,20,30,40,50\r
逐字段拆解:
P , 1 , 2 , 0 , 10 , 20 , 30 , 40 , 50 \r
│ │ │ └──────────────┬──────────────┘ │
│ │ │ │ └─ 报文结束符
│ │ │ └─ J1~J6
│ │ └─ 配方编号
│ └─ 工程编号
└─ 命令码
成功响应字段表:
顺序 |
字段 |
类型 |
示例 |
说明 |
|---|---|---|---|---|
1 |
|
整数 |
|
成功状态码。 |
2 |
|
无符号整数 |
|
本次返回 2 个位姿。 |
3~8 |
|
6 个浮点数 |
|
第 1 个位姿的 X、Y、Z、Rx、Ry、Rz。 |
9 |
|
字符串 |
|
第 1 个物体标签。 |
10~15 |
|
6 个浮点数 |
|
第 2 个位姿。 |
16 |
|
字符串 |
|
第 2 个物体标签。 |
完整成功响应:
1,2,100.000,20.000,500.000,180.000,0.000,90.000,box_A,120.000,25.000,498.000,180.000,0.000,88.000,box_B\r
无视觉结果响应:
5\r
非法命令响应:
2\r
失败响应是否只包含状态码,应在协议设计阶段固定下来。机器人端不应在失败状态下继续读取位姿数量和位姿字段。
创建和准备视觉工程
在 RVS 2.0 中创建或打开用于抓取定位的视觉工程。
确认工程中存在一个可执行工作流。
确认工作流输出包含抓取位姿。
如果需要返回标签,确认视觉结果中包含与每个位姿对应的标签。
创建至少两个配方,用于验证配方切换。
手动运行工作流,确认不通过 Adapter 时也能得到稳定结果。
配置基本设置
在 Adapter 生成器中填写:
配置项 |
样例值 |
|---|---|
工程名称 |
|
协议 |
|
数据格式 |
|
服务类型 |
|
端口 |
|
长度单位 |
|
旋转单位 |
|
旋转方式 |
|
欧拉角格式 |
|
小数位数 |
|
字段分隔符 |
|
结束符 |
|
帧前缀/后缀 |
不启用 |
配置输入指令
将拍照触发命令码设为
P。启用工程编号,位置设为 2。
启用配方编号,位置设为 3。
启用机器人拍照位姿。
位姿类型选择
JPs。位姿位置设为 4,长度为 6。
在指令预览中确认最后一个关节角位于位置 9。
配置完成后的逻辑字段应为:
1:P | 2:project_id | 3:recipe_id | 4~9:joint_angles
配置输出
启用“返回位姿数据”。
数据类型选择“视觉点数据”。
返回数量选择“全部”。
启用“返回位姿数量”。
按现场坐标定义决定是否启用“转换为机器人位姿”。
启用“返回物体标签”。
不添加其他输出端口。
配置状态码并保存
本样例沿用默认状态码 1~9。保存后检查:
robot_pick_demo/
├── configurational_adapter.json
└── generated/
├── header_parser.py
├── parser_trigger.py
├── assembler.py
├── status_code_map.py
└── register.py
生成器对本样例生成的核心执行顺序等价于:
workflow = await get_workflow_id.submit(
exec_ctx,
params={"project_id": project_id},
)
await switch_recipe.submit(
exec_ctx,
params={"project_id": project_id, "recipe_id": recipe_id},
)
await set_robot_pose.submit(
exec_ctx,
params={"project_id": project_id, "joint_angles": joint_angles},
)
await execute_workflow.submit(
exec_ctx,
params={"flow_id": workflow.data["workflow_id"]},
)
result = await get_vision_result.submit(
exec_ctx,
params={"flow_id": workflow.data["workflow_id"], "timeout": 30000},
)
备注
这段代码用于帮助理解执行顺序,无需复制到生成文件中。
使用 Python 模拟机器人
可以先用以下脚本连接 Adapter 并发送一条请求:
import socket
HOST = "127.0.0.1"
PORT = 50000
REQUEST = b"P,1,2,0,10,20,30,40,50\r"
with socket.create_connection((HOST, PORT), timeout=5) as client:
client.sendall(REQUEST)
client.settimeout(35)
response = bytearray()
while not response.endswith(b"\r"):
chunk = client.recv(4096)
if not chunk:
raise ConnectionError("Adapter closed the connection")
response.extend(chunk)
print("raw:", bytes(response))
print("text:", response.decode("utf-8").rstrip("\r"))
如果 Adapter 运行在另一台工控机上,将 HOST 改成该工控机实际网卡 IP。
解析响应
机器人端可以按以下逻辑处理响应:
def parse_response(message: str):
fields = message.rstrip("\r").split(",")
status = int(fields[0])
if status != 1:
return {"status": status, "poses": []}
count = int(fields[1])
cursor = 2
poses = []
for _ in range(count):
pose = [float(value) for value in fields[cursor:cursor + 6]]
cursor += 6
label = fields[cursor]
cursor += 1
poses.append({"pose": pose, "label": label})
if cursor != len(fields):
raise ValueError("Response contains unexpected trailing fields")
return {"status": status, "poses": poses}
联调时至少执行以下测试:
编号 |
请求或现场条件 |
期望结果 |
|---|---|---|
1 |
合法工程、配方和关节角 |
返回状态码 1 和位姿。 |
2 |
未知命令码 |
返回非法指令状态码 2。 |
3 |
不存在的工程编号 |
返回工程未加载状态码 3。 |
4 |
场景中没有目标物体 |
返回无结果状态码 5。 |
5 |
缺少一个关节角 |
返回错误状态,Adapter 不应执行工作流。 |
6 |
配方不存在 |
返回失败状态,不应继续执行工作流。 |
7 |
视觉执行超过超时 |
返回超时状态码 8。 |
8 |
处理过程中断开 TCP |
Adapter 保持可用,并允许重新连接。 |
示例:独立设置视觉步骤参数
本样例在拍照前使用单独指令修改视觉步骤参数。假设需要修改“匹配模式”和“最小置信度”。
定义指令
步骤参数指令:
S,1,0,0.850\r
位置 |
字段 |
示例 |
说明 |
|---|---|---|---|
1 |
命令码 |
|
设置参数。 |
2 |
工程编号 |
|
目标视觉工程。 |
3 |
匹配模式 |
|
示例中 |
4 |
最小置信度 |
|
浮点参数。 |
拍照指令:
P,1\r
推荐控制时序:
机器人 Adapter 视觉系统
│ S,1,0,0.850\r │ │
├────────────────────────►│ 更新步骤属性 │
│ ├─────────────────────────►│
│ 1\r │ │
│◄────────────────────────┤ │
│ P,1\r │ │
├────────────────────────►│ 执行工作流并获取结果 │
│ ├─────────────────────────►│
│ 1,1,...\r │ │
│◄────────────────────────┤ │
备注
机器人必须等到设置参数指令返回成功后再发送拍照指令。否则拍照可能仍使用旧参数。
在生成器中选择属性
启用“设置视觉步骤参数”。
不启用“合并到拍照指令”。
将步骤参数命令码设为
S。从视觉工程中选择“匹配模式”。
再选择“最小置信度”。
分别设置位置 3 和位置 4,长度均为 1。
保存后确认生成了
parser_setprop.py。
生成代码会保存每个属性的工作流 ID、步骤 ID、属性路径和属性类型。协议输入值会根据属性类型转换成视觉系统所需的 JSON 数据。
常见属性在报文中的展开方式:
属性类型 |
ASCII 输入示例 |
字段数 |
|---|---|---|
|
|
1 |
|
|
1 |
|
|
1 |
枚举 |
|
1 |
|
|
2 |
|
|
3 |
四元数位姿 |
|
7 |
属性类型和长度必须与生成器预览一致。配置长度比目标属性所需长度短时,解析或属性更新可能失败;配置过长时,多余字段会导致后续字段错位。
合并步骤参数和拍照指令
如果启用“合并到拍照指令”,可以使用:
P,1,0,0.850\r
Adapter 会在同一个请求内按以下顺序执行:
获取工作流 ID;
更新匹配模式;
更新最小置信度;
执行工作流;
获取并返回视觉结果。
任一属性更新失败时,不应继续执行工作流。
示例:带帧前后缀的 ASCII 协议
部分机器人协议要求一帧必须以固定字符串开头和结束。例如:
<STX>P,1<ETX>
在生成器中配置:
配置项 |
值 |
|---|---|
启用前后缀 |
是 |
前缀 |
|
后缀 |
|
分隔符 |
|
解析规则如下:
输入必须以前缀开始;
输入必须以后缀结束;
前后缀不会作为命令字段传给 Payload Parser;
输出状态码和业务数据也会被相同的前后缀包裹;
前后缀与业务字段之间不会自动插入分隔符。
成功响应示例:
<STX>1,1,100.000,20.000,500.000,180.000,0.000,90.000<ETX>
以下输入都应判定为非法:
P,1<ETX> # 缺少前缀
<STX>P,1 # 缺少后缀
<STX>,P,1<ETX> # 前缀后多了一个分隔符
示例:二进制协议
二进制模式适合字段宽度固定的设备协议。当前 TCP 服务端的 hex 模式要求发送端传输 ASCII 十六进制文本;通信层收到文本后,去除空格并用 bytes.fromhex() 转换成原始字节,再交给协议解析器。当前生成器中,命令码按转换后的前 4 字节识别,数值字段按配置的端序读取。
假设协议采用小端序,请求结构为:
字节偏移 |
长度 |
字段 |
类型 |
示例 |
|---|---|---|---|---|
0 |
4 |
命令码 |
4 字节 |
|
4 |
4 |
工程编号 |
|
|
8 |
24 |
六轴关节角 |
6 × |
按 IEEE 754 小端编码 |
Python 构造请求:
import socket
import struct
command = b"\x01\x00\x00\x00"
project_id = struct.pack("<I", 6)
joints = struct.pack("<6f", 0.0, 10.0, 20.0, 30.0, 40.0, 50.0)
request = command + project_id + joints
# TCPServer 的 hex 模式接收 ASCII hex 文本,而不是直接接收 request 原始字节。
wire_data = request.hex().encode("ascii")
with socket.create_connection(("127.0.0.1", 50000), timeout=5) as client:
client.sendall(wire_data)
response = client.recv(4096)
print(response.hex(" "))
例如,命令码和工程编号的原始字节为:
01 00 00 00 06 00 00 00
线上实际发送的前 16 个 ASCII 字符为:
0100000006000000
Adapter 的二进制响应由 Assembler 直接组装为字节。外部设备应根据双方约定的响应结构和端序解析,不应再把响应当成 ASCII 十六进制字符串,除非自定义 Assembler 明确进行了这种编码。
二进制联调必须明确:
命令码的 4 个字节到底是数值编码还是原始字节序列;
使用小端还是大端;
整数是否有符号;
浮点数使用 32 位还是 64 位;
报文总长度如何确定;
是否需要长度字段、校验码或转义;
一次 TCP 接收不足一帧时如何缓存。
如果协议包含 CRC、动态长度、转义或多个不同帧头,建议使用自定义 Header Parser,不要强行套用固定字段生成器。




