| | |
| | | public synchronized ShuttleThread searchIdleShuttle(Task task) { |
| | | String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); |
| | | ShuttleThread resThread = null; |
| | | Integer finalDistance = ShuttleDispatcher.INF; |
| | | |
| | | //检测目标楼层车数量是否小于允许的最大数量 |
| | | boolean checkDispatchMaxNum = checkDispatchMaxNum(Utils.getLev(locNo), task.getHostId()); |
| | | |
| | | int lev = Utils.getLev(locNo); |
| | | List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() |
| | | .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()) |
| | | .eq(Device::getHostId, task.getHostId()) |
| | | .eq(Device::getStatus, 1)); |
| | | |
| | | //获取同层小车 |
| | | List<Device> currentLevDevices = new ArrayList<>(); |
| | | //获取跨层小车 |
| | | List<Device> diffLevDevices = new ArrayList<>(); |
| | | for (Device device : list) { |
| | | //获取四向穿梭车线程 |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); |
| | | if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) == lev) { |
| | | currentLevDevices.add(device); |
| | | }else { |
| | | diffLevDevices.add(device); |
| | | } |
| | | } |
| | | //搜索同层 |
| | | resThread = this.searchCurrentLevShuttle(currentLevDevices, locNo); |
| | | |
| | | //同层没有搜索到合适小车,跨楼层搜索 |
| | | if(resThread == null) { |
| | | resThread = this.searchDiffLevShuttle(diffLevDevices, locNo, task); |
| | | } |
| | | |
| | | return resThread; |
| | | } |
| | | |
| | | private synchronized ShuttleThread searchCurrentLevShuttle(List<Device> devices, String locNo) { |
| | | ShuttleThread resThread = null; |
| | | Integer finalDistance = ShuttleDispatcher.INF; |
| | | for (Device device : devices) { |
| | | if (taskService.hasBusyOutboundByShuttle(Integer.parseInt(device.getDeviceNo()))) { |
| | | continue; |
| | | } |
| | |
| | | break; |
| | | } |
| | | |
| | | String targetLocNo = null;//默认到提升机待机位 |
| | | // 同楼层直接计算到目标库位 |
| | | if (currentLev == Utils.getLev(locNo)) { |
| | | targetLocNo = locNo; |
| | | }else { |
| | | if (!checkDispatchMaxNum) { |
| | | News.info("{}任务,{}层,已经达到当前楼层调度车辆最大值", task.getTaskNo(), Utils.getLev(locNo)); |
| | | continue; |
| | | } |
| | | |
| | | //获取距离目标位置最近的空闲可换层提升机 |
| | | LiftThread liftThread = liftDispatcher.searchIdleLift(locNo, 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)); |
| | | targetLocNo = shuttleStandby.getDeviceLoc(); |
| | | //当前穿梭车线程到当前车子所在楼层的目标库位距离 |
| | | List<NavigateNode> currentShuttlePath = NavigateUtils.calc( |
| | | currentLocNo |
| | | , locNo |
| | | , NavigationMapType.NORMAL.id |
| | | , Utils.getShuttlePoints(Integer.parseInt(shuttleThread.getDevice().getDeviceNo()), currentLev) |
| | | );//搜索空闲穿梭车,使用正常通道地图 |
| | | if (currentShuttlePath == null) { |
| | | continue; |
| | | } |
| | | |
| | | //当前穿梭车线程到当前车子所在楼层的提升机口距离 |
| | | Integer currDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离 |
| | | |
| | | // 挂载任务权重 |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | return resThread; |
| | | } |
| | | |
| | | private synchronized ShuttleThread searchDiffLevShuttle(List<Device> devices, 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; |
| | | } |
| | | |
| | | 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;//小车基础数据不存在 |
| | | } |
| | | |
| | | 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 |
| | |
| | | return false; |
| | | } |
| | | |
| | | int levCount = 0;//目标楼层车辆数量 |
| | | ArrayList<Integer> shuttleNos = new ArrayList<>(); |
| | | List<Device> list = deviceService.list(new LambdaQueryWrapper<Device>() |
| | | .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()) |
| | | .eq(Device::getHostId, hostId) |
| | |
| | | continue;//充电中 |
| | | } |
| | | |
| | | levCount++;//目标楼层有车,数量增加 |
| | | shuttleNos.add(shuttleProtocol.getShuttleNo());//目标楼层有车,添加进list |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | if (targetLev == lev) { |
| | | levCount++;//工作档目标楼层和实际楼层相同,数量增加 |
| | | //工作档目标楼层和实际楼层相同,数量增加 |
| | | if (!shuttleNos.contains(task.getShuttleNo())) { |
| | | shuttleNos.add(task.getShuttleNo()); |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | } |
| | | |
| | | //搜索是否存在前往目标楼层的小车工作档 |
| | | for (Task task : taskService.list(new LambdaQueryWrapper<Task>() |
| | | .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts, TaskStsType.ANALYZE_INBOUND.sts, TaskStsType.EXECUTE_INBOUND.sts, TaskStsType.COMPLETE_INBOUND.sts |
| | | , TaskStsType.NEW_OUTBOUND.sts, TaskStsType.ANALYZE_OUTBOUND.sts, TaskStsType.EXECUTE_OUTBOUND.sts, TaskStsType.COMPLETE_OUTBOUND.sts))) { |
| | | |
| | | List<Motion> motions = motionService.list(new LambdaQueryWrapper<Motion>() |
| | | .eq(Motion::getTaskNo, task.getTaskNo()) |
| | | .in(Motion::getMotionCtg, MotionCtgType.SHUTTLE_MOVE |
| | | , MotionCtgType.SHUTTLE_MOVE_LIFT_PALLET |
| | | , MotionCtgType.SHUTTLE_MOVE_DOWN_PALLET |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT |
| | | , MotionCtgType.SHUTTLE_MOVE_TO_LIFT |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_CONVEYOR |
| | | , MotionCtgType.SHUTTLE_MOVE_TO_CONVEYOR |
| | | , MotionCtgType.SHUTTLE_MOVE_FROM_LIFT_TO_CONVEYOR |
| | | )); |
| | | |
| | | boolean isUpdateLev = false; |
| | | for (Motion motion : motions) { |
| | | if (motion.getOrigin() == null || motion.getTarget() == null) { |
| | | continue; |
| | | } |
| | | |
| | | int sourceLev = Utils.getLev(motion.getOrigin());//动作源楼层 |
| | | int targetLev = Utils.getLev(motion.getTarget());//动作目标楼层 |
| | | if (sourceLev != targetLev) { |
| | | isUpdateLev = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if(isUpdateLev) { |
| | | levCount++;//工作档属于跨层任务,小车归属于目标楼层 |
| | | String locNo = taskService.judgeInbound(task) ? task.getDestLoc() : task.getOriginLoc(); |
| | | if (Utils.getLev(locNo) != lev) { |
| | | continue; |
| | | } |
| | | |
| | | if (task.getShuttleNo() == null) { |
| | | continue; |
| | | } |
| | | |
| | | if (!shuttleNos.contains(task.getShuttleNo())) { |
| | | shuttleNos.add(task.getShuttleNo()); |
| | | } |
| | | } |
| | | |
| | | |
| | | return levCount < Integer.parseInt(dict.getValue()); |
| | | return shuttleNos.size() < Integer.parseInt(dict.getValue()); |
| | | } |
| | | |
| | | //分析出库路径待机库位 |