自动化立体仓库 - WCS系统
#
Junjie
2023-07-31 4315668f4de2ab2bf8a24ac206d71f072dd00357
#
1个文件已添加
15个文件已修改
983 ■■■■ 已修改文件
src/main/java/com/zy/asrs/entity/BasDevp.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasDevpService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 809 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigatePositionConvert.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NyLiftUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/NyLiftTaskModelType.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/LiftAssignCommand.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ShuttleThread.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasDevpMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasDevp.java
@@ -228,6 +228,20 @@
    @TableField("loc_no")
    private String locNo;
    /**
     * 输送线楼层
     */
    @ApiModelProperty(value= "输送线楼层")
    @TableField("lev")
    private Integer lev;
    /**
     * 输送线对应提升机号
     */
    @ApiModelProperty(value= "输送线对应提升机号")
    @TableField("lift_no")
    private Integer liftNo;
    public String getIoTime$(){
        if (Cools.isEmpty(this.ioTime)){
src/main/java/com/zy/asrs/mapper/BasDevpMapper.java
@@ -23,4 +23,10 @@
    BasDevp queryByQrCode(Integer qrCodeValue);
    List<BasDevp> selectLevSite();
    //获取指定楼层有提升机号的输送站点
    List<BasDevp> selectHasLiftNoByLev(Integer lev);
    //获取指定楼层、指定提升机号对应的输送站点
    BasDevp selectByLevAndLiftNo(Integer lev, Integer liftNo);
}
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -66,4 +66,10 @@
    List<WrkMast> selectLocToLocWrkMast();//查询库位移转工作档
    WrkMast selectPickStepByBarcode(String barcode);
    WrkMast selectShuttleHasMoveWorking(@Param("shuttleNo") Integer shuttleNo);
    List<WrkMast> selectShuttleMoveWrk();
    WrkMast selectShuttleWorking(@Param("shuttleNo") Integer shuttleNo);//是否有穿梭车任务(移库任务除外)
}
src/main/java/com/zy/asrs/service/BasDevpService.java
@@ -53,4 +53,10 @@
    //获取四层楼站点105,106,107,108
    List<BasDevp> selectLevSite();
    //获取指定楼层有提升机号的输送站点
    List<BasDevp> selectHasLiftNoByLev(Integer lev);
    //获取指定楼层、指定提升机号对应的输送站点
    BasDevp selectByLevAndLiftNo(Integer lev, Integer liftNo);
}
src/main/java/com/zy/asrs/service/impl/BasDevpServiceImpl.java
@@ -84,4 +84,14 @@
    public List<BasDevp> selectLevSite() {
        return this.baseMapper.selectLevSite();
    }
    @Override
    public List<BasDevp> selectHasLiftNoByLev(Integer lev) {
        return this.baseMapper.selectHasLiftNoByLev(lev);
    }
    @Override
    public BasDevp selectByLevAndLiftNo(Integer lev, Integer liftNo) {
        return this.baseMapper.selectByLevAndLiftNo(lev, liftNo);
    }
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -96,6 +96,8 @@
    @Autowired
    private OrderDetlMapper orderDetlMapper;
    @Autowired
    private BasLiftService basLiftService;
    @Autowired
    private RedisUtil redisUtil;
    /**
@@ -803,9 +805,9 @@
                                    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);
//                                    //增加移动进提升机命令
//                                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, 500);
//                                    commands.add(moveCommand);
                                    //分配目标库位
                                    shuttleProtocol.setLocNo(liftSiteLocNo);
@@ -825,12 +827,12 @@
                                Integer staNo = Utils.levToOutInStaNo(currentLev >= 2 ? currentLev + 1 : currentLev);//站点号
                                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);//将该指令添加到队头
//                                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);//将该指令添加到队头
//                                assignCommand.setCommands(commands);
                                //分配目标库位
@@ -1268,9 +1270,9 @@
                            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);
//                            //增加移动进提升机命令
//                            ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, 500);
//                            commands.add(moveCommand);
                            //目标库位
                            assignCommand.setLocNo(liftSiteLocNo);
@@ -1306,12 +1308,12 @@
                            continue;//未找到路径
                        }
                        //此时车在提升机内部,需要多下达一步指令让车移动到提升机口
                        short startCode = liftProtocol.getBarcode();//提升机内部二维码
                        Short distCode = commands.get(0).getStartCodeNum();//目标二维码
                        //获取移动命令
                        ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, commands.get(0).getRunDirection(), null, null, 500);
                        commands.add(0, moveCommand);//将该指令添加到队头
//                        //此时车在提升机内部,需要多下达一步指令让车移动到提升机口
//                        short startCode = liftProtocol.getBarcode();//提升机内部二维码
//                        Short distCode = commands.get(0).getStartCodeNum();//目标二维码
//                        //获取移动命令
//                        ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, commands.get(0).getRunDirection(), null, null, 500);
//                        commands.add(0, moveCommand);//将该指令添加到队头
                        //分配目标库位
                        shuttleProtocol.setLocNo(wrkMast.getSourceLocNo());
@@ -1661,10 +1663,10 @@
                        //存在未完成任务号
                        continue;
                    }
                    if (liftProtocol.getPlatShuttleCheck()) {
                        //提升机此时有四向车,可能有未完成的任务,禁止分配新任务
                        continue;
                    }
//                    if (liftProtocol.getPlatShuttleCheck()) {
//                        //提升机此时有四向车,可能有未完成的任务,禁止分配新任务
//                        continue;
//                    }
                    //获取目标站
                    StaProtocol staProtocol = devpThread.getStation().get(wrkMast.getStaNo());
@@ -1683,32 +1685,32 @@
                    }
                    Integer distStaNo = Utils.levToOutInStaNo(levTmp);
                    if (liftProtocol.getPositionArrivalFeedback().intValue() != LiftLevType.TWO.realLev.intValue()) {
                        //提升机不在输送线楼层,获取到输送线层的提升机命令
                        LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), LiftLevType.TWO.lev);
                        commands.add(command1);//将命令添加进list
                    }
//                    if (liftProtocol.getPositionArrivalFeedback().intValue() != LiftLevType.TWO.realLev.intValue()) {
//                        //提升机不在输送线楼层,获取到输送线层的提升机命令
//                        LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), LiftLevType.TWO.lev);
//                        commands.add(command1);//将命令添加进list
//                    }
                    //输送线将货物运进来(无货正转)
                    LiftCommand command2 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 3);
                    command2.setOperaStaNo((short) 102);//操作102站
                    command2.setRotationDire(1);//给输送线下发链条转动信号,正转
                    command2.setDevpId(devpId);
                    command2.setStaNo(distStaNo.shortValue());//设置目标站
                    commands.add(command2);//将命令添加进list
                    //提升机前往目标楼层(工作档目标楼层)
                    LiftCommand command3 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), levTmp);
                    commands.add(command3);//将命令添加进list
                    //提升机到达指定楼层,输送线将货物移出去(正转)
                    //输送线将货物移出去
                    LiftCommand command4 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 1);
                    command4.setOperaStaNo(distStaNo.shortValue());//操作目标楼层站点
                    command4.setRotationDire(1);//给输送线下发链条转动信号,正转
                    command4.setDevpId(devpId);
                    command4.setStaNo(distStaNo.shortValue());//设置目标站
                    commands.add(command4);//将命令添加进list
//                    //输送线将货物运进来(无货正转)
//                    LiftCommand command2 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 3);
//                    command2.setOperaStaNo((short) 102);//操作102站
//                    command2.setRotationDire(1);//给输送线下发链条转动信号,正转
//                    command2.setDevpId(devpId);
//                    command2.setStaNo(distStaNo.shortValue());//设置目标站
//                    commands.add(command2);//将命令添加进list
//
//                    //提升机前往目标楼层(工作档目标楼层)
//                    LiftCommand command3 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), levTmp);
//                    commands.add(command3);//将命令添加进list
//
//                    //提升机到达指定楼层,输送线将货物移出去(正转)
//                    //输送线将货物移出去
//                    LiftCommand command4 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 1);
//                    command4.setOperaStaNo(distStaNo.shortValue());//操作目标楼层站点
//                    command4.setRotationDire(1);//给输送线下发链条转动信号,正转
//                    command4.setDevpId(devpId);
//                    command4.setStaNo(distStaNo.shortValue());//设置目标站
//                    commands.add(command4);//将命令添加进list
                    //给提升机分配任务
                    liftProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());//设置任务号
@@ -1735,13 +1737,13 @@
                    if (!shuttleProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                        continue;//小车状态忙
                    }
                    if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
                        continue;//小车当前二维码和提升机内部二维码不一致,不允许执行
                    }
                    if (!liftProtocol.getPlatShuttleCheck()) {
                        //提升机未检测到小车,禁止执行
                        continue;
                    }
//                    if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
//                        continue;//小车当前二维码和提升机内部二维码不一致,不允许执行
//                    }
//                    if (!liftProtocol.getPlatShuttleCheck()) {
//                        //提升机未检测到小车,禁止执行
//                        continue;
//                    }
                    //工作档目标库位号
                    String wrkMastLocNo = wrkMast.getLocNo();
@@ -1751,9 +1753,9 @@
                        wrkMastLocNoLey++;
                    }
                    //提升机前往目标楼层(工作档目标楼层)
                    LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
                    commands.add(command1);//将命令添加进list
//                    //提升机前往目标楼层(工作档目标楼层)
//                    LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
//                    commands.add(command1);//将命令添加进list
                    //给提升机分配任务
                    liftProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());//设置任务号
@@ -1781,13 +1783,13 @@
                    if (!shuttleProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                        continue;//小车状态忙
                    }
                    if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
                        continue;//小车当前二维码和提升机内部二维码不一致,不允许执行
                    }
                    if (!liftProtocol.getPlatShuttleCheck()) {
                        //提升机未检测到小车,禁止执行
                        continue;
                    }
//                    if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
//                        continue;//小车当前二维码和提升机内部二维码不一致,不允许执行
//                    }
//                    if (!liftProtocol.getPlatShuttleCheck()) {
//                        //提升机未检测到小车,禁止执行
//                        continue;
//                    }
                    //工作档目标库位号
                    String wrkMastLocNo = wrkMast.getSourceLocNo();
@@ -1797,9 +1799,9 @@
                        wrkMastLocNoLey++;
                    }
                    //提升机前往目标楼层(工作档目标楼层)
                    LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
                    commands.add(command1);//将命令添加进list
//                    //提升机前往目标楼层(工作档目标楼层)
//                    LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
//                    commands.add(command1);//将命令添加进list
                    //给提升机分配任务
                    liftProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());//设置任务号
@@ -1812,10 +1814,10 @@
                        //提升机存在未完成任务,且提升机任务号和当前工作档任务号不一致
                        continue;
                    }
                    if (liftProtocol.getPlatShuttleCheck()) {
                        //提升机此时有四向车,可能有未完成的任务,禁止分配新任务
                        continue;
                    }
//                    if (liftProtocol.getPlatShuttleCheck()) {
//                        //提升机此时有四向车,可能有未完成的任务,禁止分配新任务
//                        continue;
//                    }
                    //工作档源库位号
                    String wrkMastLocNo = wrkMast.getSourceLocNo();
@@ -1825,42 +1827,42 @@
                    //提升机当前楼层
                    int liftLev = liftProtocol.getLev().intValue();
                    //判断提升机是否到位
                    StaProtocol staProtocol = devpThread.getStation().get(Utils.levToOutInStaNo(wrkMastLocNoLey >= 2 ? wrkMastLocNoLey + 1 : wrkMastLocNoLey));//起始站点
                    if (liftLev != wrkMastLocNoLey && !staProtocol.isLiftArrival()) {
                        //提升机不在工作档源库位楼层,调度提升机
                        LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
                        commands.add(command1);//将命令添加进list
                    }
                    //输送线将货物运进来(无货反转)
                    LiftCommand command2 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 4);
                    command2.setOperaStaNo(staProtocol.getSiteId().shortValue());//输送线操作站点号
                    command2.setRotationDire(2);//给输送线下发链条转动信号,反转
                    command2.setDevpId(devpId);//输送线ID
                    command2.setStaNo((short) 104);//写入出库目标站104
                    commands.add(command2);//将命令添加进list
                    //提升机前往出库口,输送线楼层
                    LiftCommand command3 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), LiftLevType.TWO.lev);
                    command3.setDevpId(devpId);//输送线ID
                    commands.add(command3);//将命令添加进list
                    //提升机到达指定楼层,输送线将货物移出去(反转)
                    //输送线将货物移出去
                    LiftCommand command4 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 2);
                    command4.setOperaStaNo((short) 102);//操作102站
                    command4.setRotationDire(2);//给输送线下发链条转动信号,反转
                    command4.setDevpId(devpId);//输送线ID
                    commands.add(command4);//将命令添加进list
                    //提升机链条执行完毕后,给102站写入资料
                    LiftCommand command5 = liftThread.getResetCommand();
                    command5.setDevpId(devpId);//输送线ID
                    command5.setOperaStaNo((short) 102);//操作102站
                    command5.setStaNo((short) 104);//写入出库目标站104
                    command5.setRotationDire(0);//链条转动停止
                    commands.add(command5);
//                    //判断提升机是否到位
//                    StaProtocol staProtocol = devpThread.getStation().get(Utils.levToOutInStaNo(wrkMastLocNoLey >= 2 ? wrkMastLocNoLey + 1 : wrkMastLocNoLey));//起始站点
//                    if (liftLev != wrkMastLocNoLey && !staProtocol.isLiftArrival()) {
//                        //提升机不在工作档源库位楼层,调度提升机
//                        LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), wrkMastLocNoLey);
//                        commands.add(command1);//将命令添加进list
//                    }
//
//                    //输送线将货物运进来(无货反转)
//                    LiftCommand command2 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 4);
//                    command2.setOperaStaNo(staProtocol.getSiteId().shortValue());//输送线操作站点号
//                    command2.setRotationDire(2);//给输送线下发链条转动信号,反转
//                    command2.setDevpId(devpId);//输送线ID
//                    command2.setStaNo((short) 104);//写入出库目标站104
//                    commands.add(command2);//将命令添加进list
//
//                    //提升机前往出库口,输送线楼层
//                    LiftCommand command3 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), LiftLevType.TWO.lev);
//                    command3.setDevpId(devpId);//输送线ID
//                    commands.add(command3);//将命令添加进list
//
//                    //提升机到达指定楼层,输送线将货物移出去(反转)
//                    //输送线将货物移出去
//                    LiftCommand command4 = liftThread.getLiftTurnCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), 2);
//                    command4.setOperaStaNo((short) 102);//操作102站
//                    command4.setRotationDire(2);//给输送线下发链条转动信号,反转
//                    command4.setDevpId(devpId);//输送线ID
//                    commands.add(command4);//将命令添加进list
//
//                    //提升机链条执行完毕后,给102站写入资料
//                    LiftCommand command5 = liftThread.getResetCommand();
//                    command5.setDevpId(devpId);//输送线ID
//                    command5.setOperaStaNo((short) 102);//操作102站
//                    command5.setStaNo((short) 104);//写入出库目标站104
//                    command5.setRotationDire(0);//链条转动停止
//                    commands.add(command5);
                    //给提升机分配任务
                    liftProtocol.setTaskNo(wrkMast.getWrkNo().shortValue());//设置任务号
@@ -1899,7 +1901,7 @@
            //提升机为等待确认且空闲
            if (liftProtocol.getProtocolStatus() == LiftProtocolStatusType.WAITING.id
                    && liftProtocol.getTaskNo() != 0
                    && !liftProtocol.getRunning()
                    && !liftProtocol.getBusy()
            ) {
                DevpThread devpThread = null;
@@ -1951,9 +1953,9 @@
                            wrkMast.setWrkSts(25L);
                            break;
                        case 28://28.提升机搬运中 ==> 29.提升机搬运完成
                            if (liftProtocol.getPositionArrivalFeedback().intValue() != 2) {
                                continue;//提升机是否达到输送线楼层
                            }
//                            if (liftProtocol.getPositionArrivalFeedback().intValue() != 2) {
//                                continue;//提升机是否达到输送线楼层
//                            }
                            wrkMast.setWrkSts(29L);
                            wrkMast.setWrkSts(34L);//34.出库完成,暂时先直接完成出库工作档,后续需要根据输送线给出的状态来确定34.出库完成状态
                            //任务号清零
@@ -2007,10 +2009,10 @@
                    //设置提升机为空闲状态
                    liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                    //判断是否为四向穿梭车调度提升机,如是则无需清理任务号
                    if (!liftProtocol.getSecurityMk()) {
                        //任务号清零
                        liftProtocol.setTaskNo((short) 0);
                    }
//                    if (!liftProtocol.getSecurityMk()) {
//                        //任务号清零
//                        liftProtocol.setTaskNo((short) 0);
//                    }
                    //标记复位
                    liftProtocol.setPakMk(true);
                    //任务指令清零
@@ -2118,9 +2120,9 @@
                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);
//                //增加移动进提升机命令
//                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, 500);
//                commands.add(moveCommand);
                //分配目标库位
                shuttleProtocol.setLocNo(liftSiteLocNo);
@@ -2210,15 +2212,15 @@
                    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);//将该指令添加到队头
//                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();//使用输送站点口作为起点坐标
//                currentLocNo = basDevp.getLocNo();//使用输送站点口作为起点坐标
            }
            //直接计算车到源库位到目标库位路径
@@ -2779,9 +2781,9 @@
                    }
                    Short basDevpQrCode = Short.parseShort(basDevp.getQrCodeValue());//站点二维码
                    //增加移动进提升机命令
                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(basDevpQrCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, basDevpQrCode, 1600, 500);
                    commands.add(moveCommand);
//                    //增加移动进提升机命令
//                    ShuttleCommand moveCommand = shuttleThread.getMoveCommand(basDevpQrCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, basDevpQrCode, 1600, 500);
//                    commands.add(moveCommand);
                    //分配目标库位
                    shuttleProtocol.setLocNo(chargeLocNo);
@@ -2809,11 +2811,11 @@
                    continue;
                }
                //判断小车是否在提升机内
                if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
                    //小车不在提升机内
                    continue;
                }
//                //判断小车是否在提升机内
//                if (shuttleProtocol.getCurrentCode().intValue() != liftProtocol.getBarcode().intValue()) {
//                    //小车不在提升机内
//                    continue;
//                }
                //给提升机分配任务
                liftProtocol.setTaskNo(wrkCharge.getWrkNo().shortValue());//设置任务号
@@ -2823,10 +2825,10 @@
                //命令list
                ArrayList<LiftCommand> commands = new ArrayList<>();
                //提升机前往目标楼层
                //获取充电库位目标楼层命令
                LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), chargeLocNoLev >= 2 ? chargeLocNoLev + 1 : chargeLocNoLev);
                commands.add(command1);//将命令添加进list
//                //提升机前往目标楼层
//                //获取充电库位目标楼层命令
//                LiftCommand command1 = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), chargeLocNoLev >= 2 ? chargeLocNoLev + 1 : chargeLocNoLev);
//                commands.add(command1);//将命令添加进list
                wrkCharge.setWrkSts(54L);//提升机搬运中
                //所需命令组合完毕,更新数据库,提交到线程去工作
@@ -2866,12 +2868,12 @@
                    continue;//未找到路径
                }
                short startCode = liftProtocol.getBarcode();//提升机内部二维码
                Short distCode = Short.parseShort(basDevp.getQrCodeValue());//提升机口站点二维码
                Short runDirection = ShuttleRunDirection.BOTTOM.id;//运行方向
                //获取命令
                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, runDirection, startCode, 1600, 500);
                commands.add(0, moveCommand);//将该指令添加到队头
//                short startCode = liftProtocol.getBarcode();//提升机内部二维码
//                Short distCode = Short.parseShort(basDevp.getQrCodeValue());//提升机口站点二维码
//                Short runDirection = ShuttleRunDirection.BOTTOM.id;//运行方向
//                //获取命令
//                ShuttleCommand moveCommand = shuttleThread.getMoveCommand(startCode, distCode, 1600, runDirection, startCode, 1600, 500);
//                commands.add(0, moveCommand);//将该指令添加到队头
                //进行充电中
                shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING);
@@ -2938,6 +2940,525 @@
    }
    /**
     * 调度车辆
     */
    public void dispatchShuttle(Integer wrkNo, String locNo) {
        ArrayList<NyShuttleThread> sameLev = new ArrayList<>();//相同楼层的穿梭车
        ArrayList<NyShuttleThread> diffLev = new ArrayList<>();//不同楼层的穿梭车
        for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
            //获取四向穿梭车线程
            NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId());
            NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
                continue;
            }
            if (!shuttleProtocol.isIdle()) {
                continue;
            }
            int currentLev = shuttleProtocol.getPoint().getZ();//小车当前层高
            String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号
            if (currentLocNo.equals(locNo)) {
                //车辆当前位置已经是目标库位,调度该车
                shuttleMoveGenerate(wrkNo, locNo, shuttleProtocol.getShuttleNo().intValue());
                break;
            }
            if (currentLev == Utils.getLev(locNo)) {
                //工作档楼层相同的穿梭车
                sameLev.add(shuttleThread);
            }else {
                //工作档不同楼层的穿梭车
                diffLev.add(shuttleThread);
            }
        }
        Integer recentAllDistance = 9999999;
        NyShuttleThread recentShuttle = null;//当前距离最近的四向穿梭车线程
        if (sameLev.size() > 0) {
            //同一楼层有空闲穿梭车,则只在工作档楼层寻找
            //寻找离任务最近的穿梭车
            for (NyShuttleThread shuttleThread : sameLev) {
                //当前穿梭车库位号
                String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
                //当前穿梭车线程到目标地点距离
                List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, locNo, 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;
                }
            }
        }else {
            //同一楼层,没有空闲穿梭车,只能从其他楼层调度
            //寻找离任务最近的穿梭车
            for (NyShuttleThread 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;
                }
            }
        }
        if (recentShuttle == null) {//没有搜索到可用穿梭车
            return;
        }
        //搜索到可用穿梭车,调度该车
        shuttleMoveGenerate(wrkNo, locNo, recentShuttle.getSlave().getId());
    }
    /**
     * 小车迁移任务生成
     */
    @Transactional
    public boolean shuttleMoveGenerate(Integer wrkNo, String locNo, Integer shuttleNo) {
        Date now = new Date();
        //获取四向穿梭车线程
        NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
        if (shuttleThread == null) {
            return false;
        }
        NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
        if (shuttleProtocol == null) {
            return false;
        }
        //小车处于空闲状态
        if (!shuttleProtocol.isIdleNoCharge()) {
            return false;
        }
        //判断穿梭车是否存在未完成的小车移库任务
        WrkMast hasMoveWorking = wrkMastMapper.selectShuttleHasMoveWorking(shuttleNo);
        if (hasMoveWorking != null) {//小车存在移库任务,等待执行完成后再生成新的任务
            return false;
        }
        //判断是否有其他任务正在使用穿梭车
        WrkMast wrkMast2 = wrkMastMapper.selectShuttleWorking(shuttleNo);
        if (wrkMast2 != null) {//小车存在其他工作档任务,等待执行完成后再生成新的任务
            return false;
        }
        //判断是否有充电任务正在使用穿梭车
        WrkCharge wrkCharge = wrkChargeMapper.selectWorking(shuttleNo);
        if (wrkCharge != null) {//小车存在充电任务,等待执行完成后再生成新的任务
            return false;
        }
        // 获取工作号
        int workNo = commonService.getWorkNo(0);
        // 保存工作档
        WrkMast wrkMast = new WrkMast();
        wrkMast.setWrkNo(workNo);
        wrkMast.setIoTime(now);
        wrkMast.setWrkSts(101L); // 工作状态:101.移动到近点等待迁出
        wrkMast.setIoType(200); // 入出库状态: 200.小车移库
        wrkMast.setIoPri(20D);
        wrkMast.setShuttleNo(shuttleNo);//穿梭车号
        wrkMast.setSourceLocNo(shuttleProtocol.getCurrentLocNo()); // 源库位 => 小车当前库位号
        wrkMast.setLocNo(locNo); // 目标库位
        wrkMast.setPicking("N"); // 拣料
        wrkMast.setExitMk("N"); // 退出
        wrkMast.setLinkMis("N");
        wrkMast.setAppeTime(now);
        wrkMast.setModiTime(now);
        int res = wrkMastMapper.insert(wrkMast);
        if (res == 0) {
            News.error("小车迁移 --- 保存工作档失败! 穿梭车号:" + shuttleNo);
            throw new CoolException("保存工作档失败");
        }
        //给工作档绑定小车号
        WrkMast wrkMast1 = wrkMastMapper.selectByWorkNo(wrkNo);
        if (wrkMast1 != null) {
            wrkMast1.setShuttleNo(shuttleNo);
            wrkMastMapper.updateById(wrkMast1);
        }
        return true;
    }
    /**
     * 执行小车移库任务
     */
    public synchronized void shuttleMoveExecute() {
        //查询小车移库任务
        List<WrkMast> wrkMasts = wrkMastMapper.selectShuttleMoveWrk();
        for (WrkMast wrkMast : wrkMasts) {
            boolean step1 = this.shuttleMoveExecuteStep1(wrkMast);//小车移动到提升机中
            if (!step1) {
                continue;
            }
            boolean step2 = this.shuttleMoveExecuteStep2(wrkMast);//提升机搬运中
            if (!step2) {
                continue;
            }
            boolean step3 = this.shuttleMoveExecuteStep3(wrkMast);//小车迁出提升机中
            if (!step3) {
                continue;
            }
            boolean step4 = this.shuttleMoveExecuteStep4(wrkMast);//小车移动到目标库位中
            if (!step4) {
                continue;
            }
        }
    }
    /**
     * 小车迁移-小车移动到提升机中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStep1(WrkMast wrkMast) {
        //--------------------------------------小车移动到提升机中-----------------------------------------//
        Date now = new Date();
        //小车移动到提升机中  101.生成小车移库任务 ==> 102.小车到提升机中
        if (wrkMast.getWrkSts() == 101) {
            //获取四向穿梭车线程
            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.isIdleNoCharge()) {
                return false;
            }
            if (Utils.getLev(wrkMast.getLocNo()) == shuttleProtocol.getPoint().getZ()) {
                //目标库位和小车库位处于同一楼层,需要通过提升机调度
                return true;//直接进入108.小车移动中
            }
            //计算距离小车最近的提升机站点
            //查询小车所在楼层提升机输送站点
            int recentAllDistance = 9999999;//默认最近距离
            BasDevp recentDevp = null;//最近站点
            List<BasDevp> basDevps = basDevpService.selectHasLiftNoByLev(shuttleProtocol.getPoint().getZ());
            for (BasDevp basDevp : basDevps) {
                LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, basDevp.getLiftNo());
                if (liftThread == null) {
                    continue;
                }
                LiftProtocol liftProtocol = liftThread.getLiftProtocol();
                if (liftProtocol == null) {
                    continue;
                }
                if (!liftProtocol.isIdle()) {
                    continue;
                }
                //计算路径
                List<NavigateNode> calc = NavigateUtils.calc(shuttleProtocol.getCurrentLocNo(), basDevp.getLocNo(), NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(shuttleProtocol.getCurrentLocNo())));
                if (calc == null) {
                    continue;//计算失败,找下一个站点
                }
                Integer allDistance = NavigateUtils.getOriginPathAllDistance(calc);//根据原始节点结果,计算总行走距离
                if (recentAllDistance > allDistance) {
                    recentAllDistance = allDistance;//更新距离
                    recentDevp = basDevp;//更新输送站点
                }
            }
            if (recentDevp == null) {
                //没有找到可用输送站点
                return false;//等待下一次轮询
            }
            //获取提升机数据
            BasLift basLift = basLiftService.selectById(recentDevp.getLiftNo());
            if (basLift == null) {
                return false;//没有提升机数据
            }
            if (basLift.getPoint() == null) {
                return false;//没有设置提升机点位坐标
            }
            NavigateNode liftNode = new NavigateNode(basLift.getPoint().getX(), basLift.getPoint().getY());
            liftNode.setZ(basLift.getPoint().getZ());
            //获取小车到输送站点行走命令
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), recentDevp.getLocNo());
            //获取小车进提升机行走命令
            NyShuttleHttpCommand moveCommand = NyHttpUtils.getInOutLiftCommand(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), NavigatePositionConvert.locNoToNode(recentDevp.getLocNo()), liftNode, true);
            if (result.getCommands() == null) {
                return false;//路径计算失败
            }
            List<NyShuttleHttpCommand> commands = result.getCommands();
            commands.add(moveCommand);//添加小车迁入提升机命令
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO.id.shortValue());//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setCommands(commands);
            assignCommand.setNodes(result.getNodes());
            wrkMast.setWrkSts(102L);//小车移动到提升机中  101.生成小车移库任务 ==> 102.小车到提升机中
            wrkMast.setLiftNo(basLift.getLiftNo());//提升机号
            wrkMast.setModiTime(now);
            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 shuttleMoveExecuteStep2(WrkMast wrkMast) {
        //--------------------------------------提升机搬运中-----------------------------------------//
        Date now = new Date();
        //提升机搬运中  103.小车到提升机完成 ==> 104.提升机搬运中
        if (wrkMast.getWrkSts() == 103) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                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.isIdleNoCharge()) {
                return false;
            }
            //获取源站对应的输送站点
            BasDevp sourceBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getSourceLocNo()), liftProtocol.getLiftNo().intValue());
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), liftProtocol.getLiftNo().intValue());
            if (sourceBasDevp == null || targetBasDevp == null) {
                return false;//缺少站点信息
            }
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, sourceBasDevp.getDevNo(), targetBasDevp.getDevNo(), wrkMast.getWrkNo());
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
            //提交到线程去工作
            LiftAssignCommand assignCommand = new LiftAssignCommand();
            assignCommand.setCommands(commands);
            assignCommand.setLiftNo(liftProtocol.getLiftNo());
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
            assignCommand.setTaskMode(NyLiftTaskModelType.MOVE_CAR.id.shortValue());
            wrkMast.setWrkSts(104L);//提升机搬运中  103.小车到提升机完成 ==> 104.提升机搬运中
            wrkMast.setModiTime(now);
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
                MessageQueue.offer(SlaveType.Lift, liftProtocol.getLiftNo().intValue(), new Task(3, assignCommand));
            }
        }
        return true;
    }
    /**
     * 小车迁移-小车迁出提升机中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    private boolean shuttleMoveExecuteStep3(WrkMast wrkMast) {
        //--------------------------------------小车迁出提升机中-----------------------------------------//
        Date now = new Date();
        //小车迁出提升机中  105.提升机搬运完成 ==> 106.小车迁出提升机中
        if (wrkMast.getWrkSts() == 105) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                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.isIdleNoCharge()) {
                return false;
            }
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), liftProtocol.getLiftNo().intValue());
            if (targetBasDevp == null) {
                return false;//缺少站点信息
            }
            //获取提升机数据
            BasLift basLift = basLiftService.selectById(targetBasDevp.getLiftNo());
            if (basLift == null) {
                return false;//没有提升机数据
            }
            if (basLift.getPoint() == null) {
                return false;//没有设置提升机点位坐标
            }
            NavigateNode liftNode = new NavigateNode(basLift.getPoint().getX(), basLift.getPoint().getY());
            liftNode.setZ(basLift.getPoint().getZ());
            List<NyShuttleHttpCommand> commands = new ArrayList<>();
            //获取小车出提升机行走命令
            NyShuttleHttpCommand moveCommand = NyHttpUtils.getInOutLiftCommand(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), liftNode, NavigatePositionConvert.locNoToNode(targetBasDevp.getLocNo()), false);
            commands.add(moveCommand);//添加小车迁出提升机命令
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO.id.shortValue());//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setCommands(commands);
            assignCommand.setNodes(null);
            wrkMast.setWrkSts(106L);//小车迁出提升机中  105.提升机搬运完成 ==> 106.小车迁出提升机中
            wrkMast.setModiTime(now);
            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 shuttleMoveExecuteStep4(WrkMast wrkMast) {
        //--------------------------------------小车移动到目标库位中-----------------------------------------//
        Date now = new Date();
        //小车移动到目标库位中  107.小车迁出提升机完成 ==> 108.小车移动中
        if (wrkMast.getWrkSts() == 107) {
            //获取四向穿梭车线程
            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.isIdleNoCharge()) {
                return false;
            }
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), wrkMast.getLiftNo());
            if (targetBasDevp == null) {
                return false;//缺少站点信息
            }
            //获取提升机数据
            BasLift basLift = basLiftService.selectById(targetBasDevp.getLiftNo());
            if (basLift == null) {
                return false;//没有提升机数据
            }
            if (basLift.getPoint() == null) {
                return false;//没有设置提升机点位坐标
            }
            NavigateNode liftNode = new NavigateNode(basLift.getPoint().getX(), basLift.getPoint().getY());
            liftNode.setZ(basLift.getPoint().getZ());
            //获取小车从输送站到目标库位命令
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), targetBasDevp.getLocNo(), wrkMast.getLocNo());
            if (result.getCommands() == null) {
                return false;//路径计算失败
            }
            List<NyShuttleHttpCommand> commands = result.getCommands();
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
            assignCommand.setShuttleNo(shuttleProtocol.getShuttleNo()); // 四向穿梭车编号
            assignCommand.setTaskMode(ShuttleTaskModeType.SHUTTLE_MOVE_LOC_NO.id.shortValue());//小车移库任务
            assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());//任务号
            assignCommand.setAuto(true);//自动模式
            assignCommand.setCommands(commands);
            assignCommand.setNodes(result.getNodes());
            wrkMast.setWrkSts(108L);//小车移动到目标库位中  107.小车迁出提升机完成 ==> 108.小车移动中
            wrkMast.setModiTime(now);
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
            }
        }
        return true;
    }
    /**
     * 出入库模式切换
src/main/java/com/zy/common/utils/NavigatePositionConvert.java
@@ -6,6 +6,7 @@
import com.zy.asrs.service.BasDevpService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.NavigateNode;
/**
 * 库位编号和A*算法的xy轴转换工具类
@@ -22,6 +23,16 @@
        return newPosition;
    }
    //WCS系统库位号转路径算法节点
    public static NavigateNode locNoToNode(String locNo) {
        int col = Integer.parseInt(locNo.substring(0, 2));
        int row = Integer.parseInt(locNo.substring(2, 5));
        int[] newPosition = coverPosition(col,row);
        NavigateNode node = new NavigateNode(col, row);
        node.setZ(Utils.getLev(locNo));
        return node;
    }
    //牛眼坐标转WCS库位号
    public static String xyzToLocNo(int x, int y, int z) {
        int[] ints = NyXyzToWCSXyz(x, y, z);
src/main/java/com/zy/common/utils/NyLiftUtils.java
@@ -10,7 +10,7 @@
    /**
     * 获取提升机命令
     */
    public NyLiftCommand getLiftCommand(Integer liftNo, Integer taskModel, Integer sourceSta, Integer targetSta, Integer taskNo) {
    public static NyLiftCommand getLiftCommand(Integer liftNo, Integer taskModel, Integer sourceSta, Integer targetSta, Integer taskNo) {
        NyLiftCommand command = new NyLiftCommand();
        command.setLiftNo(liftNo.shortValue());
        command.setTaskNo(taskNo.shortValue());
src/main/java/com/zy/core/MainProcess.java
@@ -69,6 +69,8 @@
                    mainService.liftFinished();
                    //库位移转
                    mainService.locToLocExecute();
                    //执行小车移库任务
                    mainService.shuttleMoveExecute();
//                    // 异常信息记录
//                    mainService.recErr();
                    // 入库  ===>> 空栈板初始化入库,叉车入库站放货
src/main/java/com/zy/core/enums/NyLiftTaskModelType.java
New file
@@ -0,0 +1,42 @@
package com.zy.core.enums;
/**
 * 牛眼提升机任务类型枚举
 */
public enum NyLiftTaskModelType {
    MOVE_TRAY(1, "移托盘"),
    MOVE_CAR(2, "移小车")
    ;
    public Integer id;
    public String desc;
    NyLiftTaskModelType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static NyLiftTaskModelType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (NyLiftTaskModelType type : NyLiftTaskModelType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static NyLiftTaskModelType get(NyLiftTaskModelType type) {
        if (null == type) {
            return null;
        }
        for (NyLiftTaskModelType type2 : NyLiftTaskModelType.values()) {
            if (type2 == type) {
                return type2;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java
@@ -21,6 +21,7 @@
    MOVE_LIFT(16, "移动到提升机"),
    AVOID(17, "避让任务"),
    TRANSPORT(18, "搬运任务"),
    SHUTTLE_MOVE_LOC_NO(19, "小车移库任务"),
    ;
    public Integer id;
src/main/java/com/zy/core/model/command/LiftAssignCommand.java
@@ -24,11 +24,8 @@
    /**
     * 作业类型
     * 1: 上升一层
     * 2: 下降一层
     * 3: 有货正转
     * 4: 有货反转
     * 5: 复位
     * 1=移托盘;升降机将源站台托盘移到目标站台
     * 2=移小车,升降机移到目标层,等待
     */
    private Short taskMode = 0;
src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java
@@ -438,4 +438,14 @@
        }
    }
    // 是否处于空闲待命状态
    public Boolean isIdleNoCharge() {
        boolean res = this.free == ShuttleStatusType.IDLE.id
                && this.pakMk.equals(true)
                && this.errState == 0
                && this.taskNo == 0
                && this.protocolStatus == ShuttleProtocolStatusType.IDLE.id
                ;
        return res;
    }
}
src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -1076,10 +1076,10 @@
            return false;
        }
        if (liftProtocol.getPlatShuttleCheck()) {
            //提升机内有车禁止下发
            return false;
        }
//        if (liftProtocol.getPlatShuttleCheck()) {
//            //提升机内有车禁止下发
//            return false;
//        }
        if (redisCommand.getLiftSecurityMk()) {
            //已经执行过提升机命令,禁止下发
@@ -1097,15 +1097,15 @@
        liftProtocol.setTaskNo(shuttleProtocol.getTaskNo());//设置任务号
        liftProtocol.setShuttleNo(shuttleProtocol.getShuttleNo());//设置四向穿梭车号
        liftProtocol.setProtocolStatus(LiftProtocolStatusType.WORKING);//设置提升机状态为工作中
        liftProtocol.setSecurityMk(true);//标记置为true,防止其他任务占用当前提升机
//        liftProtocol.setSecurityMk(true);//标记置为true,防止其他任务占用当前提升机
        redisCommand.setLiftSecurityMk(true);//标记置为true,防止其他任务占用当前提升机
        //任务数据保存到redis
        redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand));
        //命令list
        ArrayList<LiftCommand> liftCommands = new ArrayList<>();
        LiftCommand liftCommand = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), shuttleLocNoLev);
        liftCommands.add(liftCommand);//将命令添加进list
