Junjie
2023-04-04 c08e857d010676d45ff5f4fc022613b974563d43
提升机和四向穿梭车入库出优化
9个文件已修改
754 ■■■■ 已修改文件
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 432 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/CommonUtils.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/LiftSlave.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/LiftThread.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ShuttleThread.java 185 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -98,9 +98,11 @@
    WrkMast selectRackInStep48(Short workNo,Integer sourceStaNo);
    WrkMast selectByWorkNo59(Integer workNo);
    WrkMast selectByWorkNo(Integer workNo);
    WrkMast selectLiftStep6();
    WrkMast selectLiftStep623();
    WrkMast selectByWorkNo7(Integer workNo);
    WrkMast selectByWorkNo724(Integer workNo);
    List<WrkMast> selectBy2125();
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -602,10 +602,120 @@
        }
    }
//    /**
//     * 入库  ===>>  四向穿梭车入库作业下发
//     */
//    public synchronized void shuttleIoInExecute() {
//        // 根据输送线plc遍历
//        for (DevpSlave devp : slaveProperties.getDevp()) {
//            // 遍历入库站
//            for (DevpSlave.StaRack rackInStn : devp.getRackInStn()) {
//                // 获取入库站信息
//                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
//
//                StaProtocol staProtocol = devpThread.getStation().get(rackInStn.getStaNo());
//                StaProtocol staProtocol105 = devpThread.getStation().get(105);
//                staProtocol105.setWorkNo((short) 752);
//                staProtocol105.setStaNo((short) 100);
//
//                StaProtocol staProtocol106 = devpThread.getStation().get(106);
//                staProtocol106.setWorkNo((short) 753);
//                staProtocol106.setStaNo((short) 100);
//
//                if (staProtocol == null) {
//                    continue;
//                } else {
//                    staProtocol = staProtocol.clone();
//                }
//                Short workNo = staProtocol.getWorkNo();
//
//                // 判断是否满足入库条件
//                if (true || staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable()) {
//                    WrkMast wrkMast = wrkMastMapper.selectRackInStep48(workNo, staProtocol.getSiteId());
//                    if (wrkMast != null) {
//                        if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 8) {
//                            ShuttleThread shuttleThread = null;
//                            HashMap<String, Object> searchIdleShuttle = null;
//                            if (wrkMast.getWrkSts() == 4) {
//                                //寻找最近且空闲的四向穿梭车
//                                searchIdleShuttle = this.searchIdleShuttle(wrkMast);
//                                shuttleThread = (ShuttleThread) searchIdleShuttle.get("result");
//                            }else {
//                                //状态8,四向穿梭车已在提升机口,等待命令进行入库搬运动作
//                                Integer shuttleNo = wrkMast.getShuttleNo();//四向穿梭车号
//                                shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
//                            }
//
//                            if (shuttleThread == null) {
//                                continue;
//                            }
//
//                            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
//                            if (!shuttleProtocol.isIdle()) {
//                                continue;
//                            }
//
//                            wrkMast.setShuttleNo(shuttleProtocol.getShuttleNo().intValue());//给工作档分配四向穿梭车号
//
//                            //分配任务号
//                            shuttleProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());
//                            //分配源库位
//                            shuttleProtocol.setSourceLocNo(wrkMast.getSourceLocNo());
//
//                            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
//                            //四向穿梭车号
//                            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());
//                            //任务号
//                            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
//                            //入出库模式
//                            assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());
//                            //源库位(小车当前位置)
//                            String currentLocNo = shuttleProtocol.getCurrentLocNo();
//                            assignCommand.setSourceLocNo(currentLocNo);
//
//                            if (wrkMast.getWrkSts() == 8 || Boolean.parseBoolean(searchIdleShuttle.get("sameLay").toString())) {
//                                //同一层
//                                //分配目标库位
//                                shuttleProtocol.setLocNo(wrkMast.getLocNo());
//                                //目标库位
//                                assignCommand.setLocNo(wrkMast.getLocNo());
//                                wrkMast.setWrkSts(9L);//小车入库中
//
//                                //获取从小车
//                            }else {
//                                //不同层,将目标库位分配成提升机库位号
//
//                                //小车当前层高
//                                Integer currentLev = Integer.parseInt(currentLocNo.substring(currentLocNo.length() - 2, currentLocNo.length()));
//
//                                //获取提升机
//                                LiftSlave liftSlave = slaveProperties.getLift().get(0);
//                                //提升机库位号
//                                String liftLocNo = liftSlave.getLiftLocNo(currentLev);
//                                shuttleProtocol.setLocNo(liftLocNo);
//                                //目标库位
//                                assignCommand.setLocNo(liftLocNo);
//                                wrkMast.setWrkSts(5L);//小车迁移状态
//                            }
//
//                            if (wrkMastMapper.updateById(wrkMast) > 0) {
//                                //下发任务
//                                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
//                            }
//                        }
//
//                    }
//                }
//
//            }
//        }
//
//    }
    /**
     * 入出库  ===>>  四向穿梭车入出库作业下发
     * 入库  ===>>  四向穿梭车入库作业下发
     */
    public synchronized void shuttleIoExecute() {
    public synchronized void shuttleIoInExecute() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库站
@@ -662,19 +772,28 @@
                            //分配源库位
                            shuttleProtocol.setSourceLocNo(wrkMast.getSourceLocNo());
                            //创建分配命令
                            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
                            //四向穿梭车号
                            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());
                            //任务号
                            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
                            //入出库模式
                            assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());
                            //源库位(小车当前位置)
                            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());//四向穿梭车号
                            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
                            assignCommand.setTaskMode(ShuttleTaskModeType.PAK_IN.id.shortValue());//入出库模式
                            String currentLocNo = shuttleProtocol.getCurrentLocNo();
                            assignCommand.setSourceLocNo(currentLocNo);
                            assignCommand.setSourceLocNo(currentLocNo);//源库位(小车当前位置)
                            String locNo = wrkMast.getLocNo();//当前工作档库位号
                            Integer lev = Integer.parseInt(locNo.substring(locNo.length() - 2, locNo.length()));//当前工作档库位层高
                            Integer currentLev = Integer.parseInt(currentLocNo.substring(currentLocNo.length() - 2, currentLocNo.length()));//小车当前层高
                            //获取提升机
                            LiftSlave liftSlave = slaveProperties.getLift().get(0);
                            //提升机库位号
                            String liftLocNo = liftSlave.getLiftLocNo(currentLev);
                            if (wrkMast.getWrkSts() == 8 || Boolean.parseBoolean(searchIdleShuttle.get("sameLay").toString())) {
                                //同一层
                                //同一层直接取货无需经过提升机
                                //直接计算车到提升机取货再到库位路径指令
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftLocNo, locNo);
                                assignCommand.setCommands(commands);
                                //分配目标库位
                                shuttleProtocol.setLocNo(wrkMast.getLocNo());
                                //目标库位
