Files
bj_power/bj_power_mes/docs/superpowers/specs/2026-05-20-scan-failure-waste-flow-design.md
T

4.4 KiB
Raw Blame History

扫码失败废料搬运流程

日期: 2026-05-20
状态: 已确认
类型: 新功能

1. 概述

从接驳台取料扫码后,如果扫码失败,工件放到暂存台(状态 WAITING_WASTE),等 WasteReady 信号为 true 时搬运到废料台,释放暂存台槽位,Job 标记为 SCRAPPED

流程

接驳台取料 → 扫码失败 → 放入暂存台(WAITING_WASTE) → 等待 WasteReady → 搬运至废料台 → 释放暂存台槽位 → Job SCRAPPED

2. 涉及模块

模块 改动
constants/constants.go 新增 JobStatus_WaitingWaste
schema/job.go ent 枚举更新(先改,再 go generate
internal/processor/replenisher.go 扫码失败时写 WAITING_WASTE + alarm
internal/processor/scheduler/types.go SystemState 新增 WasteReady bool
internal/processor/eventloop/scheduler_bridge.go 快照读取 WasteReady 信号
internal/processor/scheduler/generator.go 为 WAITING_WASTE job 生成废料搬运任务
internal/processor/robot_worker.go 新增 executeLoadToWaste 分发
internal/robot/dock.go 新增 PlaceWorkpieceToWasteStationM1140
internal/processor/eventloop/worker_dispatch.go 废料搬运完成后 ScrapJob + ReleaseSlot

3. 详细设计

3.1 Job 状态

新增 JobStatus_WaitingWaste = "WAITING_WASTE"

  • PositionType: ON_BUFFER(工件物理占用暂存台槽位)
  • SuspendedReason: "SCAN_FAILED"
  • 调度器 JobSuspended filter 需要同步排除此状态(WAITING_WASTE 不应被常规调度选中)

3.2 Replenisher 扫码失败逻辑

replenishOne 方法中,扫码失败后:

  1. 工件物理已在暂存台(机器人已放置)
  2. 写 DBSetStatus(WAITING_WASTE) + SetPositionType(ON_BUFFER) + SetSuspendedReason("SCAN_FAILED")
  3. DockSlot 清空(status=0),可继续接收新料
  4. 创建 alarmalarm_code: SCAN_FAILED),供追溯
  5. 不阻塞后续补料(continue 下一个 dock item

3.3 WasteReady 信号

  • 信号已定义:WasteReady = M1150.1doc/signal.csv 行 19
  • 通过 preload.GetMAddress("WasteReady") 获取地址,在 trySchedule 时读取 PLC 当前值
  • SystemState.WasteReady bool — 调度快照中携带,供 Generator 判断

3.4 调度

Generator: 遍历 RuntimeSnapshotStatus == WAITING_WASTE 的 job,若 WasteReady == true,生成:

CandidateTask{
    Action:   ActionLoadWaste,  // 已在 types.go 中定义
    TargetID: tempSlotNo,
    Priority: PriorityHigh,
}

SchedulerBridge: 映射 ActionLoadWasteRobotAction{Kind: "load_to_waste", SrcSlot: tempSlotNo}

优先级: PriorityHigh,释放暂存台资源不应被普通装料阻塞。

3.5 RobotWorker

新增 executeLoadToWaste:

// 暂存台取料 → 放入废料台
func (w *RobotWorker) executeLoadToWaste(ctx context.Context, action action.RobotAction) error {
    // 1. 从暂存台取料
    if err := w.robotCtrl.FetchWorkpieceFromTempStation(ctx, ...); err != nil {
        return fmt.Errorf("fetch from temp station: %w", err)
    }
    // 2. 放入废料台 (M1140)
    if err := w.robotCtrl.PlaceWorkpieceToWasteStation(ctx, ...); err != nil {
        return fmt.Errorf("place to waste station: %w", err)
    }
    return nil
}

3.6 Robot Controller

internal/robot/dock.go 新增:

func (c *Controller) PlaceWorkpieceToWasteStation(ctx context.Context, ...) error {
    // 发送 M1140 信号
}

3.7 EventLoop 完成处理

废料搬运成功后:

  1. TempStoreActor.ReleaseSlot(slotNo) — 释放暂存台槽位
  2. DBState.ScrapJob(jobID) — Job 标记 SCRAPPED(终态)

3.8 启动恢复

RecoverOnStartup 中:WAITING_WASTE 状态的 job 视为已正确放置在暂存台,转为 PAUSED。等待下次 tryScheduleWasteReady 信号触发搬运。

4. 边缘情况

  • 多个 WAITING_WASTE job: Generator 一次生成多个候选任务,由 PriorityPolicy 按优先级排序后依次执行
  • WasteReady 长时间为 false: job 留在暂存台,占用槽位,不阻塞其他正常 job 调度(JobSuspended filter 排除)
  • 暂存台满: replenisher 的 reserveFreeTempSlot 分配失败会正常停止补料,不会抢占废料等待工件的槽位
  • 废料台满: PLC 不会设置 WasteReady=true,搬运不会触发(硬件层保证)