//        LiftCommand liftCommand = liftThread.getLiftUpDownCommand(liftProtocol.getLiftNo(), liftProtocol.getTaskNo(), shuttleLocNoLev);
//        liftCommands.add(liftCommand);//将命令添加进list
        LiftAssignCommand liftAssignCommand = new LiftAssignCommand();
        liftAssignCommand.setCommands(liftCommands);
src/main/resources/mapper/BasDevpMapper.xml
@@ -43,6 +43,8 @@
        <result column="cart_pos" property="cartPos" />
        <result column="qr_code_value" property="qrCodeValue" />
        <result column="loc_no" property="locNo" />
        <result column="lev" property="lev" />
        <result column="lift_no" property="liftNo" />
    </resultMap>
@@ -95,4 +97,20 @@
        where 1=1
        and dev_no in ('105','106','107','108')
    </select>
    <select id="selectHasLiftNoByLev" resultMap="BaseResultMap">
        select *
        from asr_bas_devp
        where 1=1
        and lev = #{lev}
        and lift_no is not null
    </select>
    <select id="selectByLevAndLiftNo" resultMap="BaseResultMap">
        select *
        from asr_bas_devp
        where 1=1
        and lev = #{lev}
        and lift_no = #{liftNo}
    </select>
</mapper>
src/main/resources/mapper/WrkMastMapper.xml
@@ -185,4 +185,29 @@
        and barcode = #{barcode}
        order by io_pri desc,wrk_sts desc
    </select>
    <select id="selectShuttleHasMoveWorking" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast
        where 1=1
        and shuttle_no = #{shuttleNo}
        and io_type = 200
        order by io_pri desc,io_time,wrk_no asc
    </select>
    <select id="selectShuttleMoveWrk" resultMap="BaseResultMap">
        select * from dbo.asr_wrk_mast
        where 1=1
        and wrk_sts in (101,103,105,107)
        and io_type = 200
        order by io_pri desc,io_time,wrk_no asc
    </select>
    <select id="selectShuttleWorking" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast
        where 1=1
        and shuttle_no = #{shuttleNo}
        and wrk_sts not in (9,10,29,30)
        and io_type not in (200)
        order by io_pri desc,io_time,wrk_no asc
    </select>
</mapper>