@@ -683,16 +802,13 @@
                            }else {
                                //不同层,将目标库位分配成提升机库位号
                                //小车当前层高
                                Integer currentLev = Integer.parseInt(currentLocNo.substring(currentLocNo.length() - 2, currentLocNo.length()));
                                //获取提升机
                                LiftSlave liftSlave = slaveProperties.getLift().get(0);
                                //提升机库位号
                                String liftLocNo = liftSlave.getLiftLocNo(currentLev);
                                //小车移动到提升机口,计算路径
                                List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftLocNo, ShuttleTaskModeType.PAK_IN.id);
                                //分配目标库位
                                shuttleProtocol.setLocNo(liftLocNo);
                                //目标库位
                                assignCommand.setLocNo(liftLocNo);
                                assignCommand.setCommands(commands);
                                wrkMast.setWrkSts(5L);//小车迁移状态
                            }
@@ -710,8 +826,251 @@
    }
    //获取起点-终点指令。mapType:1=》无货地图,2=》有货地图
    public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String locNO,Integer mapType) {
        //计算小车起点到中点所需命令
        List<NavigateNode> calc = NavigateUtils.calc(startLocNo, locNO, mapType);
        List<ShuttleCommand> commands = new ArrayList<>();
        if (calc == null) {
            return null;
        }
        //获取分段路径
        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
        //将每一段路径分成command指令
        for (ArrayList<NavigateNode> nodes : data) {
            //开始路径
            NavigateNode startPath = nodes.get(0);
            //目标路径
            NavigateNode endPath = nodes.get(nodes.size() - 1);
            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
            ShuttleCommand command = new ShuttleCommand();
            command.setCommandWord((short) 1);
            command.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
            command.setMiddleCodeNum((short) 0);
            command.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
            command.setStartToDistDistance(allDistance);
            command.setMiddleToDistDistance(1000);
            command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
            command.setPalletLift((short) 1);
            command.setForceMoveDistance(1000);
            command.setChargeSwitch((short) 2);
            command.setIOControl((short) 0);
            command.setRunSpeed((short) 1000);
            command.setRadarTmp((short) 0);
            command.setCommandEnd((short) 1);
            commands.add(command);
        }
        return commands;
    }
    //获取起点-中点-终点指令
    public synchronized List<ShuttleCommand> shuttleAssignCommand(String startLocNo, String middleLocNo, String locNO) {
        //计算小车起点到中点所需命令
        List<NavigateNode> calc = NavigateUtils.calc(startLocNo, middleLocNo, 1);//小车无货,走入库地图
        List<ShuttleCommand> commands = new ArrayList<>();
        if (calc == null) {
            return null;
        }
        //获取分段路径
        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
        //将每一段路径分成command指令
        for (ArrayList<NavigateNode> nodes : data) {
            //开始路径
            NavigateNode startPath = nodes.get(0);
            //目标路径
            NavigateNode endPath = nodes.get(nodes.size() - 1);
            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
            ShuttleCommand command = new ShuttleCommand();
            command.setCommandWord((short) 1);
            command.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
            command.setMiddleCodeNum((short) 0);
            command.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
            command.setStartToDistDistance(allDistance);
            command.setMiddleToDistDistance(1000);
            command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
            command.setPalletLift((short) 1);
            command.setForceMoveDistance(1000);
            command.setChargeSwitch((short) 2);
            command.setIOControl((short) 0);
            command.setRunSpeed((short) 1000);
            command.setRadarTmp((short) 0);
            command.setCommandEnd((short) 1);
            commands.add(command);
        }
        //小车指令到达目标位置后,再发出一条顶升指令
        ShuttleCommand command = new ShuttleCommand();
        command.setCommandWord((short) 2);
        command.setPalletLift((short) 1);
        command.setCommandEnd((short) 1);
        commands.add(command);
        //计算小车中点到终点所需命令
        List<NavigateNode> calc2 = NavigateUtils.calc(middleLocNo, locNO, 2);//小车有货,走出库地图(出库地图有专用货道)
        if (calc2 == null) {
            return null;
        }
        //获取分段路径
        ArrayList<ArrayList<NavigateNode>> data2 = NavigateUtils.getSectionPath(calc2);
        for (ArrayList<NavigateNode> nodes : data2) {
            //开始路径
            NavigateNode startPath = nodes.get(0);
            //目标路径
            NavigateNode endPath = nodes.get(nodes.size() - 1);
            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
            command = new ShuttleCommand();
            command.setCommandWord((short) 1);
            command.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
            command.setMiddleCodeNum((short) 0);
            command.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
            command.setStartToDistDistance(allDistance);
            command.setMiddleToDistDistance(1000);
            command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
            command.setPalletLift((short) 1);
            command.setForceMoveDistance(1000);
            command.setChargeSwitch((short) 2);
            command.setIOControl((short) 0);
            command.setRunSpeed((short) 1000);
            command.setRadarTmp((short) 0);
            command.setCommandEnd((short) 1);
            commands.add(command);
        }
        //小车指令到达目标位置后,再发出一条托盘下降指令
        command = new ShuttleCommand();
        command.setCommandWord((short) 2);
        command.setPalletLift((short) 2);
        command.setCommandEnd((short) 1);
        commands.add(command);
        return commands;
    }
    /**
     * 搜索空闲且最近的四向穿梭车
     * 出库  ===>>  四向穿梭车出库作业下发
     */
    public synchronized void shuttleIoOutExecute() {
        for (WrkMast wrkMast : wrkMastMapper.selectBy2125()) {
            //提取一条待出库任务
            if (wrkMast != null) {
                String outStaLocNo = null;//出库站点库位号
                //获取出库站点
                for (DevpSlave devpSlave : slaveProperties.getDevp()) {
                    for (DevpSlave.StaRack staOutRack : devpSlave.getRackOutStn()) {
                        if (staOutRack.getStaNo().equals(wrkMast.getStaNo())) {
                            //出库站点和工作档出库站点一致
                            outStaLocNo = CommonUtils.getLocNoFromRBL(staOutRack.getRow(), staOutRack.getBay(), staOutRack.getLev());
                        }
                    }
                }
                if (wrkMast.getWrkSts() == 21
                        || wrkMast.getWrkSts() == 25
                        || wrkMast.getWrkSts() == 31) {
                    ShuttleThread shuttleThread = null;
                    HashMap<String, Object> searchIdleShuttle = null;
                    if (wrkMast.getWrkSts() == 21) {
                        //寻找最近且空闲的四向穿梭车
                        searchIdleShuttle = this.searchIdleShuttle(wrkMast);
                        shuttleThread = (ShuttleThread) searchIdleShuttle.get("result");
                    }else if(wrkMast.getWrkSts() == 31 || wrkMast.getWrkSts() == 25) {
                        //继续完成之前小车未完成的任务
                        shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
                    }
                    if (shuttleThread == null) {
                        continue;
                    }
                    ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
                    if (shuttleProtocol == null) {
                        continue;
                    }
                    if (!shuttleProtocol.isIdle()) {
                        continue;
                    }
                    if (outStaLocNo == null) {
                        continue;
                    }
                    wrkMast.setShuttleNo(shuttleProtocol.getShuttleNo().intValue());//给工作档分配四向穿梭车号
                    //源库位(小车当前位置)
                    String currentLocNo = shuttleProtocol.getCurrentLocNo();
                    //小车当前层高
                    Integer currentLev = Integer.parseInt(currentLocNo.substring(currentLocNo.length() - 2, currentLocNo.length()));
                    //获取提升机
                    LiftSlave liftSlave = slaveProperties.getLift().get(0);
                    //提升机库位号
                    String liftLocNo = liftSlave.getLiftLocNo(currentLev);
                    //分配任务号
                    shuttleProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());
                    //分配源库位
                    shuttleProtocol.setSourceLocNo(currentLocNo);
                    ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
                    //四向穿梭车号
                    assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo());
                    //任务号
                    assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
                    //入出库模式
                    assignCommand.setTaskMode(ShuttleTaskModeType.PAK_OUT.id.shortValue());
                    assignCommand.setSourceLocNo(currentLocNo);
                    if (wrkMast.getWrkSts() == 21) {
                        //判断小车和库位是否在同一层
                        if (Boolean.parseBoolean(searchIdleShuttle.get("sameLay").toString())) {
                            //同一层(将小车移动到货物位置)
                            List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, wrkMast.getSourceLocNo(), liftLocNo);
                            //分配目标库位
                            shuttleProtocol.setLocNo(wrkMast.getSourceLocNo());
                            //目标库位
                            assignCommand.setLocNo(wrkMast.getSourceLocNo());
                            assignCommand.setCommands(commands);
                            wrkMast.setWrkSts(26L);//小车搬运中
                        }else {
                            //不同层,将目标库位分配成提升机库位号(将小车移动到提升机位置)
                            //小车到提升机口指令
                            List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, liftLocNo, ShuttleTaskModeType.PAK_IN.id);
                            shuttleProtocol.setLocNo(liftLocNo);
                            //目标库位
                            assignCommand.setLocNo(liftLocNo);
                            assignCommand.setCommands(commands);
                            wrkMast.setWrkSts(22L);//小车迁移状态
                        }
                    } else if (wrkMast.getWrkSts() == 25) {
                        List<ShuttleCommand> commands = this.shuttleAssignCommand(currentLocNo, wrkMast.getSourceLocNo(), liftLocNo);
                        //分配目标库位
                        shuttleProtocol.setLocNo(wrkMast.getSourceLocNo());
                        //目标库位
                        assignCommand.setLocNo(wrkMast.getSourceLocNo());
                        assignCommand.setCommands(commands);
                        wrkMast.setWrkSts(26L);//小车搬运中
                    }
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        //下发任务
                        MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                    }
                }
            }
        }
    }
    /**
     * 搜索空闲且最近的四向穿梭车(以工作档目标库位为基点计算最近且空闲的车)
     */
    public HashMap<String,Object> searchIdleShuttle(WrkMast wrkMast) {
        HashMap<String, Object> map = new HashMap<>();
@@ -806,7 +1165,7 @@
            //四向穿梭车状态为等待确认
            if (shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id && shuttleProtocol.getTaskNo() != 0) {
                //将任务档标记为完成
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo59(shuttleProtocol.getTaskNo().intValue());
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(shuttleProtocol.getTaskNo().intValue());
                if (wrkMast != null) {
                    switch (wrkMast.getWrkSts().intValue()) {
                        case 9:
@@ -814,6 +1173,12 @@
                            break;
                        case 5:
                            wrkMast.setWrkSts(6L);
                            break;
                        case 22:
                            wrkMast.setWrkSts(23L);
                            break;
                        case 26:
                            wrkMast.setWrkSts(27L);
                            break;
                        default:
                    }
@@ -861,7 +1226,7 @@
            }
            //搜索是否有待处理的任务
            WrkMast wrkMast = wrkMastMapper.selectLiftStep6();
            WrkMast wrkMast = wrkMastMapper.selectLiftStep623();
            if (wrkMast == null) {
                continue;
            }
@@ -891,7 +1256,7 @@
            int currentLocNoLey = Integer.parseInt(currentLocNo.substring(currentLocNo.length() - 2, currentLocNo.length()));
            //工作档目标库位号
            String wrkMastLocNo = wrkMast.getLocNo();
            String wrkMastLocNo = wrkMast.getIoType() == 101 ? wrkMast.getSourceLocNo() : wrkMast.getLocNo();
            //工作档目标库位楼层
            int wrkMastLocNoLey = Integer.parseInt(wrkMastLocNo.substring(wrkMastLocNo.length() - 2, wrkMastLocNo.length()));
@@ -938,7 +1303,13 @@
            commands.add(command4);//将命令添加进list
            wrkMast.setWrkSts(7L);//移动任务
            if (wrkMast.getIoType() == 101) {
                //出库任务
                wrkMast.setWrkSts(24L);//移动任务
            }else {
                //入库任务
                wrkMast.setWrkSts(7L);//移动任务
            }
            //所需命令组合完毕,更新数据库,提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
@@ -966,9 +1337,18 @@
            //提升机为等待确认
            if (liftProtocol.getProtocolStatus() == LiftProtocolStatusType.WAITING.id && liftProtocol.getTaskNo() != 0) {
                //将任务档标记为完成
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo7(liftProtocol.getTaskNo().intValue());
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo724(liftProtocol.getTaskNo().intValue());
                if (wrkMast != null) {
                    wrkMast.setWrkSts(8L);
                    switch (wrkMast.getWrkSts().intValue()) {
                        case 7:
                            wrkMast.setWrkSts(8L);
                            break;
                        case 24:
                            wrkMast.setWrkSts(25L);
                            break;
                        default:
                    }
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        //设置提升机为空闲状态
                        liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
@@ -978,6 +1358,8 @@
                        liftProtocol.setPakMk(true);
                        //任务指令清零
                        liftProtocol.setAssignCommand(null);
                        //提升机解锁
                        liftProtocol.setLiftLock(false);
                        News.info("提升机已确认且任务完成状态,复位。提升机号={}", liftProtocol.getLiftNo());
                    } else {
                        News.error("提升机已确认且任务完成状态,复位失败,但未找到工作档。提升机号={},工作号={}", liftProtocol.getLiftNo(), liftProtocol.getTaskNo());
src/main/java/com/zy/common/utils/CommonUtils.java
@@ -44,4 +44,24 @@
        return num != 0;
    }
    //从row、bay、lev参数获取完整库位号
    public static String getLocNoFromRBL(Integer row, Integer bay, Integer lev) {
        StringBuffer sb = new StringBuffer();
        if (row < 10) {
            sb.append("0");
        }
        sb.append(row);
        if (bay < 10) {
            sb.append("00");
        } else if (bay < 100) {
            sb.append("0");
        }
        sb.append(bay);
        if (lev < 10) {
            sb.append("0");
        }
        sb.append(lev);
        return sb.toString();
    }
}
src/main/java/com/zy/core/MainProcess.java
@@ -57,8 +57,10 @@
                    mainService.crnStnToOutStn();
                    // 入出库  ===>>  堆垛机入出库作业下发
                    mainService.crnIoExecute();
                    // 入出库  ===>>  四向穿梭车入出库作业下发
                    mainService.shuttleIoExecute();
                    // 入库  ===>>  四向穿梭车入库作业下发
                    mainService.shuttleIoInExecute();
                    // 出库  ===>>  四向穿梭车出库作业下发
                    mainService.shuttleIoOutExecute();
                    //四向穿梭车任务完成
                    mainService.shuttleFinished();
                    //提升机任务
src/main/java/com/zy/core/model/LiftSlave.java
@@ -45,6 +45,9 @@
            sb.append("0");
        }
        sb.append(bay);
        if (lev < 10) {
            sb.append("0");
        }
        sb.append(lev);
        return sb.toString();
    }
