自动化立体仓库 - WCS系统
#
Junjie
2023-10-03 87186c12f7c8864da8925aea3e91ecde1d16d255
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -99,6 +99,9 @@
    private ShuttleDispatchUtils shuttleDispatchUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WrkMastLocMapper wrkMastLocMapper;
    /**
     * 组托
@@ -235,14 +238,14 @@
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            // plc 处理
                            barcodeThread.setBarcode("");
                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
                            staProtocol.setStaNo(dto.getStaNo().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                throw new CoolException("更新plc站点信息失败");
                            }
//                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
//                            staProtocol.setStaNo(dto.getStaNo().shortValue());
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//
//                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                            if (!result) {
//                                throw new CoolException("更新plc站点信息失败");
//                            }
                            // 判断重复工作档
                            WrkMast wrkMast = wrkMastMapper.selectPakInStep11(inSta.getStaNo());
@@ -264,10 +267,10 @@
                            }
                            News.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/loc/v1", JSON.toJSONString(param), response);
                        } else if (code == 700) {
                            staProtocol.setWorkNo((short) 32002);
                            staProtocol.setRollback102(1);//102站回退信号
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(5, staProtocol));
//                            staProtocol.setWorkNo((short) 32002);
//                            staProtocol.setRollback102(1);//102站回退信号
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(5, staProtocol));
                            // led 异常显示
                            if (ledThread != null) {
@@ -662,6 +665,34 @@
     * 入库  ===>>  四向穿梭车入库作业下发
     */
    public synchronized void shuttleInExecute() {
        List<WrkMast> wrkMasts = wrkMastMapper.selectInStep4();
        for (WrkMast wrkMast : wrkMasts) {
            //获取源站
            BasDevp sourceBasDevp = basDevpService.selectById(wrkMast.getSourceStaNo());
            if (sourceBasDevp == null) {
                continue;//站点不存在
            }
            //获取目标站
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(sourceBasDevp.getLiftNo(), Utils.getLev(wrkMast.getLocNo()));
            if (liftStaProtocol == null) {
                continue;//站点不存在
            }
            // 判断是否满足入库条件,自动、空闲、有物
            if (!(liftStaProtocol.getModel() && !liftStaProtocol.getBusy() && liftStaProtocol.getHasTray())) {
                continue;
            }
            boolean step1 = this.shuttleInExecuteStep1(wrkMast, liftStaProtocol);//小车搬入库中
            if (!step1) {
                continue;
            }
        }
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库站
@@ -685,30 +716,64 @@
                    continue;
                }
                WrkMast wrkMast = wrkMastMapper.selectRackInStep4(workNo, staProtocol.getSiteId());
                if (wrkMast == null) {
                    continue;
                }
                boolean step1 = this.shuttleInExecuteStep1(wrkMast, basDevp);//小车搬入库中
                if (!step1) {
                    continue;
                }
            }
        }
    }
