diff --git a/SlnMesnac.Business/base/BaseAGVBusiness.cs b/SlnMesnac.Business/base/BaseAGVBusiness.cs index 764c0fc..ff890ff 100644 --- a/SlnMesnac.Business/base/BaseAGVBusiness.cs +++ b/SlnMesnac.Business/base/BaseAGVBusiness.cs @@ -233,9 +233,9 @@ namespace SlnMesnac.Business.@base } /// - /// 结束当前任务 清除报警 下发任务 + /// 结束当前任务 清除报警 下发任务 1s /// - /// + /// /// /// 新任务GUID public string EndTaskAndClearErrorAndDownloadTask(string agvguid, string jobName) @@ -251,6 +251,7 @@ namespace SlnMesnac.Business.@base } catch (Exception ex) { + _logger.LogError($"结束当前任务清除报警任务下发失败!Message:{ex}"); return string.Empty; } } @@ -327,7 +328,12 @@ namespace SlnMesnac.Business.@base try { List lists = _AGVStateService.GetAgvState(agvType).Where(x => x.agvworkstate == "待机").ToList(); - AGVState agv = lists.Where(x => x.stackcount == lists.Min(x => x.stackcount)).FirstOrDefault(); + if (lists.Count == 0) + { + return null; + } + int min = lists.Min(x => x.stackcount); + AGVState agv = lists.Where(x => x.stackcount == min).FirstOrDefault(); //var list = _AGVStateService return agv; } @@ -338,25 +344,5 @@ namespace SlnMesnac.Business.@base } } - /// - /// AGV任务状态代码匹配 - /// - /// - /// - public static string AGVTaskStatusSelect(int no) - { - switch (no) - { - case 0: return "已终止"; - case 1: return "待执行"; - case 2: return "正在执行"; - case 3: return "已完成"; - case 4: return "已取消"; - case 5: return "已暂停"; - case 6: return "匹配中"; - case 7: return "核验中"; - default: return "未知代码"; - } - } } } diff --git a/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs b/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs index cfea540..7c5c4b1 100644 --- a/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs +++ b/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs @@ -92,12 +92,31 @@ namespace SlnMesnac.Business.@base var response = _airPorthttpClient.AGVAllStateRequest(); if(response == null) { + _logger.LogError($"AgvStateResponse返回空值!"); + return false; + } + if(response.code == 0 || response.Data == null) + { + _logger.LogError($"返回错误信息:{response.message}"); return false; } - List records = new List(); foreach (var entity in response.Data) { + var taskStateRespose = _airPorthttpClient.AGVGetTaskStateDetailRequest(new AGVRequestTaskStateDetailEntity() + { + taskId = entity.TaskID + }); + if (taskStateRespose == null) + { + _logger.LogError($"taskStateRespose返回空值!"); + return false; + } + if (taskStateRespose.code == 0 || taskStateRespose.Data == null) + { + _logger.LogError($"返回错误信息:{taskStateRespose.message}"); + return false; + } AGVState record = new AGVState() { agvno = entity.Guid, @@ -106,6 +125,7 @@ namespace SlnMesnac.Business.@base agvworkstate = AGVStatusSelect(entity.AgvMoveStatus), refreshtime = DateTime.Now, taskno = entity.TaskID, + taskstate = AGVTaskStatusSelect(taskStateRespose.Data.state) }; records.Add(record); } @@ -142,8 +162,31 @@ namespace SlnMesnac.Business.@base default: return "未知代码"; } } + + /// + /// AGV任务状态代码匹配 + /// + /// + /// + public static string AGVTaskStatusSelect(int no) + { + switch (no) + { + case 0: return "已终止"; + case 1: return "待执行"; + case 2: return "正在执行"; + case 3: return "已完成"; + case 4: return "已取消"; + case 5: return "已暂停"; + case 6: return "匹配中"; + case 7: return "核验中"; + default: return "未知代码"; + } + } } + + public enum TimerControl { Start = 1, diff --git a/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs b/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs index 959982c..567f79b 100644 --- a/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs +++ b/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs @@ -37,6 +37,7 @@ namespace SlnMesnac.Business.@base private IAGVJobService _AGVJobService; private AirPorthttpClient _airpttpClient; private BaseAGVBusiness _baseAGVBusiness; + private VisionBusiness _visionBusiness; System.Timers.Timer RefreshTimer; public BaseTaskInfoBusiness( ILogger logger, @@ -46,7 +47,8 @@ namespace SlnMesnac.Business.@base IAGVJobService agvJobService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient, - BaseAGVBusiness baseAGVBusiness) + BaseAGVBusiness baseAGVBusiness, + VisionBusiness visionBusiness) { _logger = logger; _tcpServer = tcpServer; @@ -55,11 +57,16 @@ namespace SlnMesnac.Business.@base _airpttpClient = airPorthttpClient; InitClearTimer(); //doWhileGetAGVTaskInfo(); - RefreshTimer = new System.Timers.Timer(1000); - RefreshTimer.Elapsed += (sender, e) => RefreshTaskState(); _baseAGVBusiness = baseAGVBusiness; _AGVMapPointService = aGVMapPointService; _AGVJobService = agvJobService; + + + + RefreshTimer = new System.Timers.Timer(1000); + RefreshTimer.Elapsed += (sender, e) => RefreshTaskState(); + + _visionBusiness = visionBusiness; } public static BaseTaskInfoBusiness GetInstance( @@ -70,11 +77,14 @@ namespace SlnMesnac.Business.@base IAGVJobService aAGVJobService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient, - BaseAGVBusiness baseAGVBusiness) + BaseAGVBusiness baseAGVBusiness, + VisionBusiness visionBusiness) { if (instance == null) { - instance = new BaseTaskInfoBusiness(logger, Taskservice, agvService, aGVMapPointService, aAGVJobService, tcpServer, airPorthttpClient, baseAGVBusiness); + instance = new BaseTaskInfoBusiness(logger, + Taskservice, agvService, aGVMapPointService, aAGVJobService, + tcpServer, airPorthttpClient, baseAGVBusiness, visionBusiness); } return instance; } @@ -99,8 +109,6 @@ namespace SlnMesnac.Business.@base taskstate = "等待", //需要判断,更新 任务状态 starttime = DateTime.Now, finishtime = null, - deliveragvTaskNo = string.Empty, //需要判断,更新 - amragvTaskNo = string.Empty, //需要判断,更新 }; try @@ -146,7 +154,7 @@ namespace SlnMesnac.Business.@base } /// - /// Timer刷新任务状态, 有新任务初次下发AGV + /// Timer刷新任务状态, 有新任务初次下发AGV,Timer执行 /// public void RefreshTaskState() { @@ -158,9 +166,10 @@ namespace SlnMesnac.Business.@base { //更新前端 _RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count); - foreach(AirportTask taskItem in Task) + foreach (AirportTask taskItem in Task) { - //查询待执行任务 + + //查询待执行任务,如果是新任务就下发车辆 if (taskItem.taskstate == "等待" || string.IsNullOrEmpty(taskItem.amragvno)) { //首先调一辆最优AMR @@ -168,10 +177,10 @@ namespace SlnMesnac.Business.@base string amrTaskId = _baseAGVBusiness.EndTaskAndClearErrorAndDownloadTask( firstAMR.agvno, _AGVJobService.GetAGVJobListByTypeAndConveyorNo("1000入位", taskItem.conveyorno).JobName); - taskItem.amragvTaskNo = amrTaskId; + _logger.LogInformation($"为AMR[ {firstAMR.agvno}]分配任务,目标:[ {taskItem.conveyorno} ]号传送带"); taskItem.amragvno = firstAMR.agvno; taskItem.amragvisarrive = "未到达"; - taskItem.taskstate = "执行中"; + taskItem.taskstate = "派车中"; //需要AGV和AMR才能装下 if (taskItem.totalcount > (AMRStackNumber - firstAMR.stackcount)) { @@ -180,12 +189,60 @@ namespace SlnMesnac.Business.@base string deliverTaskID = _baseAGVBusiness.EndTaskAndClearErrorAndDownloadTask( firstDeliver.agvno, _AGVJobService.GetAGVJobListByTypeAndConveyorNo("800入位", taskItem.conveyorno).JobName); - taskItem.deliveragvTaskNo = amrTaskId; + _logger.LogInformation($"为Deliver[ {firstDeliver.agvno} ]分配任务,目标:[ {taskItem.conveyorno} ]号传送带"); taskItem.deliveragvno = firstDeliver.agvno; taskItem.deliveragvisarrive = "未到达"; } _Taskservice.UpdateTaskAsync(taskItem); } + + //根据小车状态更新任务表中AMR是否到达状态,如果到达就改变任务表的状态 + if (!string.IsNullOrEmpty(taskItem.amragvno) && taskItem.amragvisarrive == "未到达") + { + AGVState agvstate = _AGVStateService.GetSingleAGVState(taskItem.amragvno); + if (agvstate.taskstate == "已暂停") + { + taskItem.amragvisarrive = "已到达"; + _logger.LogInformation($"[ {taskItem.conveyorno} ]号传送带AMR[ {agvstate.agvno} ]已到达"); + } + _Taskservice.UpdateTaskAsync(taskItem); + } + + //根据小车状态更新任务表中Deliver是否到达状态,如果到达就改变任务表的状态 + if (!string.IsNullOrEmpty(taskItem.deliveragvno) && taskItem.deliveragvisarrive == "未到达") + { + AGVState agvstate = _AGVStateService.GetSingleAGVState(taskItem.deliveragvno); + if (agvstate.taskstate == "已暂停") + { + taskItem.deliveragvisarrive = "已到达"; + _logger.LogInformation($"[ {taskItem.conveyorno} ]号传送带Deliver[ {agvstate.agvno} ]已到达"); + } + _Taskservice.UpdateTaskAsync(taskItem); + } + + //查询执行中的任务车辆是否到达,如果指派的车都到达就开始抓取 + if (taskItem.taskstate == "派车中") + { + //只有amr的情况 + if (taskItem.amragvisarrive == "已到达" && string.IsNullOrEmpty(taskItem.deliveragvno)) + { + //调用机械臂向AMR小车抓取 + _visionBusiness.RequestVisionStartWork(StackState.AMRNeedPositioning, _tcpServer.VID); + taskItem.taskstate = "抓取中"; + _Taskservice.UpdateTaskAsync(taskItem); + _logger.LogInformation($"[ {taskItem.conveyorno} ]号传送带开始工作"); + } + + //amr和deliver都用的情况 + if (taskItem.amragvisarrive == "已到达" && taskItem.deliveragvisarrive == "已到达") + { + //调用机械臂向Deliver小车抓取 + _visionBusiness.RequestVisionStartWork(StackState.AGVNeedPositioning, _tcpServer.VID); + taskItem.taskstate = "抓取中"; + _Taskservice.UpdateTaskAsync(taskItem); + _logger.LogInformation($"[ {taskItem.conveyorno} ]号传送带开始工作"); + } + } } } } @@ -193,9 +250,17 @@ namespace SlnMesnac.Business.@base { _logger.LogError($"查询任务列表初次下发任务发生错误Message:{ex.Message}"); } - } + + + + + + + + + /// /// 获取任务列表,向待执行任务派发AGV (定期执行) /// diff --git a/SlnMesnac.Business/base/VisionBusiness.cs b/SlnMesnac.Business/base/VisionBusiness.cs index e5a6814..45956f3 100644 --- a/SlnMesnac.Business/base/VisionBusiness.cs +++ b/SlnMesnac.Business/base/VisionBusiness.cs @@ -16,11 +16,15 @@ namespace SlnMesnac.Business.@base private ILogger _logger; private static VisionBusiness instance; private TcpServer _tcpServer; + private IAirportTaskService _airportTaskService; + private BaseAGVBusiness _baseAGVBusiness; - public VisionBusiness(ILogger logger, TcpServer tcpServer) + + public VisionBusiness(ILogger logger, TcpServer tcpServer, IAirportTaskService airportTaskService) { _logger = logger; _tcpServer = tcpServer; + _airportTaskService = airportTaskService; //视觉系统回复状态 _tcpServer.ReceiveVisionSysStateEvent += VisionStateRequest; @@ -34,11 +38,11 @@ namespace SlnMesnac.Business.@base _tcpServer.ReceiveStackRobotResetEvent += GetResetResult; } - public static VisionBusiness GetInstance(ILogger logger, TcpServer tcpServer) + public static VisionBusiness GetInstance(ILogger logger, TcpServer tcpServer, IAirportTaskService airportTaskService) { if (instance == null) { - instance = new VisionBusiness(logger, tcpServer); + instance = new VisionBusiness(logger, tcpServer, airportTaskService); } return instance; } @@ -111,7 +115,7 @@ namespace SlnMesnac.Business.@base bool VNow = true; public bool TotalJudge = false; /// - /// 接受码垛结果 + /// 接受码垛结果,进行下一次码垛判断 /// public void StackResultSend(TcpVisionEntity entity, string id) { @@ -123,6 +127,16 @@ namespace SlnMesnac.Business.@base //上位机回复收到码垛结果 _tcpServer.SendReplayStackResult(id); //这里写是否继续下一次码垛的判断条件 + + + //判断总数是否继续工作 + if (true) + { + + } + //如有Deliver 判断是否到达 到达向deliver发送开始工作 + + //如上一次是deliver-->则判断deliver是否装满-->装满则deliver入库-->判断剩下的数量用不用调新的deliver-->用就调新的deliver然后发向amr抓取-->不用就直接向amr抓取 if ((VDCount < VDTotal && Vjudge == true && TotalJudge == true) || (VACount < VATotal && Vjudge == false && TotalJudge == true)) { //如果码垛没结束继续发下一次的码垛信号 diff --git a/SlnMesnac.Model/domain/AGVState.cs b/SlnMesnac.Model/domain/AGVState.cs index 31cb48e..43a87ba 100644 --- a/SlnMesnac.Model/domain/AGVState.cs +++ b/SlnMesnac.Model/domain/AGVState.cs @@ -6,7 +6,7 @@ using SqlSugar; namespace SlnMesnac.Repository { /// - /// + ///AGV状态实体类 /// [SugarTable("AGVState")] public partial class AGVState @@ -43,6 +43,14 @@ namespace SlnMesnac.Repository [SugarColumn(ColumnName = "TaskNo")] public string taskno { get; set; } + /// + /// Desc:任务状态 + /// Default: + /// Nullable:False + /// + [SugarColumn(ColumnName = "TaskState")] + public string taskstate { get; set; } + /// /// Desc:AGV报警状态 /// Default: diff --git a/SlnMesnac.Model/domain/AirportTask.cs b/SlnMesnac.Model/domain/AirportTask.cs index 98c146f..a48925c 100644 --- a/SlnMesnac.Model/domain/AirportTask.cs +++ b/SlnMesnac.Model/domain/AirportTask.cs @@ -95,15 +95,9 @@ namespace SlnMesnac.Repository public DateTime? finishtime { get; set; } /// - /// 运载小车任务编号 + /// 视觉任务号 /// - [SugarColumn(ColumnName = "DeliverAGVTaskNo")] - public string deliveragvTaskNo { get; set; } - - /// - /// 机械臂小车任务编号 - /// - [SugarColumn(ColumnName = "AMRAGVTaskNo")] - public string amragvTaskNo { get; set; } + [SugarColumn(ColumnName = "VisionTaskNo")] + public string? visiontaskno { get; set; } } } diff --git a/SlnMesnac.Repository/service/Impl/AGVStateServiceImpl.cs b/SlnMesnac.Repository/service/Impl/AGVStateServiceImpl.cs index f3332e3..20c1c20 100644 --- a/SlnMesnac.Repository/service/Impl/AGVStateServiceImpl.cs +++ b/SlnMesnac.Repository/service/Impl/AGVStateServiceImpl.cs @@ -139,7 +139,7 @@ namespace SlnMesnac.Repository.service.Impl try { var lists = GetAllAGVState(); - return lists.Where(x => x.agvno == AGVguid).FirstOrDefault(); + return lists.Where(x => x.agvno == AGVguid).First(); } catch (Exception ex) { diff --git a/SlnMesnac.WPF/ViewModel/IndexPage/IndexContentViewModel.cs b/SlnMesnac.WPF/ViewModel/IndexPage/IndexContentViewModel.cs index cdd7fe4..db86a68 100644 --- a/SlnMesnac.WPF/ViewModel/IndexPage/IndexContentViewModel.cs +++ b/SlnMesnac.WPF/ViewModel/IndexPage/IndexContentViewModel.cs @@ -53,12 +53,15 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage private ILogger _taskBusinessLogger; private ILogger _stateBusinessLogger; private ILogger _AGVBusinessLogger; + private ILogger _visionBusinessLogger; private IAirportTaskService _taskservice; private IAGVStateService _agvstateService; private IAGVMapPointService _agvmapPointService; + private IAGVJobService _agvJobService; private BaseTaskInfoBusiness _taskInfoBusiness; private BaseStateRefreshBusiness _StateRefreshBusiness; private BaseAGVBusiness _baseAGVBusiness; + private VisionBusiness _visionBusiness; private DispatcherTimer _timer; private TcpServer _tcpServer; private AppConfig _appConfig; @@ -70,16 +73,21 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage _taskBusinessLogger = App.ServiceProvider.GetService>(); _stateBusinessLogger = App.ServiceProvider.GetService>(); _AGVBusinessLogger = App.ServiceProvider.GetService>(); + _visionBusinessLogger = App.ServiceProvider.GetService>(); _logger = App.ServiceProvider.GetService>(); _taskservice = App.ServiceProvider.GetService(); _agvmapPointService = App.ServiceProvider.GetService(); _agvstateService = App.ServiceProvider.GetService(); + _agvJobService = App.ServiceProvider.GetService(); _tcpServer = App.ServiceProvider.GetService(); _appConfig = App.ServiceProvider.GetService(); _airPorthttpClient = App.ServiceProvider.GetService(); + _visionBusiness = VisionBusiness.GetInstance(_visionBusinessLogger, _tcpServer, _taskservice); _baseAGVBusiness = BaseAGVBusiness.GetInstance(_AGVBusinessLogger, _airPorthttpClient, _agvstateService, _agvmapPointService, _appConfig); - _taskInfoBusiness = BaseTaskInfoBusiness.GetInstance(_taskBusinessLogger, _taskservice, _agvstateService, _agvmapPointService, _tcpServer, _airPorthttpClient, _baseAGVBusiness); + _taskInfoBusiness = BaseTaskInfoBusiness.GetInstance(_taskBusinessLogger, + _taskservice, _agvstateService, _agvmapPointService, _agvJobService, + _tcpServer, _airPorthttpClient, _baseAGVBusiness, _visionBusiness); _taskInfoBusiness._RefreshLogMessageAction += RefreshLogMessage; _taskInfoBusiness._Taskaction += task => { diff --git a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs index ba1cf68..6b21488 100644 --- a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs +++ b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs @@ -31,6 +31,7 @@ namespace SlnMesnac.WPF.ViewModel private IAGVStateService _AGVStateService; private IAGVMapPointService _AGVMapPointService; private IAGVSettingService _AGVSettingService; + private IAGVJobService _agvJobService; private TcpServer _tcpServer; //代码生成 private readonly GenerateControl generateControl = new GenerateControl(); @@ -114,11 +115,14 @@ namespace SlnMesnac.WPF.ViewModel _AGVStateService = App.ServiceProvider.GetService(); _AGVMapPointService = App.ServiceProvider.GetService(); _AGVSettingService = App.ServiceProvider.GetService(); + _agvJobService = App.ServiceProvider.GetService(); _tcpServer = App.ServiceProvider.GetService(); _airPorthttpClient = App.ServiceProvider.GetService(); - _baseTaskInfoBusiness = BaseTaskInfoBusiness.GetInstance(_BaseTaskInfoBusinesslogger, _Taskservice, _AGVStateService, _AGVMapPointService, _tcpServer, _airPorthttpClient, _baseAGVBusiness); + _baseTaskInfoBusiness = BaseTaskInfoBusiness.GetInstance(_BaseTaskInfoBusinesslogger, + _Taskservice, _AGVStateService, _AGVMapPointService, _agvJobService, + _tcpServer, _airPorthttpClient, _baseAGVBusiness, _visionBusiness); _baseAGVBusiness = BaseAGVBusiness.GetInstance(_baseAGVBusinessLogger, _airPorthttpClient, _AGVStateService, _AGVMapPointService, _appConfig); - _visionBusiness = VisionBusiness.GetInstance(_VisionBusinessLogger, _tcpServer); + _visionBusiness = VisionBusiness.GetInstance(_VisionBusinessLogger, _tcpServer, _Taskservice); _baseStateRefreshBusiness = BaseStateRefreshBusiness.GetInstance(_StateRefreshBusinessLogger, _AGVStateService, _airPorthttpClient, _AGVSettingService); ControlOnClickCommand = new RelayCommand(obj => ControlOnClick(obj)); FormControlCommand = new RelayCommand(x => FormControl(x));