228 lines
6.8 KiB
Markdown
228 lines
6.8 KiB
Markdown
# OPERATION 复合步骤设计
|
||||
|
|
|
|||
|
|
## 目标
|
|||
|
|
|
|||
|
|
将 recipe 中每个工站的 LOAD → EXECUTE → UNLOAD 三元组合并为一个 OPERATION 步骤。LOAD/UNLOAD 降级为步骤的入口/出口动作,由 resource_type 自动推导。24 步 → 12 步。
|
|||
|
|
|
|||
|
|
## 核心概念变化
|
|||
|
|
|
|||
|
|
### 旧模型
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
LOAD(CNC) → MACHINING → UNLOAD(CNC) → LOAD(Washer) → WASH → UNLOAD(Washer) → ...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
每个工站占 3 个 recipe_step,step_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` 字段:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type JobView struct {
|
|||
|
|
// ...existing...
|
|||
|
|
RawStatus string // "ON_BUFFER" / "PROCESSING" / "WAITING_UNLOAD"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Generator
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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 更新
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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 完成后
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
if stepType == OPERATION {
|
|||
|
|
l.db.SetJobProcessing(ctx, jobID, machineID, slotNo)
|
|||
|
|
} else {
|
|||
|
|
l.db.AdvanceStep(ctx, jobID, nil, OnEquipment, "eq:slot")
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
新增 `DBState.SetJobProcessing`:status=PROCESSING、position=OnEquipment、version+1。
|
|||
|
|
|
|||
|
|
### MachineDone(handleMachineDone / handleMachineWaitCandidate)
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
if stepType == OPERATION {
|
|||
|
|
l.db.SetJobWaitingUnload(ctx, jobID)
|
|||
|
|
} else {
|
|||
|
|
l.db.AdvanceStep(ctx, jobID, nil, "", "")
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
新增 `DBState.SetJobWaitingUnload`:status=WAITING_UNLOAD、version+1。
|
|||
|
|
|
|||
|
|
### MachineDone → InspectionResult(handleInspectionDone)
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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 完成后 `SetJobProcessing`,MachineDone 时 `SetJobWaitingUnload`。
|
|||
|
|
|
|||
|
|
## 数据库迁移
|
|||
|
|
|
|||
|
|
`schema/tools/data.go` 中删除旧步骤,插入新步骤。不存在活跃 job 兼容问题——dev 环境,清空 job 表后执行。
|
|||
|
|
|
|||
|
|
## 移除的常量
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
// 删除:
|
|||
|
|
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 保持正常
|