//    /**
//     * 入库  ===>>  四向穿梭车入库作业下发
//     */
//    public synchronized void shuttleInExecute() {
//        // 根据输送线plc遍历
//        for (DevpSlave devp : slaveProperties.getDevp()) {
//            // 遍历入库站
//            for (DevpSlave.StaRack staRack : devp.getRackInStn()) {
//                // 获取入库站信息
//                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
//                StaProtocol staProtocol = devpThread.getStation().get(staRack.getStaNo());
//                if (staProtocol == null) {
//                    continue;
//                } else {
//                    staProtocol = staProtocol.clone();
//                }
//                Short workNo = staProtocol.getWorkNo();
//                BasDevp basDevp = basDevpService.selectById(staProtocol.getSiteId());
//                if (basDevp == null) {
//                    continue;//站点信息不存在
//                }
//
//                // 判断是否满足入库条件,自动、有物、四向穿梭车可取信号
//                if (!(staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isShuttleTakeEnable())) {
//                    continue;
//                }
//
//                WrkMast wrkMast = wrkMastMapper.selectRackInStep4(workNo, staProtocol.getSiteId());
//                if (wrkMast == null) {
//                    continue;
//                }
//
//                boolean step1 = this.shuttleInExecuteStep1(wrkMast, basDevp);//小车搬入库中
//                if (!step1) {
//                    continue;
//                }
//
//            }
//        }
//
//    }
    /**
     * 入库-小车搬入库中
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
    public boolean shuttleInExecuteStep1(WrkMast wrkMast, BasDevp basDevp) {
    public boolean shuttleInExecuteStep1(WrkMast wrkMast, LiftStaProtocol liftStaProtocol) {
        if (wrkMast.getWrkSts() == 4) {
            if (wrkMast.getShuttleNo() == null) {//没有绑定小车,进行调度
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), basDevp.getLocNo());//调度小车到货物所在输送站点进行取货
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftStaProtocol.getLocNo());//调度小车到货物所在输送站点进行取货
                return false;
            }
@@ -729,15 +794,21 @@
                return false;//小车已被独占,禁止再派发任务
            }
            //判断小车是否存在移动任务
            WrkMast hasMoveWorking = wrkMastMapper.selectShuttleHasMoveWorking(wrkMast.getShuttleNo());
            if (hasMoveWorking != null) {
                return false;//存在移动任务,禁止执行入库任务
            }
            //判断小车是否到达输送站点库位
            if (!shuttleProtocol.getCurrentLocNo().equals(basDevp.getLocNo())) {
            if (!shuttleProtocol.getCurrentLocNo().equals(liftStaProtocol.getLocNo())) {
                //小车不在输送站点位置
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), basDevp.getLocNo(), wrkMast.getShuttleNo());//调度小车到货物所在输送站点进行取货
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftStaProtocol.getLocNo(), wrkMast.getShuttleNo());//调度小车到货物所在输送站点进行取货
                return false;
            }
            //小车已抵达输送站点位置,进行搬运货物
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), basDevp.getLocNo(), wrkMast.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
@@ -802,26 +873,15 @@
                return false;//出库站点不可出
            }
            //判断各楼层内部输送站点是否空闲无物
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, basDevp.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            //获取提升机站点list
            List<LiftStaProtocol> liftStaProtocols = liftThread.getLiftStaProtocols();
            if (liftStaProtocols.isEmpty()) {
                return false;
            //获取源站
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(basDevp.getLiftNo(), Utils.getLev(wrkMast.getSourceLocNo()));
            if (liftStaProtocol == null) {
                return false;//找不到站点
            }
            for (LiftStaProtocol liftStaProtocol : liftStaProtocols) {
                //判断当前出库任务对应楼层的提升机站点状态
                if (liftStaProtocol.getLev() == Utils.getLev(wrkMast.getSourceLocNo())) {
                    if (liftStaProtocol.getModel() && !liftStaProtocol.getBusy() && !liftStaProtocol.getHasTray()) {
                        return false;//站点必须自动、空闲、没有托盘
                    }
                }
            if (!(liftStaProtocol.getModel() && !liftStaProtocol.getBusy() && !liftStaProtocol.getHasTray())) {
                return false;//站点必须自动、空闲、没有托盘
            }
            if (wrkMast.getShuttleNo() == null) {//没有绑定小车,进行调度
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo());//调度小车到货物所在库位进行取货
@@ -848,12 +908,12 @@
            //判断小车是否到达货物库位
            if (!shuttleProtocol.getCurrentLocNo().equals(wrkMast.getSourceLocNo())) {
                //小车不在输送站点位置
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo());//调度小车到货物所在输送站点进行取货
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getShuttleNo());//调度小车到货物所在库位进行取货
                return false;
            }
            //小车已抵达货物位置,进行搬运货物
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), null);
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), liftStaProtocol.getLocNo());//将货物搬运至提升机输送站点
            if (result == null) {//出库路径计算失败
                return false;
            }
@@ -892,6 +952,8 @@
            }
            //四向穿梭车状态为等待确认、小车处于空闲状态
            if (shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id  //任务完成等待确认
                    && shuttleProtocol.getTaskNo() != 0
                    && shuttleProtocol.getFree() == ShuttleStatusType.IDLE.id
@@ -902,14 +964,16 @@
                    switch (wrkMast.getWrkSts().intValue()) {
                        case 5://5.小车搬运中 ==> 9.入库完成
                            wrkMast.setWrkSts(9L);
                            if (shuttleProtocol.getToken() == wrkMast.getWrkNo()) {
                            shuttleProtocol.setTaskNo(0);
                            if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放小车令牌
                                shuttleProtocol.setToken(0);
                            }
                            break;
                        case 22://22.小车搬运中 ==> 23.小车搬运完成
                            wrkMast.setWrkSts(23L);
                            if (shuttleProtocol.getToken() == wrkMast.getWrkNo()) {
                            shuttleProtocol.setTaskNo(0);
                            if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放小车令牌
                                shuttleProtocol.setToken(0);
                            }
@@ -919,13 +983,15 @@
                            break;
                        case 104://104.小车迁入提升机中 ==> 105.小车迁入提升机完成
                            wrkMast.setWrkSts(105L);
                            shuttleProtocol.setTaskNo(0);//清理工作号
                            break;
                        case 108://108.小车迁出提升机中 ==> 109.小车迁出提升机完成
                            wrkMast.setWrkSts(109L);
                            break;
                        case 110://110.小车移动中 ==> 111.小车移动完成
                            wrkMast.setWrkSts(111L);
                            if (shuttleProtocol.getToken() == wrkMast.getWrkNo()) {
                            shuttleProtocol.setTaskNo(0);
                            if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放小车令牌
                                shuttleProtocol.setToken(0);
                            }
@@ -934,6 +1000,17 @@
                    }
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        if (wrkMast.getWrkSts() == 111) {
                            // 保存工作主档历史档
                            if (wrkMastLocMapper.save(wrkMast.getWrkNo()) <= 0) {
                                log.info("保存工作历史档[workNo={0}]失败", wrkMast.getWrkNo());
                            }
                            // 删除工作主档
                            if (!wrkMastService.deleteById(wrkMast)) {
                                log.info("删除工作主档[workNo={0}]失败", wrkMast.getWrkNo());
                            }
                        }
                        //设置四向穿梭车为空闲状态
                        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                        //源库位清零
@@ -945,6 +1022,24 @@
                        News.info("四向穿梭车已确认且任务完成状态,复位。四向穿梭车号={}", shuttleProtocol.getShuttleNo());
                    } else {
                        News.error("四向穿梭车已确认且任务完成状态,复位失败,但未找到工作档。四向穿梭车号={},工作号={}", shuttleProtocol.getShuttleNo(), shuttleProtocol.getTaskNo());
                    }
                }else {
                    ShuttleAssignCommand assignCommand = shuttleProtocol.getAssignCommand();
                    if (!assignCommand.getAuto()) {
                        //手动模式
                        //工作号清零
                        shuttleProtocol.setTaskNo(0);
                        //设置四向穿梭车为空闲状态
                        shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
                        //源库位清零
                        shuttleProtocol.setSourceLocNo(null);
                        //目标库位清零
                        shuttleProtocol.setLocNo(null);
                        //任务指令清零
                        shuttleProtocol.setAssignCommand(null);
                        //清零令牌
                        shuttleProtocol.setToken(0);
                        News.info("四向穿梭车已确认且任务完成状态,复位。四向穿梭车号={}", shuttleProtocol.getShuttleNo());
                    }
                }
@@ -968,6 +1063,11 @@
            }
            if (!liftProtocol.isIdle()) {
                continue;
            }
            //判断提升机令牌是否被占用
            if (liftProtocol.getToken() != 0) {
                continue;
            }
@@ -1009,7 +1109,17 @@
        //2.设备上走 ==> 3.提升机搬运中
        if (wrkMast.getWrkSts() == 2) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            //获取源站
            BasDevp sourceBasDevp = basDevpService.selectById(wrkMast.getSourceStaNo());
            if (sourceBasDevp == null) {
                return false;//找不到站点
            }
            if (!sourceBasDevp.getInEnable().equals("Y")) {
                return false;//站点不可入
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, sourceBasDevp.getLiftNo());
            if (liftThread == null) {
                return false;
            }
@@ -1017,30 +1127,46 @@
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
            if (!liftProtocol.isIdle()) {
                return false;
            }
            //判断提升机令牌是否未被占领
            if (liftProtocol.getToken() != 0) {
                return false;//提升机已被独占,禁止再派发任务
            }
            //判断提升机内是否有小车
            if (liftProtocol.getHasCar()) {
                return false;//有小车,禁止派发
            }
            //判断提升机内是否有托盘
            if (liftProtocol.getHasTray()) {
                return false;//有托盘,禁止派发
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastMapper.selectLiftWrkMast(liftThread.getSlave().getId());
            if (liftWrkMast != null) {
                return false;//当前提升机存在未完成任务,等待下一次轮询
            }
            //获取源站对应的输送站点
            BasDevp sourceBasDevp = basDevpService.selectById(wrkMast.getSourceStaNo());
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (sourceBasDevp == null || targetBasDevp == null) {
                return false;//缺少站点信息
            //获取源站对应的牛眼提升机站点编号(起点编号)
            Integer startSta = Integer.parseInt(sourceBasDevp.getQrCodeValue());
            //获取提升机站点
            LiftStaProtocol targetStaProtocol = NyLiftUtils.getLiftStaByLev(liftThread.getSlave().getId(), Utils.getLev(wrkMast.getLocNo()));
            if (targetStaProtocol == null) {
                return false;//站点不存在
            }
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, sourceBasDevp.getDevNo(), targetBasDevp.getDevNo(), wrkMast.getWrkNo());
            if (targetStaProtocol.getHasTray()) {
                return false;//提升机站点有托盘,禁止派发
            }
            Integer targetSta = targetStaProtocol.getStaNo();
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, startSta, targetSta, wrkMast.getWrkNo());
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
@@ -1076,7 +1202,28 @@
        //23.小车搬运完成 ==> 24.提升机搬运中
        if (wrkMast.getWrkSts() == 23) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            //调度小车避让
            boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkMast.getSourceLocNo()), wrkMast.getShuttleNo(), shuttleThread);
            if (!result) {
                return false;
            }
            //获取出库站点(目标站)
            BasDevp basDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (basDevp == null) {
                return false;//出库站点不存在
            }
            if (!basDevp.getOutEnable().equals("Y")) {
                return false;//出库站点不可出
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, basDevp.getLiftNo());
            if (liftThread == null) {
                return false;
            }
@@ -1084,7 +1231,7 @@
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
            if (!liftProtocol.isIdle()) {
                return false;
            }
            //判断提升机令牌是否未被占领
@@ -1097,16 +1244,23 @@
                return false;//当前提升机存在未完成任务,等待下一次轮询
            }
            //获取源站对应的输送站点
            BasDevp sourceBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getSourceLocNo()), liftProtocol.getLiftNo().intValue());
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectById(wrkMast.getSourceStaNo());
            if (sourceBasDevp == null || targetBasDevp == null) {
                return false;//缺少站点信息
            //获取源站对应的牛眼提升机站点编号(起点编号)
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(liftThread.getSlave().getId(), Utils.getLev(wrkMast.getSourceLocNo()));
            if (liftStaProtocol == null) {
                return false;//找不到站点
            }
            Integer startSta = liftStaProtocol.getStaNo();
            //获目标站源站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (targetBasDevp == null) {
                return false;//站点不存在
            }
            //获取牛眼提升机站点编号(目标编号)
            Integer targetSta = Integer.parseInt(targetBasDevp.getQrCodeValue());
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, sourceBasDevp.getDevNo(), targetBasDevp.getDevNo(), wrkMast.getWrkNo());
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftThread.getSlave().getId(), NyLiftTaskModelType.MOVE_TRAY.id, startSta, targetSta, wrkMast.getWrkNo());
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
@@ -1149,7 +1303,6 @@
                    && liftProtocol.getTaskNo() != 0
                    && !liftProtocol.getBusy()
            ) {
                //将任务档标记为完成
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo324104(liftProtocol.getTaskNo().intValue());
                if (wrkMast != null) {
@@ -1157,7 +1310,7 @@
                        case 3://3.提升机搬运中 ==> 4.提升机搬运完成
                            wrkMast.setWrkSts(4L);
                            wrkMast.setLiftNo(null);//释放提升机
                            if (liftProtocol.getToken() == wrkMast.getWrkNo()) {
                            if (liftProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放提升机令牌
                                liftProtocol.setToken(0);
                            }
@@ -1167,10 +1320,16 @@
                            if (wrkMast.getIoType() == 11) {//库位移转
                                wrkMast.setWrkSts(4L);//4.提升机搬运完成
                            }
                            if (liftProtocol.getToken() == wrkMast.getWrkNo()) {
                            if (liftProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放提升机令牌
                                liftProtocol.setToken(0);
                            }
                            if (wrkMast.getMk() == null || !wrkMast.getMk().equals("Y")) {
                                //不需要用到机械臂,直接转29.出库完成
                                wrkMast.setWrkSts(29L);
                            }
                            break;
                        case 106://106.提升机搬运中 ==> 107.提升机搬运完成
                            wrkMast.setWrkSts(107L);
@@ -1187,8 +1346,19 @@
                    } else {
                        News.error("提升机已确认且任务完成状态,复位失败,但未找到工作档。提升机号={},工作号={}", liftProtocol.getLiftNo(), liftProtocol.getTaskNo());
                    }
                }else {
                    LiftAssignCommand assignCommand = liftProtocol.getAssignCommand();
                    if (assignCommand != null) {
                        if (!assignCommand.getAuto()) {
                            //手动操作
                            //设置提升机为空闲状态
                            liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                            //任务指令清零
                            liftProtocol.setAssignCommand(null);
                            News.info("提升机已确认手动操作。提升机号={}", liftProtocol.getLiftNo());
                        }
                    }
                }
            }
        }
    }
@@ -1207,7 +1377,7 @@
        //查询库位移转工作档
        List<WrkMast> wrkMasts1 = wrkMastMapper.selectLocToLocWrkMast();
        for (WrkMast wrkMast : wrkMasts1) {
            if (wrkMast.getSourceLocNo().equals(wrkMast.getLocNo())) {
            if (Utils.getLev(wrkMast.getSourceLocNo()) == Utils.getLev(wrkMast.getLocNo())) {
                boolean step1 = this.locToLocExecuteStep1(wrkMast);//同楼层库位移转
                if (!step1) {
                    continue;
@@ -1267,7 +1437,7 @@
            }
            //小车已抵达源库位,进行搬运货物
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), wrkMast.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
@@ -1326,13 +1496,17 @@
            }
            //获取穿梭车最近且空闲的提升机输送站点
            BasDevp liftSta = shuttleDispatchUtils.getRecentLiftSta(shuttleThread.getSlave().getId());
            LiftStaProtocol liftSta = shuttleDispatchUtils.getRecentLiftSta(shuttleThread.getSlave().getId());
            if (liftSta == null) {
                return false;//没有可用且空闲的输送站点
            }
            //源站
            Integer sourceStaNo = liftSta.getStaNo();
            //提升机号*100+目标楼层=目标站点
            Integer staNo = liftSta.getLiftNo() * 100 + Utils.getLev(wrkMast.getLocNo());//目标站
            //小车已抵达源库位,将货物搬运到输送站点
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getSourceLocNo(), liftSta.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), liftSta.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
@@ -1347,7 +1521,8 @@
            assignCommand.setNodes(result.getNodes());//路径节点
            wrkMast.setWrkSts(22L);//21.生成出库任务 => 22.小车搬运中
            wrkMast.setLiftNo(liftSta.getLiftNo());//设置提升机号
            wrkMast.setSourceStaNo(sourceStaNo);//源站
            wrkMast.setStaNo(staNo);//目标站
            wrkMast.setModiTime(new Date());
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
@@ -1387,16 +1562,16 @@
                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;//缺少站点信息
            //源站
            Integer sourceStaNo = wrkMast.getSourceStaNo();
            //目标站
            Integer staNo = wrkMast.getStaNo();
            if (sourceStaNo == null || staNo == null) {
                return false;//源站或目标站为空
            }
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, sourceBasDevp.getDevNo(), targetBasDevp.getDevNo(), wrkMast.getWrkNo());
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, sourceStaNo, staNo, wrkMast.getWrkNo());
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
@@ -1422,7 +1597,7 @@
    }
    /**
     * 跨楼层库位移转-调度车辆取货并运送到目标枯萎
     * 跨楼层库位移转-调度车辆取货并运送到目标库位
     * 如需主方法执行continue,请返回false
     * ps:返回值true并不代表该方法执行成功,返回值仅做标记用于主方法是否执行continue
     */