src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
@@ -230,6 +230,27 @@
        }
    }
    // 是否处于空闲待命状态,传入的taskNo和当前taskNo相同时允许放行
    public Boolean isIdle(Short taskNo) {
        boolean res = this.busyStatusType.equals(ShuttleStatusType.IDLE)
                && this.pakMk.equals(true)
                && this.errorCodeType.equals(ShuttleErrorCodeType.NORMAL)
                && (this.taskNo == 0 || this.taskNo == taskNo)
                ;
        if (!res) {
            return res;
        } else {
            // 电量
            try {
                Integer chargeLine = SpringUtils.getBean(BasShuttleService.class).selectById(this.shuttleNo).getChargeLine();
                return this.getBatteryPower$() > chargeLine;
            } catch (Exception e) {
                News.error("fail", e);
                return false;
            }
        }
    }
    //通过当前二维码获取当前库位号
    public String getCurrentLocNo() {
        LocMastService locMastService = SpringUtils.getBean(LocMastService.class);
src/main/java/com/zy/core/thread/LiftThread.java
@@ -293,32 +293,6 @@
        //将此map存入redis中
        HashMap<String, Object> map = new HashMap<>();
        //提升机号
        map.put("lift_no", assignCommand.getLiftNo());
        //工作号
        map.put("wrk_no", assignCommand.getTaskNo());
        //命令执行步序
        map.put("commandStep", 0);
        //命令
        map.put("assignCommand", assignCommand);
        //任务数据保存到redis
        redisUtil.set("lift_wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map));
        liftProtocol.setAssignCommand(assignCommand);
        liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);
        //执行下发任务
        executeWork(assignCommand);
    }
    //执行任务
    private boolean executeWork(LiftAssignCommand assignCommand) {
        //读取redis数据
        if (assignCommand == null) {
            return false;
        }
        //将标记置为false(防止重发)
        liftProtocol.setPakMk(false);
        //手动模式指令
        if (!assignCommand.getAuto()) {
            LiftCommand command = new LiftCommand();
@@ -347,16 +321,38 @@
                case 5://复位
                    command.setRun((short) 0);
                    command.setLiftLock(false);
                    liftProtocol.setTaskNo((short) 0);
                    liftProtocol.setShuttleNo((short) 0);
                    liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                    liftProtocol.setPakMk(true);
                    break;
                default:
            }
            commands.add(command);
            assignCommand.setCommands(commands);
        }
        //提升机号
        map.put("lift_no", assignCommand.getLiftNo());
        //工作号
        map.put("wrk_no", assignCommand.getTaskNo());
        //命令执行步序
        map.put("commandStep", 0);
        //命令
        map.put("assignCommand", assignCommand);
        //任务数据保存到redis
        redisUtil.set("lift_wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(map));
        liftProtocol.setAssignCommand(assignCommand);
        liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);
        //执行下发任务
        executeWork(assignCommand);
    }
    //执行任务
    private boolean executeWork(LiftAssignCommand assignCommand) {
        //读取redis数据
        if (assignCommand == null) {
            return false;
        }
        //将标记置为false(防止重发)
        liftProtocol.setPakMk(false);
        Object o = redisUtil.get("lift_wrk_no_" + assignCommand.getTaskNo());
        if (o == null) {
@@ -411,6 +407,12 @@
                    News.info("提升机任务执行完成等待确认中,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
                }else {
                    //手动模式不抛出等待状态
                    if (assignCommand.getTaskMode() == 5) {
                        liftProtocol.setTaskNo((short) 0);
                        liftProtocol.setShuttleNo((short) 0);
                        liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                        liftProtocol.setPakMk(true);
                    }
                    News.info("提升机手动任务执行完成,提升机号={},任务数据={}", command.getLiftNo(), JSON.toJSON(command));
                }
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -24,6 +24,7 @@
import com.zy.core.enums.*;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.LiftCommand;
import com.zy.core.model.command.ShuttleAssignCommand;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
@@ -345,28 +346,94 @@
    }
    //分配任务
    private void assignWork(ShuttleAssignCommand assignCommand) throws Exception {
    private void assignWork(ShuttleAssignCommand assignCommand) {
        //将此map存入redis中
        HashMap<String, Object> map = new HashMap<>();
        if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue()
                || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
            //入库或出库模式,计算路径
            //计算路径
            List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), assignCommand.getTaskMode().intValue());
            if (calc != null) {
                //获取分段路径
                ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
                //路径数据
                map.put("path", data);
                //路径次数
                map.put("pathSize", data.size());
            }else {
                if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue() || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
                    //属于入库出库,必须要计算路径,则抛出异常
                    throw new Exception("未能找到运行路径");
                }
//        if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue()
//                || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
//            //入库或出库模式,计算路径
//            //计算路径
//            List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), assignCommand.getTaskMode().intValue());
//            if (calc != null) {
//                //获取分段路径
//                ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
//                //路径数据
//                map.put("path", data);
//                //路径次数
//                map.put("pathSize", data.size());
//            }else {
//                if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue() || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue()) {
//                    //属于入库出库,必须要计算路径,则抛出异常
//                    throw new Exception("未能找到运行路径");
//                }
//            }
//        }
        if (!assignCommand.getAuto()) {
            List<ShuttleCommand> commands = new ArrayList<>();
            ShuttleCommand command = new ShuttleCommand();
            switch (assignCommand.getTaskMode()) {
                case 1://入库
                case 2://出库
                    //小车移动到提升机口,计算路径
                    //计算小车起点到中点所需命令
                    List<NavigateNode> calc = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), ShuttleTaskModeType.PAK_IN.id);
                    if (calc != null) {
                        //获取分段路径
                        ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(calc);
                        //将每一段路径分成command指令
                        for (ArrayList<NavigateNode> nodes : data) {
                            //开始路径
                            NavigateNode startPath = nodes.get(0);
                            //目标路径
                            NavigateNode endPath = nodes.get(nodes.size() - 1);
                            Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离
                            ShuttleCommand command1 = new ShuttleCommand();
                            command1.setCommandWord((short) 1);
                            command1.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
                            command1.setMiddleCodeNum((short) 0);
                            command1.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
                            command1.setStartToDistDistance(allDistance);
                            command1.setMiddleToDistDistance(1000);
                            command1.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                            command1.setPalletLift((short) 1);
                            command1.setForceMoveDistance(1000);
                            command1.setChargeSwitch((short) 2);
                            command1.setIOControl((short) 0);
                            command1.setRunSpeed((short) 1000);
                            command1.setRadarTmp((short) 0);
                            command1.setCommandEnd((short) 1);
                            commands.add(command1);
                        }
                    }
                    break;
                case 3://托盘顶升
                case 4://托盘下降
                    command.setCommandWord((short) 2);
                    command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                case 5://强制左移
                case 6://强制右移
                case 7://强制上移
                case 8://强制下移
                    command.setCommandWord((short) 3);
                    command.setForceMoveDistance(1000);
                    command.setRunDirection((short) (assignCommand.getTaskMode() - 4));
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                case 9://状态复位
                    command.setCommandWord((short) 0);
                    command.setCommandEnd((short) 1);
                    commands.add(command);
                    break;
                default:
            }
            assignCommand.setCommands(commands);
        }
        //四向穿梭车号
