Files
bj_power/bj_power_mes/docs/analysis/2026-05-17-mockrun-action-slot-analysis.md
T

530 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mockrun 工件 Action 与设备槽位状态时序分析
> **运行参数**: `go run cmd/mockrun/main.go -jobs 4 -docks 1 -product 1 -timeout 5m`
> **产品类型**: 1 (12步工艺流程)
> **工单**: 385, 工件 916/917/918/919
---
## 设备-ID 映射
| ID | 类型 | 名称 | 槽位数 | Batch | Inspection |
|----|------|------|--------|-------|------------|
| 3 | CNC | CNC-1 | 1 | false | false |
| 4 | CNC | CNC-2 | 1 | false | false |
| 5 | WASHER_HP | 高压清洗机 | 2 | true | false |
| 6 | INSPECTION | 内窥镜检测线 | 1 | false | true |
| 7 | DEBURR | 去毛刺机 | 1 | false | false |
| 8 | CLEANING_LINE | 除锈清洗线 | 1 | false | false |
---
## 工艺流程 (产品类型 1)
```
Step 1: CNC 加工 (machine 3/4) → 完成信号 → Exchange 换料
Step 2: 高压清洗 (machine 5, batch) → 完成信号 → Exchange 换料
Step 3: 内窥镜检测 (machine 6, inspection) → 检测完成 → Unload
Step 4: [内部步骤]
Step 5: 去毛刺 (machine 7) → 完成信号 → Unload
Step 6: 除锈清洗 (machine 8) → 完成信号 → Unload
Step 7: 扫码 (scan_full)
Step 8: [内部步骤]
Step 9: 打标 (mark_full)
Step 10-11: [内部步骤]
Step 12: 下料到接驳台 (unload_to_dock) → COMPLETED
```
---
## 完整时序分析
### 阶段 0: 系统初始化 + 补料 (17:59:06 ~ 17:59:26)
```
17:59:06.854 所有 equipment_slot (ID 137-164) → EMPTY (启动清空)
17:59:08.924 补料开始: 从接驳台搬运 4 个工件到暂存台
17:59:26.365 补料完成: 4 个工件已在暂存台 (slot 1-4)
job_processor: order started, jobs=4
```
**槽位状态快照(补料后)**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| 所有设备 | 全部 | EMPTY | 0 |
**暂存台分布**:
| 暂存台槽位 | JobID |
|-----------|-------|
| 1 | 916 |
| 2 | 917 |
| 3 | 918 |
| 4 | 919 |
---
### 阶段 1: CNC 加工 — Job 916/917 上料 (17:59:26 ~ 17:59:39)
```
T+0.0s dispatch j916-s1-load_to_machine → machine 3, srcSlot=1
robot worker: executing load_to_machine jobId=916
→ FetchWorkpieceFromTempStation(slot 1)
→ AllocateSlot(916) → slotNo=1 (Actor memory)
→ PlaceWorkpieceToMachine(3, slot 1)
T+3.4s dispatch j917-s1-load_to_machine → machine 4, srcSlot=2
robot worker: executing load_to_machine jobId=917
→ FetchWorkpieceFromTempStation(slot 2)
→ AllocateSlot(917) → slotNo=1 (Actor memory)
→ PlaceWorkpieceToMachine(4, slot 1)
```
**Actor LOAD_COMPLETE → DB 槽位写入**:
```
17:59:29.768 equipment 3 slot 1: EMPTY→OCCUPIED (job 916)
job 916: PROCESSING, ON_EQUIPMENT, ref=3:1
17:59:33.177 equipment 4 slot 1: EMPTY→OCCUPIED (job 917)
job 917: PROCESSING, ON_EQUIPMENT, ref=4:1
```
**槽位状态**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| CNC-1 (3) | 1 | OCCUPIED | 916 |
| CNC-2 (4) | 1 | OCCUPIED | 917 |
**暂存台**: slot 1,2 被释放 (工件已上料到 CNC)slot 3→918, 4→919
---
### 阶段 2: CNC 完成 + Exchange 换料 (17:59:39 ~ 17:59:51)
```
T+13.5s MACHINE_DONE 信号 → actor-done-3
Actor.handleSignal: 3:1 OCCUPIED→DONE
DB: equipment 3 slot 1 → DONE (job 916)
T+13.6s EventLoop: wakeJob(916) → 发现暂存台有 918 等待上料到同类设备 (CNC)
→ Exchange pair: unloadJob=916, loadJob=918
dispatch j916-s1-exchange_full → machine 3, srcSlot=3
robot worker: exchange_full
→ FetchWorkpieceFromTempStation(slot 3) // 取上料工件 918
→ FindSlotByJobID(916) → slot 1
→ ReleaseSlot(1) + AllocateSlot(918) // Actor atomic swap
→ ExchangeWorkpieceToMachine(3, slot 1) // 换料
→ PlaceWorkpieceToTempStation(slot 3) // 放下料工件 916
T+16.5s MACHINE_DONE 信号 → actor-done-4
Actor.handleSignal: 4:1 OCCUPIED→DONE
DB: equipment 4 slot 1 → DONE (job 917)
T+19.2s EventLoop: wakeJob(917) → Exchange pair: unloadJob=917, loadJob=919
dispatch j917-s1-exchange_full → machine 4, srcSlot=4
```
**Exchange LOAD_COMPLETE DB 写入 (Actor, prevStatus=DONE)**:
```
17:59:45.526 equipment 3 slot 1: DONE→OCCUPIED (job 918)
job 916: ON_BUFFER (已放回暂存台)
17:59:51.133 equipment 4 slot 1: DONE→OCCUPIED (job 919)
job 917: ON_BUFFER (已放回暂存台)
```
**槽位状态 (Exchange 后)**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| CNC-1 (3) | 1 | OCCUPIED | 918 |
| CNC-2 (4) | 1 | OCCUPIED | 919 |
**暂存台**: slot 1→916, 2→917, 3→918(已上料), 4→919(已上料)
→ 916, 917 已完成 CNC,回到暂存台等待下一步
---
### 阶段 3: 高压清洗 — Batch 上料 (17:59:51 ~ 17:59:58)
```
T+24.8s EventLoop: 916+917 CNC 步骤完成 → 下一步都是高压清洗 (machine 5)
dispatch batch-916: [load_to_machine, load_to_machine, startup_washer]
1) robot worker: load_to_machine jobId=916
→ FetchFromTempStation(slot 1)
→ AllocateSlot(916) → slotNo=1
→ PlaceWorkpieceToMachine(5, slot 1)
2) robot worker: load_to_machine jobId=917
→ FetchFromTempStation(slot 2)
→ AllocateSlot(917) → slotNo=2
→ PlaceWorkpieceToMachine(5, slot 2)
3) robot worker: startup_washer
→ StartupWasher() 触发清洗机启动信号
T+26.5s MACHINE_DONE → actor-done-3 (job 918 CNC 完成)
Actor.handleSignal: 3:1 OCCUPIED→DONE
同时 CNC-2 job 919 也完成:
T+26.6s MACHINE_DONE → actor-done-4
Actor.handleSignal: 4:1 OCCUPIED→DONE
```
**高压清洗机 Load DB 写入**:
```
17:59:57.947 equipment 5 slot 1: EMPTY→OCCUPIED (job 916)
17:59:57.948 equipment 5 slot 2: EMPTY→OCCUPIED (job 917)
```
**槽位状态 (清洗机刚上料)**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| 清洗机 (5) | 1 | OCCUPIED | 916 |
| 清洗机 (5) | 2 | OCCUPIED | 917 |
| CNC-1 (3) | 1 | DONE | 918 |
| CNC-2 (4) | 1 | DONE | 919 |
---
### 阶段 4: 清洗机完成 + CNC Unload (17:59:58 ~ 18:00:05)
```
T+32.6s 清洗机 batch 完成信号 → actor-done-5 (触发两次, 每槽一次)
Actor.handleSignal (batch=true):
→ 5:1 OCCUPIED→DONE, 5:2 OCCUPIED→DONE
T+32.6s wakeJob(916), wakeJob(917)
同时: 调度 CNC-1 unload (job 918)
dispatch j918-s1-unload_to_buffer
robot worker: unload_to_buffer jobId=918
→ FindSlotByJobID(918) → machine 3 slot 1
→ FetchWorkpieceFromMachine(3, slot 1)
→ PlaceWorkpieceToTempStation(slot 3)
T+35.1s dispatch j919-s1-unload_to_buffer
robot worker: unload_to_buffer jobId=919
```
**DB 槽位更新 (Actor handleSignal batch + UNLOAD_COMPLETE)**:
```
18:00:02.913 equipment 5 slot 1: OCCUPIED→DONE (job 916)
18:00:02.913 equipment 5 slot 2: OCCUPIED→DONE (job 917)
18:00:01.354 equipment 3 slot 1: DONE→EMPTY (job 918, UNLOAD_COMPLETE)
18:00:04.759 equipment 4 slot 1: DONE→EMPTY (job 919, UNLOAD_COMPLETE)
```
**槽位状态**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| 清洗机 (5) | 1 | DONE | 916 |
| 清洗机 (5) | 2 | DONE | 917 |
| CNC-1 (3) | 1 | EMPTY | 0 |
| CNC-2 (4) | 1 | EMPTY | 0 |
**暂存台**: 1→916, 2→917, 3→918, 4→919 (全部在暂存台)
---
### 阶段 5: 清洗机 Exchange + 检测线上料 (18:00:04 ~ 18:00:28)
```
T+38.5s EventLoop: washer unload batch check → 发现 2 个 Done 工件
dispatch batch-916: [exchange_full, exchange_full, startup_washer]
1) exchange_full jobId=916
→ FetchFromTempStation(slot 3) // 取上料工件 918
→ ReleaseSlot(1) + AllocateSlot(918) // 清洗机换料
→ ExchangeWorkpieceToMachine(5, slot 1)
2) exchange_full jobId=917
→ FetchFromTempStation(slot 4) // 取上料工件 919
→ ReleaseSlot(2) + AllocateSlot(919)
→ ExchangeWorkpieceToMachine(5, slot 2)
3) startup_washer → 启动清洗机
T+51.8s 处理 multi-action result:
exchange load completed: job 918 → machine 5 slot 1 (prevStatus=DONE)
exchange load completed: job 919 → machine 5 slot 2 (prevStatus=DONE)
exchange action completed: 916→918, 917→919
T+51.9s dispatch j916-s3-load_to_machine → machine 6 (检测线)
robot worker: load_to_machine jobId=916
→ FetchFromTempStation(slot 1)
→ AllocateSlot(916) → slotNo=1
→ PlaceWorkpieceToMachine(6, slot 1)
```
**Exchange + 检测线 Load DB 写入**:
```
18:00:17.979 equipment 5 slot 1: DONE→OCCUPIED (job 918, prevStatus=DONE)
18:00:17.981 equipment 5 slot 2: DONE→OCCUPIED (job 919, prevStatus=DONE)
18:00:20.384 (job 916 检测线上料,见下方阶段6)
```
**槽位状态 (Exchange 后)**:
| 设备 | 槽位 | 状态 | JobID | 备注 |
|------|------|------|-------|------|
| 清洗机 (5) | 1 | OCCUPIED | 918 | 新一轮清洗 |
| 清洗机 (5) | 2 | OCCUPIED | 919 | 新一轮清洗 |
| CNC-1 (3) | 1 | EMPTY | 0 |
| CNC-2 (4) | 1 | EMPTY | 0 |
| 检测线 (6) | 1 | OCCUPIED | 916 |
**暂存台**: 1→916(已取走), 2→917, 3→918(已上料), 4→919(已上料)
→ 916 在检测线上,917 还在暂存台
---
### 阶段 6: 检测线 + 清洗机并行 (18:00:18 ~ 18:00:37)
```
T+51.9s dispatch j916-s3-load_to_machine → machine 6
→ 916 上检测线
T+56.8s 清洗机 batch 完成信号 → actor-done-5 (两次)
wakeJob(918), wakeJob(919)
调度: batch-918 [unload_to_buffer, unload_to_buffer]
1) unload_to_buffer jobId=918 → machine 5 slot 1 → 暂存台 slot 3
2) unload_to_buffer jobId=919 → machine 5 slot 2 → 暂存台 slot 4
T+57.8s MACHINE_DONE → actor-insp-6 (检测完成,合格)
EventLoop: handleInspectionDone 判定合格 → CompleteStep
T+61.6s dispatch j916-s3-unload_to_buffer → machine 6
→ 916 从检测线下料到暂存台 slot 1
T+62.0s 清洗机 unload 结果处理:
unload action completed: jobId=918
unload action completed: jobId=919
T+66.0s dispatch j916-s5-load_to_machine → machine 7 (去毛刺机)
robot worker: load_to_machine jobId=916
T+68.4s dispatch j917-s3-load_to_machine → machine 6 (检测线)
robot worker: load_to_machine jobId=917
```
**DB 槽位更新 (检测线信号 + 清洗机 UNLOAD_COMPLETE + 去毛刺 Load)**:
```
18:00:22.913 equipment 5 slot 1: OCCUPIED→DONE (job 918)
18:00:22.913 equipment 5 slot 2: OCCUPIED→DONE (job 919)
(检测线 inspection done — handleSignal 不写 DB,由 EventLoop CompleteStep 处理)
18:00:27.724 equipment 5 slot 1: DONE→EMPTY (UNLOAD_COMPLETE)
18:00:27.726 equipment 5 slot 2: DONE→EMPTY (UNLOAD_COMPLETE)
18:00:34.536 equipment 7 slot 1: EMPTY→OCCUPIED (job 916, LOAD_COMPLETE)
```
**槽位状态**:
| 设备 | 槽位 | 状态 | JobID |
|------|------|------|-------|
| 检测线 (6) | 1 | OCCUPIED | 917 |
| 去毛刺 (7) | 1 | OCCUPIED | 916 |
| 清洗机 (5) | 1 | EMPTY | 0 |
| 清洗机 (5) | 2 | EMPTY | 0 |
| CNC-1 (3) | 1 | EMPTY | 0 |
| CNC-2 (4) | 1 | EMPTY | 0 |
---
### 阶段 7: 去毛刺完成 + 检测线完成 (18:00:36 ~ 18:00:57)
```
T+70.8s MACHINE_DONE → actor-done-7
Actor.handleSignal: 7:1 OCCUPIED→DONE (job 916)
wakeJob(916) → dispatch j916-s5-unload_to_buffer
T+74.2s dispatch j916-s6-load_to_machine → machine 8 (除锈清洗线)
robot worker: load_to_machine jobId=916
T+74.8s MACHINE_DONE → actor-insp-6 (917 检测完成)
EventLoop: handleInspectionDone 判定合格
T+80.6s dispatch j917-s3-unload_to_buffer → machine 6
T+82.8s MACHINE_DONE → actor-done-8 (916 除锈清洗线完成)
wakeJob(916)
T+84.0s dispatch j916-s6-unload_to_buffer → machine 8
T+86.4s dispatch j917-s5-load_to_machine → machine 7 (去毛刺)
T+88.8s dispatch j918-s3-load_to_machine → machine 6 (检测线)
T+91.2s dispatch j916-s7-scan_full → 扫码
T+91.8s MACHINE_DONE → actor-done-7 (917 去毛刺完成)
wakeJob(917)
```
**DB 槽位更新**:
```
18:00:36.913 equipment 7 slot 1: OCCUPIED→DONE (job 916, signal)
(unload 后写 DB: EMPTY)
18:00:40.913 equipment 6 slot 1: inspection done (合格)
equipment 8 slot 1: EMPTY→OCCUPIED (job 916, LOAD_COMPLETE)
18:00:48.913 equipment 8 slot 1: OCCUPIED→DONE (job 916, signal)
(unload 后写 DB: EMPTY)
18:00:52.567 equipment 7 slot 1: EMPTY→OCCUPIED (job 917, LOAD_COMPLETE)
```
---
### 阶段 8: 流水线持续推进 (18:00:54 ~ 18:01:36)
```
T+88.8s dispatch j918-s3-load_to_machine → machine 6
T+94.8s dispatch j917-s5-unload_to_buffer → machine 7
T+98.2s dispatch j918-s3-unload_to_buffer → machine 6
T+100.7s dispatch j917-s6-load_to_machine → machine 8
T+107.1s dispatch j918-s5-load_to_machine → machine 7
T+109.8s MACHINE_DONE → actor-done-8 (917 清洗完成)
T+111.5s dispatch j917-s6-unload_to_buffer → machine 8
T+113.1s MACHINE_DONE → actor-done-7 (918 去毛刺完成)
T+113.9s dispatch j918-s5-unload_to_buffer → machine 7
T+117.3s dispatch j918-s6-load_to_machine → machine 8
T+123.7s dispatch j919-s3-load_to_machine → machine 6
T+126.8s MACHINE_DONE → actor-done-8 (918 清洗完成)
T+127.1s dispatch j918-s6-unload_to_buffer → machine 8
T+129.5s dispatch j916-s9-mark_full → 打标
```
---
### 阶段 9: 后处理 — 扫码/打标/下料 (18:01:36 ~ 18:02:34)
```
T+129.5s 916 mark_full
T+133.1s MACHINE_DONE → actor-insp-6 (919 检测完成, 合格)
T+133.1s 916 unload_to_dock (Step 12 — 最后一步)
T+136.5s 916 finished via advanceStep → COMPLETED ✓
T+138.9s dispatch j919-s3-unload_to_buffer → 检测线
T+141.3s j917 scan_full
T+144.9s dispatch j919-s5-load_to_machine → 机器 7 (去毛刺)
T+152.7s j917 mark_full
T+156.7s MACHINE_DONE → actor-done-8 (...)
T+159.3s j917 unload_to_dock
T+161.7s 917 finished via advanceStep → COMPLETED ✓
T+161.8s j919-s5-unload_to_buffer → 去毛刺
T+164.1s j918 scan_full
T+168.7s j918 mark_full
T+173.3s j918 unload_to_dock
T+175.7s 918 finished via advanceStep → COMPLETED ✓
T+175.8s j919-s6-load_to_machine → 机器 8 (除锈清洗线)
T+181.4s j919-s6-unload_to_buffer
T+184.1s j919 scan_full
T+188.7s j919 mark_full
T+193.3s j919 unload_to_dock
T+196.7s 919 finished via advanceStep → COMPLETED ✓
===== 全部完成 =====
```
---
## 设备槽位状态变迁总结
### CNC-1 (machine 3, 1 slot)
```
EMPTY → [load 916] → OCCUPIED(916) → [done signal] → DONE(916) → [exchange 918, prev=DONE] → OCCUPIED(918) → [done signal] → DONE(918) → [unload 918] → EMPTY
```
**DB 写入序列**:
1. `EMPTY→OCCUPIED job=916` (LOAD_COMPLETE, Actor)
2. `OCCUPIED→DONE job=916` (handleSignal, Actor)
3. `DONE→OCCUPIED job=918 prevStatus=DONE` (Exchange LOAD_COMPLETE, Actor)
4. `OCCUPIED→DONE job=918` (handleSignal, Actor)
5. `DONE→EMPTY currentJob=NULL` (UNLOAD_COMPLETE, Actor)
### CNC-2 (machine 4, 1 slot)
```
EMPTY → [load 917] → OCCUPIED(917) → [done signal] → DONE(917) → [exchange 919, prev=DONE] → OCCUPIED(919) → [done signal] → DONE(919) → [unload 919] → EMPTY
```
### 高压清洗机 (machine 5, 2 slots, batch)
```
Slot 1: EMPTY → [load 916] → OCCUPIED(916) → [batch done] → DONE(916) → [exchange 918, prev=DONE] → OCCUPIED(918) → [batch done] → DONE(918) → [unload 918] → EMPTY
Slot 2: EMPTY → [load 917] → OCCUPIED(917) → [batch done] → DONE(917) → [exchange 919, prev=DONE] → OCCUPIED(919) → [batch done] → DONE(919) → [unload 919] → EMPTY
```
**Batch 信号处理**: Actor.handleSignal 检测到 `batch=true``MarkAllOccupiedDone()` 一次性将所有 OCCUPIED 槽位 → DONE。两次信号(每槽一次 MACHINE_DONE 事件)但 batch 模式确保两槽同步完成。
### 内窥镜检测线 (machine 6, 1 slot, inspection)
```
EMPTY → [load 916] → OCCUPIED(916) → [inspection done, pass] → CompleteStep → [unload 916] → EMPTY
EMPTY → [load 917] → OCCUPIED(917) → [inspection done, pass] → CompleteStep → [unload 917] → EMPTY
EMPTY → [load 918] → OCCUPIED(918) → [inspection done, pass] → CompleteStep → [unload 918] → EMPTY
EMPTY → [load 919] → OCCUPIED(919) → [inspection done, pass] → CompleteStep → [unload 919] → EMPTY
```
**检测设备特殊逻辑**: handleSignal 不直接写 DONE 状态,而是由 EventLoop.handleInspectionDone 判定合格/不合格 → CompleteStep → AdvanceStep。
### 去毛刺机 (machine 7, 1 slot)
```
EMPTY → [load 916] → OCCUPIED(916) → [done signal] → DONE(916) → [unload 916] → EMPTY
EMPTY → [load 917] → OCCUPIED(917) → [done signal] → DONE(917) → [unload 917] → EMPTY
EMPTY → [load 918] → OCCUPIED(918) → [done signal] → DONE(918) → [unload 918] → EMPTY
EMPTY → [load 919] → OCCUPIED(919) → [done signal] → DONE(919) → [unload 919] → EMPTY
```
### 除锈清洗线 (machine 8, 1 slot)
```
EMPTY → [load 916] → OCCUPIED(916) → [done signal] → DONE(916) → [unload 916] → EMPTY
EMPTY → [load 917] → OCCUPIED(917) → [done signal] → DONE(917) → [unload 917] → EMPTY
EMPTY → [load 918] → OCCUPIED(918) → [done signal] → DONE(918) → [unload 918] → EMPTY
EMPTY → [load 919] → OCCUPIED(919) → [done signal] → DONE(919) → [unload 919] → EMPTY
```
---
## Actor 槽位 DB 写入路径验证
| 操作 | 写入者 | 方法 | 条件更新 |
|------|--------|------|---------|
| 初次上料 | Actor.handleMessage | LOAD_COMPLETE | `prevStatus: EMPTY→OCCUPIED` |
| Exchange 上料 | Actor.handleMessage | LOAD_COMPLETE | `prevStatus: DONE→OCCUPIED` |
| 完成信号 | Actor.handleSignal | SignalDone | `Occupied→DONE` |
| 下料清空 | Actor.handleMessage | UNLOAD_COMPLETE | `Done→EMPTY` |
**关键验证点**:
- ✅ 所有 equipment_slot 写入均由 Actor 完成 (无外部直接写)
- ✅ Exchange 场景下 prevStatus="DONE" 正确传递 (无 Empty→Occupied 的预期冲突)
- ✅ Batch 设备 (清洗机) 两槽同时 Done 后独立 Exchange
- ✅ UNLOAD_COMPLETE 在 guard 内写 DB (仅当 slotJobs 仍匹配时)
- ✅ 最终所有 equipment_slot 恢复 Empty
---
## 工件完成时序
| 工件 | 完成时间 | 耗时 |
|------|---------|------|
| 916 | 18:01:42 | 2m 16s |
| 917 | 18:02:07 | 2m 41s |
| 918 | 18:02:21 | 2m 55s |
| 919 | 18:02:33 | 3m 07s |
总耗时: 3 分 7 秒 (4 个工件全部完成)