@@ -1460,7 +1635,7 @@
            }
            //小车已抵达目标输送站点,将货物搬运到目标库位
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), targetBasDevp.getLocNo(), wrkMast.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), targetBasDevp.getLocNo(), wrkMast.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
@@ -1475,6 +1650,7 @@
            assignCommand.setNodes(result.getNodes());//路径节点
            wrkMast.setWrkSts(5L);//4.提升机搬运完成 => 5.小车搬运中
            wrkMast.setLiftNo(null);//释放提升机
            wrkMast.setModiTime(new Date());
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
@@ -1762,15 +1938,15 @@
                        Integer code = jsonObject.getInteger("code");
                        if (code.equals(200)) {
                            StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                            // 更新站点信息 且 下发plc命令
                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
                            staProtocol.setStaNo(dto.getStaNo().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                throw new CoolException("更新plc站点信息失败");
                            }
                            barcodeThread.setBarcode("");
//                            // 更新站点信息 且 下发plc命令
//                            staProtocol.setWorkNo(dto.getWorkNo().shortValue());
//                            staProtocol.setStaNo(dto.getStaNo().shortValue());
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                            if (!result) {
//                                throw new CoolException("更新plc站点信息失败");
//                            }
                        } else {
                            if (ledThread != null) {
                                String errorMsg = jsonObject.getString("msg");
@@ -1788,6 +1964,97 @@
                }
            }
        }
    }
    /**
     * AGV补货 => 机械臂拣料
     */
    public void agvRestockByRobot() {
        //检测300站是否自动、有物、工作号
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 获取入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            StaProtocol staProtocol = devpThread.getStation().get(300);
            if (staProtocol == null) {
                continue;
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() != 0) {
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                if (wrkMast.getWrkSts() != 25) {//25.提升机搬运完成
                    continue;
                }
                if (wrkMast.getMk() != null && wrkMast.getMk().equals("Y")) {//标记为Y表示需要用到机械臂拣料
                    Short targetSta = null;//目标站
                    //判断机械臂拣料站是否空闲
                    StaProtocol staProtocol303 = devpThread.getStation().get(303);
                    StaProtocol staProtocol317 = devpThread.getStation().get(317);
                    if (staProtocol303.isAutoing() && !staProtocol303.isLoading()) {
                        //自动、无物
                        targetSta = (short) 303;
                    } else if (staProtocol317.isAutoing() && !staProtocol317.isLoading()) {
                        //自动、无物
                        targetSta = (short) 317;
                    }else {
                        continue;//没有空闲站点
                    }
                    targetSta = (short) 317;
                    if (wrkMast.getStaNo() != 303 && wrkMast.getStaNo() != 317) {
                        //覆盖工作档目标站
                        wrkMast.setStaNo(targetSta.intValue());
                        if (wrkMastMapper.updateById(wrkMast) > 0) {
                            //向300站写入目标站
                            staProtocol = staProtocol.clone();
                            staProtocol.setStaNo(targetSta);//移动到目标站
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            try {
                                Thread.sleep(500);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            continue;
                        }
                    }
                }
            }
            StaProtocol staProtocol303 = devpThread.getStation().get(303);
            StaProtocol staProtocol317 = devpThread.getStation().get(317);
            if (staProtocol303.isAutoing() && staProtocol303.isLoading() && staProtocol303.getWorkNo() != 0) {
                //调度机械臂
//                //查询是否有工作档
//                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol303.getWorkNo().intValue());
//                if (wrkMast == null) {
//                    continue;
//                }
//                WrkDetl wrkDetl = wrkDetlService.selectById(wrkMast.getWrkNo());
//                if (wrkDetl == null) {
//                    continue;
//                }
//                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), wrkDetl.getAnfme().intValue(), "303");
                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), -1, "303");
            }else if (staProtocol317.isAutoing() && staProtocol317.isLoading() && staProtocol317.getWorkNo() != 0) {
                //调度机械臂
//                //查询是否有工作档
//                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol317.getWorkNo().intValue());
//                if (wrkMast == null) {
//                    continue;
//                }
//                WrkDetl wrkDetl = wrkDetlService.selectById(wrkMast.getWrkNo());
//                if (wrkDetl == null) {
//                    continue;
//                }
//                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), wrkDetl.getAnfme().intValue(), "317");
                RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), -1, "317");
            }
        }
    }
