Files
docsify-jsonrpc/zh-cn/dispatch_vehicle_scheduling.md
T
ykxiao 1f0c8ebe4e feat(dispatch): 添加调度车调度逻辑文档
- 编写从视觉扫描到立锯加工的完整调度流程说明
- 包含升降调度车送料、取料回退、立锯分配、等待位调度等环节
- 绘制整体流程图和详细时序图辅助理解
- 介绍调度逻辑触发机制及立锯分配策略(B优先)
- 详细描述送料调度车取料及送料到立锯的控制和安全位检查
- 说明等待位机制及A/B立锯协调逻辑,确保调度高效运行
- 详细列出寄存器和关键坐标常量定义,便于系统集成
- 引入通道驱动、任务计数和安全标志的并发与安全机制
- 设计超时保护策略防止异常情况导致调度堵塞
2026-07-01 11:15:49 +08:00

14 KiB
Raw Blame History

调度车调度逻辑

本文档阐述从视觉扫描完成到送料调度车取料、送至立锯加工完成的完整调度加工逻辑,涵盖升降调度车送料、取料回退、立锯分配、等待位调度、龙门取料入锯及立锯切割加工全链路。


1. 整体流程概览

graph TB
    A[升降调度车送料到视觉拍照位] --> B[视觉3D扫描 + 算法处理]
    B --> C[视觉顶针旋转完成 M46=true]
    C --> D[sawDispatchTrigger通道触发]
    D --> E{立锯空闲判断<br/>B优先}
    
    E -->|有空闲| F[取料 → 回退]
    E -->|都繁忙| G[取料 → 回退 → 等待位]
    
    F --> H[送料到立锯]
    G --> I[轮询监控立锯空闲 → 分配]
    
    H --> J[龙门取料入锯]
    I --> K[送料到立锯 → 龙门取料]
    
    J --> L[立锯切割加工]
    K --> L

2. 时序图

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 任务计数管理

  • pendingSawTaskCountatomic 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秒 强制清除运动标记