| | |
| | | return true; |
| | | } |
| | | |
| | | //获取起点-终点指令 |
| | | public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String locNo, Integer mapType, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) { |
| | | //获取小车移动速度 |
| | | BasShuttle basShuttle = basShuttleService.selectById(assignCommand.getShuttleNo()); |
| | | Integer runSpeed = 1000; |
| | | // if (basShuttle != null) { |
| | | // Integer runSpeed1 = basShuttle.getRunSpeed(); |
| | | // if (runSpeed1 != null) { |
| | | // runSpeed = runSpeed1; |
| | | // } |
| | | // } |
| | | |
| | | //计算小车起点到中点所需命令 |
| | | List<NavigateNode> calc = NavigateUtils.calc(startLocNo, locNo, mapType, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(startLocNo))); |
| | | List<ShuttleCommand> commands = new ArrayList<>(); |
| | | if (calc == null) { |
| | | return null; |
| | | } |
| | | if (!Utils.checkShuttlePath(calc, shuttleThread.getSlave().getId())) {//检测穿梭车行走路径,是否存在其他小车,如有其他小车则进行调离 |
| | | return null; |
| | | } |
| | | List<NavigateNode> allNode = new ArrayList<>(); |
| | | allNode.addAll(calc); |
| | | |
| | | //获取分段路径 |
| | | ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc); |
| | | //将每一段路径分成command指令 |
| | | for (ArrayList<NavigateNode> nodes : data) { |
| | | //开始路径 |
| | | NavigateNode startPath = nodes.get(0); |
| | | |
| | | //中间路径 |
| | | NavigateNode middlePath = null; |
| | | //通过xy坐标小车二维码 |
| | | Short middleCodeNum = null; |
| | | Integer middleToDistDistance = null;//计算中间点到目标点行走距离 |
| | | if (nodes.size() > 10) {//中段码传倒数第三个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 3); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } else if (nodes.size() > 5) {//中段码传倒数第二个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 2); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } |
| | | |
| | | //目标路径 |
| | | NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | | //通过xy坐标小车二维码 |
| | | Short startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ()); |
| | | //通过xy坐标小车二维码 |
| | | Short distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ()); |
| | | //获取移动命令 |
| | | ShuttleCommand command = shuttleThread.getMoveCommand(startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCodeNum, middleToDistDistance, runSpeed); |
| | | commands.add(command); |
| | | } |
| | | |
| | | assignCommand.setNodes(allNode);//当前任务所占用的节点list |
| | | //所使用的路径进行锁定禁用 |
| | | NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(startLocNo)); |
| | | navigateMapData.writeNavigateNodeToRedisMap(allNode, true);////所使用的路径进行锁定禁用 |
| | | |
| | | return commands; |
| | | } |
| | | |
| | | //获取起点-中点-终点指令 |
| | | public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String middleLocNo, String locNo, ShuttleAssignCommand assignCommand, ShuttleThread shuttleThread) { |
| | | //获取小车移动速度 |
| | | BasShuttle basShuttle = basShuttleService.selectById(assignCommand.getShuttleNo()); |
| | | Integer runSpeed = 1000; |
| | | // if (basShuttle != null) { |
| | | // Integer runSpeed1 = basShuttle.getRunSpeed(); |
| | | // if (runSpeed1 != null) { |
| | | // runSpeed = runSpeed1; |
| | | // } |
| | | // } |
| | | |
| | | List<NavigateNode> allNode = new ArrayList<>(); |
| | | |
| | | //计算小车起点到中点所需命令 |
| | | List<NavigateNode> calc = NavigateUtils.calc(startLocNo, middleLocNo, NavigationMapType.NORMAL.id, null);//小车无货,走正常库位通道 |
| | | List<ShuttleCommand> commands = new ArrayList<>(); |
| | | |
| | | if (calc != null) { |
| | | if (!Utils.checkShuttlePath(calc, shuttleThread.getSlave().getId())) {//检测穿梭车行走路径,是否存在其他小车,如有其他小车则进行调离 |
| | | return null; |
| | | } |
| | | |
| | | allNode.addAll(calc); |
| | | //获取分段路径 |
| | | ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc); |
| | | //将每一段路径分成command指令 |
| | | for (ArrayList<NavigateNode> nodes : data) { |
| | | //开始路径 |
| | | NavigateNode startPath = nodes.get(0); |
| | | |
| | | //中间路径 |
| | | NavigateNode middlePath = null; |
| | | //通过xy坐标小车二维码 |
| | | Short middleCodeNum = null; |
| | | Integer middleToDistDistance = null;//计算中间点到目标点行走距离 |
| | | if (nodes.size() > 10) {//中段码传倒数第三个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 3); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } else if (nodes.size() > 5) {//中段码传倒数第二个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 2); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } |
| | | |
| | | //目标路径 |
| | | NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | | |
| | | //通过xy坐标小车二维码 |
| | | Short startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ()); |
| | | //通过xy坐标小车二维码 |
| | | Short distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ()); |
| | | //获取移动命令 |
| | | ShuttleCommand command = shuttleThread.getMoveCommand(startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCodeNum, middleToDistDistance, runSpeed); |
| | | commands.add(command); |
| | | } |
| | | } |
| | | |
| | | //小车指令到达目标位置后,再发出一条顶升指令 |
| | | commands.add(shuttleThread.getPalletCommand((short) 1)); |
| | | |
| | | //计算小车中点到终点所需命令 |
| | | List<NavigateNode> calc2 = NavigateUtils.calc(middleLocNo, locNo, NavigationMapType.DFX.id, null);//小车有货,走禁用过DFX库位的地图通道 |
| | | if (calc2 == null) { |
| | | return null; |
| | | } |
| | | if (!Utils.checkShuttlePath(calc2, shuttleThread.getSlave().getId())) {//检测穿梭车行走路径,是否存在其他小车,如有其他小车则进行调离 |
| | | return null; |
| | | } |
| | | allNode.addAll(calc2); |
| | | |
| | | //获取分段路径 |
| | | ArrayList<ArrayList<NavigateNode>> data2 = NavigateUtils.getSectionPath(calc2); |
| | | for (ArrayList<NavigateNode> nodes : data2) { |
| | | //开始路径 |
| | | NavigateNode startPath = nodes.get(0); |
| | | |
| | | //中间路径 |
| | | NavigateNode middlePath = null; |
| | | //通过xy坐标小车二维码 |
| | | Short middleCodeNum = null; |
| | | Integer middleToDistDistance = null;//计算中间点到目标点行走距离 |
| | | if (nodes.size() > 10) {//中段码传倒数第三个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 3); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } else if (nodes.size() > 5) {//中段码传倒数第二个 |
| | | //中间路径 |
| | | middlePath = nodes.get(nodes.size() - 2); |
| | | //通过xy坐标小车二维码 |
| | | middleCodeNum = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ()); |
| | | middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 |
| | | } |
| | | |
| | | //目标路径 |
| | | NavigateNode endPath = nodes.get(nodes.size() - 1); |
| | | Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 |
| | | |
| | | //通过xy坐标小车二维码 |
| | | Short startCodeNum = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ()); |
| | | //通过xy坐标小车二维码 |
| | | Short distCodeNum = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ()); |
| | | ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCodeNum, distCodeNum, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCodeNum, middleToDistDistance, runSpeed); |
| | | commands.add(moveCommand); |
| | | } |
| | | |
| | | //小车指令到达目标位置后,再发出一条托盘下降指令 |
| | | commands.add(shuttleThread.getPalletCommand((short) 2)); |
| | | |
| | | assignCommand.setNodes(allNode);//当前任务所占用的节点list |
| | | //所使用的路径进行锁定禁用 |
| | | NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(startLocNo)); |
| | | navigateMapData.writeNavigateNodeToRedisMap(allNode, true);////所使用的路径进行锁定禁用 |
| | | |
| | | return commands; |
| | | } |
| | | |
| | | /** |
| | | * 出库 ===>> 四向穿梭车出库作业下发 |
| | | */ |
| | |
| | | continue; |
| | | } |
| | | |
| | | boolean step2 = this.locToLocExecuteStep2(wrkMast);//调度小车到目标楼层 |
| | | if (!step2) { |
| | | continue; |
| | | } |
| | | |
| | | boolean step3 = this.locToLocExecuteStep3(wrkMast);//同楼层库位移转 |
| | | if (!step3) { |
| | | continue; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | wrkMast.setShuttleNo(shuttleThread.getSlave().getId());//给工作档分配四向穿梭车号 |
| | | wrkMastMapper.updateById(wrkMast); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 调度小车到目标楼层 |
| | | * 如需主方法执行continue,请返回false |
| | | * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue |
| | | */ |
| | | private boolean locToLocExecuteStep2(WrkMast wrkMast) { |
| | | if (wrkMast.getWrkSts() == 1 && wrkMast.getShuttleNo() != null) { |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); |
| | | if (!shuttleProtocol.isIdle(wrkMast.getWrkNo().shortValue())) { |
| | | return false;//小车处于不空闲状态 |
| | | } |
| | | |
| | | String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 |
| | | int shuttleLev = Utils.getLev(currentLocNo);//小车所在楼层 |
| | | |
| | | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); |
| | | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); |
| | | |
| | | //判断小车是否再目标楼层 |
| | | if (shuttleLev != Utils.getLev(wrkMast.getLocNo())) { |
| | | //小车和目标不在同一楼层 |
| | | |
| | | //提升机口站点库位号 |
| | | String liftSiteLocNo = Utils.levToOutInStaLocNo(shuttleLev); |
| | | |
| | | //创建分配命令 |
| | | ShuttleAssignCommand assignCommand = new ShuttleAssignCommand(); |
| | | assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号 |
| | | assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号 |
| | | assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入出库模式 |
| | | assignCommand.setSourceLocNo(currentLocNo);//源库位(小车当前位置) |
| | | |
| | | //小车移动到提升机口,计算路径 |
| | | List<ShuttleCommand> commands = this.shuttleAssignCommand(shuttleProtocol.getLocNo(), liftSiteLocNo, NavigationMapType.NONE.id, assignCommand, shuttleThread); |
| | | if (commands == null) { |
| | | return false;//未找到路径 |
| | | } |
| | | |
| | | //获取当前小车所在楼层的站点信息 |
| | | BasDevp basDevp = basDevpService.queryByLocNo(liftSiteLocNo); |
| | | Short endStartCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码 |
| | | |
| | | // //增加移动进提升机命令 |
| | | // ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, 500); |
| | | // commands.add(moveCommand); |
| | | |
| | | //分配目标库位 |
| | | shuttleProtocol.setLocNo(liftSiteLocNo); |
| | | //目标库位 |
| | | assignCommand.setLocNo(liftSiteLocNo); |
| | | // assignCommand.setCommands(commands); |
| | | wrkMast.setWrkSts(5L);//小车迁移状态 |
| | | |
| | | if (wrkMastMapper.updateById(wrkMast) > 0) { |
| | | //下发任务 |
| | | MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand)); |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 同楼层库位移转 |
| | | * 如需主方法执行continue,请返回false |
| | | * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue |
| | | */ |
| | | private boolean locToLocExecuteStep3(WrkMast wrkMast) { |
| | | if (wrkMast.getShuttleNo() == null) { |
| | | return false; |
| | | } |
| | | |
| | | ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); |
| | | ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); |
| | | if (!shuttleProtocol.isIdle(wrkMast.getWrkNo().shortValue())) { |
| | | return false;//小车处于不空闲状态 |
| | | } |
| | | |
| | | LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); |
| | | LiftProtocol liftProtocol = liftThread.getLiftProtocol(); |
| | | |
| | | DevpThread devpThread = null; |
| | | for (DevpSlave devp : slaveProperties.getDevp()){ |
| | | // 获取入库站信息 |
| | | devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId()); |
| | | } |
| | | |
| | | //判断小车是否在工作档任务目标楼层 |
| | | String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号 |
| | | int shuttleLev = Utils.getLev(currentLocNo);//小车所在楼层 |
| | | if (shuttleLev != Utils.getLev(wrkMast.getLocNo())) { |
| | | return false;//不在同一楼层 |
| | | } |
| | | |
| | | if (wrkMast.getWrkSts() == 1 || wrkMast.getWrkSts() == 8) { |
| | | //调度小车执行同楼层移库任务 |
| | | |
| | | //创建分配命令 |
| | | ShuttleAssignCommand assignCommand = new ShuttleAssignCommand(); |
| | | assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号 |
| | | assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号 |
| | | assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入出库模式 |
| | | assignCommand.setSourceLocNo(currentLocNo);//源库位(小车当前位置) |
| | | |
| | | List<ShuttleCommand> commands = new ArrayList<>(); |
| | | |
| | | if (wrkMast.getWrkSts() == 8) {//8.提升机迁移小车完成,需要将小车移出提升机 |
| | | //判断提升机是否空闲 |
| | | if (!liftProtocol.isIdleNoTask()) { |
| | | return false;//提升机忙 |
| | | } |
| | | //判断提升机任务号和当前工作档任务号是否一致 |
| | | if (liftProtocol.getTaskNo().intValue() != 0 && liftProtocol.getTaskNo().intValue() != wrkMast.getWrkNo()) { |
| | | return false; |
| | | } |
| | | |
| | | //判断提升机楼层是否到位,判断站点是否给出提升机到位信号 |
| | | String locNo = wrkMast.getLocNo(); |
| | | int lev = Utils.getLev(locNo);//目标二维码所在楼层 |
| | | int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层 |
| | | if (liftLev != lev) { |
| | | return false;//提升机不在目标楼层跳过 |
| | | } |
| | | |
| | | Integer staNo = Utils.levToOutInStaNo(lev >= 2 ? lev + 1 : lev); |
| | | //获取目标站信息 |
| | | StaProtocol staProtocol1 = devpThread.getStation().get(staNo); |
| | | if (staProtocol1 == null) { |
| | | return false;//站点信息不存在 |
| | | } |
| | | if (!staProtocol1.isLiftArrival()) { |
| | | return false;//站点提升机到位信号false |
| | | } |
| | | |
| | | // BasDevp basDevp = basDevpService.selectById(staNo); |
| | | // short startCode = liftProtocol.getBarcode();//提升机内部二维码 |
| | | // Short distCode = Short.parseShort(basDevp.getQrCodeValue());//提升机口站点二维码 |
| | | // Short runDirection = ShuttleRunDirection.BOTTOM.id;//运行方向 |
| | | // //获取命令 |
| | | // ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, runDirection, null, null, 500); |
| | | // commands.add(0, moveCommand);//将该指令添加到队头 |
| | | |
| | | // currentLocNo = basDevp.getLocNo();//使用输送站点口作为起点坐标 |
| | | } |
| | | |
| | | //直接计算车到源库位到目标库位路径 |
| | | List<ShuttleCommand> commands1 = this.shuttleAssignCommand(currentLocNo, wrkMast.getSourceLocNo(), wrkMast.getLocNo(), assignCommand, shuttleThread); |
| | | if (commands1 == null) { |
| | | return false;//找不到路径等待下一次 |
| | | } |
| | | commands.addAll(commands1); |
| | | |
| | | //分配任务号 |
| | | shuttleProtocol.setTaskNo(wrkMast.getWrkNo().shortValue()); |
| | | //分配源库位 |
| | | shuttleProtocol.setSourceLocNo(wrkMast.getSourceLocNo()); |
| | | |
| | | // assignCommand.setCommands(commands); |
| | | //分配目标库位 |
| | | shuttleProtocol.setLocNo(wrkMast.getLocNo()); |
| | | //目标库位 |
| | | assignCommand.setLocNo(wrkMast.getLocNo()); |
| | | wrkMast.setWrkSts(9L);//小车入库中 |
| | | if (wrkMastMapper.updateById(wrkMast) > 0) { |
| | | //下发任务 |
| | | MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand)); |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |