using Admin.NET.Core.TaskModule.Enum; using iWareCC.ConveyorService; using iWareCommon.Utils; using iWareModel; using iWareModel.Entity.AGV; using iWareModel.EnumType.AoSinPublicCommon; using iWareModel.EnumType.EDevice.AGV; using iWareSql; using iWareSql.DbOrm; using iWareSql.Orm; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; //using WZ.Useful.Commons; using XiGang.Core.Model; using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header; namespace iWareCC { public class AGVThreadService : DeviceThreadServiceHandle { private string _namespace = "iWareCC.AGVThreadService"; public string host = ConfigHelper.GetConfigString("AgvHost"); public string createTask = ConfigHelper.GetConfigString("createTask"); public string wmshost = ConfigHelper.GetConfigString("WMSHost"); public string agvcallback = ConfigHelper.GetConfigString("agvcallback"); public string continueTask = ConfigHelper.GetConfigString("continueTask"); private AGVThreadService() { } public AGVThreadService(LogType logType) { base.currentLogType = logType; } public override void StartService() { Task.Run(() => { try { //自动执行立库Agv任务线程 Log4NetHelper.WriteInfoLog(base.currentLogType, "[自动执行立库AGV任务线程] 启动了"); ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(DoAgvTask)), (int)EDevice.AGV); //自动结束立库输送线任务线程 //ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(FinishTask)), (int)EDevice.AGV); //自动结束立库输送线任务线程 ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(HandleTask)), (int)EDevice.AGV); } catch (Exception ex) { Log4NetHelper.WriteErrorLog(base.currentLogType, "ConveyorThreadService线程启动出现异常", ex); } }); } /// /// 自动执行立库输送线任务 /// /// private void DoAgvTask(object deviceId) { string errMsg = ""; while (true) { if (SystemValue.isStartedModel) { DoAgvTaskByThead(deviceId, out errMsg); } SystemWarningMsg._lbl_Alert_ConveyerRelease = errMsg; Thread.Sleep(cycleDelay); } } /// /// 自动执行立库AGV任务(线程) /// /// private void DoAgvTaskByThead(object deviceId, out string errMsg) { errMsg = ""; try { int int_deviceId = (int)deviceId; using (DbOrm dbOrm = new DbOrm()) { var currentTask = dbOrm.ware_task_sub.Where(u => u.DeviceId == int_deviceId && u.TaskState == (int)SubTaskStateEnum.未开始).OrderBy(u => u.CreatedTime).FirstOrDefault(); if (currentTask == null) { return; } if (!FormCC.IsSimulationPLC) { //验证起始点和目标点是否正确 RealPlaceEntity realPlaceEntity = null; if (!ValdiatePalceIsRight(dbOrm, currentTask.SourcePlace, currentTask.ToPlace, ref realPlaceEntity)) return; List itemlist = new List(){ new PositionCodePathItem(){positionCode = currentTask.SourcePlace,type = EnumberHelper.GetEnumDescription(AgvPositionType.位置编号)}, new PositionCodePathItem(){positionCode = currentTask.ToPlace,type = EnumberHelper.GetEnumDescription(AgvPositionType.位置编号)}, }; AgvSchedulingTaskDto taskDto = new AgvSchedulingTaskDto() { reqCode = DateTime.Now.ToString("yyyyMMddhhmmssfff"), taskTyp = currentTask.TaskType == (int)TaskCategoryEnum.OutStock ? AgvTaskTypeEnum.CK01.ToString() : AgvTaskTypeEnum.RK01.ToString(), positionCodePath = itemlist, }; var response = HttpHelper.GetHttpResponse(host + createTask, taskDto, 10000); if (response.code == "0") { //4、下发成功后,更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.已下发; currentTask.UpdatedTime = DateTime.Now;//下发时间 currentTask.AgvTaskCode = response.data; SystemWarningMsg._lbl_Alert_Agv = "AGV任务下发成功"; } else { Log4NetHelper.WriteErrorLog(currentLogType, response.message); } } else { currentTask.TaskState = (int)SubTaskStateEnum.已下发; currentTask.UpdatedTime = DateTime.Now;//下发时间 currentTask.AgvTaskCode = currentTask.Id.ToString(); } dbOrm.SaveChanges(); } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(currentLogType, "发送失败"); SystemWarningMsg._lbl_Alert_Agv = "AGV任务下发失败" + ex.Message; } } /// /// 验证立库输送线是否允许任务开始 /// public bool ValidateDeviceTaskIsAllowStart(ware_task_sub subtask, DbOrm dbOrm) { var queryTaskState1 = (int)SubTaskStateEnum.已下发; //要判断和他同一个任务的且任务优先级高的堆垛机任务是不是已经已完成,如果是就允许开始任务,如果不是,就不允许开始 var srmTask = dbOrm.ware_task_sub.Where(x => x.TaskId == subtask.TaskId && x.TaskSequence < subtask.TaskSequence && x.TaskState != queryTaskState1).FirstOrDefault(); if (srmTask != null) { return false; } return true; } #region 模拟用 ///// ///// 模拟结束立库AGV任务线程 ///// ///// //private void FinishTask(object deviceId) //{ // string errMsg = ""; // while (true) // { // if (SystemValue.isStartedModel) // { // FinishAgvTaskByThead(deviceId, out errMsg); // } // SystemWarningMsg._lbl_Alert_ConveyerReleaseFinish = errMsg; // Thread.Sleep(cycleDelay); // } //} ///// ///// 自动结束立库AGV任务线程(线程) ///// ///// //public void FinishAgvTaskByThead(object deviceId, out string errMsg) //{ // errMsg = ""; // try // { // int int_deviceId = (int)deviceId; // using (DbOrm dbOrm = new DbOrm()) // { // #region //3、判断数据库中是否有可要完成的任务,如果有判断是否跟立库输送线中的完成任务相符,如果相符就处理 // var currTasks = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && (x.TaskState == (int)SubTaskStateEnum.已下发 || x.TaskState == (int)SubTaskStateEnum.执行中)).ToList().OrderBy(x => x.CreatedTime).ToList();//按照主任务优先级的升序排序 // if (currTasks == null || currTasks.Count == 0) // { // //表示DB中没有任务要发送给立库输送线 // return; // } // #endregion // foreach (var currentTask in currTasks) // { // try // { // AgvCallbackRequestDto requestDto = new AgvCallbackRequestDto() // { // reqCode = "", // reqTime = "", // cooX = "", // cooY = "", // method = currentTask.TaskState == (int)SubTaskStateEnum.已下发 ? "start" : "end", // robotCode = "6001", // taskCode = currentTask.AgvTaskCode, // }; // var response = HttpHelper.GetHttpResponse(wmshost + agvcallback, requestDto, 10000); // } // catch (Exception ex) // { // throw; // } // } // } // } // catch (Exception ex) // { // //ExceptionHandels.GetExceptionInfoForError("自动结束立库输送线任务线程(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception); // //ExceptionHandels.InsertExceptionInfo(exception, true); // Log4NetHelper.WriteErrorLog(currentLogType, "给输送线完成任务指令出现异常,deviceId:" + deviceId + ",异常:" + ex.Message); // } //} #endregion /// /// 处理AGV任务 /// private void HandleTask(object deviceId) { string errMsg = ""; while (true) { if (SystemValue.isStartedModel) { HandleAgvTaskByThead(deviceId, out errMsg); } SystemWarningMsg._lbl_Alert_ConveyerReleaseFinish = errMsg; Thread.Sleep(cycleDelay); } } public SdaResEntity sdaResult = new SdaResEntity(); public ConveyerServiceClient vs = null; public List currTasks = null; public AgvCommonResponseDto response = null; /// /// AGV任务处理线程(线程) /// /// public void HandleAgvTaskByThead(object deviceId, out string errMsg) { errMsg = ""; try { int int_deviceId = (int)deviceId; //读取 vs = new ConveyerServiceClient(); if (vs.ReadAddress("6900|502.3")) { sdaResult = vs.WriteAGVRequestOutArr(3, false); } using (DbOrm dbOrm = new DbOrm()) { #region //3、判断数据库中是否有可要完成的任务,如果有判断是否跟立库输送线中的完成任务相符,如果相符就处理 currTasks = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId /*&& (x.TaskState == (int)SubTaskStateEnum.请求进 || x.TaskState == (int)SubTaskStateEnum.进到位 || x.TaskState == (int)SubTaskStateEnum.出到位 || x.TaskState == (int)SubTaskStateEnum.请求出)*/).ToList().OrderBy(x => x.CreatedTime).ToList();//按照主任务优先级的升序排序 if (currTasks == null || currTasks.Count == 0) { //表示DB中没有任务要发送给立库输送线 return; } #endregion foreach (var currentTask in currTasks) { try { switch (currentTask.TaskState) { case (int)SubTaskStateEnum.请求进: //currentTask.TaskState = (int)SubTaskStateEnum.等待允许进; //这里增加一个判断,当前升降机有任务就不发 var isExist1 = dbOrm.ware_task_sub.AsNoTracking().Any(u => u.TaskId != currentTask.TaskId && u.DeviceId == 3 && u.TaskState != (int)SubTaskStateEnum.未开始); if (isExist1) { SystemWarningMsg._lbl_Alert_Agv = "升降机有执行中的任务,等待下发"; continue; } //向plc写入请求进 sdaResult = vs.WriteAGVRequestIn(3, true); if (sdaResult.result) { sdaResult = vs.WriteAGVTaskType(3, Convert.ToInt16(currentTask.TaskType)); if (sdaResult.result) { try { //入库时同时下发升降机任务 var tranTask = dbOrm.ware_task_sub.Where(u => u.DeviceId == 3 && u.TaskId == currentTask.TaskId && u.TaskType == (int)TaskCategoryEnum.InStock && u.TaskState == (int)SubTaskStateEnum.未开始).FirstOrDefault(); //var maintask = dbOrm.ware_task.AsNoTracking().Where(u => u.Id == currentTask.TaskId).FirstOrDefault(); if (tranTask != null) { if (FormCC.IsSimulationPLC) { sdaResult.result = true; } else { sdaResult = vs.SendConveyerTask((int)tranTask.DeviceId, Convert.ToInt32(tranTask.TaskNo), tranTask.SourcePlace, tranTask.ToPlace, "1", Convert.ToString(tranTask.TaskType)); //sdaResult = JsonConvert.DeserializeObject(sdaResultStr); } if (sdaResult.result == false) { //给立库输送线下发指令失败 Log4NetHelper.WriteErrorLog(currentLogType, "agv请求进时下发升降机任务失败"); return; } else { tranTask.TaskState = (int)SubTaskStateEnum.已下发; currentTask.TaskState = (int)SubTaskStateEnum.等待允许进; Log4NetHelper.WriteErrorLog(currentLogType, $"agv请求进时下发升降机任务成功,deviceId:{deviceId}"); SystemWarningMsg._lbl_Alert_Agv = "AGV等待允许进"; } } else { currentTask.TaskState = (int)SubTaskStateEnum.等待允许进; Log4NetHelper.WriteErrorLog(currentLogType, $"agv请求进时下发升降机任务成功,deviceId:{deviceId}"); } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(currentLogType, $"给立库输送线发送任务指令出现异常,deviceId:{deviceId},异常:{ex.Message}"); return; } } } break; case (int)SubTaskStateEnum.等待允许进: //PLC允许进 if (vs.ReadAddress("6900|502.0") || FormCC.IsSimulationPLC) { sdaResult = vs.WriteAGVRequestIn(3, false); if (sdaResult.result == false) { Log4NetHelper.WriteErrorLog(currentLogType, "给立库输送线清请求进"); } currentTask.TaskState = (int)SubTaskStateEnum.允许进; //agv任务继续 response = ContinueTask(currentTask); if (response.code == "0") { //4、下发成功后,更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.等待进到位; currentTask.UpdatedTime = DateTime.Now;//下发时间 SystemWarningMsg._lbl_Alert_Agv = "AGV等待进到位"; } else { Log4NetHelper.WriteErrorLog(currentLogType, $"ag继续任务失败,{response.message}"); SystemWarningMsg._lbl_Alert_Agv = $"ag继续任务失败,{response.message}"; return; } } break; case (int)SubTaskStateEnum.进到位: //向plc写入进到位 sdaResult = vs.WriteAGVRequestInArr(3, true); if (sdaResult.result == false) { Log4NetHelper.WriteErrorLog(currentLogType, "agv请求进时下发进到位失败"); return; } currentTask.TaskState = (int)SubTaskStateEnum.等待升降完成; SystemWarningMsg._lbl_Alert_Agv = "AGV等待升降完成"; break; case (int)SubTaskStateEnum.等待升降完成: if (FormCC.IsSimulationPLC) { currentTask.TaskState = (int)SubTaskStateEnum.升降完成; } var tranTask1 = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.DeviceId == 3 && u.TaskId == currentTask.TaskId).FirstOrDefault(); if (tranTask1 != null) { if (tranTask1.TaskState == (int)SubTaskStateEnum.已完成) { currentTask.TaskState = (int)SubTaskStateEnum.升降完成; } } break; case (int)SubTaskStateEnum.升降完成: sdaResult = vs.WriteAGVRequestInArr(3, false); if (sdaResult.result == false) { Log4NetHelper.WriteErrorLog(currentLogType, "给立库输送线清请求进"); } //agv任务继续 response = ContinueTask(currentTask); if (response.code == "0") { //4、下发成功后,更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.请求出; currentTask.UpdatedTime = DateTime.Now;//下发时间 } else { Log4NetHelper.WriteErrorLog(currentLogType, $"ag继续任务失败,{response.message}"); SystemWarningMsg._lbl_Alert_Agv = $"ag继续任务失败,{response.message}"; return; } break; case (int)SubTaskStateEnum.请求出: sdaResult = vs.WriteAGVRequestOUT(3, true); if (sdaResult.result == true) { currentTask.TaskState = (int)SubTaskStateEnum.等待允许出; SystemWarningMsg._lbl_Alert_Agv = "AGV等待允许出"; } break; case (int)SubTaskStateEnum.等待允许出: //if (FormCC.conveyerView.R_AGV_AllowOut || FormCC.IsSimulationPLC) if (vs.ReadAddress("6900|502.2") || FormCC.IsSimulationPLC) { sdaResult = vs.WriteAGVRequestOUT(3, false); if (sdaResult.result == true) { //currentTask.TaskState = (int)SubTaskStateEnum.等待离开; //agv任务继续 response = ContinueTask(currentTask); if (response.code == "0") { //4、下发成功后,更新任务状态 currentTask.TaskState = (int)SubTaskStateEnum.等待出到位; currentTask.UpdatedTime = DateTime.Now;//下发时间 SystemWarningMsg._lbl_Alert_Agv = "AGV等待出到位"; } else { Log4NetHelper.WriteErrorLog(currentLogType, $"ag继续任务失败, {response.message}"); SystemWarningMsg._lbl_Alert_Agv = $"ag继续任务失败,{response.message}"; } } } break; case (int)SubTaskStateEnum.离开: sdaResult = vs.WriteAGVRequestOutArr(3, true); if (sdaResult.result) { sdaResult = vs.WriteAGVTaskType(3, 0); response = ContinueTask(currentTask); if (response.code == "0") { //4、下发成功后,更新任务状态 //currentTask.TaskState = (int)SubTaskStateEnum.等待完成; currentTask.TaskState = (int)SubTaskStateEnum.已完成; currentTask.UpdatedTime = DateTime.Now;//下发时间 var isExist = dbOrm.ware_task_sub.Any(u => u.TaskId == currentTask.TaskId && u.TaskState != (int)SubTaskStateEnum.已完成 && u.Id != currentTask.Id); if (!isExist) { var maintask = dbOrm.ware_task.Where(u => u.Id == currentTask.TaskId).FirstOrDefault(); if (maintask != null) { maintask.TaskState = (int)TaskStateEnum.已完成; maintask.FinishedTime = DateTime.Now; } } SystemWarningMsg._lbl_Alert_Agv = "AGV完成"; } else { Log4NetHelper.WriteErrorLog(currentLogType, $"ag继续任务失败,{response.message}"); SystemWarningMsg._lbl_Alert_Agv = $"ag继续任务失败,{response.message}"; } } break; default: break; } } catch (Exception ex) { Log4NetHelper.WriteErrorLog(currentLogType, ex.Message); throw; } } dbOrm.SaveChanges(); } vs.Close(); } catch (Exception ex) { //ExceptionHandels.GetExceptionInfoForError("自动结束立库输送线任务线程(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception); //ExceptionHandels.InsertExceptionInfo(exception, true); SystemWarningMsg._lbl_Alert_Agv = ex.Message; Log4NetHelper.WriteErrorLog(currentLogType, $"给输送线完成任务指令出现异常,deviceId:{deviceId},异常:{ex.Message}"); } } /// /// 通用AGV继续任务 /// /// /// public AgvCommonResponseDto ContinueTask(ware_task_sub currentTask) { //agv任务继续 var agvtaskcontinue = new AgvContinueTask() { reqCode = DateTime.Now.ToString("yyyyMMddhhmmssfff"), //agvCode = currentTask.AgvCode, taskCode = currentTask.AgvTaskCode, }; return HttpHelper.GetHttpResponse(host + continueTask, agvtaskcontinue, 10000); } } }