Files
bj_power/bj_power_mes/docs/superpowers/specs/2026-05-16-operation-step-design.md
T

6.8 KiB
Raw Blame History

OPERATION 复合步骤设计

目标

将 recipe 中每个工站的 LOAD → EXECUTE → UNLOAD 三元组合并为一个 OPERATION 步骤。LOAD/UNLOAD 降级为步骤的入口/出口动作,由 resource_type 自动推导。24 步 → 12 步。

核心概念变化

旧模型

LOAD(CNC) → MACHINING → UNLOAD(CNC) → LOAD(Washer) → WASH → UNLOAD(Washer) → ...

每个工站占 3 个 recipe_stepstep_index 推进 3 次。

新模型

OPERATION(resource=CNC) → OPERATION(resource=Washer) → ...

每个工站 1 个 recipe_step。步骤内有三个子阶段,由 job.status 驱动:

ON_BUFFER ──Load──→ PROCESSING ──MachineDone──→ WAITING_UNLOAD ──Unload──→ 下一步

step_index 只在 Unload 完成后推进一次。

recipe_step 变更

step_type 枚举

新增 OPERATION

OPERATION   ← 新增
DECISION    ← 保留
JUDGE       ← 保留
FINAL_SCAN  ← 保留
LASER_MARK  ← 保留
UNLOAD      ← 保留(OP110 下料接驳台)

删除:
LOAD, MACHINING, WASH, DEBURR, RUST_WASH, INSPECTION(被 OPERATION + resource_type 替代)

resource_type 复用

现有 resourceType 字段直接用于 OPERATION 步骤区分设备类型。Generator 根据 resource_type 推断 Load/Unload 动作类型:

resource_type Load Action Unload Action
CNC ActionLoadCNC ActionUnloadCNC
WASHER_HP ActionLoadWasher ActionUnloadWasher
CLEANING_LINE ActionLoadCleaning ActionUnloadCleaning
DEBURR ActionLoadDeburr ActionUnloadDeburr
INSPECTION ActionLoadInspection ActionUnloadInspection
SAMPLING ActionLoadSampling ActionUnloadSampling

迁移后数据

step_index  step_id    step_type    resource_type    step_name
────────────────────────────────────────────────────────────
1           OP10       OPERATION    CNC              CNC加工
2           OP20       OPERATION    WASHER_HP       高压清洗
3           OP30       OPERATION    INSPECTION      内窥镜检测
4           OP40       JUDGE                       检测判断
5           OP50       OPERATION    DEBURR          热能去毛刺
6           OP60       OPERATION    CLEANING_LINE   除锈清洗
7           OP70       FINAL_SCAN                   终检扫码
8           OP80       DECISION                     打标判断
9           OP90       LASER_MARK                   激光打标
10          OP100      DECISION                     抽检判断
11          OP110      OPERATION    SAMPLING        抽检
12          OP120      UNLOAD                       下料接驳台

nextStepBranches 示例:

  • OP40 branch MEASURE_NG: OP110
  • OP80 branch NEED_MARKING: OP90
  • OP100 branch NEED_SAMPLING: OP110

job 状态机

OPERATION 步骤内 status 驱动,现有枚举不变:

ON_BUFFER       → Worker Load → PROCESSING → MachineDone →
WAITING_UNLOAD  → Worker Unload → OnBuffer + AdvanceStep

检测设备 (INSPECTION/SAMPLING) 特殊路径

PROCESSING → MachineDone(inspectionPass=true)  → WAITING_UNLOAD → Worker Unload → AdvanceStep
PROCESSING → MachineDone(inspectionPass=false) → Scrapped(不卸载)

handleInspectionDone 变更:pass=true 时不调 AdvanceStep,改为 SetJobWaitingUnload,等待调度器生成 Unload 候选由 Worker 卸下。Unload 完成后才 AdvanceStep 推进到下一步。

调度器变更