@@ -1978,11 +2245,39 @@
                continue;
            }
            //小车所在楼层
            int lev = Utils.getLev(shuttleProtocol.getCurrentLocNo());
            ShuttleChargeType shuttleCharge = null;
            //搜索小车所在楼层有没有充电桩
            for (ShuttleChargeType chargeType : ShuttleChargeType.values()) {
                if (lev != Utils.getLev(chargeType.locNo)) {
                    continue;//小车和充电桩不在同一层
                }
                //小车和充电桩在同一层
                if (wrkChargeService.selectWorkingOfCharge(chargeType.id) == null) {
                    shuttleCharge = chargeType;
                    break;
                }
            }
            if (shuttleCharge == null) {
                //同楼层没有找到充电桩,找可用充电桩
                //小车同楼层没有充电桩,只要充电桩可用就生成充电任务
                for (ShuttleChargeType chargeType : ShuttleChargeType.values()) {
                    if (wrkChargeService.selectWorkingOfCharge(chargeType.id) == null) {
                        //判断当前充电桩楼层是否有小车,如有小车,不分配该充电桩
                        int chargeLev = Utils.getLev(chargeType.locNo);//充电桩楼层
                        boolean checkLevHasShuttle = Utils.checkLevHasShuttle(chargeLev);//检测楼层是否有穿梭车
                        if (checkLevHasShuttle) {
                            //当前充电桩楼层有穿梭车,不分配该充电桩
                            continue;
                        }
                        shuttleCharge = chargeType;
                        break;
                    }
                }
            }
