|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); | 
|---|
|  |  |  | NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); | 
|---|
|  |  |  | if (shuttleThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | if (shuttleProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); | 
|---|
|  |  |  | NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); | 
|---|
|  |  |  | if (shuttleThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | if (shuttleProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 搜索空闲且最近的四向穿梭车(以工作档目标库位为基点计算最近且空闲的车) | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public HashMap<String,Object> searchIdleShuttle(WrkMast wrkMast) { | 
|---|
|  |  |  | HashMap<String, Object> map = new HashMap<>(); | 
|---|
|  |  |  | String locNo = wrkMast.getIoType() < 101 ? wrkMast.getLocNo() : wrkMast.getSourceLocNo();//库位号 | 
|---|
|  |  |  | LocMast locMast = locMastService.queryByLoc(locNo);//找到库位记录 | 
|---|
|  |  |  | int lev = Utils.getLev(locNo);//当前工作档库位层高 | 
|---|
|  |  |  | ShuttleThread recentShuttle = null;//当前距离最近的四向穿梭车线程 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ArrayList<ShuttleThread> sameLev = new ArrayList<>();//相同楼层的穿梭车 | 
|---|
|  |  |  | ArrayList<ShuttleThread> diffLev = new ArrayList<>();//不同楼层的穿梭车 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //判断其他空闲穿梭车是否离任务最近 | 
|---|
|  |  |  | String distLocNo = null;//目标地点,入库=》提升机口,出库=》货物库位号 | 
|---|
|  |  |  | if (wrkMast.getIoType() < 101 && wrkMast.getIoType() != 11) { | 
|---|
|  |  |  | //入库 | 
|---|
|  |  |  | distLocNo = Utils.levToOutInStaLocNo(lev); | 
|---|
|  |  |  | }else if(wrkMast.getIoType() >= 101){ | 
|---|
|  |  |  | //出库 | 
|---|
|  |  |  | distLocNo = locNo; | 
|---|
|  |  |  | } else if (wrkMast.getIoType() == 11) { | 
|---|
|  |  |  | //库位移转 | 
|---|
|  |  |  | distLocNo = wrkMast.getSourceLocNo(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //判断当前任务所在楼层是否有其他任务已经分配了小车,如有则直接用该小车(一层楼仅分配一台车) | 
|---|
|  |  |  | List<WrkMast> wrkMasts = wrkMastService.selectShuttleWrkByLev(lev);//判断当前穿梭车楼层是否已有分配车辆的任务,如果有则分配这辆车 | 
|---|
|  |  |  | if (wrkMasts.size() > 0) { | 
|---|
|  |  |  | //存在其他任务,分配这辆车 | 
|---|
|  |  |  | WrkMast wrkMast1 = wrkMasts.get(0); | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast1.getShuttleNo()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | map.put("sameLay", true);//同层 | 
|---|
|  |  |  | map.put("result", shuttleThread); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (ShuttleSlave shuttle : slaveProperties.getShuttle()) { | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId()); | 
|---|
|  |  |  | ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!shuttleProtocol.isIdle()) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String shuttleLocNo = shuttleProtocol.getCurrentLocNo();//二维码对应库位号 | 
|---|
|  |  |  | if (shuttleLocNo == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (shuttleLocNo.equals(distLocNo)) { | 
|---|
|  |  |  | //车辆当前位置已经是目标库位,无需计算 | 
|---|
|  |  |  | map.put("sameLay", true);//同层 | 
|---|
|  |  |  | map.put("result", shuttleThread); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int shuttleLocNoLey = Utils.getLev(shuttleLocNo);//库位号对应层高 | 
|---|
|  |  |  | if (lev == shuttleLocNoLey) { | 
|---|
|  |  |  | //工作档楼层相同的穿梭车 | 
|---|
|  |  |  | sameLev.add(shuttleThread); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | //工作档不同楼层的穿梭车 | 
|---|
|  |  |  | diffLev.add(shuttleThread); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer recentAllDistance = 9999999; | 
|---|
|  |  |  | if (sameLev.size() > 0) { | 
|---|
|  |  |  | //同一楼层有空闲穿梭车,则只在工作档楼层寻找 | 
|---|
|  |  |  | //寻找离任务最近的穿梭车 | 
|---|
|  |  |  | for (ShuttleThread shuttleThread : sameLev) { | 
|---|
|  |  |  | //当前穿梭车库位号 | 
|---|
|  |  |  | String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo(); | 
|---|
|  |  |  | //当前穿梭车线程到目标地点距离 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, distLocNo, NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(currentLocNo)));//搜索空闲穿梭车,使用正常通道地图 | 
|---|
|  |  |  | if (currentShuttlePath == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  | if (currentAllDistance < recentAllDistance) { | 
|---|
|  |  |  | //如果当前楼层的车路径更小,则更新最近穿梭车 | 
|---|
|  |  |  | recentShuttle = shuttleThread; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | map.put("sameLay", true);//同层 | 
|---|
|  |  |  | map.put("result", recentShuttle); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | //同一楼层,没有空闲穿梭车,只能从其他楼层调度 | 
|---|
|  |  |  | //寻找离任务最近的穿梭车 | 
|---|
|  |  |  | for (ShuttleThread shuttleThread : diffLev) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //当前穿梭车库位号 | 
|---|
|  |  |  | String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo(); | 
|---|
|  |  |  | int currentLev = Utils.getLev(currentLocNo); | 
|---|
|  |  |  | List<WrkMast> wrkMasts1 = wrkMastService.selectNoShuttleWrkByLev(currentLev);//判断当前穿梭车楼层是否有待分配车辆的任务,如果有则不分配这辆车 | 
|---|
|  |  |  | if (wrkMasts1.size() > 0) { | 
|---|
|  |  |  | //存在其他任务,跳过这辆车 | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //当前穿梭车线程到当前车子所在楼层的提升机口距离 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, Utils.levToOutInStaLocNo(currentLev), NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), currentLev));//搜索空闲穿梭车,使用正常通道地图 | 
|---|
|  |  |  | if (currentShuttlePath == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  | if (currentAllDistance < recentAllDistance) { | 
|---|
|  |  |  | //如果当前楼层的车路径更小,则更新最近穿梭车 | 
|---|
|  |  |  | recentShuttle = shuttleThread; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | map.put("sameLay", false);//不同层 | 
|---|
|  |  |  | map.put("result", recentShuttle); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | //查询库位移转工作档 | 
|---|
|  |  |  | List<WrkMast> wrkMasts1 = wrkMastMapper.selectLocToLocWrkMast(); | 
|---|
|  |  |  | for (WrkMast wrkMast : wrkMasts1) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | boolean step1 = this.locToLocExecuteStep1(wrkMast);//绑定小车 | 
|---|
|  |  |  | boolean step1 = this.locToLocExecuteStep1(wrkMast);//库位移转 | 
|---|
|  |  |  | if (!step1) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 绑定小车并调度车 | 
|---|
|  |  |  | * 库位移转 | 
|---|
|  |  |  | * 如需主方法执行continue,请返回false | 
|---|
|  |  |  | * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private boolean locToLocExecuteStep1(WrkMast wrkMast) { | 
|---|
|  |  |  | if (wrkMast.getShuttleNo() == null) {//给库位移转绑定穿梭车号 | 
|---|
|  |  |  | //寻找最近且空闲的四向穿梭车 | 
|---|
|  |  |  | HashMap<String,Object> searchIdleShuttle = this.searchIdleShuttle(wrkMast); | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) searchIdleShuttle.get("result"); | 
|---|
|  |  |  | if (shuttleThread == null) { | 
|---|
|  |  |  | //没有找到空闲穿梭车 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | wrkMast.setShuttleNo(shuttleThread.getSlave().getId());//给工作档分配四向穿梭车号 | 
|---|
|  |  |  | wrkMastMapper.updateById(wrkMast); | 
|---|
|  |  |  | if (wrkMast.getShuttleNo() == null) { | 
|---|
|  |  |  | shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//调度小车到源库位进行取货 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); | 
|---|
|  |  |  | if (shuttleThread == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); | 
|---|
|  |  |  | if (shuttleProtocol == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!shuttleProtocol.isIdle()) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //判断小车是否到达源库位 | 
|---|
|  |  |  | if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) { | 
|---|
|  |  |  | //小车不在源库位位置 | 
|---|
|  |  |  | shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo());//调度小车到源库位进行取货 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //小车已抵达源库位,进行搬运货物 | 
|---|
|  |  |  | NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), wrkMast.getLocNo()); | 
|---|
|  |  |  | if (result == null) {//路径计算失败 | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //创建分配命令 | 
|---|
|  |  |  | ShuttleAssignCommand assignCommand = new ShuttleAssignCommand(); | 
|---|
|  |  |  | assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号 | 
|---|
|  |  |  | assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号 | 
|---|
|  |  |  | assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入库模式 | 
|---|
|  |  |  | assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位(小车当前位置) | 
|---|
|  |  |  | assignCommand.setCommands(result.getCommands());//运行命令 | 
|---|
|  |  |  | assignCommand.setNodes(result.getNodes());//路径节点 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | wrkMast.setWrkSts(5L);//1.生成入库任务 => 5.小车搬运中 | 
|---|
|  |  |  | wrkMast.setModiTime(new Date()); | 
|---|
|  |  |  | if (wrkMastMapper.updateById(wrkMast) > 0) { | 
|---|
|  |  |  | //下发任务 | 
|---|
|  |  |  | MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|