@@ -401,79 +468,15 @@
            return false;
        }
        HashMap map = JSON.parseObject(o.toString(), HashMap.class);
        List<ShuttleCommand> commands = assignCommand.getCommands();
        //当前步序
        int commandStep = Integer.parseInt(map.get("commandStep").toString());
        //path路径数目
        int size = 0;
        //下发命令
        ShuttleCommand command = new ShuttleCommand();
        switch (assignCommand.getTaskMode()) {
            case 1://入库
            case 2://出库
                //当前路径数据
                Object data = map.get("path");
                ArrayList pathList = JSON.parseObject(data.toString(), ArrayList.class);
                //取第一条路径
                Object o1 = pathList.get(commandStep);
                ArrayList objectPath = JSON.parseObject(o1.toString(), ArrayList.class);
                ArrayList<NavigateNode> path = new ArrayList<>();
                for (Object o2 : objectPath) {
                    NavigateNode navigateNode = JSON.parseObject(o2.toString(), NavigateNode.class);
                    path.add(navigateNode);
                }
                Integer allDistance = NavigateUtils.getCurrentPathAllDistance(path);//计算当前路径行走总距离
        int size = commands.size();
                size = Integer.parseInt(map.get("pathSize").toString());
                //开始路径
                NavigateNode startPath = path.get(0);
                //目标路径
                NavigateNode endPath = path.get(path.size() - 1);
        //取出命令
        ShuttleCommand command = commands.get(commandStep);
                command.setCommandWord((short) 1);
                command.setStartCodeNum(NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY()));
                command.setMiddleCodeNum((short) 0);
                command.setDistCodeNum(NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY()));
                command.setStartToDistDistance(allDistance);
                command.setMiddleToDistDistance(1000);
                command.setRunDirection(ShuttleRunDirection.get(startPath.getDirection()).id);
                command.setPalletLift((short) 1);
                command.setForceMoveDistance(1000);
                command.setChargeSwitch((short) 2);
                command.setIOControl((short) 0);
                command.setRunSpeed((short) 1000);
                command.setRadarTmp((short) 0);
                break;
            case 3://托盘顶升
            case 4://托盘下降
                command.setCommandWord((short) 2);
                command.setPalletLift(assignCommand.getTaskMode() == 3 ? (short)1 : (short)2);
                command.setCommandEnd((short) 1);
                break;
            case 5://强制左移
            case 6://强制右移
            case 7://强制上移
            case 8://强制下移
                command.setCommandWord((short) 3);
                command.setForceMoveDistance(1000);
                command.setRunDirection((short) (assignCommand.getTaskMode() - 4));
                command.setCommandEnd((short) 1);
                break;
            case 9://状态复位
                command.setCommandWord((short) 0);
                //设置四向穿梭车为空闲状态
                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                //任务号清零
                shuttleProtocol.setTaskNo((short) 0);
                //标记复位
                shuttleProtocol.setPakMk(true);
                //任务指令清零
                shuttleProtocol.setAssignCommand(null);
                break;
            default:
        }
        command.setCommandEnd((short) 1);
        //下发命令
        if (!write(command)) {
            News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
@@ -513,6 +516,16 @@
                if (!assignCommand.getAuto()) {
                    //手动模式不抛出等待状态,直接复位
                    if (assignCommand.getTaskMode() == 9) {
                        //设置四向穿梭车为空闲状态
                        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                        //任务号清零
                        shuttleProtocol.setTaskNo((short) 0);
                        //标记复位
                        shuttleProtocol.setPakMk(true);
                        //任务指令清零
                        shuttleProtocol.setAssignCommand(null);
                    }
                    News.info("四向穿梭车手动任务执行完成,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command));
                }else {
                    //对主线程抛出等待确认状态waiting
src/main/resources/mapper/WrkMastMapper.xml
@@ -246,22 +246,27 @@
        order by io_pri desc,wrk_sts desc
    </select>
    <select id="selectByWorkNo59" resultMap="BaseResultMap">
    <select id="selectByWorkNo" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast
        where wrk_no=#{workNo}
        and wrk_sts in (5,9)
    </select>
    <select id="selectLiftStep6" resultMap="BaseResultMap">
    <select id="selectLiftStep623" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast
        where wrk_sts in (6)
        where wrk_sts in (6,23)
        and shuttle_no is not null
        order by io_pri desc,wrk_sts desc
    </select>
    <select id="selectByWorkNo7" resultMap="BaseResultMap">
    <select id="selectByWorkNo724" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast
        where wrk_no=#{workNo}
        and wrk_sts in (7)
        and wrk_sts in (7,24)
    </select>
    <select id="selectBy2125" resultMap="BaseResultMap">
        select * from dbo.asr_wrk_mast
        where wrk_sts in (21,25)
        order by io_pri desc,wrk_sts desc
    </select>
</mapper>