@@ -2005,7 +2300,6 @@
                continue;
            }
            shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING);//充电中
            News.info("保存{}号四向穿梭车充电任务成功!!!", shuttle.getId());
        }
    }
@@ -2060,7 +2354,8 @@
                }
            } else if (wrkCharge.getWrkSts() == 52) {
                //检测小车是否满电
                if (shuttleProtocol.getPowerPercent() < 100) {
                int maxPower = 95;
                if (shuttleProtocol.getPowerPercent() < maxPower) {
                    continue;
                }
@@ -2076,21 +2371,34 @@
                assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位(小车当前位置)
                assignCommand.setCommands(commands);//运行命令
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                wrkCharge.setWrkSts(53L);//52.小车去充电中 => 53.小车充电完成
                wrkCharge.setModiTime(new Date());
                if (wrkChargeMapper.updateById(wrkCharge) > 0) {
                    //下发任务
                    MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
                    shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE.id);
                    shuttleProtocol.setTaskNo(0);
                    shuttleProtocol.setPakMk(false);
                }
            } else if (wrkCharge.getWrkSts() == 53) {
                boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkCharge.getLocNo()), shuttleThread.getSlave().getId(), shuttleThread);
                if (!result) {
                    continue;
                }
                if (shuttleProtocol.getChargState() == 0) {//小车处于未充电状态
                    boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkCharge.getLocNo()), shuttleThread.getSlave().getId(), shuttleThread);
                    if (!result) {
                        continue;
                    }
                wrkCharge.setWrkSts(60L);//53.小车充电完成 => 60.充电任务完成
                wrkCharge.setModiTime(new Date());
                wrkChargeMapper.updateById(wrkCharge);
                    wrkCharge.setWrkSts(60L);//53.小车充电完成 => 60.充电任务完成
                    wrkCharge.setModiTime(new Date());
                    if (wrkChargeMapper.updateById(wrkCharge) > 0) {
                    }
                }
            }
        }
