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
|
{
|
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<int>(taskInteractiveR);//1收到
|
int TaskInteractiveW = agv.Communicator.Read<int>(taskInteractiveW);//0初始/1下发/2取消/3更改
|
int resetTaskInteractiveW = agv.Communicator.Read<int>(resetTaskW);
|
int resetTaskInteractiver = agv.Communicator.Read<int>(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<int>(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<int>(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<string>(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<int>(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<int>(taskInteractiveR);
|
if (ReadTask_0_OK == 0)
|
{
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>();
|
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<int>(taskInteractiveR);
|
if (ReadTask_0_Error == 0)
|
{
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskOutStatusEnum>();
|
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<Int16>(taskInteractiveR); // 1表示收到
|
int taskInteractiveW = agv.Communicator.Read<Int16>(taskInteractiveW1); // 0初始/1下发/2取消/3更改
|
int resetTaskInteractiveW = agv.Communicator.Read<Int16>(resetTaskW);
|
int resetTaskInteractiver = agv.Communicator.Read<Int16>(resetTaskInteractiveR);
|
|
// 处理任务交互W和重置交互W不为0的情况
|
if (isTrue1 && name1 == agv.DeviceName)
|
{
|
if (taskInteractiveW != 0 || resetTaskInteractiveW != 0 || taskInteractive != 0)
|
{
|
agv.Communicator.Write<UInt16>(resetTaskW, 1);
|
Task.Delay(2000).Wait();
|
resetTaskInteractiveW = agv.Communicator.Read<Int16>(resetTaskW);
|
|
if (resetTaskInteractiveW == 1)
|
{
|
agv.Communicator.Write<UInt16>(resetTaskW, 0);
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
}
|
return;
|
}
|
isTrue1 = false;
|
name1 = "";
|
}
|
|
// 如果重置交互R为1,则重置任务交互W
|
if (resetTaskInteractiver == 1)
|
{
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
for (int i = 0; i < 5; i++)
|
{
|
Task.Delay(300).Wait(); // 用Task.Delay代替Thread.Sleep,以避免线程阻塞
|
int agvNumber = agv.Communicator.Read<Int16>(taskInteractiveW1);
|
if (agvNumber != 0)
|
{
|
agv.Communicator.Write<UInt16>(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<string>(taskID);
|
string numberPart = taskId.Split('-')[1];
|
if (numberPart != agvTask.TaskNum.ToString())
|
{
|
throw new Exception($"给AGV写入任务失败,任务号{agvTask.TaskNum}");
|
}
|
|
// 如果任务信息写入成功
|
if (string.IsNullOrEmpty(rel))
|
{
|
// 写入任务确认信号1
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 1);
|
Task.Delay(1000).Wait();
|
|
// 读取AGV的确认信号
|
int readTask1Ok = agv.Communicator.Read<Int16>(taskInteractiveR);
|
if (readTask1Ok == 1)
|
{
|
// 写入WCS的确认信号0
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
|
// 再次读取AGV的确认信号
|
int readTask0Ok = agv.Communicator.Read<Int16>(taskInteractiveR);
|
if (readTask0Ok == 0)
|
{
|
// 更新任务状态并保存
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>();
|
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<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
int readTask0Error = agv.Communicator.Read<int>(taskInteractiveR);
|
|
if (readTask0Error == 0)
|
{
|
// 更新任务状态为异常并保存
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskOutStatusEnum>();
|
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<byte> sendData = new List<byte>();
|
string tmp = "KH-" + agvTask.TaskNum.ToString();
|
List<byte> 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<byte> 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<byte> 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<byte> containerType = Encoding.Default.GetBytes(agvTask.Barcode).ToList();
|
containerType.Insert(0, 30);
|
containerType.Insert(1, Convert.ToByte(agvTask.Barcode.Length));
|
|
for (int i = 0; i < 30 - agvTask.Barcode.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 "";
|
}
|
}
|
}
|