| | |
| | | /// <returns></returns> |
| | | public static List<CarModel> GetCarPathUp(List<CarModel> list, int moveType) |
| | | { |
| | | if (list == null) |
| | | { |
| | | return null; |
| | | } |
| | | for (int i = 0; i < list.Count; i++) |
| | | { |
| | | if (i >= 0 && i < list.Count - 1) |
| | |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// |
| | | /// </summary> |
| | | /// <param name="data">当前任务总路径</param> |
| | | /// <param name="kXCarList">所有小车</param> |
| | | /// <param name="assignCar">当前分配小车</param> |
| | | /// <param name="waitTask">当前总任务</param> |
| | | /// <param name="moveType">0去取货任务 1去放货</param> |
| | | /// <returns></returns> |
| | | public static bool AddCarTask(List<CarModel> data, List<CarInfo> kXCarList, CarInfo assignCar, WcsTask waitTask,int moveType) |
| | | { |
| | | #region 获取适合执行当前任务的小车 生成路径(需考虑小车阻阻挡) |
| | |
| | | executionPath1 += pathXYZQian + ";"; |
| | | } |
| | | executionPath2 += pathXYZQian + ";"; |
| | | //判断添加前置任务Id |
| | | if (!preId1.Contains(item + "")) |
| | | { |
| | | preId1 += item + ";"; |
| | | } |
| | | |
| | | } |
| | | |
| | | //判断添加前置任务Id |
| | | if (!preId1.Contains(item + "")) |
| | | { |
| | | preId1 += item + ";"; |
| | | } |
| | | |
| | | isOk = "2"; |
| | | } |
| | |
| | | PalletNo = "", |
| | | Status = TaskStatusEnum.Wait, |
| | | Levels = 999, |
| | | Origin = "WCS" |
| | | Origin = "WCS", |
| | | CarIp = item.CarPlcIp |
| | | }; |
| | | _db.Insertable(modTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); |
| | |
| | | #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 taskListTask4 = _db.Queryable<WcsCarTasks>().Where(m => m.IsDelete == false && (m.Status == TaskStatusEnum.Wait || m.Status == TaskStatusEnum.Doing) && m.CarNo!=assignCar.CarPlcIp).GroupBy(m=>m.TaskNo).Select(m=>m.TaskNo).ToList(); |
| | | 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 = "";//所有已分配或执行的任务全路径之和 |
| | | |
| | |
| | | str4 += item.Path; |
| | | } |
| | | //判断现有任务中最终节点是否在当前分配路径中,如有 添加移走小车任务并加入前置任务 |
| | | foreach (var item in taskList4) |
| | | foreach (var item in taskListTask4) |
| | | { |
| | | var lastPathList = item.ExecutionPath.Split(';'); |
| | | var lastTask = taskList4.Where(m => m.TaskNo == item ).OrderBy(m=>m.CreateTime).LastOrDefault(); |
| | | if (lastTask == null) |
| | | { |
| | | continue; |
| | | } |
| | | var lastPathList = lastTask.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 = ""; |
| | |
| | | //查找目标位置 |
| | | while (endLocate == "" || datas4.Count == 0 || datas4 == null) |
| | | { |
| | | endLocate = FourWayCarUtil.GetCarEndLocation(lastPath, str4); |
| | | endLocate = FourWayCarUtil.GetCarEndLocation(lastPath, str4+path); |
| | | var data4 = FourWayCarUtil.GetCarPath(lastPath, endLocate); |
| | | datas4 = FourWayCarUtil.GetCarPathUp(data4, 0); |
| | | } |
| | |
| | | PalletNo = "", |
| | | Status = TaskStatusEnum.Wait, |
| | | Levels = 999, |
| | | Origin = "WCS" |
| | | Origin = "WCS", |
| | | CarIp = lastTask.CarNo |
| | | }; |
| | | _db.Insertable(modTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(modTask.Adapt<WcsTaskOutput>()); |
| | |
| | | PreId = "", |
| | | ExecutionPath = executionPath4, |
| | | Path = path4, |
| | | CarNo = item.CarNo, |
| | | CarNo = lastTask.CarNo, |
| | | Status = TaskStatusEnum.Wait |
| | | }; |
| | | var idLong = _db.Insertable(carTaskYC).ExecuteReturnSnowflakeId(); |
| | |
| | | var carTask2 = new WcsCarTasks() |
| | | { |
| | | TaskNo = waitTask.TaskNo, |
| | | PreId = preId1, |
| | | PreId = "", |
| | | ExecutionPath = executionPath2, |
| | | Path = path, |
| | | CarNo = assignCar.CarPlcIp, |
| | |
| | | }; |
| | | _db.Insertable(carTask2).ExecuteCommand(); |
| | | } |
| | | waitTask.CarIp = assignCar.CarPlcIp; |
| | | if (moveType == 1) |
| | | { |
| | | // 改变总任务表状态 |
| | | waitTask.Status = TaskStatusEnum.Doing; |
| | | waitTask.UpdateTime = DateTime.Now; |
| | | _db.Updateable(waitTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(waitTask.Adapt<WcsTaskOutput>()); |
| | | waitTask.UpdateTime = DateTime.Now; |
| | | } |
| | | |
| | | _db.Updateable(waitTask).ExecuteCommand(); |
| | | HubUtil.PublicTask(waitTask.Adapt<WcsTaskOutput>()); |
| | | |
| | | return true; |
| | | #endregion |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | if (current.Equals(end)) |
| | | { |
| | | Log.Error(ReconstructPath(cameFrom, current).ToString()); |
| | | Log.Error("小车路径分配:" +ReconstructPath(cameFrom, current).ToString()); |
| | | return ReconstructPath(cameFrom, current); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /// <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 |
| | | |
| | | #region 使用算法计算小车可移动的目标路径 |
| | | //try |
| | | //{ |
| | | |
| | | // // 定义关闭节点字典 |
| | | // var closeSet = new Dictionary<CarModel, CarModel>(); |
| | | |
| | | // // 存储小车可运行的方向 |
| | | // var validDirections = new List<CarModel>(); |
| | | // var currentLocation = locationModels.FirstOrDefault(m => m.Row == start.X && m.Column == start.Y); |
| | | // if (currentLocation.Make == "0") |
| | | // { |
| | | // // 主通道 |
| | | // validDirections.Add(new CarModel() { X = 1, Y = 0 }); // 右 |
| | | // validDirections.Add(new CarModel() { X = -1, Y = 0 }); // 左 |
| | | // validDirections.Add(new CarModel() { X = 0, Y = 1 }); // 下 |
| | | // validDirections.Add(new CarModel() { X = 0, Y = -1 }); // 上 |
| | | // } |
| | | |
| | | // if (currentLocation.Make == "1") |
| | | // { |
| | | // // 子通道 |
| | | // // 先拆分出口 |
| | | // var outNode = currentLocation.AisleOne; |
| | | // if (string.IsNullOrEmpty(outNode)) |
| | | // { |
| | | // throw new Exception("当前位置没有维护出口!"); |
| | | // } |
| | | // int outX = int.Parse(outNode.Substring(0, 2)); |
| | | // int outY = int.Parse(outNode.Substring(2, 2)); |
| | | // if (start.X == outX) |
| | | // { |
| | | // validDirections.Add(new CarModel() { X = 0, Y = 1 }); // 下 |
| | | // validDirections.Add(new CarModel() { X = 0, Y = -1 }); // 上 |
| | | |
| | | // } |
| | | // else |
| | | // { |
| | | // validDirections.Add(new CarModel() { X = 1, Y = 0 }); // 右 |
| | | // validDirections.Add(new CarModel() { X = -1, Y = 0 }); // 左 |
| | | // } |
| | | // } |
| | | |
| | | // foreach (var dir in validDirections) |
| | | // { |
| | | // CarModel neighbor = new CarModel() { X = start.X + dir.X, Y = start.Y + dir.Y, Z = layer }; |
| | | |
| | | // // 验证下一节点位置是否可通行并且判断是否被其他小车占用 |
| | | |
| | | |
| | | // // 判断下一节点是否关闭 |
| | | // if (closeSet.ContainsKey(neighbor)) |
| | | // { |
| | | // closeSet[neighbor] = neighbor; |
| | | // } |
| | | |
| | | // // 当前节点 |
| | | // var currentModel = locationModels.FirstOrDefault(it => it.Row == start.X && it.Column == start.Y); |
| | | // // 下一节点 |
| | | // var locationModel = locationModels.FirstOrDefault(it => it.Row == neighbor.X && it.Column == neighbor.Y); |
| | | |
| | | // // 不存在此位置信息 |
| | | // if (locationModel == null) |
| | | // { |
| | | // closeSet[neighbor] = neighbor; |
| | | // continue; |
| | | // } |
| | | // // 储位状态为损坏不可通行 储位状态为屏蔽为可通行不可存储托盘 |
| | | // if (locationModel.Flag == "2") |
| | | // { |
| | | // closeSet[neighbor] = neighbor; |
| | | // continue; |
| | | // } |
| | | |
| | | // } |
| | | |
| | | |
| | | |
| | | //} |
| | | //catch (Exception) |
| | | //{ |
| | | // throw; |
| | | //} |
| | | |
| | | //return null; |
| | | #endregion |
| | | } |
| | | |
| | | 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; |
| | | |
| | | } |
| | | |
| | | /// <summary> |