@@ -2129,6 +2437,8 @@
                continue;
            }
//            this.shuttleMoveExecuteStepClearWrkMast(wrkMast);//清理111.小车移动完成
        }
    }
@@ -2154,7 +2464,7 @@
            }
            //小车处于空闲状态
            if (!shuttleProtocol.isIdleNoCharge()) {
            if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) {
                return false;
            }
@@ -2175,14 +2485,20 @@
                return false;
            }
            //获取目标输送站
            BasDevp basDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (basDevp == null) {
                return false;//找不到输送站点
            //获取源输送站
            LiftStaProtocol liftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            }
            //判断提升机是否有其他任务(该任务需要换层必须提前独占提升机)
            WrkMast liftWrkMast = wrkMastMapper.selectLiftWrkMast(liftSta.getLiftNo());
            if (liftWrkMast != null) {
                return false;//当前提升机存在未完成任务,等待下一次轮询
            }
            //获取小车到输送站点行走命令
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), basDevp.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), liftSta.getLocNo(), NavigationMapType.NORMAL.id);
            List<NyShuttleHttpCommand> commands = result.getCommands();
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
@@ -2195,6 +2511,7 @@
            wrkMast.setWrkSts(102L);//小车移动到提升机中  101.生成小车移库任务 ==> 102.小车移动至站点
            wrkMast.setModiTime(now);
            wrkMast.setLiftNo(liftSta.getLiftNo());//提前锁定提升机
            shuttleProtocol.setToken(wrkMast.getWrkNo());//独占该小车令牌
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
@@ -2217,14 +2534,20 @@
        //小车移动到提升机中  103.小车移动至站点完成 ==> 104.小车迁入提升机中
        if (wrkMast.getWrkSts() == 103) {
            //获取源站
            LiftStaProtocol sourceLiftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            if (sourceLiftSta == null) {
                return false;//找不到站点
            }
            //获取目标输送站
            BasDevp basDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (basDevp == null) {
                return false;//找不到输送站点
            LiftStaProtocol liftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            }
            //获取提升机数据
            BasLift basLift = basLiftService.selectById(basDevp.getLiftNo());
            BasLift basLift = basLiftService.selectById(liftSta.getLiftNo());
            if (basLift == null) {
                return false;//没有提升机数据
            }
@@ -2236,10 +2559,12 @@
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastMapper.selectLiftWrkMast(basLift.getLiftNo());
            if (liftWrkMast != null) {
                return false;//当前提升机存在未完成任务,等待下一次轮询
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, basDevp.getLiftNo());
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftSta.getLiftNo());
            if (liftThread == null) {
                return false;
            }
@@ -2247,6 +2572,7 @@
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                return false;
            }
@@ -2262,7 +2588,12 @@
            }
            //小车处于空闲状态
            if (!shuttleProtocol.isIdleNoCharge()) {
            if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) {
                return false;
            }
            //小车令牌是否被任务独占
            if (!shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                return false;
            }
