From 1f0c8ebe4e14661e70312e602f50559cc9405b0e Mon Sep 17 00:00:00 2001 From: ykxiao Date: Wed, 1 Jul 2026 11:15:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(dispatch):=20=E6=B7=BB=E5=8A=A0=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E8=BD=A6=E8=B0=83=E5=BA=A6=E9=80=BB=E8=BE=91=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 编写从视觉扫描到立锯加工的完整调度流程说明 - 包含升降调度车送料、取料回退、立锯分配、等待位调度等环节 - 绘制整体流程图和详细时序图辅助理解 - 介绍调度逻辑触发机制及立锯分配策略(B优先) - 详细描述送料调度车取料及送料到立锯的控制和安全位检查 - 说明等待位机制及A/B立锯协调逻辑,确保调度高效运行 - 详细列出寄存器和关键坐标常量定义,便于系统集成 - 引入通道驱动、任务计数和安全标志的并发与安全机制 - 设计超时保护策略防止异常情况导致调度堵塞 --- _sidebar.md | 3 +- zh-cn/dispatch_vehicle_scheduling.md | 457 +++++++++++++++++++++++++++ 2 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 zh-cn/dispatch_vehicle_scheduling.md diff --git a/_sidebar.md b/_sidebar.md index f9df607..59dcefe 100644 --- a/_sidebar.md +++ b/_sidebar.md @@ -13,4 +13,5 @@ * **Excel服务模块** * [导出/导入](zh-cn/excel_output_process) * **硬件服务模块** - * [硬件视觉时序](zh-cn/hardware_vision_scheduling) \ No newline at end of file + * [硬件视觉时序](zh-cn/hardware_vision_scheduling) + * [调度车调度逻辑](zh-cn/dispatch_vehicle_scheduling) \ No newline at end of file diff --git a/zh-cn/dispatch_vehicle_scheduling.md b/zh-cn/dispatch_vehicle_scheduling.md new file mode 100644 index 0000000..56ea9c2 --- /dev/null +++ b/zh-cn/dispatch_vehicle_scheduling.md @@ -0,0 +1,457 @@ +# 调度车调度逻辑 + +> 本文档阐述从视觉扫描完成到送料调度车取料、送至立锯加工完成的完整调度加工逻辑,涵盖升降调度车送料、取料回退、立锯分配、等待位调度、龙门取料入锯及立锯切割加工全链路。 + +--- + +## 1. 整体流程概览 + +```mermaid +graph TB + A[升降调度车送料到视觉拍照位] --> B[视觉3D扫描 + 算法处理] + B --> C[视觉顶针旋转完成 M46=true] + C --> D[sawDispatchTrigger通道触发] + D --> E{立锯空闲判断
B优先} + + E -->|有空闲| F[取料 → 回退] + E -->|都繁忙| G[取料 → 回退 → 等待位] + + F --> H[送料到立锯] + G --> I[轮询监控立锯空闲 → 分配] + + H --> J[龙门取料入锯] + I --> K[送料到立锯 → 龙门取料] + + J --> L[立锯切割加工] + K --> L +``` + +--- + +## 2. 时序图 + +```mermaid +sequenceDiagram + participant 升降车 as 升降调度车 + participant 视觉 as 视觉算法系统 + participant 上位机 as go-auto上位机 + participant PLC as 主控PLC + participant 送料车 as 送料调度车 + participant 龙门 as 龙门(A/B) + participant 立锯 as 立锯(A/B) + + 升降车->>PLC: D2200=2630 送视觉拍照位 + PLC->>上位机: X72=true(升降车有料) + 上位机->>视觉: start_vision_algorithm + 视觉-->>上位机: capture_ready + 上位机->>PLC: M103(启动扫描轨道) + 上位机->>视觉: order_info(扫描结束) + 视觉-->>上位机: algorithm_coordinates(切割坐标) + Note over PLC: M46=true(视觉顶针旋转完成) + + alt 立锯有空闲 + 上位机->>上位机: sawDispatchTrigger触发 + 上位机->>上位机: B优先分配立锯,更新DB + 上位机->>PLC: M57(启动取料) + PLC-->>上位机: M58=true(取料完成) + 上位机->>PLC: M117(顶针回退)+M121(扫描架回退) + PLC-->>上位机: M118+M122=true(回退完成) + 上位机->>上位机: 安全位检查(龙门坐标) + 上位机->>PLC: D2044=目标坐标+M59(启动送料) + PLC-->>上位机: D2042回读验证 + else 立锯都繁忙 + 上位机->>PLC: M57(启动取料) + PLC-->>上位机: M58=true(取料完成) + 上位机->>PLC: M117+M121(回退) + PLC-->>上位机: M118+M122=true(回退完成) + 上位机->>PLC: D2194=2300+M107(等待位) + PLC-->>上位机: M52=true+D2042=2300(到达等待位) + 上位机->>上位机: 轮询监控A/B立锯空闲 + 上位机->>上位机: 立锯空闲后分配,通道通知龙门 + end + + 上位机->>龙门: gantryDispatchTrigger通知 + 龙门->>PLC: M67/M85(龙门取料) + PLC-->>龙门: M68/M86=true(取料完成) + 龙门->>PLC: M73/M91(龙门入锯) + PLC->>立锯: M74/M92上升沿(触发加工) + 立锯->>立锯: 写入坐标→切割→避让→回原 +``` + +--- + +## 3. 升降调度车送料(前置流程) + +升降调度车负责将原木从储料区送至视觉拍照位,是送料调度车取料的前置步骤。 + +### 3.1 控制逻辑 + +| 逻辑 | 触发条件 | 动作 | 说明 | +|------|---------|------|------| +| 顶料 | D2130在原点(0±0.01) + X56=true + M19=true | 写入M25上升顶料 | 升降车回到原位且有料时触发 | +| 送视觉拍照位 | M41=true + D2042≥2300 + X72=true + M26=true | D2200=2630 + M808启动 | 视觉顶针空闲时送到拍照位 | +| 送等待位 | M41=false + X72=true | D2200=1100 + M808启动 | 视觉顶针繁忙时送到等待位 | +| 升降回原 | D62>60 + D2130在拍照位(2630±5) | 写入M113启动回原 | M114上升沿重置允许下次回原 | + +### 3.2 关键坐标 + +| 寄存器 | 含义 | 值 | +|--------|------|-----| +| D2200 | 升降车目标位 | 2630(拍照位) / 1100(等待位) | +| D2130 | 升降车实时坐标 | 0=原点 | +| X72 | 升降车有料检测 | bool | +| M808 | 启动送料 | bool | + +--- + +## 4. 视觉扫描完成触发调度 + +视觉算法处理完成后,通过 `sawDispatchTrigger` 通道事件驱动调度逻辑启动。 + +### 4.1 触发机制 + +``` +视觉算法完成 → 上位机异步处理器 → sawDispatchTrigger通道写入 + → monitorSawDispatchTrigger()消费事件 + → pendingSawTaskCount原子计数器+1 +``` + +### 4.2 立锯分配策略(B优先) + +``` +pendingSawTaskCount++ + ↓ +检查B立锯空闲? ──是──→ 分配B立锯, D2044=8522 + │否 +检查A立锯空闲? ──是──→ 分配A立锯, D2044=4000 + │否 +都繁忙 → 启动取料+等待位流程 +``` + +**分配动作**(`passCoordinatesToSaws`): +1. **立锯置忙**:通过 `SawProcessor.currentWoodID.Store(WoodID)` 立即置忙,防止窗口期重复分配 +2. **DB更新**:`saw_type`=A/B, `process_status`=加工中(1) +3. **LED推送**:调用 `updateLEDSawStatus()` 更新LED面板显示 + +--- + +## 5. 送料调度车取料流程 + +### 5.1 取料触发条件(逻辑2) + +``` +M46=true(视觉顶针旋转完成) + && M51=true(送料调度车空闲) + && D2042=2300±0.1mm(调度车在取料位) + && visionProcessing=false(视觉处理安全标志) + → 写入M57=true(启动取料) +``` + +### 5.2 取料完成检测(逻辑3) + +``` +M58上升沿(false→true) = 取料完成 + → 并行写入: + M117=true(视觉顶针回退) + M121=true(相机扫描架回退) +``` + +### 5.3 回退完成监控(逻辑4) + +``` +M118上升沿(顶针回退完成) + && M122上升沿(扫描架回退完成) + → 根据sawAvailable决定后续动作: + true → executeDispatchToSaw(送料到立锯) + false → executeDispatchToWaitPosition(送到等待位) +``` + +> 超时保护:M58检测超时3600秒,M118/M122检测超时30秒 + +--- + +## 6. 送料到立锯 + +### 6.1 安全位检查 + +送料到立锯前,必须先通过动态安全位检查(`dispatcher_sorting_safety.go`): + +**送料到A立锯**(`CheckDispatcherSortingSafetyToA`): +- A龙门夹臂在原点(D2174/D2176=1500±5) 且 D2046=0±5mm + +**送料到B立锯**(`CheckDispatcherSortingSafetyToB`): +- A龙门安全检查(二选一): + - D2046 ≥ D2188-5(实时坐标≥静态坐标-容差) + - 夹臂在原点 + D2046=0±5 +- B龙门安全检查:D2062=0±5 且 D2178/D2180=1500±5 +- 安全位不满足时,自动写入D2194等待位+M107暂停 + +### 6.2 送料执行 + +``` +安全位检查通过 + → 写入D2044目标坐标(A=4000 / B=8522) + → 写入M59=true(启动送料) + → 持续监测D2042回读值,等待D2042=D2044±0.1 + → 设置dispatcherMoving=false + → 推送LED面板状态 +``` + +> 回读验证超时300秒,失败时调用 `rollbackSawAssignment()` 回滚立锯分配状态 + +### 6.3 分配回滚机制 + +当D2044写入失败、M59写入失败或回读超时时,执行回滚: +1. 清除 `SawProcessor.currentWoodID`(立锯置闲) +2. DB中 `process_status` 恢复为未加工(0),`saw_type` 清空 + +--- + +## 7. 等待位流程 + +### 7.1 进入等待位(逻辑6) + +当A/B立锯都繁忙时: +``` +写入D2194=2300(A等待位坐标) + → 写入M107=true(启动等待位) + → dispatcherMoving=true + → 推送LED面板(A/B都繁忙) + → 监控调度车到达等待位 +``` + +### 7.2 A等待位有料检测(逻辑7) + +``` +D2042=2300±5mm(到达A等待位) + && M52=true(调度车有料) + → 上升沿触发(只执行一次) + → dispatcherMoving=false + → startSawIdleMonitoring()启动空闲轮询 +``` + +### 7.3 立锯空闲轮询(逻辑8) + +> 双重检查锁 + goroutine防泄漏设计 + +``` +startSawIdleMonitoring(): + ├─ 检查pendingSawTaskCount > 0 + ├─ 并行启动: + │ ├─ monitorSawAIdleAndDispatch() + │ └─ monitorSawBIdleAndDispatch() + └─ 任务完成后回到检查,计数=0时退出 + +monitorSawAIdleAndDispatch(): + A空闲 && B空闲 → 优先B,A退出 + A空闲 && B忙 → 查询DB,分配到A立锯 + → gantryADispatchTrigger通道通知龙门 + +monitorSawBIdleAndDispatch(): + B空闲 → 查询DB,分配到B立锯 + → gantryBDispatchTrigger通道通知龙门 +``` + +--- + +## 8. A/B立锯协调逻辑 + +### 8.1 B立锯优先完成调度(逻辑9) + +当调度车在A等待位(D2042=2300)且有料(M52=true),A/B立锯都忙时: + +``` +实时对比A/B立锯加工进度比例: + sawBProgress = processedCoords / totalCoords (B锯) + sawAProgress = processedCoords / totalCoords (A锯) + + 当 sawBProgress > sawAProgress + 0.001: + → B立锯将优先完成 + → CheckDispatcherSortingSafetyToB(非阻塞A龙门检查) + → 写入B等待位坐标,调度车提前移动到B等待位 +``` + +### 8.2 B等待位有料监控(逻辑10) + +``` +M52=true(调度车有料) + && D2042=6208±5mm(到达B等待位) + → 检查龙门安全位(B优先,再尝试A) + → 写入D2044目标坐标 + M59送料 + → M52下降沿重置防重复标志 +``` + +--- + +## 9. 龙门取料与入锯 + +送料调度车到达立锯位置后,龙门执行取料→入锯→加工流程。 + +### 9.1 龙门取料触发 + +``` +A龙门: D2042=4000±0.5 + M52上升沿 → executeGantryAPickup() +B龙门: D2042=8522±0.5 + M52上升沿 → executeGantryBPickup() +``` + +### 9.2 龙门取料流程(以A龙门为例) + +``` +1. 红外测距仪写入夹臂顶料位置坐标 +2. 调度车升到预定高度(D2196, M800启动, M801完成) + 公式: 820 + (-18 - max(D2182, D2184)) + D2172 +3. M67/M85启动取料 +4. M68/M86上升沿确认取料完成 +5. 计算龙门入锯坐标: 1500 - 左夹臂当前位置 → D2186/D2190 +6. 调度车高度降到0(D2196=0) +7. M73/M91龙门入锯 +8. D2194=2300 + M107调度车回等待位 +9. 异步监控M108到达等待位,触发立锯调度(triggerDispatch=true) +``` + +--- + +## 10. 立锯加工流程 + +### 10.1 触发条件 + +``` +A立锯: M74上升沿 && M68=true(启用) +B立锯: M92上升沿 && M86=true(启用) +``` + +### 10.2 加工流程(每次M74/M92上升沿执行一轮) + +``` +1. 数据加载: 从DB加载原木left/right坐标数组 +2. 坐标写入: + left → D2014 + M108 → 等待M109上升沿(调整完成) + right → D2016 + M110 → 等待M111上升沿(调整完成) +3. 切割触发: M75/M93启动切割 +4. 切割完成: M76/M94上升沿 → M112/M114锯片避让 → 龙门回退 +5. 循环: currentIndex++, 处理下一组坐标 +6. 全部完成: handleCompletion() + → 更新DB process_status=已完成(2) + → 清除currentWoodID(立锯置闲) + → M71/M89龙门回原 → M72/M90确认 +``` + +> 坐标修正:坐标值减去最小间距的一半(8.9/2=4.45cm)后写入PLC,防止双锯碰撞 + +--- + +## 11. 寄存器总表 + +### 11.1 送料调度车 + +| 寄存器 | 类型 | 说明 | +|--------|------|------| +| D2042 | D(读) | 送料调度车当前坐标 | +| D2044 | D(写) | 送料调度车目标坐标 | +| D2194 | D(写) | 等待位坐标写入 | +| M46 | M(读) | 视觉顶针旋转完成 | +| M51 | M(读) | 送料调度车空闲 | +| M52 | M(读) | 送料调度车有料 | +| M57 | M(写) | 送料调度车取料启动 | +| M58 | M(读) | 送料调度车取料完成 | +| M59 | M(写) | 送料调度车送料启动 | +| M107 | M(写) | 送料调度车等待位启动 | +| M108 | M(读) | 送料调度车到达等待位 | +| M117 | M(写) | 视觉顶针回退 | +| M118 | M(读) | 视觉顶针回退完成 | +| M121 | M(写) | 相机扫描架回退 | +| M122 | M(读) | 相机扫描架回退完成 | + +### 11.2 升降调度车 + +| 寄存器 | 类型 | 说明 | +|--------|------|------| +| D2130 | D(读) | 升降车实时坐标 | +| D2200 | D(写) | 升降车目标位置 | +| X56 | X(读) | 升降台回原位感应 | +| X72 | X(读) | 升降调度车有料检测 | +| M25 | M(写) | 升降车上升顶料 | +| M41 | M(读) | 视觉顶针空闲状态 | +| M808 | M(写) | 启动送料 | + +### 11.3 龙门(A/B) + +| 寄存器 | A龙门 | B龙门 | 说明 | +|--------|-------|-------|------| +| 实时坐标 | D2046 | D2062 | 龙门轨道坐标 | +| 静态坐标 | D2188 | D2192 | 龙门静态坐标 | +| 夹臂左位 | D2174 | D2178 | 左夹臂坐标 | +| 夹臂右位 | D2176 | D2180 | 右夹臂坐标 | +| 入锯坐标 | D2186 | D2190 | 龙门入锯坐标 | +| 取料启动 | M67 | M85 | 龙门取料指令 | +| 取料完成 | M68 | M86 | 取料完成确认 | +| 入锯指令 | M73 | M91 | 龙门入锯 | +| 回原指令 | M71 | M89 | 龙门回原 | +| 回原确认 | M72 | M90 | 回原完成 | + +### 11.4 立锯(A/B) + +| 寄存器 | A立锯 | B立锯 | 说明 | +|--------|-------|-------|------| +| 监控触发 | M74 | M92 | 立锯监控寄存器 | +| 启用状态 | M68 | M86 | 立锯启用 | +| 切割启动 | M75 | M93 | 启动切割 | +| 切割完成 | M76 | M94 | 切割完成上升沿 | +| left坐标 | D2014 | D2014 | 立锯left坐标值 | +| right坐标 | D2016 | D2016 | 立锯right坐标值 | + +--- + +## 12. 关键坐标常量 + +| 常量 | 值(mm) | 说明 | +|------|--------|------| +| GantryATargetPosition | 4000 | A立锯取料绝对坐标 | +| GantryBTargetPosition | 8522 | B立锯取料绝对坐标 | +| DispatcherAWaitPosition | 2300 | A点等待位坐标 | +| DispatcherBWaitPosition | 6208 | B点等待位坐标 | +| VisionPhotoPosition | 2630 | 视觉拍照位置 | +| LiftWaitPosition | 1100 | 升降车等待位 | +| DispatcherPositionTolerance | 0.1 | 调度车到位容差 | +| PositionTolerance2 | 0.5 | 位置容差(宽) | +| LeftClampOriginPosition | 1500 | 左夹臂原点位置 | +| DispatcherBaseHeight | 820 | 调度车基准高度 | + +--- + +## 13. 并发与安全机制 + +### 13.1 通道驱动 + +| 通道 | 触发方 | 消费方 | 说明 | +|------|--------|--------|------| +| sawDispatchTrigger | 视觉扫描完成 | monitorSawDispatchTrigger | 调度任务入口 | +| gantryADispatchTrigger | 立锯空闲轮询 | 龙门调度模块 | A龙门送料通知 | +| gantryBDispatchTrigger | 立锯空闲轮询 | 龙门调度模块 | B龙门送料通知 | + +### 13.2 任务计数管理 + +- `pendingSawTaskCount`(atomic int32):管理待处理任务数 +- +1时机:sawDispatchTrigger收到事件 +- -1时机:分配成功、查询失败、超时、M107写入失败 +- 目的:防止任务泄漏和goroutine无限堆积 + +### 13.3 安全标志 + +| 标志 | 作用 | +|------|------| +| visionProcessing | 视觉处理中禁止取料,防止视觉设备运动中调度车动作 | +| m57WriteExecuted | 防止M57重复写入 | +| bWaitPosFeedExecuted | 防止B等待位送料重复执行,M52下降沿重置 | +| dispatcherMoving | 调度车运动中标志,取料/送料时置true,到位后置false | +| isMonitoringSawIdle | 防止轮询goroutine泄漏 | + +### 13.4 超时保护 + +| 场景 | 超时时间 | 处理 | +|------|---------|------| +| M58取料完成检测 | 3600秒 | 减少计数器,记录异常 | +| M118/M122回退完成 | 30秒 | 记录异常,停止流程 | +| D2042回读验证 | 300秒 | 回滚立锯分配 | +| 等待位到达检测 | 3600秒 | 减少计数器,记录异常 | +| M108到达等待位 | 30秒 | 强制清除运动标记 |