| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Quartz; |
| | | using System.Net; |
| | | using Serilog; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Core.Caches; |
| | | using WIDESEAWCS_Common; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoRepository; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_QuartzJob; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_Tasks.SocketServer; |
| | | using WIDESEAWCS_Tasks.Workflow; |
| | | using WIDESEAWCS_Tasks.Workflow.Abstractions; |
| | |
| | | [DisallowConcurrentExecution] |
| | | public class RobotJob : IJob |
| | | { |
| | | /// <summary> |
| | | /// 任务总数上限 |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// 当机器人处理的货物数量达到此上限时,不再下发新任务。 |
| | | /// 防止机器人过度劳累或系统过载。 |
| | | /// </remarks> |
| | | private const int MaxTaskTotalNum = 48; |
| | | |
| | | /// <summary> |
| | | /// 消息事件订阅标志 |
| | | /// </summary> |
| | |
| | | /// <summary> |
| | | /// 日志记录器 |
| | | /// </summary> |
| | | private readonly ILogger<RobotJob> _logger; |
| | | private readonly ILogger _logger; |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | |
| | | /// <param name="tcpSocket">TCP Socket 服务器实例</param> |
| | | /// <param name="robotTaskService">机器人任务服务</param> |
| | | /// <param name="taskService">通用任务服务</param> |
| | | /// <param name="cache">缓存服务</param> |
| | | /// <param name="robotStateRepository">机器人状态仓储</param> |
| | | /// <param name="httpClientHelper">HTTP 客户端帮助类,用于调用 WMS 接口</param> |
| | | /// <param name="logger">日志记录器</param> |
| | | public RobotJob( |
| | | TcpSocketServer tcpSocket, |
| | | IRobotTaskService robotTaskService, |
| | | ITaskService taskService, |
| | | ICacheService cache, |
| | | IRobotStateRepository robotStateRepository, |
| | | HttpClientHelper httpClientHelper, |
| | | ILogger<RobotJob> logger) |
| | | ILogger logger, |
| | | IFakeBatteryPositionService fakeBatteryPositionService) |
| | | { |
| | | // 初始化状态管理器,传入缓存服务 |
| | | _stateManager = new RobotStateManager(cache, _logger); |
| | | // 初始化状态管理器,传入仓储服务 |
| | | _stateManager = new RobotStateManager(robotStateRepository, _logger); |
| | | _logger = logger; |
| | | |
| | | // 创建 Socket 网关,封装 TcpSocketServer 的访问 |
| | |
| | | ISocketClientGateway socketGateway = new SocketClientGateway(tcpSocket); |
| | | |
| | | // 初始化任务处理器 |
| | | _taskProcessor = new RobotTaskProcessor(socketGateway, _stateManager, robotTaskService, taskService, httpClientHelper, _logger); |
| | | _taskProcessor = new RobotTaskProcessor(socketGateway, _stateManager, robotTaskService, taskService, httpClientHelper, _logger, fakeBatteryPositionService); |
| | | |
| | | // 初始化客户端管理器 |
| | | _clientManager = new RobotClientManager(tcpSocket, _stateManager, _logger); |
| | | |
| | | // 初始化命令处理器 |
| | | // 简单命令处理器:处理状态更新等简单命令 |
| | | var simpleCommandHandler = new RobotSimpleCommandHandler(_taskProcessor); |
| | | var simpleCommandHandler = new RobotSimpleCommandHandler(_taskProcessor, socketGateway, _logger); |
| | | // 前缀命令处理器:处理 pickfinished、putfinished 等带参数的命令 |
| | | var prefixCommandHandler = new RobotPrefixCommandHandler(robotTaskService, _taskProcessor, _stateManager, socketGateway); |
| | | var prefixCommandHandler = new RobotPrefixCommandHandler(robotTaskService, _taskProcessor, _stateManager, socketGateway, fakeBatteryPositionService, _logger); |
| | | |
| | | // 初始化消息路由器 |
| | | _messageRouter = new RobotMessageHandler(socketGateway, _stateManager, cache, simpleCommandHandler, prefixCommandHandler, logger); |
| | | _messageRouter = new RobotMessageHandler(socketGateway, _stateManager, simpleCommandHandler, prefixCommandHandler, logger); |
| | | |
| | | // 初始化工作流编排器 |
| | | _workflowOrchestrator = new RobotWorkflowOrchestrator(_stateManager, _clientManager, _taskProcessor, robotTaskService, _logger); |
| | |
| | | { |
| | | // 将消息路由器的处理方法绑定到 TCP 服务器的消息接收事件 |
| | | tcpSocket.MessageReceived += _messageRouter.HandleMessageReceivedAsync; |
| | | _logger.LogError("机器手TCP消息事件已订阅"); |
| | | QuartzLogger.Error($"机器手TCP消息事件已订阅"); |
| | | QuartzLogHelper.LogError(_logger, $"机器手TCP消息事件已订阅", "Unknown"); |
| | | } |
| | | } |
| | | |
| | |
| | | /// <param name="state">断开连接的机械手状态</param> |
| | | private void OnClientDisconnected(object? sender, RobotSocketState state) |
| | | { |
| | | _logger.LogError("客户端已断开连接"); |
| | | QuartzLogger.Error($"客户端已断开连接", state.RobotCrane.DeviceName); |
| | | QuartzLogHelper.LogError(_logger, $"客户端已断开连接", state.RobotCrane.DeviceName); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | return; |
| | | } |
| | | |
| | | if (state.CurrentAction == "Picking" || state.CurrentAction == "Puting") |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // 轮询获取该设备的待处理任务 |
| | | var task = _taskProcessor.GetTask(robotCrane); |
| | | |
| | | // 如果没有获取到待处理任务,且RobotArmObject为1(有物料),则获取该设备执行中的任务 |
| | | if (task == null && state.RobotArmObject == 1) |
| | | { |
| | | task = _taskProcessor.GetExecutingTask(robotCrane); |
| | | } |
| | | |
| | | // 如果有待处理任务 |
| | | if (task != null) |
| | |
| | | } |
| | | |
| | | // 检查任务总数是否未达到上限 |
| | | if (latestState.RobotTaskTotalNum < MaxTaskTotalNum) |
| | | if (latestState.RobotTaskTotalNum < RobotConst.MaxTaskTotalNum) |
| | | { |
| | | // 调用工作流编排器执行任务 |
| | | // 编排器会根据当前状态决定下一步动作 |
| | |
| | | { |
| | | // 异常处理已在组件内部进行,Job 层保持兜底语义 |
| | | // 记录异常而不是静默吞掉,便于排查问题 |
| | | _logger?.LogError(ex, "RobotJob执行异常,IP: {IpAddress}", ipAddress); |
| | | QuartzLogger.Error($"RobotJob执行异常,IP: {ipAddress}", state.RobotCrane.DeviceName, ex); |
| | | QuartzLogHelper.LogError(_logger, ex, $"RobotJob执行异常,IP: {ipAddress}", $"RobotJob执行异常,IP: {ipAddress}", state.RobotCrane.DeviceName); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |