From ad64840cc04dac2278ca02f22ddc02b1a218e9cf Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期三, 15 四月 2026 22:44:18 +0800
Subject: [PATCH] feat(机器人任务): 实现换盘任务假电芯补充逻辑
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs | 144 +++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 136 insertions(+), 8 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
index 1b0f476..fb5ef53 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -1,3 +1,4 @@
+using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WIDESEA_Core;
using WIDESEAWCS_Common;
@@ -68,6 +69,19 @@
private readonly HttpClientHelper _httpClientHelper;
/// <summary>
+ /// 鍋囩數鑺钩闈㈢偣浣嶆湇鍔�
+ /// </summary>
+ /// <remarks>
+ /// 鐢ㄤ簬绠$悊鍋囩數鑺钩闈㈢偣浣嶇殑鍒嗛厤鍜岀姸鎬併��
+ /// </remarks>
+ private readonly IFakeBatteryPositionService _fakeBatteryPositionService;
+
+ /// <summary>
+ /// 鏃ュ織璁板綍鍣�
+ /// </summary>
+ private readonly ILogger _logger;
+
+ /// <summary>
/// 鏋勯�犲嚱鏁�
/// </summary>
/// <param name="socketClientGateway">Socket 缃戝叧</param>
@@ -75,18 +89,23 @@
/// <param name="robotTaskService">鏈哄櫒浜轰换鍔℃湇鍔�</param>
/// <param name="taskService">閫氱敤浠诲姟鏈嶅姟</param>
/// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
+ /// <param name="logger">鏃ュ織璁板綍鍣�</param>
public RobotTaskProcessor(
ISocketClientGateway socketClientGateway,
RobotStateManager stateManager,
IRobotTaskService robotTaskService,
ITaskService taskService,
- HttpClientHelper httpClientHelper)
+ HttpClientHelper httpClientHelper,
+ ILogger logger,
+ IFakeBatteryPositionService fakeBatteryPositionService)
{
_socketClientGateway = socketClientGateway;
_stateManager = stateManager;
_robotTaskService = robotTaskService;
_taskService = taskService;
_httpClientHelper = httpClientHelper;
+ _logger = logger;
+ _fakeBatteryPositionService = fakeBatteryPositionService;
}
/// <summary>
@@ -101,6 +120,20 @@
public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
{
return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
+ }
+
+ /// <summary>
+ /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勬墽琛屼腑浠诲姟
+ /// </summary>
+ /// <remarks>
+ /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑鎵ц涓満鍣ㄤ汉浠诲姟銆�
+ /// 褰揜obotArmObject涓�1锛堟湁鐗╂枡锛変笖娌℃湁寰呭鐞嗕换鍔℃椂璋冪敤銆�
+ /// </remarks>
+ /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
+ /// <returns>鎵ц涓殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
+ public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
+ {
+ return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
}
/// <summary>
@@ -141,8 +174,9 @@
if (result)
{
- // 鍙戦�佹垚鍔燂紝璁板綍鏃ュ織
- QuartzLogger.Error($"涓嬪彂鍙栬揣鎸囦护锛屾寚浠�: {taskString}", state.RobotCrane.DeviceName);
+ // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
+ _logger.LogInformation("涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
+ QuartzLogger.Info($"涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
// 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
@@ -157,6 +191,80 @@
await _robotTaskService.UpdateRobotTaskAsync(task);
}
}
+ else
+ {
+ // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
+ _logger.LogError("涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
+ QuartzLogger.Error($"涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
+ }
+ }
+
+ /// <summary>
+ /// 涓嬪彂鍋囩數鑺彇璐ф寚浠ゅ埌鏈哄櫒浜哄鎴风
+ /// </summary>
+ /// <remarks>
+ /// 鍙戦�佹牸寮忥細Pickbattery,5,{startPosition}-{endPosition}
+ /// 渚嬪锛歅ickbattery,5,1-3 琛ㄧず浠庡亣鐢佃姱浣嶇疆5鎶撳彇锛屽钩闈㈢偣浣�1鍒�3
+ ///
+ /// 涓嬪彂鎴愬姛鍚庯細
+ /// 1. 鏍囪鐐逛綅涓哄凡浣跨敤
+ /// 2. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+ /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
+ /// </remarks>
+ /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+ /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+ /// <param name="positions">瑕佹姄鍙栫殑骞抽潰鐐逛綅鍒楄〃</param>
+ public async Task SendSocketRobotFakeBatteryPickAsync(Dt_RobotTask task, RobotSocketState state, List<int> positions)
+ {
+ if (positions == null || positions.Count == 0)
+ {
+ _logger.LogWarning("SendSocketRobotFakeBatteryPickAsync锛氬钩闈㈢偣浣嶅垪琛ㄤ负绌猴紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
+ return;
+ }
+
+ // 璁$畻鐐逛綅鑼冨洿锛屾牸寮忥細1-3
+ int startPos = positions.Min();
+ int endPos = positions.Max();
+ string taskString = $"Pickbattery,5,{startPos}-{endPos}";
+
+ // 鏍囪鐐逛綅涓哄凡浣跨敤
+ _fakeBatteryPositionService.MarkAsUsed(positions);
+
+ // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+ bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+ if (result)
+ {
+ _logger.LogInformation("涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {TaskString}锛岀偣浣�: {Positions}锛岃澶�: {DeviceName}",
+ taskString, string.Join(",", positions), state.RobotCrane?.DeviceName);
+ QuartzLogger.Info($"涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}", 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>
+ /// <param name="count">闇�瑕佽幏鍙栫殑鐐逛綅鏁伴噺</param>
+ /// <returns>鍙敤鐐逛綅鍒楄〃</returns>
+ public List<int> GetNextAvailableFakeBatteryPositions(int count)
+ {
+ return _fakeBatteryPositionService.GetNextAvailable(count);
}
/// <summary>
@@ -182,6 +290,8 @@
var currentTask = state.CurrentTask;
if (currentTask == null)
{
+ _logger.LogDebug("HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�");
+ QuartzLogger.Debug($"HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�", state.RobotCrane?.DeviceName ?? "Unknown");
return false;
}
@@ -190,7 +300,7 @@
// 鏍规嵁宸烽亾鍚嶇О鍒ゆ柇浠撳簱 ID
// ZYRB1 -> 1, HPRB001 -> 2, 鍏朵粬 -> 3
- int warehouseId = currentTask.RobotRoadway == "ZYRB1" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
+ int warehouseId = currentTask.RobotRoadway == "娉ㄦ恫缁勭洏鏈烘鎵�" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
// 浠诲姟绫诲瀷锛�0 琛ㄧず鏈畾涔夛紝绋嶅悗鏍规嵁浠诲姟绫诲瀷璁剧疆锛�
int taskType = 0;
@@ -213,6 +323,8 @@
{
case RobotTaskTypeEnum.GroupPallet:
// 缁勭洏浠诲姟涓嶄娇鐢ㄦ簮鍦板潃锛岀洿鎺ヨ繑鍥� false
+ _logger.LogDebug("HandleInboundTaskAsync锛氱粍鐩樹换鍔′笉浣跨敤婧愬湴鍧�");
+ QuartzLogger.Debug($"HandleInboundTaskAsync锛氱粍鐩樹换鍔′笉浣跨敤婧愬湴鍧�", state.RobotCrane?.DeviceName ?? "Unknown");
return false;
case RobotTaskTypeEnum.ChangePallet:
@@ -237,6 +349,8 @@
case RobotTaskTypeEnum.SplitPallet:
// 鎷嗙洏浠诲姟涓嶄娇鐢ㄧ洰鏍囧湴鍧�
+ _logger.LogDebug("HandleInboundTaskAsync锛氭媶鐩樹换鍔′笉浣跨敤鐩爣鍦板潃");
+ QuartzLogger.Debug($"HandleInboundTaskAsync锛氭媶鐩樹换鍔′笉浣跨敤鐩爣鍦板潃", state.RobotCrane?.DeviceName ?? "Unknown");
return true;
}
}
@@ -253,12 +367,18 @@
TaskType = taskType // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
};
+ // 璁板綍鏃ュ織锛氬紑濮嬭皟鐢� WMS 鍒涘缓鍏ュ簱浠诲姟
+ _logger.LogInformation("HandleInboundTaskAsync锛氳皟鐢╓MS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {TaskType}", PalletCode, taskType);
+ QuartzLogger.Info($"璋冪敤WMS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
+
// 璋冪敤 WMS 鎺ュ彛鍒涘缓鍏ュ簱浠诲姟
var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
// 濡傛灉璋冪敤澶辫触鎴栬繑鍥為敊璇姸鎬�
if (!result.Data.Status && result.IsSuccess)
{
+ _logger.LogError("HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵�侊紝Status: {Status}", result.Data.Status);
+ QuartzLogger.Error($"HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵��", state.RobotCrane?.DeviceName ?? "Unknown");
return false;
}
@@ -269,11 +389,14 @@
var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
if (!content.Status)
{
+ _logger.LogError("HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触");
+ QuartzLogger.Error($"HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触", state.RobotCrane?.DeviceName ?? "Unknown");
return false;
}
// 瑙f瀽杩斿洖鐨勪换鍔′俊鎭�
- var taskInfo = JsonConvert.DeserializeObject<Dt_Task>(content.Data.ToJson() ?? string.Empty) ?? new Dt_Task();
+ var taskInfos = JsonConvert.DeserializeObject<List<Dt_Task>>(content.Data.ToJson() ?? string.Empty) ?? new List<Dt_Task>();
+ var taskInfo = taskInfos.FirstOrDefault();
// 鑾峰彇婧愬湴鍧�
string sourceAddress = taskDTO.SourceAddress;
@@ -292,12 +415,14 @@
// 璁剧疆杈撻�佺嚎鐨勪换鍔″彿
conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, taskInfo.TaskNum, sourceAddress);
- // 瑙﹀彂杈撻�佺嚎寮�濮嬫墽琛岋紙鍐欏叆 WCS_STB = 1锛�
- conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_STB, 1, sourceAddress);
+ // 瑙﹀彂杈撻�佺嚎寮�濮嬫墽琛岋紙鍐欏叆 WCS_ACK = 1锛�
+ conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, sourceAddress);
// 鏇存柊浠诲姟鐘舵�佸埌涓嬩竴闃舵
if (_taskService.UpdateTaskStatusToNext(taskInfo).Status)
{
+ _logger.LogInformation("HandleInboundTaskAsync锛氬叆搴撲换鍔″鐞嗘垚鍔燂紝浠诲姟鍙�: {TaskNum}", taskInfo.TaskNum);
+ QuartzLogger.Info($"HandleInboundTaskAsync锛氬叆搴撲换鍔″鐞嗘垚鍔燂紝浠诲姟鍙�: {taskInfo.TaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
return true;
}
}
@@ -331,6 +456,9 @@
// 鐩爣杈撻�佺嚎缂栧彿
TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
+ // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
+ Roadway = state.CurrentTask.RobotRoadway,
+
// 鐢垫睜浣嶇疆璇︽儏鍒楄〃
// 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
// 鎸変綅缃紪鍙锋帓搴�
@@ -341,7 +469,7 @@
.Select((x, idx) => new StockDetailDTO
{
// 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
- Quantity = state.RobotTaskTotalNum > 0 ? state.RobotTaskTotalNum + positions.Length : positions.Length,
+ Quantity = 1,
// 閫氶亾/浣嶇疆缂栧彿
Channel = x,
--
Gitblit v1.9.3