@@ -2271,10 +2602,15 @@
                //提升机不在小车楼层
                //调度提升机
                //获取源站对应的输送站点
                BasDevp sourceBasDevp = basDevpService.selectByLevAndLiftNo(liftProtocol.getLev().intValue(), liftProtocol.getLiftNo().intValue());
                //获取提升机命令
                NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, sourceBasDevp.getDevNo(), basDevp.getDevNo(), wrkMast.getWrkNo());
                if (liftProtocol.getToken() != 0) {
                    return false;//提升机令牌被占用
                }
                //获取提升机命令,调度提升机到源站位置
                NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, sourceLiftSta.getStaNo(), sourceLiftSta.getStaNo(), wrkMast.getWrkNo());
                Random random = new Random();
                liftCommand.setTaskNo((short) Math.abs((liftCommand.getTaskNo().intValue() + random.nextInt(9999))));//更换随机任务号
                ArrayList<NyLiftCommand> commands = new ArrayList<>();
                commands.add(liftCommand);
@@ -2285,6 +2621,7 @@
                assignCommand.setLiftNo(liftProtocol.getLiftNo());
                assignCommand.setTaskNo(wrkMast.getWrkNo().shortValue());
                assignCommand.setTaskMode(NyLiftTaskModelType.MOVE_CAR.id.shortValue());
                assignCommand.setAuto(false);
                wrkMast.setLiftNo(liftThread.getSlave().getId());//锁定提升机防止被占用
                wrkMast.setModiTime(now);
@@ -2296,22 +2633,28 @@
                return false;//等待提升机到小车楼层
            }
            if (liftProtocol.getToken() == 0) {//提升机令牌未被占用
                //独占提升机
                liftProtocol.setToken(wrkMast.getShuttleNo());
                return false;//等待下一次执行
            }
            //判断提升机令牌是否为当前小车
            if (liftProtocol.getToken() != wrkMast.getShuttleNo()) {
            if (!liftProtocol.getToken().equals(wrkMast.getShuttleNo())) {
                return false;//提升机已被独占,禁止再派发任务
            }
            //判断小车是否为当前任务独占
            if (shuttleProtocol.getToken() != wrkMast.getWrkNo()) {
            if (!shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                return false;
            }
            //站点节点
            NavigateNode staNode = NavigatePositionConvert.locNoToNode(basDevp.getLocNo());
            NavigateNode staNode = NavigatePositionConvert.locNoToNode(sourceLiftSta.getLocNo());
            //提升机节点
            NavigateNode liftNode = new NavigateNode(basLift.getPoint$().getX(), basLift.getPoint$().getY());
            liftNode.setZ(basLift.getPoint$().getZ());
            liftNode.setZ(staNode.getZ());
            //获取小车进提升机行走命令
            NyShuttleHttpCommand moveCommand = NyHttpUtils.getInOutLiftCommand(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), staNode, liftNode, true);
@@ -2331,6 +2674,8 @@
            wrkMast.setWrkSts(104L);//小车移动到提升机中  103.小车移动至站点完成 ==> 104.小车迁入提升机中
            wrkMast.setModiTime(now);
            wrkMast.setLiftNo(liftThread.getSlave().getId());//锁定提升机防止被占用
            liftProtocol.setToken(wrkMast.getShuttleNo());//提升机令牌绑定当前小车
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
@@ -2365,9 +2710,22 @@
            if (!liftProtocol.isIdle(wrkMast.getWrkNo().shortValue())) {
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastMapper.selectLiftWrkMast(liftThread.getSlave().getId());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            //判断提升机令牌是否为当前小车
            if (liftProtocol.getToken() != wrkMast.getShuttleNo()) {
            if (!liftProtocol.getToken().equals(wrkMast.getShuttleNo())) {
                return false;//提升机令牌和当前小车不一致,禁止派发
            }
            //判断提升机内是否有小车
            if (!liftProtocol.getHasCar()) {
                return false;//提升机内无小车
            }
            //获取四向穿梭车线程
@@ -2386,20 +2744,20 @@
            }
            //判断小车是否为当前任务独占
            if (shuttleProtocol.getToken() != wrkMast.getWrkNo()) {
            if (!shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                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) {
            //获取源站
            LiftStaProtocol sourceLiftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getSourceStaNo());
            //获取目标站
            LiftStaProtocol liftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
            if (sourceLiftSta == null || liftSta == null) {
                return false;//缺少站点信息
            }
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, sourceBasDevp.getDevNo(), targetBasDevp.getDevNo(), wrkMast.getWrkNo());
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, sourceLiftSta.getStaNo(), liftSta.getStaNo(), wrkMast.getWrkNo());
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
@@ -2446,8 +2804,16 @@
                return false;
            }
            //判断提升机是否有其他任务
            WrkMast liftWrkMast = wrkMastMapper.selectLiftWrkMast(liftThread.getSlave().getId());
            if (liftWrkMast != null) {
                if (!liftWrkMast.getWrkNo().equals(wrkMast.getWrkNo())) {//提升机任务和当前任务不相同
                    return false;//当前提升机存在未完成任务,等待下一次轮询
                }
            }
            //判断提升机令牌是否为当前小车
            if (liftProtocol.getToken() != wrkMast.getShuttleNo()) {
            if (!liftProtocol.getToken().equals(wrkMast.getShuttleNo())) {
                return false;//提升机令牌和当前小车不一致,禁止派发
            }
@@ -2467,14 +2833,14 @@
            }
            //判断小车是否为当前任务独占
            if (shuttleProtocol.getToken() != wrkMast.getWrkNo()) {
            if (!shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                return false;
            }
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), liftProtocol.getLiftNo().intValue());
            if (targetBasDevp == null) {
                return false;//缺少站点信息
            //获取目标站
            LiftStaProtocol liftSta = NyLiftUtils.getLiftStaByStaNo(wrkMast.getStaNo());
            if (liftSta == null) {
                return false;//找不到站点
            }
            //获取提升机数据
@@ -2486,11 +2852,15 @@
                return false;//没有设置提升机点位坐标
            }
            NavigateNode liftNode = new NavigateNode(basLift.getPoint$().getX(), basLift.getPoint$().getY());
            liftNode.setZ(basLift.getPoint$().getZ());
            liftNode.setZ(liftSta.getLev());
            List<NyShuttleHttpCommand> commands = new ArrayList<>();
            //获取小车更新楼层命令
            NyShuttleHttpCommand updateZCommand = NyHttpUtils.getUpdateZCommand(shuttleThread.getSlave().getId(), liftProtocol.getLev().intValue(), wrkMast.getWrkNo());
            commands.add(updateZCommand);
            //获取小车出提升机行走命令
            NyShuttleHttpCommand moveCommand = NyHttpUtils.getInOutLiftCommand(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), liftNode, NavigatePositionConvert.locNoToNode(targetBasDevp.getLocNo()), false);
            NyShuttleHttpCommand moveCommand = NyHttpUtils.getInOutLiftCommand(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), liftNode, NavigatePositionConvert.locNoToNode(liftSta.getLocNo()), false);
            commands.add(moveCommand);//添加小车迁出提升机命令
            ShuttleAssignCommand assignCommand = new ShuttleAssignCommand();
