- 将图像大小字段的字节序从大端序改为小端序 - 更新协议文档中关于图像大小字节序的描述和示例 - 修改示例代码,将大小端转换函数由htobe64改为htole64 - 确保协议发送阶段中的图像大小字段正确使用小端序编码
529 lines
17 KiB
Markdown
529 lines
17 KiB
Markdown
# 硬件视觉调度时序图
|
||
|
||
## 概述
|
||
|
||
本文档描述了硬件视觉调度系统的完整时序流程,展示了从调度车托料完成到最终调度至立锯的全过程。
|
||
|
||
## 上位机控制时序图-视觉部分
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
autonumber
|
||
participant 调度车
|
||
participant 上位机
|
||
participant 下位机
|
||
participant 侧面相机
|
||
participant 视觉相机
|
||
participant 视觉算法
|
||
|
||
%% 为每个参与者设置不同颜色
|
||
box rgb(173, 216, 230) 硬件调度系统
|
||
participant 调度车
|
||
end
|
||
box rgb(255, 218, 185) 控制系统
|
||
participant 上位机
|
||
participant 下位机
|
||
end
|
||
box rgb(221, 160, 221) 视觉系统
|
||
participant 侧面相机
|
||
participant 视觉相机
|
||
end
|
||
box rgb(152, 251, 152) 算法系统
|
||
participant 视觉算法
|
||
end
|
||
|
||
Note over 调度车,视觉算法: 系统初始化阶段
|
||
调度车->>上位机: 托料完成
|
||
|
||
Note over 调度车,视觉算法: 视觉定位阶段
|
||
上位机->>侧面相机: 发送取中拍照指令
|
||
侧面相机->>侧面相机: 计算对中坐标
|
||
侧面相机->>上位机: 返回中心坐标结果
|
||
alt 超时重试
|
||
上位机-->>侧面相机: 超时重试请求
|
||
侧面相机-->>上位机: 返回坐标
|
||
end
|
||
上位机->>下位机: 写入顶中坐标
|
||
下位机->>下位机: 顶针对中顶料
|
||
|
||
Note over 调度车,视觉算法: 物理定位与扫描准备阶段
|
||
下位机->>下位机: 顶料至预定位置
|
||
上位机->>下位机: 发送扫描指令
|
||
alt 超时重试
|
||
上位机-->>下位机: 超时重试扫描指令
|
||
end
|
||
|
||
Note over 调度车,视觉算法: 并行扫描处理阶段(三方并行)
|
||
par 上位机等待扫描完成
|
||
上位机->>下位机: 等待扫描完成指令
|
||
下位机->>上位机: 扫描完成通知
|
||
alt 超时重试
|
||
上位机-->>下位机: 超时重试等待
|
||
end
|
||
and 下位机硬触发相机
|
||
下位机->>视觉相机: 硬触发扫描动作
|
||
and 发送算法参数
|
||
上位机->>视觉算法: 发送原木长度与顶针预留长度
|
||
上位机->>视觉算法: 推送工单信息(规格/等级等)
|
||
end
|
||
|
||
Note over 调度车,视觉算法: 视觉算法处理阶段
|
||
上位机->>视觉算法: 触发视觉算法处理
|
||
视觉相机->>视觉算法: 提供扫描数据
|
||
视觉算法->>视觉算法: 算法处理中
|
||
视觉算法->>上位机: 等待算法结果
|
||
alt 超时重试
|
||
上位机-->>视觉算法: 超时重试请求
|
||
end
|
||
|
||
par 算法结果输出
|
||
视觉算法->>上位机: 建模完成
|
||
and 算法完成
|
||
视觉算法->>上位机: 算法完成
|
||
end
|
||
|
||
Note over 调度车,视觉算法: 数据汇聚与处理阶段
|
||
上位机->>上位机: 返回视觉算法数据
|
||
上位机->>下位机: 写入算法旋转角度
|
||
|
||
Note over 调度车,视觉算法: 旋转与调度执行阶段
|
||
下位机->>下位机: 执行旋转完成切割角度旋转
|
||
调度车->>调度车: 取料
|
||
上位机->>调度车: 写入算法规划图
|
||
上位机->>调度车: 下发调度指令
|
||
调度车->>调度车: 调度至立锯
|
||
```
|
||
|
||
---
|
||
|
||
## 流程说明
|
||
|
||
### 1. 初始阶段
|
||
- **调度车托料完成**: 系统开始进入视觉调度流程
|
||
|
||
### 2. 视觉定位阶段
|
||
- **上位机发送取中拍照指令**: 启动视觉系统进行中心定位
|
||
- **等待中心坐标结果**: 等待视觉算法处理结果,支持超时重试机制
|
||
|
||
### 3. 物理定位阶段
|
||
- **写入下位机顶中坐标并顶料至线扫位置**: 将获取的中心坐标传递给下位机,同时执行物理定位
|
||
|
||
### 4. 视觉扫描阶段
|
||
- **视觉扫描到达线扫速度并发送扫描指令**: 系统准备进行线扫描并启动扫描流程,支持超时重试
|
||
- **上位机等待扫描完成指令并写入下位机**: 等待扫描完成信号并将完成指令传递给下位机,支持超时重试(三方并行执行)
|
||
- **视觉相机硬触发扫描动作**: 视觉相机执行硬件触发扫描操作,采集视觉数据(与上位机等待和算法处理并行执行)
|
||
- **等待视觉算法处理**: 视觉算法处理扫描数据,支持超时重试(与上位机等待和相机触发并行执行)
|
||
|
||
### 5. 数据处理与旋转阶段
|
||
- **返回视觉数据并写入算法旋转角度**: 算法处理完成,返回结果并将旋转角度传递给下位机
|
||
- **下位机执行旋转完成旋转**: 执行物理旋转操作直至完成
|
||
|
||
### 6. 调度执行阶段
|
||
- **调度车取料并写入算法规划图**: 调度车取走已处理的物料,同时将算法规划结果写入系统
|
||
- **下发调度指令并调度至立锭**: 发送调度执行指令并完成最终的调度至立锯操作
|
||
|
||
## 关键特性
|
||
|
||
- **超时重试机制**: 在关键步骤(中心坐标获取、视觉扫描、扫描完成、视觉算法)设置了超时重试机制,确保系统稳定性
|
||
- **三方并行执行**: “上位机等待扫描完成指令”、“视觉相机硬触发扫描动作”和“等待视觉算法”为三方并行执行,提高执行效率
|
||
- **分阶段执行**: 整个流程分为视觉定位、物理定位、视觉扫描、旋转调整和调度执行五个主要阶段
|
||
- **算法集成**: 深度集成视觉算法,实现自动化的坐标定位和旋转角度计算
|
||
|
||
## 注意事项
|
||
|
||
1. 每个阶段的执行都依赖于前一阶段的成功完成
|
||
2. 超时重试机制需要合理设置重试次数和超时时间
|
||
3. 视觉算法的准确性直接影响整个调度流程的效果
|
||
4. 上位机与下位机之间的通信稳定性至关重要
|
||
5. "上位机等待扫描完成指令"、"视觉相机硬触发扫描动作"和"等待视觉算法"是三方并行执行的,需要做好同步协调
|
||
|
||
## TCP请求上位机数据接口
|
||
|
||
### 接口概述
|
||
|
||
硬件视觉调度系统通过TCP协议与上位机进行数据交互,支持多种动作类型的请求处理。
|
||
|
||
### 通用请求格式
|
||
|
||
```json
|
||
{
|
||
"id": "req001",
|
||
"action": "test",
|
||
"data": {
|
||
"message": "hello server",
|
||
"param1": "value1"
|
||
},
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
#### 请求参数说明
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ---- | ---- | ---- |
|
||
| id | string | 是 | 请求唯一标识符 |
|
||
| action | string | 是 | 动作类型,决定具体的处理逻辑 |
|
||
| data | object | 否 | 请求数据,根据不同action有不同结构 |
|
||
| timestamp | number | 否 | 请求时间戳(毫秒) |
|
||
|
||
### 支持的动作类型
|
||
|
||
#### 1. center_photo_result - 视觉写入侧面对中坐标
|
||
|
||
**功能说明:** 用于将视觉系统获取的原木端面对中坐标写入下位机,为后续的顶针定位操作提供准确的坐标参考。
|
||
|
||
**调用方法:** `s.hardwareController.WriteVisionPinCoordinate()`
|
||
|
||
**请求示例:**
|
||
```json
|
||
{
|
||
"id": "req001",
|
||
"action": "center_photo_result",
|
||
"data": {
|
||
"left": {
|
||
"x": 100.5,
|
||
"y": 200.3,
|
||
"z": 300.7,
|
||
"diameter": 34.5
|
||
},
|
||
"right": {
|
||
"x": 100.5,
|
||
"y": 200.3,
|
||
"z": 300.7,
|
||
"diameter": 34.5
|
||
},
|
||
"x_diameter": 34.5,
|
||
"y_diameter": 34.5,
|
||
"error_id": "err001",
|
||
"wood id": "WooD _20251103 162602 004 2ace914e",
|
||
"reg_timestamp": 1762158362326,
|
||
"recv_timestamp": 1762308226907,
|
||
"send _timestamp": 1762308230194
|
||
},
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
**data参数说明:**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ---- | ---- | ---- |
|
||
| left | object | 是 | 左侧坐标 |
|
||
| left.x | number | 是 | X坐标 |
|
||
| left.y | number | 是 | Y坐标 |
|
||
| left.z | number | 是 | Z坐标 |
|
||
| left.diameter | number | 否 | 原木直径 |
|
||
| right | object | 是 | 右侧坐标 |
|
||
| right.x | number | 是 | X坐标 |
|
||
| right.y | number | 是 | Y坐标 |
|
||
| right.z | number | 是 | Z坐标 |
|
||
| right.diameter | number | 否 | 原木直径 |
|
||
| x_diameter | number | 否 | X方向原木直径 |
|
||
| y_diameter | number | 否 | Y方向原木直径 |
|
||
| error_id | string | 否 | 错误标识 |
|
||
| wood_id | string | 否 | 原木标识 |
|
||
| reg_timestamp | number | 否 | 注册时间戳 |
|
||
| recv_timestamp | number | 否 | 接收时间戳 |
|
||
| send_timestamp | number | 否 | 发送时间戳 |
|
||
|
||
**响应示例:**
|
||
```json
|
||
{
|
||
"id": "req001",
|
||
"success": true,
|
||
"data": {
|
||
"coordinates": {
|
||
"left": {
|
||
"x": 100.5,
|
||
"y": 200.3,
|
||
"z": 300.7
|
||
},
|
||
"right": {
|
||
"x": 100.5,
|
||
"y": 200.3,
|
||
"z": 300.7
|
||
}
|
||
},
|
||
"error_id": "err001",
|
||
"message": "视觉顶针坐标写入成功",
|
||
"wood_id": ""
|
||
},
|
||
"error": "",
|
||
"timestamp": 1762561787764
|
||
}
|
||
```
|
||
|
||
#### 2. scan_completed - 视觉扫描完成推送图像流
|
||
|
||
**功能说明:** 用于通知系统视觉扫描已完成并推送建模图像,触发硬件控制器将M106寄存器设置为true,标记扫描流程的完成。
|
||
|
||
**调用方法:** `s.hardwareController.ProcessVisionScanComplete()`
|
||
|
||
**寄存器操作:** 将M106寄存器设置为true
|
||
|
||
**请求示例:**
|
||
```json
|
||
{
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"action": "scan_completed",
|
||
"data": {
|
||
"wood_id": "WD0001",
|
||
"image_size": 314572800,
|
||
"image_format": "jpg"
|
||
},
|
||
"timestamp": 1705300000000
|
||
}
|
||
```
|
||
|
||
**传输格式**
|
||
协议设计(三段式)
|
||
|
||
1. JSON元数据:{"id": "...", "action": "scan_completed", "data": {"wood_id": "WD0001", "image_size": 314572800, "image_format": "jpg"}}
|
||
2. 8字节小端序整数:图像大小
|
||
3. 原始二进制图像数据流
|
||
|
||
**支持的图像格式:**
|
||
- 普通图像:jpg, jpeg, png, bmp, tiff
|
||
- 点云数据:pcd, ply, las, xyz
|
||
- 3D模型:obj
|
||
|
||
| 阶段 | 描述 | 示例 |
|
||
| ---- | ---- | ---- |
|
||
| 1 | JSON元数据(以'}'结束,触发JSON解析) | {"id":"xxx","action":"scan_completed","data":{"wood_id":"WD0001","image_size":314572800,"image_format":"jpg"},"timestamp":1705300000000} |
|
||
| 2 | 8字节小端序整数(图像大小) | [0x00][0x1C][0xC1][0x12][0x00][0x00][0x00][0x00] = 314572800 bytes (约300MB) |
|
||
| 3 | 原始二进制图像数据流 | [图像二进制数据... 共314572800字节] |
|
||
|
||
**说明:** 用于通知系统视觉扫描已完成并推送建模图像。系统接收到此请求后会自动将M106寄存器设置为true。
|
||
|
||
**参数说明:**
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
| ---- | ---- | ---- |
|
||
| wood_id | string | 原木唯一标识ID |
|
||
| image_size | number | 图像大小 |
|
||
| image_format | string | 图像格式 |
|
||
| timestamp | number | 请求时间戳(毫秒) |
|
||
|
||
```c
|
||
// 第一阶段:发送JSON元数据
|
||
json request = {
|
||
{"id", "req_123"},
|
||
{"action", "scan_completed"},
|
||
{"data", {
|
||
{"wood_id", "WD0001"},
|
||
{"image_size", 314572800}, // 300MB
|
||
{"image_format", "jpg"}
|
||
}}
|
||
};
|
||
send(sock, request.dump().c_str(), ...);
|
||
|
||
// 第二阶段:发送8字节小端序图像大小
|
||
int64_t imageSize = 314572800;
|
||
int64_t networkSize = htole64(imageSize); // 转换为小端序
|
||
send(sock, &networkSize, 8, 0);
|
||
|
||
// 第三阶段:发送原始二进制图像流
|
||
FILE* fp = fopen("image.jpg", "rb");
|
||
char buffer[32768];
|
||
while ((n = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
|
||
send(sock, buffer, n, 0);
|
||
}
|
||
fclose(fp);
|
||
```
|
||
|
||
**响应示例:**
|
||
```json
|
||
{
|
||
"id": "req002",
|
||
"success": true,
|
||
"data": {
|
||
"message": "视觉扫描完成处理成功",
|
||
"action": "scan_completed",
|
||
"register": "M106=true"
|
||
},
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
#### 3. algorithm_coordinates - 算法坐标和旋转角度
|
||
|
||
**功能说明:** 用于处理视觉算法计算得出的最终坐标和旋转角度,将这些数据传递给下位机进行物理旋转操作。
|
||
|
||
**调用方法:** `s.hardwareController.ProcessVisionScanCoordinate()`
|
||
|
||
**参数处理:** 将坐标数据构建为[4]float32数组,旋转角度转换为float32
|
||
|
||
**请求示例:**
|
||
```json
|
||
{
|
||
"id": "req003",
|
||
"action": "algorithm_coordinates",
|
||
"data": {
|
||
"left": [120.5, 120.5, 86.12],
|
||
"right": [160.8, 124.5, 17.2],
|
||
"rotation_angle": 15.5,
|
||
"available_volume": 0.85
|
||
},
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
**data参数说明:**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ---- | ---- |---------|
|
||
| left | float64 | 是 | 左侧锯路坐标 |
|
||
| right | float64 | 是 | 右侧锯路坐标 |
|
||
| rotation_angle | float64 | 是 | 旋转角度(度) |
|
||
|
||
**响应示例:**
|
||
```json
|
||
{
|
||
"id": "req003",
|
||
"success": true,
|
||
"data": {
|
||
"message": "视觉算法坐标处理成功",
|
||
"coordinates": {
|
||
"left": [120.5,32.4],
|
||
"right": [160.8,12]
|
||
},
|
||
"rotation_angle": 15.5,
|
||
"available_volume": 0.85
|
||
},
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
#### 4. center_photo_taking - 视觉取中拍照命令下发
|
||
|
||
**功能说明:** 用于下发视觉取中拍照命令,指定需要拍照的原木ID,触发视觉系统进行中心定位拍照操作。
|
||
|
||
**请求示例:**
|
||
```json
|
||
{
|
||
"id": "",
|
||
"action": "center_photo_taking",
|
||
"data": {
|
||
"left": {
|
||
"x": 55050,
|
||
"y": 32849,
|
||
"z": 0
|
||
},
|
||
"right": {
|
||
"x": 55050,
|
||
"y": 32849,
|
||
"z": 0
|
||
},
|
||
"wood_id": "WOOD_20251103_162602_004_2ace914e"
|
||
},
|
||
"timestamp": 1762158362326
|
||
}
|
||
```
|
||
|
||
**data参数说明:**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ---- | ---- | ---- |
|
||
| wood_id | string | 是 | 原木唯一标识ID |
|
||
|
||
**响应示例:**
|
||
```json
|
||
{
|
||
"id": "",
|
||
"success": true,
|
||
"data": {
|
||
"message": "视觉取中拍照命令下发成功",
|
||
"wood_id": "WOOD_20251102_094718_004_8b369a99"
|
||
},
|
||
"timestamp": 1762048038500
|
||
}
|
||
```
|
||
|
||
#### 5. order_info - 工单信息下发
|
||
|
||
**功能说明:** 用于下发工单信息至视觉系统,包含工单编号、规格和原木ID等关键信息,为后续的加工流程提供数据支持。
|
||
|
||
**请求示例:**
|
||
```json
|
||
{
|
||
"id": "",
|
||
"action": "order_info",
|
||
"data": {
|
||
"grade": "等级A",
|
||
"has_bark": true,
|
||
"order_sn": "SO20251101000002",
|
||
"order_spec": "11*12*12",
|
||
"sub_spec": ["38*89*3.98", "37*66*4.1"],
|
||
"wood_id": "WOOD_20251103_162602_004_2ace914e",
|
||
"start_distance": 10.5,
|
||
"end_distance": 10.5,
|
||
"length": 4100.0,
|
||
"saw_thickness": 1.8,
|
||
"scan_start": "left"
|
||
},
|
||
"timestamp": 1762158534297
|
||
}
|
||
```
|
||
|
||
**data参数说明:**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
| ---- | ---- | ---- |----------------|
|
||
| order_sn | string | 是 | 工单编号 |
|
||
| order_spec | string | 是 | 工单主规格(格式:厚*宽*长) |
|
||
| wood_id | string | 是 | 原木唯一标识ID |
|
||
| grade | string | 否 | 原木等级 |
|
||
| has_bark | bool | 否 | 是否有 bark (带树皮) |
|
||
| sub_spec | []string | 否 | 原木副规格(格式:厚*宽*长) |
|
||
| left_distance | number | 否 | 原木左端距离 |
|
||
| right_distance | number | 否 | 原木右端距离 |
|
||
| length | number | 否 | 原木长度 |
|
||
| saw_thickness | number | 否 | 锯片厚度 (锯路) |
|
||
| scan_start | string | 否 | 初始扫描方向(left或right) |
|
||
|
||
**响应示例:**
|
||
```json
|
||
{
|
||
"id": "",
|
||
"success": true,
|
||
"data": {
|
||
"message": "工单信息下发成功",
|
||
"order_sn": "SO20251101000002",
|
||
"order_spec": "11*12*12",
|
||
"wood_id": "WOOD_20251102_094814_007_e5337aa2"
|
||
},
|
||
"timestamp": 1762048153709
|
||
}
|
||
```
|
||
|
||
### 错误响应格式
|
||
|
||
当请求处理失败时,系统会返回错误响应:
|
||
|
||
```json
|
||
{
|
||
"id": "req001",
|
||
"success": false,
|
||
"error": "错误描述信息",
|
||
"timestamp": 1705123456789
|
||
}
|
||
```
|
||
|
||
#### 常见错误类型
|
||
|
||
1. **请求解析失败**: `"请求解析失败: invalid JSON format"`
|
||
2. **硬件控制器未初始化**: `"硬件控制器未初始化"`
|
||
3. **缺少必要数据**: `"缺少坐标数据"` 或 `"缺少坐标和角度数据"`
|
||
4. **数据格式错误**: `"坐标数据格式错误,需要left_x, left_y, right_x, right_y字段"`
|
||
5. **硬件操作失败**: `"写入视觉顶针坐标失败: [specific error]"`
|
||
|
||
### 接口使用注意事项
|
||
|
||
1. **数据格式**:所有请求必须是有效的JSON格式,系统会自动清理前后空白字符和换行符
|
||
2. **坐标精度**:坐标值支持float64精度,系统内部会转换为float32处理
|
||
3. **硬件控制器**:所有涉及硬件操作的接口都需要硬件控制器已正确初始化
|
||
4. **请求ID**:建议使用唯一的请求ID,便于追踪和调试,系统会在响应中返回相同ID
|
||
5. **超时处理**:建议客户端设置合理的超时时间,特别是涉及硬件操作的请求
|
||
6. **错误处理**:客户端应当处理所有可能的错误响应,包括JSON解析错误、硬件操作失败等
|
||
7. **日志记录**:系统会记录所有请求的处理过程,包括成功和失败情况,方便问题排查
|
||
8. **并发处理**:系统支持并发处理多个请求,但建议按照时序发送相关请求 |