# 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 个工件全部完成)