@@ -2525,15 +2895,6 @@
        //小车移动到目标库位中  109.小车迁出提升机完成 ==> 110.小车移动中
        if (wrkMast.getWrkSts() == 109) {
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
            if (liftProtocol == null) {
                return false;
            }
            //获取四向穿梭车线程
            NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
@@ -2545,34 +2906,34 @@
            }
            //小车处于空闲状态
            if (!shuttleProtocol.isIdleNoCharge()) {
            if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) {
                return false;
            }
            //判断小车令牌是否为当前任务
            if (shuttleProtocol.getToken() != wrkMast.getWrkNo()) {
            if (shuttleProtocol.getToken() != 0 && !shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                return false;
            }
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), wrkMast.getLiftNo());
            if (targetBasDevp == null) {
                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());
            //获取提升机数据
            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());
            //获取小车到目标库位命令
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.NORMAL.id);
            if (result == null) {
                return false;//路径计算失败
            }
@@ -2585,11 +2946,27 @@
            assignCommand.setAuto(true);//自动模式
            assignCommand.setCommands(commands);
            assignCommand.setNodes(result.getNodes());
            assignCommand.setSourceLocNo(shuttleProtocol.getCurrentLocNo());//源库位
            assignCommand.setLocNo(wrkMast.getLocNo());//目标库位
            if (wrkMast.getLiftNo() != null) {
                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.getToken().equals(shuttleProtocol.getShuttleNo().intValue())) {
                    liftProtocol.setToken(0);//释放提升机令牌
                }
            }
            wrkMast.setWrkSts(110L);//小车移动到目标库位中  109.小车迁出提升机完成 ==> 110.小车移动中
            wrkMast.setLiftNo(null);//释放提升机
            wrkMast.setModiTime(now);
            liftProtocol.setToken(0);//释放提升机令牌
            if (wrkMastMapper.updateById(wrkMast) > 0) {
                //下发任务
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
@@ -2599,6 +2976,69 @@
    }
    /**
     * 小车迁移-清理111.小车移动完成
     */
    private boolean shuttleMoveExecuteStepClearWrkMast(WrkMast wrkMast) {
        if (wrkMast.getWrkSts() == 111) {
            //获取四向穿梭车线程
            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(wrkMast.getWrkNo())) {
                return false;
            }
            Object o = redisUtil.get("shuttle_wrk_no_" + shuttleProtocol.getTaskNo());
            if (o != null) {
                ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class);
                ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand();
                int size = assignCommand.getCommands().size();
                NyShuttleHttpCommand command = assignCommand.getCommands().get(size - 1);//获取最后一段命令
                if (!command.getComplete()) {
                    return false;//最后一段命令还未完成,不做操作
                }
                NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(shuttleProtocol.getCurrentLocNo()));
                navigateMapData.writeNavigateNodeToRedisMap(assignCommand.getNodes(), false);//解锁路径
                //删除redis
                redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo());
            }
            // 保存工作主档历史档
            if (wrkMastLocMapper.save(wrkMast.getWrkNo()) <= 0) {
                log.info("保存工作历史档[workNo={0}]失败", wrkMast.getWrkNo());
            }
            // 删除工作主档
            if (!wrkMastService.deleteById(wrkMast)) {
                log.info("删除工作主档[workNo={0}]失败", wrkMast.getWrkNo());
            }
            //设置四向穿梭车为空闲状态
            shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE);
            //源库位清零
            shuttleProtocol.setSourceLocNo(null);
            //目标库位清零
            shuttleProtocol.setLocNo(null);
            //任务指令清零
            shuttleProtocol.setAssignCommand(null);
            //工作号清零
            shuttleProtocol.setTaskNo(0);
            //清除令牌
            shuttleProtocol.setToken(0);
            News.info("四向穿梭车已确认且移动任务完成状态,复位。四向穿梭车号={}", shuttleProtocol.getShuttleNo());
        }
        return true;
    }
    /**
     * 出入库模式切换
     */
    public synchronized void outAndIn() {