Admin.NET/WCS.Application/Entity/WcsStorageLocat.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
Admin.NET/WCS.Application/OpenApi/OpenApi.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
Admin.NET/WCS.Application/PLC/PLCService.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
Admin.NET/WCS.Application/Util/FourWayCarUtil.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
Admin.NET/WCS.Application/Entity/WcsStorageLocat.cs
@@ -126,7 +126,7 @@ public string? AisleTwo { get; set; } /// <summary> /// 储位类型 1储位 0通道 /// 储位类型 1子通道 0主通道 2 输送线口 /// </summary> [SugarColumn(ColumnName = "Make", ColumnDescription = "储位类型", Length = 32)] public string? Make { get; set; } Admin.NET/WCS.Application/OpenApi/OpenApi.cs
@@ -42,38 +42,38 @@ { throw Oops.Bah("任务:" + models.TaskNo + ";不存在!"); } var data1 = FourWayCarUtil.GetCarPath(taskInfo.StartLocate, taskInfo.EndLocate); var data1 = FourWayCarUtil.GetCarPath("090501", "080501","0"); if (data1 == null) //|| data1.Count == 0 { throw Oops.Bah("分配路径不存在!"); } // 根据任务状态 补充起始结束节点状态 var data2 = FourWayCarUtil.GetCarPathUp(data1, 1); var data2 = FourWayCarUtil.GetCarPathUp(data1, 0); var path = ""; var executionPath1 = ""; foreach (var item in data1) { //路径节点 var pathXYZ = item.X.ToString().PadLeft(2, '0') + item.Y.ToString().PadLeft(2, '0') + item.Z.ToString().PadLeft(2, '0') + item.NodeCom.ToString(); path += pathXYZ + ";"; if (item.IsSendPlc) { executionPath1 += pathXYZ + ";"; } } // 插入四向车任务表 var carTask1 = new WcsCarTasks() { TaskNo = taskInfo.TaskNo, PreId = "", ExecutionPath = executionPath1, Path = path, CarNo = "", Status = TaskStatusEnum.Wait }; var i = _db.Insertable(carTask1).ExecuteCommand(); Console.WriteLine(""+i); //foreach (var item in data1) //{ // //路径节点 // var pathXYZ = item.X.ToString().PadLeft(2, '0') + item.Y.ToString().PadLeft(2, '0') + item.Z.ToString().PadLeft(2, '0') + item.NodeCom.ToString(); // path += pathXYZ + ";"; // if (item.IsSendPlc) // { // executionPath1 += pathXYZ + ";"; // } //} //// 插入四向车任务表 //var carTask1 = new WcsCarTasks() //{ // TaskNo = taskInfo.TaskNo, // PreId = "", // ExecutionPath = executionPath1, // Path = path, // CarNo = "", // Status = TaskStatusEnum.Wait //}; //var i = _db.Insertable(carTask1).ExecuteCommand(); //Console.WriteLine(""+i); } /// WCS接受WMS下发的任务(多 Admin.NET/WCS.Application/PLC/PLCService.cs
@@ -159,8 +159,8 @@ var (resultTaskStatus, valueTaskStatus) = plcConn.GetDBValue(modPosTaskStatus.PosType, modPosTaskStatus.PlcPos); //判断读取任务状态是否成功 并且任务状态是1 0:无任务,1:任务完成,2:任务取消,3:任务暂停,4:任务异常 5:任务执行中 WcsCarTasks carTask2 = null;//null 新任务 not null 路径2任务 WcsCarTasks carTaskNext = null;//null 新任务 not null 当前小车&&当前任务 下一节任务 if (resultTaskStatus.IsSucceed && valueTaskStatus == 1) { var modPosTask = modDevice.listStation.FirstOrDefault(s => s.Text == "任务号"); @@ -182,7 +182,7 @@ break;//没有查询到总任务 } //获取路径2的任务 下发 carTask2 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == carTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.PreId.Contains(carTask.Id.ToString())).OrderBy(m=>m.CreateTime).First(); carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == carTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status <= TaskStatusEnum.Doing).OrderBy(m=>m.CreateTime).First(); if (carTask != null && carTask.Status != TaskStatusEnum.Complete) { @@ -201,8 +201,8 @@ HubUtil.PublicTaskMonitor(taskMonitor.Adapt<WcsTaskMonitorOutput>()); } //没有路径2的任务 变更总任务信息 if (carTask2 == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) //总任务下没有其他未执行小车的任务 变更总任务信息 if (carTaskNext == null && modFinshTask != null && modFinshTask.Status != TaskStatusEnum.Complete) { modFinshTask.Status = TaskStatusEnum.Complete; modFinshTask.FinishDate = DateTime.Now; @@ -233,40 +233,40 @@ var modStationZ = modDevice.listStation.FirstOrDefault(s => s.Text == "四向车位置(Z)"); var (resultz, valuez) = plcConn.GetDBValue(modStationZ.PosType, modStationZ.PlcPos); WcsTask modTask; //要下发路径2任务 if (carTask2 != null) if (carTaskNext != null) { modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTask2.TaskNo && s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar); modTask = _db.Queryable<WcsTask>().First(s => s.IsDelete == false && s.TaskNo == carTaskNext.TaskNo && s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar); carTask2= _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP).OrderBy(m => m.CreateTime).First(); carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status == TaskStatusEnum.Wait).OrderBy(m => m.CreateTime).First(); } else { // 获取任务信息 modTask = _db.Queryable<WcsTask>().Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar).OrderBy(m => m.Levels, OrderByType.Asc).OrderBy(m => m.CreateTime).First(); modTask = _db.Queryable<WcsTask>().Where(s => s.Status <= TaskStatusEnum.Doing && s.Type == PLCTypeEnum.ShuttleCar).OrderBy(m => m.Levels).OrderBy(m => m.CreateTime).First(); if (modTask == null) { return; } carTask2 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP).OrderBy(m => m.CreateTime).First(); carTaskNext = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == modTask.TaskNo && m.CarNo == modDevice.PlcIdIP && m.Status == TaskStatusEnum.Wait).OrderBy(m => m.CreateTime).First(); } //return; if (modTask == null || carTask2 == null) if (modTask == null || carTaskNext == null) { //判断小车是否有空闲时间记录 没有:添加 有:判断当前时间与记录时间是否满足5分钟 满足:添加让小车去充电任务 return; } if (carTask2.Status == TaskStatusEnum.Doing) if (carTaskNext.Status == TaskStatusEnum.Doing) { Thread.Sleep(3000); return; } //判断当前任务是否还有前置任务未完成 var preStrs = carTask2.PreId.Split(';'); var preStrs = carTaskNext.PreId.Split(';'); foreach (var preStr in preStrs) { if (string.IsNullOrWhiteSpace(preStr)) @@ -301,7 +301,7 @@ int posStatus = Convert.ToInt32(modNodeStatus.PlcPos); //交互路径 var execuPath = carTask2.ExecutionPath.Split(';'); var execuPath = carTaskNext.ExecutionPath.Split(';'); if (Convert.ToInt32(valuex) != Convert.ToInt32(execuPath[0].Substring(0, 2)) || Convert.ToInt32(valuey) != Convert.ToInt32(execuPath[0].Substring(2, 2)) || Convert.ToInt32(valuez) != Convert.ToInt32(execuPath[0].Substring(4, 2))) { return; //小车位置与路径起始位置不同 @@ -343,15 +343,15 @@ var result = plcConn.SetDBValue(modStart.PosType, modStart.PlcPos, "1"); if (result.IsSucceed) { carTask2.Status = TaskStatusEnum.Doing; carTask2.CarTaskNo = carTaskNo; _db.Updateable(carTask2).ExecuteCommand(); carTaskNext.Status = TaskStatusEnum.Doing; carTaskNext.CarTaskNo = carTaskNo; _db.Updateable(carTaskNext).ExecuteCommand(); //清除小车空闲时间 var taskMonitor = new WcsTaskMonitor() { TaskNo = carTask2.TaskNo, TaskNo = carTaskNext.TaskNo, PlcName = modDevice.Text, InteractiveMsg = $"向穿梭车下发任务{carTask2.TaskNo}" InteractiveMsg = $"向穿梭车下发任务{carTaskNext.TaskNo}" }; _db.Insertable(taskMonitor).ExecuteCommand(); //下发任务日志 Admin.NET/WCS.Application/PLC/PLCTaskAction.cs
@@ -90,7 +90,7 @@ /// <summary> /// 初始化PLC连接 /// </summary> public static void Init() public static void Init() { cts.Cancel(); listPlc = _db.Queryable<WcsPlc>() @@ -338,7 +338,7 @@ Thread.Sleep(1000); Thread.Sleep(3000); } catch (OperationCanceledException) { @@ -460,266 +460,58 @@ #endregion #region 获取适合执行当前任务的小车 生成路径(需考虑小车阻阻挡) // 获取适合执行当前任务的小车 生成路径(需考虑小车阻阻挡) var assignCar = kXCarList.OrderBy(m => m.Level).FirstOrDefault(); if (assignCar == null) { continue;//没有空闲小车 } var data = new List<CarModel>(); if (assignCar.Level != 0) { //判断小车位置是否与任务的起始储位相同,不相同:获取小车到取货储位路径 var carLocate = assignCar.X.ToString().PadLeft(2, '0')+assignCar.Y.ToString().PadLeft(2, '0')+ assignCar.Z.ToString().PadLeft(2, '0'); //获取小车去取货储位任务路径 var data1 = FourWayCarUtil.GetCarPath(carLocate, waitTask.StartLocate); var datas = FourWayCarUtil.GetCarPathUp(data1, 0); data.AddRange(datas); var datas1 = FourWayCarUtil.GetCarPathUp(data1, 0); if (datas1 == null) { continue; } else { var bl = FourWayCarUtil.AddCarTask(datas1, kXCarList, assignCar, waitTask,0); //分配错误,删除分配信息 if (!bl) { var carTask = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && m.TaskNo == waitTask.TaskNo).ToList(); _db.Deleteable(carTask).ExecuteCommand(); } } } //获取小车去放货储位任务路径 var data2 = FourWayCarUtil.GetCarPath(waitTask.StartLocate, waitTask.EndLocate, "1"); var datas2 = FourWayCarUtil.GetCarPathUp(data2, 1); data.AddRange(datas2); if (data == null) { continue; } var preId1 = "";//前置任务Id var executionPath1 = "";//交互路径 var executionPath2 = "";//交互路径 var path = "";//所有路径 var isOk = "1"; //是否完整路径 1完整 2 两条路径 for (int i = 0; i < data.Count; i++) { //路径节点 var pathXYZ = data[i].X.ToString().PadLeft(2, '0') + data[i].Y.ToString().PadLeft(2, '0') + data[i].Z.ToString().PadLeft(2, '0')+ data[i].NodeCom.ToString(); path += pathXYZ + ";"; //获取等待或正在执行的任务中包含当前节点的小车任务 var taskList = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.Path.Contains(pathXYZ)).Select(m => m.Id).Distinct().ToList(); foreach (var item in taskList) { //判断如果是完整路径 记录交互路径 if (isOk == "1") { //if (i == 0) //{ // return;//第一个节点有和其他任务路径冲突,无法避免 //} var pathXYZQian = data[i - 1].X.ToString().PadLeft(2, '0') + data[i - 1].Y.ToString().PadLeft(2, '0') + data[i - 1].Z.ToString().PadLeft(2, '0') + data[i].NodeCom.ToString(); if (!executionPath1.Contains(pathXYZQian)) { executionPath1 += pathXYZQian + ";"; } executionPath2 += pathXYZQian + ";"; } //判断添加前置任务Id if (!preId1.Contains(item + "")) { preId1 += item + ";"; } isOk = "2"; } if (data[i].IsSendPlc) { if (isOk == "1") { executionPath1 += pathXYZ + ";"; } else { executionPath2 += pathXYZ + ";"; } } if (datas2 == null) { continue; } #endregion #region 判断是否有空闲小车阻挡路径 3 var preId3 = "";//前置任务Id foreach (var item in kXCarList) else { if (item == assignCar) var bl = FourWayCarUtil.AddCarTask(datas2,kXCarList,assignCar,waitTask,1); //分配错误,删除分配信息 if (!bl) { continue;//排除当前分配任务的小车 } //小车位置 var carXYZ = item.X.ToString().PadLeft(2, '0') + item.Y.ToString().PadLeft(2, '0') + item.Z.ToString().PadLeft(2, '0') ; //分配的任务路径中 当前小车是否阻挡 if (path.Contains(carXYZ)) { //获取等待或正在执行的任务中包含当前节点的小车任务,不会有太多任务,同层有几个小车最多有几个任务 var taskList3 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing)).ToList(); var str3 = "";//所有已分配或执行的任务全路径之和 foreach (var item2 in taskList3) { str3 += item2.Path; } var endLocate3 = ""; var executionPath3 = ""; var path3 = ""; var datas3 = new List<CarModel>(); //查找目标位置 while (endLocate3 == "" || datas3.Count == 0 || datas3 == null) { endLocate3 = FourWayCarUtil.GetCarEndLocation(carXYZ, str3); var data3 = FourWayCarUtil.GetCarPath(carXYZ, endLocate3, "0"); datas3 = FourWayCarUtil.GetCarPathUp(data3, 0); } foreach (var itemPath in datas3) { var pathXYZ = itemPath.X.ToString().PadLeft(2, '0') + itemPath.Y.ToString().PadLeft(2, '0') + itemPath.Z.ToString().PadLeft(2, '0') + itemPath.NodeCom.ToString(); path3 += pathXYZ + ";"; if (itemPath.IsSendPlc) { executionPath3 += pathXYZ + ";"; } } WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.ShuttleCar, StartLocate = carXYZ, EndLocate = endLocate3, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 2, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); //移动小车 var carTaskYC = new WcsCarTasks() { TaskNo = modTask.TaskNo, PreId = "", ExecutionPath = executionPath3, Path = path3, CarNo = item.CarPlcIp, Status = TaskStatusEnum.Wait }; var idLong = _db.Insertable(carTaskYC).ExecuteReturnBigIdentity(); preId3 += idLong + ";"; waitTask.Status = TaskStatusEnum.Wait; _db.Updateable(waitTask).ExecuteCommand(); var carTask = _db.Queryable<WcsCarTasks>().Where(m=>m.IsDelete == false && m.TaskNo == waitTask.TaskNo).ToList(); _db.Deleteable(carTask).ExecuteCommand(); } } #endregion #region 判断现有任务中最终节点是否在当前分配路径中,如有 添加移走小车任务并加入前置任务 4 //获取等待或正在执行的任务中包含当前节点的小车任务,不会有太多任务,同层有几个小车最多有几个任务 var taskList4 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing)).ToList(); var preId4 = "";//前置任务Id var str4 = "";//所有已分配或执行的任务全路径之和 foreach (var item in taskList4) { str4 += item.Path; } //判断现有任务中最终节点是否在当前分配路径中,如有 添加移走小车任务并加入前置任务 foreach (var item in taskList4) { var lastPathList = item.ExecutionPath.Split(';'); // a;b;c; 最后一个位是“”,所以lastPathList.Length - 2 var lastPath = lastPathList[lastPathList.Length - 2]; //如果此此分配路径包含醉舞中最终节点路径,添加移走小车 if (path.Contains(lastPath)) { var endLocate = ""; var executionPath4 = ""; var path4 = ""; var datas4 = new List<CarModel>(); //查找目标位置 while (endLocate == "" || datas4.Count == 0 || datas4 == null) { endLocate = FourWayCarUtil.GetCarEndLocation(lastPath, str4); var data4 = FourWayCarUtil.GetCarPath(lastPath, endLocate); datas4 = FourWayCarUtil.GetCarPathUp(data4, 0); } foreach (var itemPath in datas4) { var pathXYZ = itemPath.X.ToString().PadLeft(2, '0') + itemPath.Y.ToString().PadLeft(2, '0') + itemPath.Z.ToString().PadLeft(2, '0') + itemPath.NodeCom.ToString(); path4 += pathXYZ + ";"; if (itemPath.IsSendPlc) { executionPath4 += pathXYZ + ";"; } } WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.ShuttleCar, StartLocate = lastPath, EndLocate = endLocate, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 2, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); //移动小车 var carTaskYC = new WcsCarTasks() { TaskNo = modTask.TaskNo, PreId = "", ExecutionPath = executionPath4, Path = path4, CarNo = item.CarNo, Status = TaskStatusEnum.Wait }; var idLong = _db.Insertable(carTaskYC).ExecuteReturnBigIdentity(); preId4 += idLong + ";"; } } #endregion #region 插入任务数据 改变任务状态 // 插入四向车任务表 var carTask1 = new WcsCarTasks() { TaskNo = waitTask.TaskNo, PreId = preId1+ preId3+preId4, ExecutionPath = executionPath1, Path = path, CarNo = assignCar.CarPlcIp, Status = TaskStatusEnum.Wait }; _db.Insertable(carTask1).ExecuteCommand(); if (!string.IsNullOrWhiteSpace(executionPath1) && isOk == "2") { // 插入四向车任务表 var carTask2 = new WcsCarTasks() { TaskNo = waitTask.TaskNo, PreId = preId1, ExecutionPath = executionPath2, Path = path, CarNo = assignCar.CarPlcIp, Status = TaskStatusEnum.Wait }; _db.Insertable(carTask2).ExecuteCommand(); } // 改变总任务表状态 waitTask.Status = TaskStatusEnum.Doing; waitTask.UpdateTime = DateTime.Now; _db.Updateable(waitTask).ExecuteCommand(); HubUtil.PublicTask(waitTask.Adapt<WcsTaskOutput>()); #endregion Thread.Sleep(3000); } Admin.NET/WCS.Application/Util/FourWayCarUtil.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks; using WCS.Application.Entity; using static Elastic.Clients.Elasticsearch.JoinField; using static SKIT.FlurlHttpClient.Wechat.Api.Models.CustomServiceKfSessionGetWaitCaseResponse.Types; namespace WCS.Application.Util; @@ -15,17 +16,19 @@ { private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private static readonly WcsTaskService _taskService = App.GetService<WcsTaskService>(); /// <summary> /// /// 完善小车下发节点、节点命令 /// </summary> /// <param name="list">集合</param> /// <param name="moveType">移动类型 0:移动 1:移货 </param> /// <returns></returns> public static List<CarModel> GetCarPathUp(List<CarModel> list,int moveType) public static List<CarModel> GetCarPathUp(List<CarModel> list, int moveType) { for (int i = 0; i < list.Count; i++) { if (i > 0 && i < list.Count - 1) if (i >= 0 && i < list.Count - 1) { if (list[i].X == list[i + 1].X) { @@ -35,8 +38,23 @@ { list[i].NodeCom = 3; } } if (i== 0) if (i > 0 && i < list.Count - 1) { if (list[i].Make != list[i - 1].Make || list[i].Make != list[i + 1].Make) { if (list[i].X != list[i - 1].X || list[i].X != list[i + 1].X) { list[i].IsSendPlc = true; } //list[i - 1].IsSendPlc = true; } } if (i == 0) { list[i].IsSendPlc = true; if (moveType == 0) @@ -45,19 +63,26 @@ { continue; } } else else { list[i].NodeCom = 1; } } if (i == list.Count-1) if (i == list.Count - 1) { list[i].IsSendPlc = true; if (moveType == 0) { list[i].NodeCom = list[i + 1].NodeCom; if (list[i].X == list[i - 1].X) { list[i].NodeCom = 2; } else if (list[i].Y == list[i - 1].Y) { list[i].NodeCom = 3; } } else { @@ -67,6 +92,328 @@ } return list; } /// <summary> /// 获取小车移动的目标位置 /// </summary> /// <param name="startLocation">起始位置</param> /// <param name="noPathStr">不能存放的储位字符串</param> /// <returns></returns> public static string GetCarEndLocation(string startLocation, string noPathStr) { if (string.IsNullOrEmpty(startLocation)) { return null; } // 起始位置 CarModel start = new CarModel() { X = int.Parse(startLocation.Substring(0, 2)), Y = int.Parse(startLocation.Substring(2, 2)), Z = int.Parse(startLocation.Substring(4, 2)), NodeCom = 0 }; // 获取储位表信息存储到集合里 var layer = int.Parse(startLocation.Substring(4, 2)); // 获取当前层储位信息 var locationModels = _db.Queryable<WcsStorageLocat>() .Where(m => m.WareHouseNo == "W01" && m.Layer == layer && m.IsDelete == false) .ToList(); #region MyRegion var list = locationModels.Where(m => !noPathStr.Contains(m.LocatNo)).OrderBy(m => Math.Abs(start.X - m.Row) + Math.Abs(start.Y - m.Column)).ToList(); var locateStr = ""; foreach (var item in list) { // 储位状态为损坏不可通行 储位状态为屏蔽为可通行不可存储托盘 if (item.Flag == "2") { continue; } locateStr = item.LocatNo; break; } return locateStr; #endregion } /// <summary> /// 获取任务号 /// </summary> /// <returns></returns> public static int GetTaskNo() { var list = _db.Queryable<WcsCarTasks>().ToList(); var maxNo = list.Max(m => m.CarTaskNo); if (maxNo != null && maxNo > 0) { if (maxNo++ > 65535) { return 1; } return (int)maxNo++; } return 1; } public static bool AddCarTask(List<CarModel> data, List<CarInfo> kXCarList, CarInfo assignCar, WcsTask waitTask,int moveType) { #region 获取适合执行当前任务的小车 生成路径(需考虑小车阻阻挡) var preId1 = "";//前置任务Id var executionPath1 = "";//交互路径 var executionPath2 = "";//交互路径 var path = "";//所有路径 var isOk = "1"; //是否完整路径 1完整 2 两条路径 for (int i = 0; i < data.Count; i++) { //路径节点 var pathXYZ = data[i].X.ToString().PadLeft(2, '0') + data[i].Y.ToString().PadLeft(2, '0') + data[i].Z.ToString().PadLeft(2, '0') + data[i].NodeCom.ToString(); var pathXYZ2 = data[i].X.ToString().PadLeft(2, '0') + data[i].Y.ToString().PadLeft(2, '0') + data[i].Z.ToString().PadLeft(2, '0'); path += pathXYZ + ";"; //获取等待或正在执行的任务中包含当前节点的小车任务 var taskList = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.Path.Contains(pathXYZ2) && m.CarNo != assignCar.CarPlcIp).Select(m => m.Id).Distinct().ToList(); foreach (var item in taskList) { //判断如果是完整路径 记录交互路径 if (isOk == "1") { if (i == 0) { continue; } var pathXYZQian = data[i - 1].X.ToString().PadLeft(2, '0') + data[i - 1].Y.ToString().PadLeft(2, '0') + data[i - 1].Z.ToString().PadLeft(2, '0')+ data[i - 1].NodeCom.ToString(); var pathXYZQian2 = data[i - 1].X.ToString().PadLeft(2, '0') + data[i - 1].Y.ToString().PadLeft(2, '0') + data[i - 1].Z.ToString().PadLeft(2, '0'); if (!executionPath1.Contains(pathXYZQian2)) { executionPath1 += pathXYZQian + ";"; } executionPath2 += pathXYZQian + ";"; //判断添加前置任务Id if (!preId1.Contains(item + "")) { preId1 += item + ";"; } } isOk = "2"; } if (data[i].IsSendPlc) { if (isOk == "1") { executionPath1 += pathXYZ + ";"; } else { executionPath2 += pathXYZ + ";"; } } } #endregion #region 判断是否有空闲小车阻挡路径 3 var preId3 = "";//前置任务Id foreach (var item in kXCarList) { if (item == assignCar) { continue;//排除当前分配任务的小车 } //小车位置 var carXYZ = item.X.ToString().PadLeft(2, '0') + item.Y.ToString().PadLeft(2, '0') + item.Z.ToString().PadLeft(2, '0'); //分配的任务路径中 当前小车是否阻挡 if (path.Contains(carXYZ)) { //获取等待或正在执行的任务中包含当前节点的小车任务,不会有太多任务,同层有几个小车最多有几个任务 var taskList3 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing)).ToList(); var str3 = "";//所有已分配或执行的任务全路径之和 foreach (var item2 in taskList3) { str3 += item2.Path; } var endLocate3 = ""; var executionPath3 = ""; var path3 = ""; var datas3 = new List<CarModel>(); //查找目标位置 while (endLocate3 == "" || datas3.Count == 0 || datas3 == null) { endLocate3 = FourWayCarUtil.GetCarEndLocation(carXYZ, str3); var data3 = FourWayCarUtil.GetCarPath(carXYZ, endLocate3, "0"); datas3 = FourWayCarUtil.GetCarPathUp(data3, 0); } foreach (var itemPath in datas3) { var pathXYZ = itemPath.X.ToString().PadLeft(2, '0') + itemPath.Y.ToString().PadLeft(2, '0') + itemPath.Z.ToString().PadLeft(2, '0') + itemPath.NodeCom.ToString(); path3 += pathXYZ + ";"; if (itemPath.IsSendPlc) { executionPath3 += pathXYZ + ";"; } } WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.ShuttleCar, StartLocate = carXYZ, EndLocate = endLocate3, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 999, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); //移动小车 var carTaskYC = new WcsCarTasks() { TaskNo = modTask.TaskNo, PreId = "", ExecutionPath = executionPath3, Path = path3, CarNo = item.CarPlcIp, Status = TaskStatusEnum.Wait }; var idLong = _db.Insertable(carTaskYC).ExecuteReturnSnowflakeId(); preId3 += idLong + ";"; } } #endregion #region 判断现有任务中最终节点是否在当前分配路径中,如有 添加移走小车任务并加入前置任务 4 //获取等待或正在执行的任务中包含当前节点的小车任务,不会有太多任务,同层有几个小车最多有几个任务 var taskList4 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.CarNo!=assignCar.CarPlcIp).ToList(); var preId4 = "";//前置任务Id var str4 = "";//所有已分配或执行的任务全路径之和 foreach (var item in taskList4) { str4 += item.Path; } //判断现有任务中最终节点是否在当前分配路径中,如有 添加移走小车任务并加入前置任务 foreach (var item in taskList4) { var lastPathList = item.ExecutionPath.Split(';'); // a;b;c; 最后一个位是“”,所以lastPathList.Length - 2 var lastPath = lastPathList[lastPathList.Length - 2]; var lastPath2 = lastPath.Substring(0,6); //如果此此分配路径包含醉舞中最终节点路径,添加移走小车 if (path.Contains(lastPath2)) { var endLocate = ""; var executionPath4 = ""; var path4 = ""; var datas4 = new List<CarModel>(); //查找目标位置 while (endLocate == "" || datas4.Count == 0 || datas4 == null) { endLocate = FourWayCarUtil.GetCarEndLocation(lastPath, str4); var data4 = FourWayCarUtil.GetCarPath(lastPath, endLocate); datas4 = FourWayCarUtil.GetCarPathUp(data4, 0); } foreach (var itemPath in datas4) { var pathXYZ = itemPath.X.ToString().PadLeft(2, '0') + itemPath.Y.ToString().PadLeft(2, '0') + itemPath.Z.ToString().PadLeft(2, '0') + itemPath.NodeCom.ToString(); path4 += pathXYZ + ";"; if (itemPath.IsSendPlc) { executionPath4 += pathXYZ + ";"; } } WcsTask modTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.ShuttleCar, StartLocate = lastPath, EndLocate = endLocate, PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 999, Origin = "WCS" }; _db.Insertable(modTask).ExecuteCommand(); HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); //移动小车 var carTaskYC = new WcsCarTasks() { TaskNo = modTask.TaskNo, PreId = "", ExecutionPath = executionPath4, Path = path4, CarNo = item.CarNo, Status = TaskStatusEnum.Wait }; var idLong = _db.Insertable(carTaskYC).ExecuteReturnSnowflakeId(); preId4 += idLong + ";"; } } #endregion #region 插入任务数据 改变任务状态 // 插入四向车任务表 var carTask1 = new WcsCarTasks() { TaskNo = waitTask.TaskNo, PreId = preId1 + preId3 + preId4, ExecutionPath = executionPath1, Path = path, CarNo = assignCar.CarPlcIp, Status = TaskStatusEnum.Wait }; _db.Insertable(carTask1).ExecuteCommand(); if (!string.IsNullOrWhiteSpace(executionPath1) && isOk == "2") { // 插入四向车任务表 var carTask2 = new WcsCarTasks() { TaskNo = waitTask.TaskNo, PreId = preId1, ExecutionPath = executionPath2, Path = path, CarNo = assignCar.CarPlcIp, Status = TaskStatusEnum.Wait }; _db.Insertable(carTask2).ExecuteCommand(); } if (moveType == 1) { // 改变总任务表状态 waitTask.Status = TaskStatusEnum.Doing; waitTask.UpdateTime = DateTime.Now; _db.Updateable(waitTask).ExecuteCommand(); HubUtil.PublicTask(waitTask.Adapt<WcsTaskOutput>()); } return true; #endregion } /// <summary> /// 获取小车路径 @@ -142,7 +489,7 @@ // 存储小车可运行的方向 var validDirections = new List<CarModel>(); var currentLocation = locationModels.FirstOrDefault(m => m.Row == current.X && m.Column == current.Y); if (currentLocation.Make == "0") if (currentLocation.Make == "0"|| currentLocation.Make == "2") { // 主通道 validDirections.Add(new CarModel() { X = 1, Y = 0 }); // 右 @@ -227,55 +574,9 @@ { neighbor.IsSendPlc = false; //if (current.X == neighbor.X) //{ // current.NodeCom = 2; //} //else if (current.Y == neighbor.Y) //{ // current.NodeCom = 3; //} //// 补充参数 //if (current.Equals(start)) //{ // current.NodeCom = moveType; // current.IsSendPlc = true; //} //if (neighbor.Equals(end)) //{ // //neighbor.NodeCom = moveType != 0 ? 2:0 ; // if (moveType == 1) // { // neighbor.NodeCom = 4; // } // else // { // neighbor.NodeCom = current.NodeCom; // } // neighbor.IsSendPlc = true; //} if (currentModel.Make != locationModel.Make) { //if (current.X != neighbor.X) //{ // current.IsSendPlc = true; //} if (current.Y > neighbor.Y) { current.IsSendPlc = true; } else if (current.Y < neighbor.Y) { neighbor.IsSendPlc = true; } //current.IsSendPlc = true; } neighbor.Make = locationModel.Make; current.Make = currentModel.Make; // 更新实际距离与预估距离 cameFrom[neighbor] = current; gScore[neighbor] = tentativeGScore; @@ -531,6 +832,11 @@ /// </summary> public bool IsSendPlc { get; set; } /// <summary> /// 0通道 1 储位 /// </summary> public string Make { get; set; } public int CompareTo(CarModel other) { if (other == null)