using System.Diagnostics; using System.Text; using WIDESEAWCS_Common.AGVEnum; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; namespace WIDESEAWCS_Tasks.AGVJob { public class SendTaskAGV { private static int _readSendAGVTaskSignalso = 0; private static bool isTrue1 = false; private static string name1 = ""; public static void SendAGVTask1(AGV agv, ITaskRepository _taskRepository) { //TODO: Implement sending task to AGV try { if (agv == null) { return; } var taskInteractiveR = agv.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskInteractiveR.ToString()).FirstOrDefault().DeviceProAddress; var taskInteractiveW = agv.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskInteractiveW.ToString()).FirstOrDefault().DeviceProAddress; var resetTaskW = agv.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveW.ToString()).FirstOrDefault().DeviceProAddress; var resetTaskInteractiveR = agv.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveR.ToString()).FirstOrDefault().DeviceProAddress; var taskID = agv.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskID.ToString()).FirstOrDefault().DeviceProAddress; int TaskInteractive = agv.Communicator.Read(taskInteractiveR);//1收到 int TaskInteractiveW = agv.Communicator.Read(taskInteractiveW);//0初始/1下发/2取消/3更改 int resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); int resetTaskInteractiver = agv.Communicator.Read(resetTaskInteractiveR); if (isTrue1 && name1 == agv.DeviceName) { if (TaskInteractiveW != 0 || resetTaskInteractiveW != 0 || TaskInteractive != 0) { agv.Communicator.Write(resetTaskW, 1); Task.Delay(2000).Wait(); resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); if (resetTaskInteractiveW == 1) { agv.Communicator.Write(resetTaskW, 0); agv.Communicator.Write(taskInteractiveW, 0); Task.Delay(2000).Wait(); } return; } else { isTrue1 = false; name1 = ""; } } if (resetTaskInteractiver == 1) { agv.Communicator.Write(taskInteractiveW, 0); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = Convert.ToInt32(agv.Communicator.Read(taskInteractiveW)); if (agvnumber != 0) { agv.Communicator.Write(taskInteractiveW, 0); } else { break; } } } if (0 == TaskInteractive && TaskInteractiveW == 0) { Dt_Task agvTask = _taskRepository.QueryData(r => r.TaskState == (int)TaskInStatusEnum.InNew && r.Roadway == agv.DeviceName && r.TaskType == (int)TaskOutboundTypeEnum.Outbound).OrderBy(r => r.CreateDate).OrderByDescending(r => r.Grade).FirstOrDefault(); if (null != agvTask) { //写入任务信息 string rel = TaskWrite(agv, agvTask, AGVJobEnum.newTaskEnum); Thread.Sleep(1000); string taskId = agv.Communicator.Read(taskID).ToString(); if (taskId != agvTask.TaskNum.ToString()) { isTrue1 = true; name1 = agv.DeviceName; //WriteLog.Info("SendAGVTask").Write("给AGV写入任务失败," + agvTask.agv_tasknum + DateTime.Now, "SendAGVTask"); throw new Exception(string.Format("给AGV写入任务失败,任务号{0}", agvTask.TaskNum)); } if (string.IsNullOrEmpty(rel)) { //写入任务确认1 agv.Communicator.Write(taskInteractiveW, 1); Thread.Sleep(1000); //读取AGV信号 int ReadTask_1_OK = agv.Communicator.Read(taskInteractiveR); if (ReadTask_1_OK == 1) { //写入WCS确认信号0 agv.Communicator.Write(taskInteractiveW, 0); Thread.Sleep(2000); //读取AGV信号是否为0 int ReadTask_0_OK = agv.Communicator.Read(taskInteractiveR); if (ReadTask_0_OK == 0) { int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); // 上传AGV运行数据 by xiaoyang //SendMESTask.SendMesTask(agvTask, 0); } else { isTrue1 = true; name1 = agv.DeviceName; throw new Exception(string.Format("给AGV写入任务确认0失败,任务号{0}", agvTask.TaskNum)); } } else if (ReadTask_1_OK == 11) { agv.Communicator.Write(taskInteractiveW, 0); Thread.Sleep(2000); int ReadTask_0_Error = agv.Communicator.Read(taskInteractiveR); if (ReadTask_0_Error == 0) { int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); } else { isTrue1 = true; name1 = agv.DeviceName; throw new Exception(string.Format("给AGV写入任务异常确认0失败,任务号{0}", agvTask.TaskNum)); } } else { isTrue1 = true; name1 = agv.DeviceName; throw new Exception(string.Format("给AGV写入任务确认1失败,任务号{0}", agvTask.TaskNum)); } } else { isTrue1 = true; name1 = agv.DeviceName; throw new Exception(string.Format("给AGV写入任务失败,任务号{0}" + rel, agvTask.TaskNum)); } } } } catch (Exception ex) { StackTrace sta = new StackTrace(ex, true); StackTrace st = new StackTrace(new StackFrame(true)); StackFrame sf = sta.GetFrame(0); //WriteLog.Info("SendAGVTask").Write(ex.Message + "行号" + sf.GetFileLineNumber(), "SendAGVTask"); } finally { // WriteLog.Info("SendAGVTask").Write(agv.PLCName+"\t"+DateTime.Now, "SendAGVTask"); Interlocked.Exchange(ref _readSendAGVTaskSignalso, 0); } } public static void SendAGVTask(AGV agv, ITaskRepository _taskRepository) { // 检查AGV是否为空 if (agv == null) { return; } // 获取任务交互和重置交互的设备地址 var taskInteractiveR = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskInteractiveR.ToString())?.DeviceProAddress; var taskInteractiveW1 = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskInteractiveW.ToString())?.DeviceProAddress; var resetTaskW = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveW.ToString())?.DeviceProAddress; var resetTaskInteractiveR = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveR.ToString())?.DeviceProAddress; var taskID = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskID.ToString())?.DeviceProAddress; // 如果地址未找到,直接返回 if (taskInteractiveR is null || taskInteractiveW1 is null || resetTaskW is null || resetTaskInteractiveR is null || taskID is null) { return; } try { // 读取任务交互和重置交互的状态 int taskInteractive = agv.Communicator.Read(taskInteractiveR); // 1表示收到 int taskInteractiveW = agv.Communicator.Read(taskInteractiveW1); // 0初始/1下发/2取消/3更改 int resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); int resetTaskInteractiver = agv.Communicator.Read(resetTaskInteractiveR); // 处理任务交互W和重置交互W不为0的情况 if (isTrue1 && name1 == agv.DeviceName) { if (taskInteractiveW != 0 || resetTaskInteractiveW != 0 || taskInteractive != 0) { agv.Communicator.Write(resetTaskW, 1); Task.Delay(2000).Wait(); resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); if (resetTaskInteractiveW == 1) { agv.Communicator.Write(resetTaskW, 0); agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); } return; } isTrue1 = false; name1 = ""; } // 如果重置交互R为1,则重置任务交互W if (resetTaskInteractiver == 1) { agv.Communicator.Write(taskInteractiveW1, 0); for (int i = 0; i < 5; i++) { Task.Delay(300).Wait(); // 用Task.Delay代替Thread.Sleep,以避免线程阻塞 int agvNumber = agv.Communicator.Read(taskInteractiveW1); if (agvNumber != 0) { agv.Communicator.Write(taskInteractiveW1, 0); } else { break; } } } // 如果AGV没有任务且任务交互W为0 if (taskInteractive == 0 && taskInteractiveW == 0) { // 查询新任务 Dt_Task agvTask = _taskRepository.QueryData(r => r.TaskState == (int)TaskInStatusEnum.InNew && r.Roadway == agv.DeviceName && r.TaskType == (int)TaskOutboundTypeEnum.Outbound) .OrderBy(r => r.CreateDate).ThenByDescending(r => r.Grade).FirstOrDefault(); if (agvTask != null) { // 写入任务信息 string rel = TaskWrite(agv, agvTask, AGVJobEnum.newTaskEnum); Task.Delay(1000).Wait(); // 检查任务ID是否写入正确 string taskId = agv.Communicator.Read(taskID); if (taskId != agvTask.TaskNum.ToString()) { throw new Exception($"给AGV写入任务失败,任务号{agvTask.TaskNum}"); } // 如果任务信息写入成功 if (string.IsNullOrEmpty(rel)) { // 写入任务确认信号1 agv.Communicator.Write(taskInteractiveW1, 1); Task.Delay(1000).Wait(); // 读取AGV的确认信号 int readTask1Ok = agv.Communicator.Read(taskInteractiveR); if (readTask1Ok == 1) { // 写入WCS的确认信号0 agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); // 再次读取AGV的确认信号 int readTask0Ok = agv.Communicator.Read(taskInteractiveR); if (readTask0Ok == 0) { // 更新任务状态并保存 int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); // 上传AGV运行数据(注释掉的代码) // SendMESTask.SendMesTask(agvTask, 0); } else { throw new Exception($"给AGV写入任务确认0失败,任务号{agvTask.TaskNum}"); } } else if (readTask1Ok == 11) { // 处理任务异常情况 agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); int readTask0Error = agv.Communicator.Read(taskInteractiveR); if (readTask0Error == 0) { // 更新任务状态为异常并保存 int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); } else { throw new Exception($"给AGV写入任务异常确认0失败,任务号{agvTask.TaskNum}"); } } else { throw new Exception($"给AGV写入任务确认1失败,任务号{agvTask.TaskNum}"); } } else { throw new Exception($"给AGV写入任务失败,任务号{agvTask.TaskNum} {rel}"); } } } } catch (Exception ex) { // 记录异常信息(注释掉的代码) // StackTrace sta = new StackTrace(ex, true); // StackFrame sf = sta.GetFrame(0); // WriteLog.Info("SendAGVTask").Write(ex.Message + " 行号 " + sf.GetFileLineNumber(), "SendAGVTask"); } finally { // 记录日志(注释掉的代码) // WriteLog.Info("SendAGVTask").Write(agv.PLCName + "\t" + DateTime.Now, "SendAGVTask"); // 重置信号量 Interlocked.Exchange(ref _readSendAGVTaskSignalso, 0); } } public static string TaskWrite(AGV client, Dt_Task agvTask, AGVJobEnum jobEnum) { List sendData = new List(); string tmp = agvTask.TaskNum.ToString(); List taskID = Encoding.Default.GetBytes(tmp).ToList();//任务ID taskID.Insert(0, 30); taskID.Insert(1, Convert.ToByte(tmp.Length)); for (int i = 0; i < 30 - tmp.Length; i++) { taskID.Add(0); } sendData.AddRange(taskID); List taskStart = Encoding.Default.GetBytes(agvTask.SourceAddress).ToList(); taskStart.Insert(0, 20); taskStart.Insert(1, Convert.ToByte(agvTask.SourceAddress.Length)); for (int i = 0; i < 20 - agvTask.SourceAddress.Length; i++) { taskStart.Add(0); } sendData.AddRange(taskStart); List taskEnd = Encoding.Default.GetBytes(agvTask.TargetAddress).ToList(); taskEnd.Insert(0, 20); taskEnd.Insert(1, Convert.ToByte(agvTask.TargetAddress.Length)); for (int i = 0; i < 20 - agvTask.TargetAddress.Length; i++) { taskEnd.Add(0); } sendData.AddRange(taskEnd); byte[] taskType = BitConverter.GetBytes((ushort)1).ToArray(); Array.Reverse(taskType); sendData.AddRange(taskType); List containerType = Encoding.Default.GetBytes(agvTask.PalletCode).ToList(); containerType.Insert(0, 30); containerType.Insert(1, Convert.ToByte(agvTask.PalletCode.Length)); for (int i = 0; i < 30 - agvTask.PalletCode.Length; i++) { containerType.Add(0); } sendData.AddRange(containerType); byte[] taskPriority = BitConverter.GetBytes((ushort)1).ToArray(); Array.Reverse(taskPriority); sendData.AddRange(taskPriority); byte[] taskFlag = BitConverter.GetBytes((ushort)jobEnum).ToArray(); Array.Reverse(taskFlag); sendData.AddRange(taskFlag); var operateResult = client.Communicator.Write("DB1000.0", sendData.ToArray()); if (!operateResult) return "AGV发送任务失败"; //WriteLog.Info("AGV发送任务").Write("任务号" + agvTask.agv_tasknum + "AGV编号" + client.PLCName + DateTime.Now, "AGV发送任务"); return ""; } } }