feat(机械手任务): 实现换盘任务多阶段处理逻辑
重构换盘任务处理流程,将原有单阶段实现拆分为多阶段处理:
1. 新增 Phase 1-5 状态定义,区分正常电芯和假电芯处理阶段
2. 实现流向A/B的差异化处理逻辑
3. 添加假电芯批次取货指令下发功能
4. 完善状态机切换和任务计数管理
新增文档说明换盘任务完整流程和阶段切换逻辑
| | |
| | | { |
| | | "updatedAt": "2026-04-18T07:46:50.058Z", |
| | | "updatedAt": "2026-04-18T08:52:24.581Z", |
| | | "missions": [ |
| | | { |
| | | "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none", |
| | |
| | | "sourceKey": "session-stop:aa71986c72a8dd1f4" |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "session:78e67b30-83ce-4757-a175-68c3442c4534:none", |
| | | "source": "session", |
| | | "name": "none", |
| | | "objective": "Session mission", |
| | | "createdAt": "2026-04-18T08:34:11.529Z", |
| | | "updatedAt": "2026-04-18T08:52:24.581Z", |
| | | "status": "done", |
| | | "workerCount": 1, |
| | | "taskCounts": { |
| | | "total": 1, |
| | | "pending": 0, |
| | | "blocked": 0, |
| | | "inProgress": 0, |
| | | "completed": 1, |
| | | "failed": 0 |
| | | }, |
| | | "agents": [ |
| | | { |
| | | "name": "general-purpose:a6a0c97", |
| | | "role": "general-purpose", |
| | | "ownership": "a6a0c97facebc27a6", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-18T08:52:24.581Z" |
| | | } |
| | | ], |
| | | "timeline": [ |
| | | { |
| | | "id": "session-start:a6a0c97facebc27a6:2026-04-18T08:34:11.529Z", |
| | | "at": "2026-04-18T08:34:11.529Z", |
| | | "kind": "update", |
| | | "agent": "general-purpose:a6a0c97", |
| | | "detail": "started general-purpose:a6a0c97", |
| | | "sourceKey": "session-start:a6a0c97facebc27a6" |
| | | }, |
| | | { |
| | | "id": "session-stop:acc34e8d2cd052b69:2026-04-18T08:42:23.674Z", |
| | | "at": "2026-04-18T08:42:23.674Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:a6a0c97", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:acc34e8d2cd052b69" |
| | | }, |
| | | { |
| | | "id": "session-stop:a6a0c97facebc27a6:2026-04-18T08:52:24.581Z", |
| | | "at": "2026-04-18T08:52:24.581Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:a6a0c97", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:a6a0c97facebc27a6" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | "status": "completed", |
| | | "completed_at": "2026-04-18T07:46:15.279Z", |
| | | "duration_ms": 58126 |
| | | }, |
| | | { |
| | | "agent_id": "a6a0c97facebc27a6", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-18T08:34:11.529Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-18T08:52:24.581Z", |
| | | "duration_ms": 1093052 |
| | | } |
| | | ], |
| | | "total_spawned": 82, |
| | | "total_completed": 82, |
| | | "total_spawned": 83, |
| | | "total_completed": 83, |
| | | "total_failed": 0, |
| | | "last_updated": "2026-04-18T07:46:50.164Z" |
| | | "last_updated": "2026-04-18T14:04:59.113Z" |
| | | } |
| | |
| | | /// <remarks> |
| | | /// é¶æ®µå®ä¹ï¼ |
| | | /// 0: æªå¼å§ |
| | | /// 1: 忣叏çµè¯ï¼æµåBï¼ / ååçµè¯ï¼æµåAï¼ |
| | | /// 2: æ¾æ£å¸¸çµè¯ï¼æµåBï¼ / æ¾åçµè¯ï¼æµåAï¼ |
| | | /// 3: ååçµè¯ï¼æµåB Phase2ï¼ |
| | | /// 4: æ¾åçµè¯å°5å·ä½ï¼æµåB Phase2ï¼ |
| | | /// 1: 忣叏çµè¯ï¼ä¸¤æµåç¸åï¼ |
| | | /// 2: æ¾æ£å¸¸çµè¯å°ç®æ æçï¼ä¸¤æµåç¸åï¼ |
| | | /// 3: æµåAï¼æ£å¸¸åå®â空æçååºâååçµè¯ä»5å·ä½ / æµåBï¼æ£å¸¸åå®âååçµè¯ä»æºå°å |
| | | /// 4: æµåAï¼æ¾åçµè¯å°ç®æ æç / æµåBï¼æ¾åçµè¯å°5å·ä½ |
| | | /// 5: æµåAï¼åæ¾å®âallputfinishedå
¥åºHCSC1 / æµåBï¼ååå®â空æçååºHCSC1+ç»çå
¥åºGWSC1 |
| | | /// </remarks> |
| | | public int ChangePalletPhase { get; set; } |
| | | |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¸ååçµè¯åè´§æä»¤ï¼å¸¦æ¹æ¬¡æ ¼å¼åæ»æ°ï¼ |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// åé顺åºï¼ |
| | | /// 1. PickTotalNum,{N} -- çå®çµè¯æ»æ° |
| | | /// 2. Pickbattery,5,{start}-{end} -- æ¹æ¬¡åè´§æä»¤ï¼åºå®ä»5å·ä½åï¼ |
| | | /// |
| | | /// ä¸åæååæ´æ°ä»»å¡ç¶æä¸º"æºå¨äººæ§è¡ä¸"ã |
| | | /// </remarks> |
| | | /// <param name="task">è¦ä¸åçä»»å¡å¯¹è±¡</param> |
| | | /// <param name="state">æºå¨äººå½åç¶æ</param> |
| | | /// <param name="batchStart">æ¹æ¬¡èµ·å§ç¼å·</param> |
| | | /// <param name="batchEnd">æ¹æ¬¡ç»æç¼å·</param> |
| | | public async Task SendFakeBatteryPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, int batchStart, int batchEnd) |
| | | { |
| | | // å
åéæ»æ°æä»¤ |
| | | string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}"; |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd); |
| | | |
| | | // ååéæ¹æ¬¡åè´§æä»¤ï¼åçµè¯åºå®ä»5å·ä½åï¼ |
| | | string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}"; |
| | | string taskString = $"Pickbattery,5,{range}"; |
| | | |
| | | bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString); |
| | | |
| | | if (result) |
| | | { |
| | | _logger.LogInformation("ä¸ååçµè¯æ¹æ¬¡åè´§æä»¤æåï¼æä»¤: {TaskString}ï¼æ¹æ¬¡: {Range}ï¼è®¾å¤: {DeviceName}", |
| | | taskString, range, state.RobotCrane?.DeviceName); |
| | | QuartzLogger.Info($"ä¸ååçµè¯æ¹æ¬¡åè´§æä»¤æåï¼æä»¤: {taskString}ï¼æ¹æ¬¡: {range}", state.RobotCrane?.DeviceName); |
| | | |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | state.CurrentTask = task; |
| | | |
| | | if (_stateManager.TryUpdateStateSafely(state.IPAddress, state)) |
| | | { |
| | | await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | _logger.LogError("ä¸ååçµè¯æ¹æ¬¡åè´§æä»¤å¤±è´¥ï¼æä»¤: {TaskString}ï¼è®¾å¤: {DeviceName}", taskString, state.RobotCrane?.DeviceName); |
| | | QuartzLogger.Error($"ä¸ååçµè¯æ¹æ¬¡åè´§æä»¤å¤±è´¥ï¼æä»¤: {taskString}", state.RobotCrane?.DeviceName); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// ä¸åæ¾è´§æä»¤ï¼å¸¦æ¹æ¬¡æ ¼å¼åæ»æ°ï¼ |
| | | /// </summary> |
| | | /// <remarks> |
| | |
| | | // æ¢çä»»å¡ï¼æ ¹æ®é¶æ®µåºåå¤ç |
| | | if (state.ChangePalletPhase == 2) |
| | | { |
| | | if (isFlowA) |
| | | { |
| | | // æµåA Phase2ï¼æ¾åçµè¯å°ç®æ æçï¼ä¸è°ç¨ APIï¼ä¸éå¢è®¡æ° |
| | | // ä»
æ´æ°ç¶æ |
| | | } |
| | | else |
| | | { |
| | | // æµåB Phase2ï¼æ¾æ£å¸¸çµè¯ï¼éå¢è®¡æ° |
| | | // Phase 2ï¼æ¾æ£å¸¸çµè¯å°ç®æ æç宿ï¼éå¢è®¡æ° |
| | | state.RobotTaskTotalNum += positions.Length; |
| | | if (task != null) |
| | | task.RobotTaskTotalNum -= positions.Length; |
| | | |
| | | // æå»ºåºå DTO å¹¶è°ç¨ ChangePalletAsync API |
| | | if (isFlowA) |
| | | { |
| | | // æµåAï¼ä¸è°ç¨ APIï¼ä»
éå¢è®¡æ° |
| | | } |
| | | else |
| | | { |
| | | // æµåBï¼è°ç¨æ¢ç API |
| | | var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions); |
| | | var result = _taskProcessor.PostGroupPalletAsync(nameof(ConfigKey.ChangePalletAsync), stockDTO); |
| | | putSuccess = result.Data.Status && result.IsSuccess; |
| | | } |
| | | |
| | | // åå Phase 1ï¼ç»§ç»åæ£å¸¸çµè¯ |
| | | state.ChangePalletPhase = 1; |
| | | } |
| | | else if (state.ChangePalletPhase == 4) |
| | | { |
| | | // æµåB Phase4ï¼æ¾åçµè¯å°5å·ä½ï¼ä¸è°ç¨ APIï¼ä¸éå¢è®¡æ°ï¼éæ¾ç¹ä½ |
| | | if (isFlowA) |
| | | { |
| | | // æµåAï¼æ¾åçµè¯å°ç®æ æçï¼éå¢è®¡æ°ï¼è°ç¨æ¢ç API |
| | | state.RobotTaskTotalNum += positions.Length; |
| | | if (task != null) |
| | | task.RobotTaskTotalNum -= positions.Length; |
| | | |
| | | var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions); |
| | | var result = _taskProcessor.PostGroupPalletAsync(nameof(ConfigKey.ChangePalletAsync), stockDTO); |
| | | putSuccess = result.Data.Status && result.IsSuccess; |
| | | } |
| | | else |
| | | { |
| | | // æµåBï¼æ¾åçµè¯å°5å·ä½ï¼éæ¾ç¹ä½ |
| | | _fakeBatteryPositionService.MarkAsAvailable(positions.ToList()); |
| | | } |
| | | |
| | | // åå Phase 3ï¼ç»§ç»ååçµè¯ |
| | | state.ChangePalletPhase = 3; |
| | | } |
| | | else |
| | | { |
| | | // éæ¹æ¬¡æ¨¡å¼ï¼æ£å¸¸éå¢è®¡æ°å¹¶è°ç¨ API |
| | |
| | | // 夿任å¡ç±»å |
| | | var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType; |
| | | |
| | | // æ¢çä»»å¡ï¼ä»
彿æé¶æ®µå®ææ¶æå¤çå
¥åº |
| | | // æ¢çä»»å¡ï¼æ ¹æ®é¶æ®µåºåå¤ç |
| | | if (robotTaskType == RobotTaskTypeEnum.ChangePallet) |
| | | { |
| | | if (state.ChangePalletPhase == 0) |
| | | { |
| | | // è°ç¨æ¹éæç确认æ¥å£ï¼æ¢çåå®é¶æ®µï¼ |
| | | // è°ç¨æ¹éæç确认æ¥å£ |
| | | var sourcePallet = state.CurrentTask.RobotSourceAddressPalletCode; |
| | | var confirmResult = _taskProcessor.PostSplitPalletConfirmAsync(sourcePallet, state.RobotCrane?.DeviceName); |
| | | if (!confirmResult.IsSuccess) |
| | | { |
| | | QuartzLogger.Error($"æ¹éæç确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | // ææé¶æ®µå®æï¼å¤çå
¥åº |
| | | if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | if (state.ChangePalletPhase == 5) |
| | | { |
| | | // å
¥åºæåï¼å é¤ä»»å¡è®°å½ |
| | | _taskProcessor.DeleteTask(currentTask.RobotTaskId); |
| | | // FlowB æç»é¶æ®µï¼åçµè¯åå®ï¼æºç©ºæçååº HCSC1 |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allpickfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãSwap,diskFinishedã", state.RobotCrane.DeviceName); |
| | | |
| | | // éç½®æ¹æ¬¡ç¶æ |
| | | state.CurrentTask = null; |
| | | state.RobotTaskTotalNum = 0; |
| | | state.CellBarcode = new List<string>(); |
| | | state.ChangePalletPhase = 0; |
| | | state.CurrentBatchIndex = 1; |
| | | state.IsInFakeBatteryMode = false; |
| | | return true; |
| | | } |
| | | else if (state.ChangePalletPhase != 0) |
| | | { |
| | | // FlowA ä¸é´é¶æ®µï¼æ£å¸¸çµè¯åå®ï¼æºç©ºæçååº GWSC1 |
| | | // ä¸å é¤ä»»å¡ï¼ä¸éç½®ç¶æï¼ç»§ç» Phase 3-4 åçµè¯æµç¨ |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | { |
| | | return false; |
| | | } |
| | | // ä¸é´é¶æ®µä¸å¤çï¼ä»
æ´æ°ç¶æ |
| | | return true; |
| | | } |
| | | |
| | | // Phase == 0: éæ¹æ¬¡æ¨¡å¼ï¼ç®æ æ»æ°==48ï¼ |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allpickfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãSwap,diskFinishedã", state.RobotCrane.DeviceName); |
| | | |
| | | state.ChangePalletPhase = 0; |
| | | state.CurrentBatchIndex = 1; |
| | | state.IsInFakeBatteryMode = false; |
| | | return true; |
| | | } |
| | | |
| | |
| | | if (!confirmResult.IsSuccess) |
| | | { |
| | | QuartzLogger.Error($"æ¹éæç确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // å
¥åºæåï¼å é¤ä»»å¡è®°å½ |
| | | _taskProcessor.DeleteTask(currentTask.RobotTaskId); |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allpickfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãSwap,diskFinishedã", state.RobotCrane.DeviceName); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | |
| | | // 夿任å¡ç±»å |
| | | var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType; |
| | | |
| | | // æ¢çä»»å¡ï¼ä»
彿æé¶æ®µå®ææ¶æå¤çå
¥åº |
| | | // æ¢çä»»å¡ï¼æ ¹æ®é¶æ®µåºåå¤ç |
| | | if (robotTaskType == RobotTaskTypeEnum.ChangePallet) |
| | | { |
| | | if (state.ChangePalletPhase == 0) |
| | | { |
| | | // è°ç¨æ¹éç»ç确认æ¥å£ï¼æ¢çæ¾å®é¶æ®µï¼ |
| | | // è°ç¨æ¹éç»ç确认æ¥å£ |
| | | var targetPallet = state.CurrentTask.RobotTargetAddressPalletCode; |
| | | var confirmResult = _taskProcessor.PostGroupPalletConfirmAsync(targetPallet, state.RobotCrane?.DeviceName); |
| | | if (!confirmResult.IsSuccess) |
| | | { |
| | | QuartzLogger.Error($"æ¹éç»ç确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | // ææé¶æ®µå®æï¼å¤çå
¥åº |
| | | if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | if (state.ChangePalletPhase == 5) |
| | | { |
| | | // å
¥åºæåï¼å é¤ä»»å¡è®°å½ |
| | | _taskProcessor.DeleteTask(currentTask.RobotTaskId); |
| | | // FlowA æç»é¶æ®µï¼åçµè¯æ¾å®ï¼ç®æ æç满48å
¥åº HCSC1 |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // æ¸
çç¶æï¼ä¸ºä¸ä¸ä¸ªä»»å¡ååå¤ |
| | | state.CurrentTask = null; // æ¸
é¤å½åä»»å¡ |
| | | state.RobotTaskTotalNum = 0; // é置任å¡è®¡æ° |
| | | state.CellBarcode = new List<string>(); // æ¸
空æ¡ç å表 |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allputfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãGroup,diskFinishedã", state.RobotCrane.DeviceName); |
| | | state.CurrentTask = null; |
| | | state.RobotTaskTotalNum = 0; |
| | | state.CellBarcode = new List<string>(); |
| | | |
| | | // éç½®æ¹æ¬¡ç¶æ |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãSwap,diskFinishedã", state.RobotCrane.DeviceName); |
| | | |
| | | state.ChangePalletPhase = 0; |
| | | state.CurrentBatchIndex = 1; |
| | | state.IsInFakeBatteryMode = false; |
| | | return true; |
| | | } |
| | | else if (state.ChangePalletPhase != 0) |
| | | { |
| | | // FlowB ä¸é´é¶æ®µï¼æ£å¸¸çµè¯æ¾å®ï¼æè´§æçç»çå
¥åº GWSC1 |
| | | // ä¸å é¤ä»»å¡ï¼ä¸éç½®ç¶æï¼ç»§ç» Phase 3-4 åçµè¯æµç¨ |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | { |
| | | return false; |
| | | } |
| | | // ä¸é´é¶æ®µä¸å¤çï¼ä»
æ´æ°ç¶æ |
| | | return true; |
| | | } |
| | | |
| | | // Phase == 0: éæ¹æ¬¡æ¨¡å¼ï¼ç®æ æ»æ°==48ï¼ |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allputfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | state.CurrentTask = null; |
| | | state.RobotTaskTotalNum = 0; |
| | | state.CellBarcode = new List<string>(); |
| | | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Swap,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãSwap,diskFinishedã", state.RobotCrane.DeviceName); |
| | | |
| | | state.ChangePalletPhase = 0; |
| | | state.CurrentBatchIndex = 1; |
| | | state.IsInFakeBatteryMode = false; |
| | | return true; |
| | | } |
| | | |
| | |
| | | if (robotTaskType == RobotTaskTypeEnum.GroupPallet) |
| | | { |
| | | // è°ç¨æ¹éç»ç确认æ¥å£ |
| | | //var targetPallet = state.CurrentTask.RobotTargetAddressPalletCode; |
| | | //_taskProcessor.PostGroupPalletConfirmAsync(targetPallet, state.RobotCrane?.DeviceName); |
| | | var targetPallet = state.CurrentTask.RobotTargetAddressPalletCode; |
| | | var confirmResult = _taskProcessor.PostGroupPalletConfirmAsync(targetPallet, state.RobotCrane?.DeviceName); |
| | | if (!confirmResult.IsSuccess) |
| | | { |
| | | QuartzLogger.Error($"æ¹éç»ç确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | // å¤çå
¥åºä»»å¡åä¼ |
| | | // useSourceAddress: false 表示使ç¨ç®æ å°åï¼ç»çåºæ¯ï¼ |
| | | if (await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: false)) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // å
¥åºæåï¼å é¤ä»»å¡è®°å½ |
| | | _taskProcessor.DeleteTask(currentTask.RobotTaskId); |
| | | if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true) |
| | | { |
| | | QuartzLogger.Error($"allputfinishedï¼å é¤ä»»å¡è®°å½å¤±è´¥ï¼ä»»å¡å·: {currentTask.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown"); |
| | | return false; |
| | | } |
| | | |
| | | // æ¸
çç¶æï¼ä¸ºä¸ä¸ä¸ªä»»å¡ååå¤ |
| | | state.CurrentTask = null; // æ¸
é¤å½åä»»å¡ |
| | |
| | | await _socketClientGateway.SendToClientAsync(state.IPAddress, $"Group,diskFinished"); |
| | | QuartzLogger.Info($"åéæ¶æ¯ï¼ãGroup,diskFinishedã", state.RobotCrane.DeviceName); |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | |
| | | |
| | | var state = _stateManager.GetState(ipAddress); |
| | | |
| | | // æ¢çä»»å¡ä½¿ç¨æ¹æ¬¡æ ¼å¼ |
| | | // æ¢ç任塿¹æ¬¡æ¨¡å¼ |
| | | if (task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode()) |
| | | { |
| | | int targetNormalCount = task.RobotTaskTotalNum; |
| | |
| | | |
| | | bool isFlowA = task.RobotSourceAddressLineCode is "11001" or "11010"; |
| | | |
| | | // æµåA Phase 2ï¼æ¾åçµè¯å°ç®æ æç |
| | | if (isFlowA && state?.ChangePalletPhase == 2) |
| | | // ==================== Phase 2: æ¾æ£å¸¸çµè¯å°ç®æ æçï¼ä¸¤æµåç¸åï¼==================== |
| | | // PickFinished å°è¾¾ï¼Phase 1 ç Pick å½ä»¤å®æï¼ç°å¨ä¸å Put å½ä»¤æ¾æ£å¸¸çµè¯ |
| | | if (state?.ChangePalletPhase == 2) |
| | | { |
| | | int remaining = 48 - currentCompletedCount; |
| | | if (remaining <= 0) return; |
| | | |
| | | int batchStart = targetNormalCount + 1 + (state.CurrentBatchIndex - 1); |
| | | int putCount = Math.Min(4, remaining); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end); |
| | | int remainingNormal = targetNormalCount - currentCompletedCount; |
| | | if (remainingNormal <= 0) |
| | | { |
| | | // æ£å¸¸çµè¯å
¨é¨æ¾å®ï¼çå¾
HandlePutFinishedAsync åæ¢å° Phase 3 |
| | | return; |
| | | } |
| | | |
| | | // æµåB Phase 4ï¼æ¾åçµè¯å°5å·ä½ |
| | | if (!isFlowA && state?.ChangePalletPhase == 4) |
| | | int batchStart = (currentCompletedCount / 4) * 4 + 1; |
| | | int putCount = Math.Min(4, remainingNormal); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end); |
| | | |
| | | // Phase ä¿æä¸º 2ï¼ç HandlePutFinishedAsync å¤ç宿¾è´§è®¡æ°åååå Phase 1 |
| | | _stateManager.TryUpdateStateSafely(ipAddress, state); |
| | | return; |
| | | } |
| | | |
| | | // ==================== Phase 4: æ¾åçµè¯ï¼ä¸¤æµåååï¼==================== |
| | | // PickFinished å°è¾¾ï¼Phase 3 ç Pick å½ä»¤å®æï¼ç°å¨ä¸å Put å½ä»¤æ¾åçµè¯ |
| | | if (state?.ChangePalletPhase == 4) |
| | | { |
| | | int fakeCount = 48 - targetNormalCount; |
| | | int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount); |
| | | int remainingFake = fakeCount - completedFake; |
| | | |
| | | if (remainingFake <= 0) return; |
| | | if (remainingFake <= 0) |
| | | { |
| | | // åçµè¯å
¨é¨æ¾å®ï¼çå¾
allputfinished 触å Phase 5 å
¥åº |
| | | return; |
| | | } |
| | | |
| | | if (isFlowA) |
| | | { |
| | | // æµåAï¼æ¾åçµè¯å°ç®æ æç |
| | | int batchStart = targetNormalCount + 1 + (state.CurrentBatchIndex - 1); |
| | | int putCount = Math.Min(4, remainingFake); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end); |
| | | |
| | | state.CurrentBatchIndex += putCount; |
| | | // Phase ä¿æä¸º 4ï¼ç HandlePutFinishedAsync å¤çå®åååå Phase 3 |
| | | _stateManager.TryUpdateStateSafely(ipAddress, state); |
| | | } |
| | | else |
| | | { |
| | | // æµåBï¼æ¾åçµè¯å°5å·ä½ |
| | | var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(Math.Min(4, remainingFake)); |
| | | if (positions.Count == 0) |
| | | { |
| | |
| | | int end = positions.Max(); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, state, "5", start, end); |
| | | |
| | | // Phase ä¿æä¸º 4ï¼ç HandlePutFinishedAsync å¤çå®åååå Phase 3 |
| | | _stateManager.TryUpdateStateSafely(ipAddress, state); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | // æµåB Phase 2ï¼æ¾æ£å¸¸çµè¯å°ç®æ æç |
| | | if (!isFlowA && state?.ChangePalletPhase == 2) |
| | | { |
| | | int remainingNormal = targetNormalCount - currentCompletedCount; |
| | | if (remainingNormal <= 0) return; |
| | | |
| | | int batchStart = ((currentCompletedCount - 1) / 4) * 4 + 1; |
| | | int putCount = Math.Min(4, remainingNormal); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, state, task.RobotTargetAddress, start, end); |
| | | // éæ¹æ¬¡æ¨¡å¼æå
¶ä»é¶æ®µä¸ä¸åæä»¤ |
| | | return; |
| | | } |
| | | |
| | | // é»è®¤ï¼ä½¿ç¨åææ ¼å¼ |
| | | taskString = $"Putbattery,{task.RobotTargetAddress}"; |
| | | } |
| | | else |
| | | { |
| | | // 鿢çä»»å¡ï¼ä½¿ç¨åææ ¼å¼ |
| | | if (state != null && state.IsGroupPallet && task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode()) |
| | | { |
| | | // ç»çä»»å¡ï¼æ¾è´§é夿æ¯å¦NGï¼å¦æNGåæ¾å°NGå£ |
| | | if (state.IsScanNG) |
| | | { |
| | | taskString = $"Putbattery,4"; |
| | |
| | | } |
| | | else |
| | | taskString = $"Putbattery,{task.RobotTargetAddress}"; |
| | | } |
| | | |
| | | bool result = await _clientManager.SendToClientAsync(ipAddress, taskString); |
| | | |
| | |
| | | else if (task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode()) |
| | | { |
| | | const int targetTotal = 48; |
| | | // æ¢çä»»å¡è¿å
¥æ¹æ¬¡æ¨¡å¼ï¼åé¶æ®µå¤çæ£å¸¸çµè¯ååçµè¯ ï¼æºå¨äººä»»å¡æ»æ°ï¼ |
| | | int targetNormalCount = task.RobotTaskTotalNum; |
| | | // å½å已宿æ°éï¼åè´§å®æçæ°éï¼ï¼åå§ä¸ºç¶æä¸ç RobotTaskTotalNumï¼åç»æ ¹æ®åè´§å®æçæ°éå¨ææ´æ° |
| | | int currentCompletedCount = stateForUpdate.RobotTaskTotalNum; |
| | | |
| | | // 夿æµåï¼null-safeï¼ |
| | |
| | | stateForUpdate.CurrentBatchIndex = 1; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æ¢çä»»å¡è¿å
¥æ¹æ¬¡æ¨¡å¼ï¼ä»»å¡å·: {TaskNum}ï¼æµå: {Flow}", |
| | | task.RobotTaskNum, isFlowA ? "A" : "B"); |
| | | _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate); |
| | | } |
| | | |
| | | // ==================== æµåAï¼è¡¥åçµè¯å°ç®æ æç ==================== |
| | | if (isFlowA) |
| | | { |
| | | // Phase 1: ååçµè¯ï¼ä»5å·ä½ï¼ä½¿ç¨ PositionIndexï¼ |
| | | if (stateForUpdate.ChangePalletPhase == 1) |
| | | { |
| | | int remaining = targetTotal - currentCompletedCount; |
| | | if (remaining <= 0) |
| | | { |
| | | stateForUpdate.ChangePalletPhase = 0; |
| | | stateForUpdate.CurrentBatchIndex = 1; |
| | | stateForUpdate.IsInFakeBatteryMode = false; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æµåA宿ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | return; |
| | | } |
| | | |
| | | int pickCount = Math.Min(4, remaining); |
| | | var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(pickCount); |
| | | if (positions.Count == 0) |
| | | { |
| | | _logger.LogError("HandlePutFinishedStateAsyncï¼æ å¯ç¨åçµè¯ç¹ä½ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | return; |
| | | } |
| | | |
| | | await _taskProcessor.SendSocketRobotFakeBatteryPickAsync(task, stateForUpdate, positions); |
| | | stateForUpdate.ChangePalletPhase = 2; |
| | | } |
| | | // Phase 2: æ¾åçµè¯å°ç®æ æçï¼ä» targetNormalCount+1 å¼å§éå¢ï¼ |
| | | else if (stateForUpdate.ChangePalletPhase == 2) |
| | | { |
| | | int remaining = targetTotal - currentCompletedCount; |
| | | if (remaining <= 0) |
| | | { |
| | | stateForUpdate.ChangePalletPhase = 0; |
| | | stateForUpdate.CurrentBatchIndex = 1; |
| | | stateForUpdate.IsInFakeBatteryMode = false; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æµåA宿ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | return; |
| | | } |
| | | |
| | | // è®¡ç®æ¾è´§æ¹æ¬¡ç¼å·ï¼ä» targetNormalCount + 1 å¼å§ |
| | | int batchStart = targetNormalCount + 1 + (stateForUpdate.CurrentBatchIndex - 1); |
| | | int putCount = Math.Min(4, remaining); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, task.RobotTargetAddress, start, end); |
| | | |
| | | stateForUpdate.CurrentBatchIndex += putCount; |
| | | stateForUpdate.ChangePalletPhase = 1; |
| | | } |
| | | } |
| | | // ==================== æµåBï¼åæ£å¸¸çµè¯ + åæ¶åçµè¯ ==================== |
| | | else |
| | | { |
| | | // Phase 1: 忣叏çµè¯ï¼ä»æºå°åï¼ä»1å¼å§éå¢ï¼ |
| | | // ==================== Phase 1: 忣叏çµè¯ï¼ä¸¤æµåç¸åï¼==================== |
| | | if (stateForUpdate.ChangePalletPhase == 1) |
| | | { |
| | | int remainingNormal = targetNormalCount - currentCompletedCount; |
| | | if (remainingNormal <= 0) |
| | | { |
| | | // æ£å¸¸çµè¯åå®ï¼åæ¢å° Phase 3 |
| | | // æ£å¸¸çµè¯åå®ï¼åæ¢å° Phase 3 ååçµè¯ |
| | | stateForUpdate.ChangePalletPhase = 3; |
| | | stateForUpdate.CurrentBatchIndex = targetNormalCount + 1; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æ£å¸¸çµè¯å
¨é¨åå®ï¼è¿å
¥Phase 3åæ¶åçµè¯ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | stateForUpdate.CurrentBatchIndex = 1; // åçµè¯æ¹æ¬¡ä»å¤´å¼å§ |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æ£å¸¸çµè¯åå®ï¼åæ¢å°Phase 3ååçµè¯ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate); |
| | | return; |
| | | } |
| | | |
| | |
| | | await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end); |
| | | |
| | | stateForUpdate.CurrentBatchIndex += pickCount; |
| | | // åå® Pick ååæ¢å° Phase=2ï¼ç PickFinished 触å HandlePickFinishedStateAsync ä¸åæ¾è´§æä»¤ |
| | | stateForUpdate.ChangePalletPhase = 2; |
| | | } |
| | | // Phase 2: æ¾æ£å¸¸çµè¯å°ç®æ æçï¼æ¾è´§ç¼å·ä¸åè´§ç¼å·ä¸è´ï¼ |
| | | else if (stateForUpdate.ChangePalletPhase == 2) |
| | | { |
| | | int remainingNormal = targetNormalCount - currentCompletedCount; |
| | | if (remainingNormal <= 0) |
| | | { |
| | | // æ£å¸¸çµè¯æ¾å®ï¼åæ¢å° Phase 3 |
| | | stateForUpdate.ChangePalletPhase = 3; |
| | | stateForUpdate.CurrentBatchIndex = targetNormalCount + 1; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æ£å¸¸çµè¯å
¨é¨æ¾å®ï¼è¿å
¥Phase 3åæ¶åçµè¯ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate); |
| | | return; |
| | | } |
| | | |
| | | // è®¡ç®æ¬æ¹æ¾è´§ç¼å·ï¼åºäº currentCompletedCount æ¨å¯¼æ¹æ¬¡èµ·å§ |
| | | int batchStart = ((currentCompletedCount - 1) / 4) * 4 + 1; |
| | | int putCount = Math.Min(4, remainingNormal); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(batchStart, putCount); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, task.RobotTargetAddress, start, end); |
| | | |
| | | stateForUpdate.ChangePalletPhase = 1; |
| | | } |
| | | // Phase 3: ååçµè¯ï¼ä»æºå°åï¼ä» targetNormalCount+1 å¼å§éå¢ï¼ |
| | | else if (stateForUpdate.ChangePalletPhase == 3) |
| | | // ==================== Phase 3: å¤çåçµè¯ï¼æµåA/B ååï¼ï¼èªå·±å¾ªç¯ ==================== |
| | | if (stateForUpdate.ChangePalletPhase == 3) |
| | | { |
| | | int fakeCount = targetTotal - targetNormalCount; |
| | | int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount); |
| | |
| | | |
| | | if (remainingFake <= 0) |
| | | { |
| | | stateForUpdate.ChangePalletPhase = 0; |
| | | stateForUpdate.CurrentBatchIndex = 1; |
| | | stateForUpdate.IsInFakeBatteryMode = false; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æµåB宿ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | // åçµè¯å
¨é¨å¤çå®ï¼åæ¢å° Phase 5 çå¾
å
¥åº |
| | | stateForUpdate.ChangePalletPhase = 5; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼åçµè¯å¤ç宿¯ï¼åæ¢å°Phase 5çå¾
å
¥åºï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate); |
| | | return; |
| | | } |
| | | |
| | | int pickCount = Math.Min(4, remainingFake); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount); |
| | | |
| | | await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end); |
| | | |
| | | stateForUpdate.CurrentBatchIndex += pickCount; |
| | | stateForUpdate.ChangePalletPhase = 4; |
| | | } |
| | | // Phase 4: æ¾åçµè¯å°5å·ä½ï¼ä½¿ç¨ PositionIndexï¼ |
| | | else if (stateForUpdate.ChangePalletPhase == 4) |
| | | if (isFlowA) |
| | | { |
| | | int fakeCount = targetTotal - targetNormalCount; |
| | | int completedFake = Math.Max(0, currentCompletedCount - targetNormalCount); |
| | | int remainingFake = fakeCount - completedFake; |
| | | |
| | | if (remainingFake <= 0) |
| | | { |
| | | stateForUpdate.ChangePalletPhase = 0; |
| | | stateForUpdate.CurrentBatchIndex = 1; |
| | | stateForUpdate.IsInFakeBatteryMode = false; |
| | | _logger.LogInformation("HandlePutFinishedStateAsyncï¼æµåB宿ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | return; |
| | | } |
| | | |
| | | // æµåAï¼ä»5å·ä½ååçµè¯ |
| | | var positions = _taskProcessor.GetNextAvailableFakeBatteryPositions(Math.Min(4, remainingFake)); |
| | | if (positions.Count == 0) |
| | | { |
| | | _logger.LogError("HandlePutFinishedStateAsyncï¼æ å¯ç¨åçµè¯ç¹ä½ï¼ä»»å¡å·: {TaskNum}", task.RobotTaskNum); |
| | | return; |
| | | } |
| | | |
| | | int start = positions.Min(); |
| | | int end = positions.Max(); |
| | | |
| | | await _taskProcessor.SendPutWithBatchAsync(task, stateForUpdate, "5", start, end); |
| | | |
| | | stateForUpdate.ChangePalletPhase = 3; |
| | | await _taskProcessor.SendSocketRobotFakeBatteryPickAsync(task, stateForUpdate, positions); |
| | | } |
| | | else |
| | | { |
| | | // æµåBï¼ä»æºå°åååçµè¯ |
| | | int pickCount = Math.Min(4, remainingFake); |
| | | var (start, end) = _taskProcessor.BuildBatchRange(stateForUpdate.CurrentBatchIndex, pickCount); |
| | | await _taskProcessor.SendPickWithBatchAsync(task, stateForUpdate, task.RobotSourceAddress, start, end); |
| | | stateForUpdate.CurrentBatchIndex += pickCount; |
| | | } |
| | | |
| | | // åå® Pick ååæ¢å° Phase=4ï¼ç PickFinished 触å HandlePickFinishedStateAsync ä¸åæ¾è´§æä»¤ |
| | | stateForUpdate.ChangePalletPhase = 4; |
| | | _stateManager.TryUpdateStateSafely(ipAddress, stateForUpdate); |
| | | return; |
| | | } |
| | | |
| | | // ==================== Phase 5: 宿å
¥åºï¼allputfinished / allpickfinished 触åï¼==================== |
| | | if (stateForUpdate.ChangePalletPhase == 5) |
| | | { |
| | | // Phase 5 ç± allpickfinished/allputfinished 触åå
¥åºï¼æ¬æ¹æ³ä¸åä¸åæä»¤ |
| | | return; |
| | | } |
| | | } |
| | | else |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ¢çä»»å¡å®æ´æµç¨åæ |
| | | |
| | | ## ä»»å¡åæ° |
| | | |
| | | | åæ° | å¼ | |
| | | |------|-----| |
| | | | æµå | **Flow A** (isFlowA = true, æºå°å LineCode = "11001") | |
| | | | æºå°å | 11001 | |
| | | | ç®æ å°å | 2101 | |
| | | | æ£å¸¸çµè¯æ°é | **33** | |
| | | | åçµè¯æ°é | 48 - 33 = **15** | |
| | | | ç®æ æ»æ° | 48 | |
| | | |
| | | --- |
| | | |
| | | ## é¶æ®µç¶æå®ä¹ |
| | | |
| | | | Phase | å«ä¹ | |
| | | |-------|------| |
| | | | 0 | æªå¼å§ | |
| | | | 1 | 忣叏çµè¯ | |
| | | | 2 | æ¾æ£å¸¸çµè¯ | |
| | | | 3 | ååçµè¯ï¼Flow A: ä»5å·ä½åï¼ | |
| | | | 4 | æ¾åçµè¯ï¼Flow A: æ¾å°ç®æ æçï¼ | |
| | | | 5 | çå¾
å
¥åºå®æ | |
| | | |
| | | --- |
| | | |
| | | ## 宿´ä»£ç æ§è¡æµç¨ï¼33 æ£å¸¸ + 15 å = 48 æ»è®¡ï¼ |
| | | |
| | | ### åå§ç¶æ |
| | | |
| | | ``` |
| | | ChangePalletPhase = 0 |
| | | currentCompletedCount = 0 |
| | | targetNormalCount = 33 |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ### 第1è½®ï¼Pick 1-4 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 1 | HandlePutFinishedStateAsync | 1 | 0 | 33 - 0 = **33** | PickBatch(1, 4) â Phase=2 | |
| | | | 2 | (æºæ¢°ææ§è¡åè´§) | - | - | - | - | |
| | | | 3 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished, taskç¶æ=RobotPickFinish | |
| | | | 4 | HandlePickFinishedStateAsync | 2 | 0 | 33 - 0 = **33** | PutBatch(1, 4) â Phase=1 | |
| | | | 5 | (æºæ¢°ææ§è¡æ¾è´§) | - | - | - | - | |
| | | | 6 | HandlePutFinishedAsync | - | **4** | - | currentCompletedCount+=4, task.RobotTaskTotalNum-=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第2è½®ï¼Pick 5-8 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 7 | HandlePutFinishedStateAsync | 1 | 4 | 33 - 4 = **29** | PickBatch(5, 8) â Phase=2 | |
| | | | 8 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 9 | HandlePickFinishedStateAsync | 2 | 4 | 33 - 4 = **29** | PutBatch(1, 4) â Phase=1 | |
| | | | 10 | HandlePutFinishedAsync | - | **8** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第3è½®ï¼Pick 9-12 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 11 | HandlePutFinishedStateAsync | 1 | 8 | 33 - 8 = **25** | PickBatch(9, 12) â Phase=2 | |
| | | | 12 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 13 | HandlePickFinishedStateAsync | 2 | 8 | 33 - 8 = **25** | PutBatch(1, 4) â Phase=1 | |
| | | | 14 | HandlePutFinishedAsync | - | **12** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第4è½®ï¼Pick 13-16 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 15 | HandlePutFinishedStateAsync | 1 | 12 | 33 - 12 = **21** | PickBatch(13, 16) â Phase=2 | |
| | | | 16 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 17 | HandlePickFinishedStateAsync | 2 | 12 | 33 - 12 = **21** | PutBatch(1, 4) â Phase=1 | |
| | | | 18 | HandlePutFinishedAsync | - | **16** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第5è½®ï¼Pick 17-20 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 19 | HandlePutFinishedStateAsync | 1 | 16 | 33 - 16 = **17** | PickBatch(17, 20) â Phase=2 | |
| | | | 20 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 21 | HandlePickFinishedStateAsync | 2 | 16 | 33 - 16 = **17** | PutBatch(1, 4) â Phase=1 | |
| | | | 22 | HandlePutFinishedAsync | - | **20** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第6è½®ï¼Pick 21-24 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 23 | HandlePutFinishedStateAsync | 1 | 20 | 33 - 20 = **13** | PickBatch(21, 24) â Phase=2 | |
| | | | 24 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 25 | HandlePickFinishedStateAsync | 2 | 20 | 33 - 20 = **13** | PutBatch(1, 4) â Phase=1 | |
| | | | 26 | HandlePutFinishedAsync | - | **24** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第7è½®ï¼Pick 25-28 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 27 | HandlePutFinishedStateAsync | 1 | 24 | 33 - 24 = **9** | PickBatch(25, 28) â Phase=2 | |
| | | | 28 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 29 | HandlePickFinishedStateAsync | 2 | 24 | 33 - 24 = **9** | PutBatch(1, 4) â Phase=1 | |
| | | | 30 | HandlePutFinishedAsync | - | **28** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第8è½®ï¼Pick 29-32 æ£å¸¸çµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 31 | HandlePutFinishedStateAsync | 1 | 28 | 33 - 28 = **5** | PickBatch(29, 32) â Phase=2 | |
| | | | 32 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 33 | HandlePickFinishedStateAsync | 2 | 28 | 33 - 28 = **5** | PutBatch(1, 4) â Phase=1 | |
| | | | 34 | HandlePutFinishedAsync | - | **32** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第9è½®ï¼Pick 33 æ£å¸¸çµè¯ï¼æå1ä¸ªï¼ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 35 | HandlePutFinishedStateAsync | 1 | 32 | 33 - 32 = **1** | PickBatch(33, 33) â Phase=2 | |
| | | | 36 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 37 | HandlePickFinishedStateAsync | 2 | 32 | 33 - 32 = **1** | PutBatch(33, 33) â Phase=1 | |
| | | | 38 | HandlePutFinishedAsync | - | **33** | - | currentCompletedCount+=1 | |
| | | |
| | | --- |
| | | |
| | | ### 第10è½®ï¼æ£å¸¸çµè¯å
¨é¨å®æ â 忢 Phase 3 |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingNormal | æä½ | |
| | | |------|------|-------|---------------------|----------------|------| |
| | | | 39 | HandlePutFinishedStateAsync | 1 | **33** | 33 - 33 = **0** â â¤0 | **忢 Phase=3**, Pick fake from 5å·ä½ | |
| | | |
| | | > **Flow A ç¹æ§**ï¼æ£å¸¸çµè¯åå®åï¼æºæçï¼11001ï¼å·²ç©ºãæ¤æ¶æºæ¢°ææºå¸¦æå䏿¹æ£å¸¸çµè¯æ¾å°ç®æ æçåï¼æºæçèªå¨ç©ºåºååºã代ç ä¸ä¸éè¦æ¾å¼å¤çè¿ä¸ªååºå¨ä½ââç±è¾é线èªå¨å®æã |
| | | |
| | | --- |
| | | |
| | | ### 第11è½®ï¼Pick 1-4 åçµè¯ï¼ä»5å·ä½ï¼ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingFake | æä½ | |
| | | |------|------|-------|---------------------|--------------|------| |
| | | | 40 | HandlePutFinishedStateAsync | 3 | 33 | 15 - 0 = **15** | Pick fake from 5å·ä½(1,4) â Phase=4 | |
| | | | 41 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 42 | HandlePickFinishedStateAsync | 4 | 33 | 15 - 0 = **15** | Put fake to target(BatchStart=34, 4个) â Phase=3 | |
| | | | 43 | HandlePutFinishedAsync | - | **37** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第12è½®ï¼Pick 5-8 åçµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingFake | æä½ | |
| | | |------|------|-------|---------------------|--------------|------| |
| | | | 44 | HandlePutFinishedStateAsync | 3 | 37 | 15 - 4 = **11** | Pick fake from 5å·ä½(5,8) â Phase=4 | |
| | | | 45 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 46 | HandlePickFinishedStateAsync | 4 | 37 | 15 - 4 = **11** | Put fake to target(BatchStart=38, 4个) â Phase=3 | |
| | | | 47 | HandlePutFinishedAsync | - | **41** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第13è½®ï¼Pick 9-12 åçµè¯ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingFake | æä½ | |
| | | |------|------|-------|---------------------|--------------|------| |
| | | | 48 | HandlePutFinishedStateAsync | 3 | 41 | 15 - 8 = **7** | Pick fake from 5å·ä½(9,12) â Phase=4 | |
| | | | 49 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 50 | HandlePickFinishedStateAsync | 4 | 41 | 15 - 8 = **7** | Put fake to target(BatchStart=42, 4个) â Phase=3 | |
| | | | 51 | HandlePutFinishedAsync | - | **45** | - | currentCompletedCount+=4 | |
| | | |
| | | --- |
| | | |
| | | ### 第14è½®ï¼Pick 13-15 åçµè¯ï¼æå3ä¸ªï¼ |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingFake | æä½ | |
| | | |------|------|-------|---------------------|--------------|------| |
| | | | 52 | HandlePutFinishedStateAsync | 3 | 45 | 15 - 12 = **3** | Pick fake from 5å·ä½(13,15) â Phase=4 | |
| | | | 53 | HandlePickFinishedAsync | - | - | - | CurrentAction=PickFinished | |
| | | | 54 | HandlePickFinishedStateAsync | 4 | 45 | 15 - 12 = **3** | Put fake to target(BatchStart=46, 3个) â Phase=3 | |
| | | | 55 | HandlePutFinishedAsync | - | **48** | - | currentCompletedCount+=3 | |
| | | |
| | | --- |
| | | |
| | | ### 第15è½®ï¼åçµè¯å
¨é¨å®æ â 忢 Phase 5 |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | currentCompletedCount | remainingFake | æä½ | |
| | | |------|------|-------|---------------------|--------------|------| |
| | | | 56 | HandlePutFinishedStateAsync | 3 | **48** | 15 - 15 = **0** â â¤0 | **忢 Phase=5**, çå¾
å
¥åº | |
| | | |
| | | --- |
| | | |
| | | ### 第16è½®ï¼å
¨é¨æ¾è´§å®æ â å
¥åº |
| | | |
| | | | æ¥éª¤ | æ¹æ³ | Phase | æä½ | |
| | | |------|------|-------|------| |
| | | | 57 | HandlePutFinishedAsync | - | PutFinished â allputfinished | |
| | | | 58 | ExecuteAsync | - | æ£æµ allputfinished â RobotSimpleCommandHandler å¤ç | |
| | | | 59 | RobotSimpleCommandHandler | **5** | Phase=5 â è°ç¨ HandleInboundTaskAsync(useSourceAddress=false) å
¥åºå° **HCSC1** | |
| | | | 60 | - | - | å é¤ä»»å¡è®°å½ï¼éç½®ç¶æï¼åé "Group,diskFinished" | |
| | | |
| | | --- |
| | | |
| | | ## æ°æ®æµæ±æ» |
| | | |
| | | ### currentCompletedCount åå |
| | | |
| | | ``` |
| | | 0 â 4 â 8 â 12 â 16 â 20 â 24 â 28 â 32 â 33 â 37 â 41 â 45 â 48 |
| | | | | | | | | | | | | | | | | |
| | | æ£å¸¸çµè¯æ¹æ¬¡ æ£å¸¸å®æ åçµè¯æ¹æ¬¡ æ»å®æ |
| | | (æ¯æ¹4个) +0 (æ¯æ¹4个) +3 |
| | | ``` |
| | | |
| | | ### Phase åæ¢å¾ |
| | | |
| | | ``` |
| | | Phase=0 ââ(åå§å)ââ⺠Phase=1 ââ⺠Phase=2 ââ⺠Phase=1 ââ⺠... ââ⺠Phase=1 |
| | | (Pick 1-4) (Put 1-4) (Pick 5-8) (Pick 33) |
| | | â |
| | | Phase=2 ââ⺠... ââ⺠Phase=2 |
| | | (Put 5-8) (Put 33) |
| | | â |
| | | ââââââââââââââââââââââââââââââââââââââââ |
| | | â Phase=1 (remainingNormal=0) â |
| | | â â â |
| | | â Phase=3 (ååçµè¯) â |
| | | â Pick fake â Phase=4 â Put fake â |
| | | â ⺠â |
| | | â ç´å° remainingFake=0 â |
| | | â â â |
| | | â Phase=5 (å
¥åº) â |
| | | ââââââââââââââââââââââââââââââââââââââââ |
| | | ``` |
| | | |
| | | ### å
³é®æ°æ®å¯¹ç
§è¡¨ |
| | | |
| | | | 轮次 | Phase | æä½ | currentCompletedCount | remainingNormal | remainingFake | åéæä»¤ | |
| | | |------|-------|------|---------------------|----------------|--------------|---------| |
| | | | 1 | 1â2 | Pick 1-4 | 0 | 33 | - | PickBatch(1,4) | |
| | | | 1 | 2â1 | Put 1-4 | 4 | 33 | - | PutBatch(1,4) | |
| | | | 2 | 1â2 | Pick 5-8 | 4 | 29 | - | PickBatch(5,8) | |
| | | | 2 | 2â1 | Put 5-8 | 8 | 29 | - | PutBatch(1,4) | |
| | | | 3 | 1â2 | Pick 9-12 | 8 | 25 | - | PickBatch(9,12) | |
| | | | 3 | 2â1 | Put 9-12 | 12 | 25 | - | PutBatch(1,4) | |
| | | | 4 | 1â2 | Pick 13-16 | 12 | 21 | - | PickBatch(13,16) | |
| | | | 4 | 2â1 | Put 13-16 | 16 | 21 | - | PutBatch(1,4) | |
| | | | 5 | 1â2 | Pick 17-20 | 16 | 17 | - | PickBatch(17,20) | |
| | | | 5 | 2â1 | Put 17-20 | 20 | 17 | - | PutBatch(1,4) | |
| | | | 6 | 1â2 | Pick 21-24 | 20 | 13 | - | PickBatch(21,24) | |
| | | | 6 | 2â1 | Put 21-24 | 24 | 13 | - | PutBatch(1,4) | |
| | | | 7 | 1â2 | Pick 25-28 | 24 | 9 | - | PickBatch(25,28) | |
| | | | 7 | 2â1 | Put 25-28 | 28 | 9 | - | PutBatch(1,4) | |
| | | | 8 | 1â2 | Pick 29-32 | 28 | 5 | - | PickBatch(29,32) | |
| | | | 8 | 2â1 | Put 29-32 | 32 | 5 | - | PutBatch(1,4) | |
| | | | 9 | 1â2 | Pick 33 | 32 | 1 | - | PickBatch(33,33) | |
| | | | 9 | 2â1 | Put 33 | 33 | 0 | - | PutBatch(33,33) | |
| | | | 10 | 1â**3** | **忢** | 33 | **0** | 15 | Pick fake(5å·ä½ 1-4) | |
| | | | 11 | 3â4 | Pick fake 1-4 | 33 | 0 | 15 | PickBattery,5,1-4 | |
| | | | 11 | 4â3 | Put fake 34-37 | 37 | 0 | 11 | PutBatch(34,37) | |
| | | | 12 | 3â4 | Pick fake 5-8 | 37 | 0 | 11 | PickBattery,5,5-8 | |
| | | | 12 | 4â3 | Put fake 38-41 | 41 | 0 | 7 | PutBatch(38,41) | |
| | | | 13 | 3â4 | Pick fake 9-12 | 41 | 0 | 7 | PickBattery,5,9-12 | |
| | | | 13 | 4â3 | Put fake 42-45 | 45 | 0 | 3 | PutBatch(42,45) | |
| | | | 14 | 3â4 | Pick fake 13-15 | 45 | 0 | 3 | PickBattery,5,13-15 | |
| | | | 14 | 4â3 | Put fake 46-48 | 48 | 0 | 0 | PutBatch(46,48) | |
| | | | 15 | 3â**5** | **忢** | 48 | 0 | **0** | çå¾
å
¥åº | |
| | | | 16 | 5 | **å
¥åº** | - | - | - | allputfinished â HandleInboundTaskAsync â HCSC1 | |
| | | |
| | | --- |
| | | |
| | | ## 代ç è责对ç
§ |
| | | |
| | | | æ¹æ³ | 使¶è°ç¨ | èè´£ | |
| | | |------|---------|------| |
| | | | HandlePutFinishedStateAsync | `ExecuteAsync` æ£æµ PutFinished | åé **Pick** æä»¤ï¼æ´æ° Phase | |
| | | | HandlePickFinishedStateAsync | `ExecuteAsync` æ£æµ PickFinished | åé **Put** æä»¤ | |
| | | | HandlePickFinishedAsync | prefix command `pickfinished` | æ´æ°ç¶æ CurrentAction | |
| | | | HandlePutFinishedAsync | prefix command `putfinished` | æ´æ° currentCompletedCount è®¡æ° | |
| | | | RobotSimpleCommandHandler | å½ä»¤ `allpickfinished` / `allputfinished` | 触åå
¥åºï¼æ¸
çç¶æ | |