JobView 扩展

Generator 需要区分 OPERATION 步骤内的子阶段。JobView 新增 RawStatus 字段:

type JobView struct {
    // ...existing...
    RawStatus string // "ON_BUFFER" / "PROCESSING" / "WAITING_UNLOAD"
}

Generator

case constants.StepType_Operation:
    switch job.RawStatus {
    case "ON_BUFFER":
        candidates = append(candidates, CandidateTask{
            Action:   g.loadActionFor(step.ResourceType),
            TargetID: 0, // findIdleMachine 在 trySchedule 中分配
            Priority: PriorityNormal,
        })
    case "PROCESSING":
        candidates = append(candidates, CandidateTask{
            Action:   ActionLoadCNC, // 占位
            TargetID: job.CurrentStep.TargetID,
            Meta:     map[string]any{"machineWait": true},
        })
    case "WAITING_UNLOAD":
        candidates = append(candidates, CandidateTask{
            Action:   g.unloadActionFor(step.ResourceType),
            TargetID: job.CurrentStep.TargetID,
            Priority: PriorityHigh,
        })
    }

findExchangePair 更新

if bufSnap.StepType == constants.StepType_Operation &&
    bufSnap.Status == "ON_BUFFER" &&
    bufSnap.PositionType == string(constants.PositionType_OnBuffer) &&
    bufSnap.ResourceType == unloadSnap.ResourceType {
    return bufSnap.JobID
}

Filter / Policy / Exchange

不变。

事件循环变更

Load 完成后

if stepType == OPERATION {
    l.db.SetJobProcessing(ctx, jobID, machineID, slotNo)
} else {
    l.db.AdvanceStep(ctx, jobID, nil, OnEquipment, "eq:slot")
}

新增 DBState.SetJobProcessingstatus=PROCESSING、position=OnEquipment、version+1。

MachineDonehandleMachineDone / handleMachineWaitCandidate

if stepType == OPERATION {
    l.db.SetJobWaitingUnload(ctx, jobID)
} else {
    l.db.AdvanceStep(ctx, jobID, nil, "", "")
}

新增 DBState.SetJobWaitingUnloadstatus=WAITING_UNLOAD、version+1。

MachineDone → InspectionResulthandleInspectionDone

if pass {
    l.db.SetJobWaitingUnload(ctx, jobID)
} else {
    l.db.CompleteStep(ctx, jobID, job.CurrentStepIndex, 
        map[string]any{"inspectionPass": false})
    l.db.RaiseAlarm(...)
    l.db.FinishJob(ctx, jobID, job.WorkOrderId, Scrapped)
    l.db.SetEquipmentSlot(ctx, machineID, slotNo, Done, Empty, 0)
}

Unload 完成后

不变。AdvanceStep 推进到下一步。

清洗机批量编排

WASHER_HP 的 2 槽位 Load/Unload 批量逻辑不变。Load 完成后 SetJobProcessingMachineDone 时 SetJobWaitingUnload

数据库迁移

schema/tools/data.go 中删除旧步骤,插入新步骤。不存在活跃 job 兼容问题——dev 环境,清空 job 表后执行。

移除的常量

// 删除:
StepType_Load, StepType_Machining
StepType_Wash, StepType_Deburr, StepType_RustWash, StepType_Inspection

// 新增:
StepType_Operation  StepType = "OPERATION"

测试

  • Generator: OPERATION 步骤在 ON_BUFFER/PROCESSING/WAITING_UNLOAD 三个状态下生成正确 Action
  • 事件循环: Load→SetJobProcessing, MachineDone→SetJobWaitingUnload, Unload→AdvanceStep
  • findExchangePair: OPERATION+ON_BUFFER 匹配正确
  • 检测设备: InspectionResult 合格→WAITING_UNLOAD→Unload→AdvanceStep;不合格→Scrapped
  • 清洗机: 2 槽位批量 Load/Unload 保持正常