|  |  |  | 
|---|
|  |  |  | private ShuttleStandbyService shuttleStandbyService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private DictService dictService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private NavigateUtils navigateUtils; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public synchronized ShuttleThread searchIdleShuttle(Task task) { | 
|---|
|  |  |  | String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); | 
|---|
|  |  |  | 
|---|
|  |  |  | //获取同层小车 | 
|---|
|  |  |  | List<Device> currentLevDevices = new ArrayList<>(); | 
|---|
|  |  |  | //获取跨层小车 | 
|---|
|  |  |  | List<Device> diffLevDevices = new ArrayList<>(); | 
|---|
|  |  |  | HashMap<Integer,List<Device>> diffLevDeviceMap = new HashMap<>(); | 
|---|
|  |  |  | for (Device device : list) { | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|---|
|  |  |  | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) == lev) { | 
|---|
|  |  |  | int shuttleLev = Utils.getLev(shuttleProtocol.getCurrentLocNo()); | 
|---|
|  |  |  | if (shuttleLev == lev) { | 
|---|
|  |  |  | currentLevDevices.add(device); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | diffLevDevices.add(device); | 
|---|
|  |  |  | List<Device> devices = null; | 
|---|
|  |  |  | if(diffLevDeviceMap.containsKey(shuttleLev)) { | 
|---|
|  |  |  | devices = diffLevDeviceMap.get(shuttleLev); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | devices = new ArrayList<>(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | devices.add(device); | 
|---|
|  |  |  | diffLevDeviceMap.put(shuttleLev, devices); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //搜索同层 | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //同层没有搜索到合适小车,跨楼层搜索 | 
|---|
|  |  |  | if(resThread == null) { | 
|---|
|  |  |  | resThread = this.searchDiffLevShuttle(diffLevDevices, locNo, task); | 
|---|
|  |  |  | resThread = this.searchDiffLevShuttle(diffLevDeviceMap, locNo, task); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return resThread; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 同楼层直接计算到目标库位 | 
|---|
|  |  |  | //当前穿梭车线程到当前车子所在楼层的目标库位距离 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = NavigateUtils.calc( | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = navigateUtils.calc( | 
|---|
|  |  |  | currentLocNo | 
|---|
|  |  |  | , locNo | 
|---|
|  |  |  | , NavigationMapType.NORMAL.id | 
|---|
|  |  |  | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  | Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 挂载任务权重 | 
|---|
|  |  |  | List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null); | 
|---|
|  |  |  | 
|---|
|  |  |  | return resThread; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private synchronized ShuttleThread searchDiffLevShuttle(List<Device> devices, String locNo, Task task) { | 
|---|
|  |  |  | private synchronized ShuttleThread searchDiffLevShuttle(HashMap<Integer,List<Device>> devicesMap, String locNo, Task task) { | 
|---|
|  |  |  | ShuttleThread resThread = null; | 
|---|
|  |  |  | Integer finalDistance = ShuttleDispatcher.INF; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检测目标楼层车数量是否小于允许的最大数量 | 
|---|
|  |  |  | boolean checkDispatchMaxNum = checkDispatchMaxNum(Utils.getLev(locNo), task.getHostId()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | for (Device device : devices) { | 
|---|
|  |  |  | if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|---|
|  |  |  | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); | 
|---|
|  |  |  | if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | for (Map.Entry<Integer, List<Device>> entry : devicesMap.entrySet()) { | 
|---|
|  |  |  | Integer lev = entry.getKey(); | 
|---|
|  |  |  | List<Device> devices = entry.getValue(); | 
|---|
|  |  |  | for (Device device : devices) { | 
|---|
|  |  |  | if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //获取四向穿梭车线程 | 
|---|
|  |  |  | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); | 
|---|
|  |  |  | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); | 
|---|
|  |  |  | if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!shuttleThread.isIdle()) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (!shuttleThread.isIdle()) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>() | 
|---|
|  |  |  | .eq(BasShuttle::getShuttleNo, device.getDeviceNo()) | 
|---|
|  |  |  | .eq(BasShuttle::getHostId, device.getHostId())); | 
|---|
|  |  |  | if (basShuttle == null) { | 
|---|
|  |  |  | continue;//小车基础数据不存在 | 
|---|
|  |  |  | } | 
|---|
|  |  |  | BasShuttle basShuttle = basShuttleService.getOne(new LambdaQueryWrapper<BasShuttle>() | 
|---|
|  |  |  | .eq(BasShuttle::getShuttleNo, device.getDeviceNo()) | 
|---|
|  |  |  | .eq(BasShuttle::getHostId, device.getHostId())); | 
|---|
|  |  |  | if (basShuttle == null) { | 
|---|
|  |  |  | continue;//小车基础数据不存在 | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(basShuttle.getDisableLev())) { | 
|---|
|  |  |  | List<Integer> disableLev = JSON.parseArray(basShuttle.getDisableLev(), Integer.class); | 
|---|
|  |  |  | //检查小车是否禁用该楼层 | 
|---|
|  |  |  | if (disableLev.contains(Utils.getLev(locNo))) { | 
|---|
|  |  |  | continue;//小车禁用该楼层跳过该车 | 
|---|
|  |  |  | if (!Cools.isEmpty(basShuttle.getDisableLev())) { | 
|---|
|  |  |  | List<Integer> disableLev = JSON.parseArray(basShuttle.getDisableLev(), Integer.class); | 
|---|
|  |  |  | //检查小车是否禁用该楼层 | 
|---|
|  |  |  | if (disableLev.contains(Utils.getLev(locNo))) { | 
|---|
|  |  |  | continue;//小车禁用该楼层跳过该车 | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检测是否存在充电任务 | 
|---|
|  |  |  | Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo())); | 
|---|
|  |  |  | if (taskCharge != null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 有没有被其他任务调度 | 
|---|
|  |  |  | int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高 | 
|---|
|  |  |  | String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!checkDispatchMaxNum) { | 
|---|
|  |  |  | News.info("{}任务,{}层,已经达到当前楼层调度车辆最大值", task.getTaskNo(), Utils.getLev(locNo)); | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取距离小车位置最近的空闲可换层提升机 | 
|---|
|  |  |  | LiftThread liftThread = liftDispatcher.searchIdleLift(currentLocNo, task.getHostId(), true); | 
|---|
|  |  |  | if (liftThread == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Device recentTransferLift = liftThread.getDevice(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取小车楼层提升机待机位 | 
|---|
|  |  |  | ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|---|
|  |  |  | .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId()) | 
|---|
|  |  |  | .eq(ShuttleStandby::getDeviceLev, currentLev) | 
|---|
|  |  |  | .eq(ShuttleStandby::getStatus, 1)); | 
|---|
|  |  |  | String targetLocNo = shuttleStandby.getDeviceLoc(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //当前穿梭车线程到当前车子所在楼层的提升机待机位距离 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = navigateUtils.calc( | 
|---|
|  |  |  | currentLocNo | 
|---|
|  |  |  | , targetLocNo | 
|---|
|  |  |  | , NavigationMapType.NORMAL.id | 
|---|
|  |  |  | , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev) | 
|---|
|  |  |  | );//搜索空闲穿梭车,使用正常通道地图 | 
|---|
|  |  |  | if (currentShuttlePath == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 不同楼层权重 | 
|---|
|  |  |  | if (currentLev != Utils.getLev(locNo)) { | 
|---|
|  |  |  | currDistance += WEIGHT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 挂载任务权重 | 
|---|
|  |  |  | List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null); | 
|---|
|  |  |  | if (!Cools.isEmpty(tasks)) { | 
|---|
|  |  |  | currDistance += tasks.size() * WEIGHT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (currDistance < finalDistance) { | 
|---|
|  |  |  | finalDistance = currDistance; | 
|---|
|  |  |  | resThread = shuttleThread; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //检测是否存在充电任务 | 
|---|
|  |  |  | Task taskCharge = taskService.selectChargeWorking(Integer.valueOf(device.getDeviceNo())); | 
|---|
|  |  |  | if (taskCharge != null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 有没有被其他任务调度 | 
|---|
|  |  |  | int currentLev = Utils.getLev(shuttleProtocol.getCurrentLocNo());//小车当前层高 | 
|---|
|  |  |  | String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!checkDispatchMaxNum) { | 
|---|
|  |  |  | News.info("{}任务,{}层,已经达到当前楼层调度车辆最大值", task.getTaskNo(), Utils.getLev(locNo)); | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取距离小车位置最近的空闲可换层提升机 | 
|---|
|  |  |  | LiftThread liftThread = liftDispatcher.searchIdleLift(currentLocNo, task.getHostId(), true); | 
|---|
|  |  |  | if (liftThread == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Device recentTransferLift = liftThread.getDevice(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //获取小车楼层提升机待机位 | 
|---|
|  |  |  | ShuttleStandby shuttleStandby = shuttleStandbyService.getOne(new LambdaQueryWrapper<ShuttleStandby>() | 
|---|
|  |  |  | .eq(ShuttleStandby::getDeviceId, recentTransferLift.getId()) | 
|---|
|  |  |  | .eq(ShuttleStandby::getDeviceLev, currentLev) | 
|---|
|  |  |  | .eq(ShuttleStandby::getStatus, 1)); | 
|---|
|  |  |  | String targetLocNo = shuttleStandby.getDeviceLoc(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //当前穿梭车线程到当前车子所在楼层的提升机待机位距离 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = NavigateUtils.calc( | 
|---|
|  |  |  | currentLocNo | 
|---|
|  |  |  | , targetLocNo | 
|---|
|  |  |  | , NavigationMapType.NORMAL.id | 
|---|
|  |  |  | , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev) | 
|---|
|  |  |  | );//搜索空闲穿梭车,使用正常通道地图 | 
|---|
|  |  |  | if (currentShuttlePath == null) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 不同楼层权重 | 
|---|
|  |  |  | if (currentLev != Utils.getLev(locNo)) { | 
|---|
|  |  |  | currDistance += WEIGHT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 挂载任务权重 | 
|---|
|  |  |  | List<Task> tasks = taskService.selectWorkingByShuttle(Integer.valueOf(device.getDeviceNo()), null); | 
|---|
|  |  |  | if (!Cools.isEmpty(tasks)) { | 
|---|
|  |  |  | currDistance += tasks.size() * WEIGHT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (currDistance < finalDistance) { | 
|---|
|  |  |  | finalDistance = currDistance; | 
|---|
|  |  |  | resThread = shuttleThread; | 
|---|
|  |  |  | if (resThread != null) { | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return resThread; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | String recentLoc = null; | 
|---|
|  |  |  | for (String loc : locNos) { | 
|---|
|  |  |  | //当前穿梭车到避让位计算 | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = NavigateUtils.calc( | 
|---|
|  |  |  | List<NavigateNode> currentShuttlePath = navigateUtils.calc( | 
|---|
|  |  |  | currentLocNo | 
|---|
|  |  |  | , loc | 
|---|
|  |  |  | , NavigationMapType.NORMAL.id | 
|---|
|  |  |  | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  | Integer currDistance = navigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 | 
|---|
|  |  |  | if (currDistance < finalDistance) { | 
|---|
|  |  |  | finalDistance = currDistance; | 
|---|
|  |  |  | recentLoc = loc; | 
|---|
|  |  |  | 
|---|
|  |  |  | //分析出库路径待机库位 | 
|---|
|  |  |  | public String analyzeOutPathWaitLoc(String startLoc, String targetLoc, Device shuttleDevice) { | 
|---|
|  |  |  | //计算路径并分解成两段动作 | 
|---|
|  |  |  | List<NavigateNode> nodeList = NavigateUtils.calc(startLoc, targetLoc, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(startLoc))); | 
|---|
|  |  |  | List<NavigateNode> nodeList = navigateUtils.calc(startLoc, targetLoc, NavigationMapType.DFX.id, Utils.getShuttlePoints(Integer.parseInt(shuttleDevice.getDeviceNo()), Utils.getLev(startLoc))); | 
|---|
|  |  |  | if (nodeList == null) { | 
|---|
|  |  |  | News.error("{} dash {} can't find navigate path!", startLoc, targetLoc); | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //获取分段路径 | 
|---|
|  |  |  | ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodeList); | 
|---|
|  |  |  | ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodeList); | 
|---|
|  |  |  | if (data.size() <= 1) { | 
|---|
|  |  |  | return startLoc;//两点之间只有一段路径,在起点位置等待 | 
|---|
|  |  |  | } | 
|---|