/// <summary> /// 计算路径以及转向逻辑 /// </summary> /// <param name="insInfo"></param> /// <param name="path1"></param> /// <param name="path2"></param> /// <param name="rackItem"></param> private void ComputePath(InstructionInfo insInfo, string path1, string path2 = null, RackInfo rackItem = null) { string[] path1Arr = path1.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); int path1Length = path1Arr.Length; for (int i = 0; i < path1Length; i++) { string path = path1Arr[i]; if (i == 0 && !string.IsNullOrEmpty(lastRoute)) //如果取/卸货仓位是紧邻的仓位,则指令需要跳过下一位置 { var rackInfo = rackList.Where(a => a.RouteCode == path).FirstOrDefault(); if (rackInfo != null) { var lastInfo = rackList.Where(a => a.RouteCode == lastRoute).FirstOrDefault(); if (lastInfo != null) { continue; } } } lastRoute = path; var item = routelist.Where(a => a.Routecode == path1Arr[i]).FirstOrDefault(); if (i + 1 < path1Length) //还有下一节点 { string next = path1Arr[i + 1]; var nextItem = routelist.Where(a => a.Routecode == next).FirstOrDefault(); int xsub = item.X - nextItem.X; int ysub = item.Y - nextItem.Y; if (xsub == 0) { if (ysub > 0) //向南 { insInfo.AddItem(path, insInfo.getWay(direction, DirectionWay.South)); direction = DirectionWay.South; } else //向北 { insInfo.AddItem(path, insInfo.getWay(direction, DirectionWay.North)); direction = DirectionWay.North; } } else if (ysub == 0) { if (xsub > 0) //向西 { insInfo.AddItem(path, insInfo.getWay(direction, DirectionWay.West)); direction = DirectionWay.West; } else //向东 { insInfo.AddItem(path, insInfo.getWay(direction, DirectionWay.Easet)); direction = DirectionWay.Easet; } } } else if (!string.IsNullOrEmpty(path2)) //一期默认货架在右侧,即X正,Y负 { setRouteByRack(insInfo, path2, path, item, rackItem); } } }
/// <summary> /// 计算仓位的转向逻辑 /// </summary> /// <param name="insInfo"></param> /// <param name="nextPathArray"></param> /// <param name="lastPath"></param> /// <param name="item"></param> /// <param name="rackItem"></param> private void setRouteByRack(InstructionInfo insInfo, string nextPathArray, string lastPath, RouteInfo item, RackInfo rackItem) { string[] path2Arr = nextPathArray.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); string next = path2Arr[0]; var nextItem = routelist.Where(a => a.Routecode == next).FirstOrDefault(); int xsub = item.X - nextItem.X; int ysub = item.Y - nextItem.Y; int xrack = 0; int yrack = 0; if (rackItem != null) { xrack = item.X - rackItem.X; yrack = item.Y - rackItem.Y; } if (xsub == 0) { if (ysub > 0) //向南 { if (lastPath == inpackroute || lastPath == outpackroute) { if (direction == DirectionWay.South) { if (xrack > 0) //右手 { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Right); } else { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Left); } } else if (direction == DirectionWay.North) { if (xrack > 0) //左手 { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Right); } else { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Left); } } else if (direction == DirectionWay.West) { insInfo.AddItem(lastPath, TurnWay.Left); //insInfo.AddItem(lastPath, TurnWay.Next); } else { insInfo.AddItem(lastPath, TurnWay.Right); //insInfo.AddItem(lastPath, TurnWay.Next); } } direction = DirectionWay.South; } else //向北 { if (lastPath == inpackroute || lastPath == outpackroute) { if (direction == DirectionWay.South) { if (xrack > 0) //右手 { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Left); } else { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Right); } } else if (direction == DirectionWay.North) { if (xrack > 0) //左手 { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Left); } else { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Right); } } else if (direction == DirectionWay.Easet) { insInfo.AddItem(lastPath, TurnWay.Left); //insInfo.AddItem(lastPath, TurnWay.Next); } else { insInfo.AddItem(lastPath, TurnWay.Right); //insInfo.AddItem(lastPath, TurnWay.Next); } } direction = DirectionWay.North; } } else if (ysub == 0) { if (xsub > 0) //向西 { if (lastPath == inpackroute || lastPath == outpackroute) { if (direction == DirectionWay.South) { insInfo.AddItem(lastPath, TurnWay.Right); //insInfo.AddItem(lastPath, TurnWay.Back); //insInfo.AddItem(lastPath, TurnWay.Left); } else if (direction == DirectionWay.Easet) { if (yrack > 0) //右手 { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Left); } else { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Right); } } else if (direction == DirectionWay.West) { if (yrack > 0) //左手 { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Left); } else { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Right); } } else { insInfo.AddItem(lastPath, TurnWay.Left); //insInfo.AddItem(lastPath, TurnWay.Back); //insInfo.AddItem(lastPath, TurnWay.Right); } } direction = DirectionWay.West; } else //向东 { if (lastPath == inpackroute || lastPath == outpackroute) { if (direction == DirectionWay.South) { insInfo.AddItem(lastPath, TurnWay.Left); //insInfo.AddItem(lastPath, TurnWay.Back); //insInfo.AddItem(lastPath, TurnWay.Right); } else if (direction == DirectionWay.Easet) { if (yrack > 0) //右手 { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Right); } else { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Left); } } else if (direction == DirectionWay.West) { if (yrack > 0) //左手 { insInfo.AddItem(lastPath, TurnWay.Right); insInfo.AddItem(lastPath, TurnWay.Right); } else { insInfo.AddItem(lastPath, TurnWay.Left); insInfo.AddItem(lastPath, TurnWay.Left); } } else { insInfo.AddItem(lastPath, TurnWay.Right); //insInfo.AddItem(lastPath, TurnWay.Back); //insInfo.AddItem(lastPath, TurnWay.Left); } } direction = DirectionWay.Easet; } } }
/// <summary> /// 构造指令地图 /// </summary> /// <param name="iotype">出库入库</param> /// <param name="rackcode1">取货仓位编码</param> /// <param name="rackcode2">卸货仓位编码</param> /// <param name="tuopancode">托盘编码</param> /// <returns></returns> public InstructionInfo SetToMap(InOutType iotype, string rackcode1, string rackcode2, string tuopancode) { initData(); InstructionInfo insInfo = new InstructionInfo(); RackLayerService x_rlService = new RackLayerService(); var rlayer = x_rlService.Get(a => a.RackLayerCode == rackcode1).FirstOrDefault(); if (rlayer != null) { var rkitem = rackList.Single(a => a.Id == rlayer.RackId); insInfo.InPackCode = rkitem.RouteCode; insInfo.InPackLayer = rlayer.RackLayerNum.ToString("x2"); } var rlayer2 = x_rlService.Get(a => a.RackLayerCode == rackcode2).FirstOrDefault(); if (rlayer2 != null) { var rkitem = rackList.Single(a => a.Id == rlayer2.RackId); insInfo.OutPackCode = rkitem.RouteCode; insInfo.OutPackLayer = rlayer2.RackLayerNum.ToString("x2"); } TruckInfo freetruck = getLatestTruck(insInfo.InPackCode); //寻找最近空闲叉车 if (freetruck == null) { insInfo.StatusEnum = InstructionStatus.NoTruck; return(insInfo); } string truckcode = freetruck.Truckcode; string truckcoderoute = freetruck.TruckrouteCode; insInfo.StartCode = insInfo.getStartType(StartType.Start); insInfo.InOut = insInfo.getIOType(iotype); insInfo.TruckCode = truckcode; insInfo.TuopanCode = tuopancode; if (iotype == InOutType.In) { insInfo.RackLayerCode = rackcode2; } else { insInfo.RackLayerCode = rackcode1; } var packList = routelist.Where(a => a.Isstart == 2); TruckService x_tkServic = new TruckService(); var tkList = x_tkServic.Get(a => a.Isvalid == 1 && a.HouseId == HouseId); //排除掉已占用的停车位,还需要排除掉已被规划的停车位 foreach (var item in packList) { foreach (var titem in tkList) { if (titem.TruckrouteCode == item.Routecode) { item.IsValid = 0; } } } foreach (var item in waylist) { var code = item[item.Count - 1].RouteCode; foreach (var pitem in packList) { if (pitem.Routecode == code) { pitem.IsValid = 0; } } } string endroute = ""; var end_item = packList.Where(a => a.IsValid == 1).FirstOrDefault(); if (end_item != null) { endroute = end_item.Routecode; } else { endroute = truckcoderoute; end_item = routelist.Where(a => a.Routecode == endroute).First(); } //开始计算路径 PathMathHelper.InitRouteNodes(nodeDict); PathMathResult result = PathMathHelper.Start(truckcoderoute, insInfo.InPackCode); //取货路径 string path1 = truckcoderoute + result.Path; //取货路径 insInfo.PathList.Add(path1); PathMathHelper.InitRouteNodes(nodeDict); result = PathMathHelper.Start(insInfo.InPackCode, insInfo.OutPackCode); string path2 = result.Path; //卸货路径 insInfo.PathList.Add(path2); PathMathHelper.InitRouteNodes(nodeDict); result = PathMathHelper.Start(insInfo.OutPackCode, endroute); //停车路径 string path3 = result.Path; //停车路径 insInfo.PathList.Add(path3); var rack_item = rackList.Where(a => a.Rackcode == insInfo.InPackCode).FirstOrDefault(); var out_rack_item = rackList.Where(a => a.Rackcode == insInfo.OutPackCode).FirstOrDefault(); ComputePath(insInfo, path1, path2, rack_item); ComputePath(insInfo, path2, path3, out_rack_item); ComputePath(insInfo, path3); //如果终点是停车位,则反转停车位的转向 if (end_item != null && end_item.Isstart == 2) { if (insInfo.RouteWay.Count > 2) { var wayinfo = insInfo.RouteWay.Last(); if (wayinfo.Way == TurnWay.Left) { wayinfo.Way = TurnWay.Right; insInfo.AddItem(wayinfo.RouteCode, TurnWay.Back); } else if (wayinfo.Way == TurnWay.Right) { wayinfo.Way = TurnWay.Left; insInfo.AddItem(wayinfo.RouteCode, TurnWay.Back); } } } insInfo.AddItem(end_item.Routecode, TurnWay.Stop); waylist.Add(insInfo.RouteWay); return(insInfo); }