#
Junjie
2023-07-31 4315668f4de2ab2bf8a24ac206d71f072dd00357
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;
    }
    /**
     * 出入库模式切换