自动化立体仓库 - WCS系统
#
Junjie
2023-10-20 16bb4a6e5bf59c308ff351c5060875629f93291c
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -25,6 +25,8 @@
import com.zy.core.model.protocol.*;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.*;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -102,6 +104,10 @@
    private RedisUtil redisUtil;
    @Autowired
    private WrkMastLocMapper wrkMastLocMapper;
    @Autowired
    private BasLiftOptService basLiftOptService;
    @Autowired
    private ConfigService configService;
    /**
@@ -225,7 +231,7 @@
                        param.setBarcode(barcode);
                        param.setIoType(1);
                        param.setSourceStaNo(inSta.getStaNo());
//                        param.setLocType1(locTypeDto.getLocType1());
                        param.setLocType1(locTypeDto.getLocType1());
                        String response = new HttpHandler.Builder()
                                .setUri(wmsUrl)
                                .setPath("/rpc/pakin/loc/v1")
@@ -406,8 +412,8 @@
                }
                if (staProtocol.isAutoing()
                        && staProtocol.isLoading()
                        && (staProtocol.getWorkNo() > 0 && staProtocol.getWorkNo() < 9999)
                        && staProtocol.getStaNo().equals(staProtocol.getSiteId().shortValue())
//                        && (staProtocol.getWorkNo() > 0 && staProtocol.getWorkNo() < 9999)
//                        && staProtocol.getStaNo().equals(staProtocol.getSiteId().shortValue())
                        && staProtocol.isPakMk()){
                    // 获取条码扫描仪信息
@@ -508,14 +514,21 @@
                            }
                            String sourceLocNo = wrkMast.getSourceLocNo().trim();
                            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(pickSta.getLiftNo(), Utils.getLev(sourceLocNo));//获取回库提升机目标站
                            if (liftStaProtocol == null) {
                                continue;
                            }
                            // 更新工作档数据状态
                            wrkMast.setIoType(wrkMast.getIoType() - 50); // 入出库类型: 103->53,104->54,107->57
                            wrkMast.setWrkSts(2L); // 工作状态: 2.设备上走
                            wrkMast.setSourceStaNo(pickSta.getStaNo()); // 源站
                            wrkMast.setStaNo(dto.getStaNo()); // 目标站
                            wrkMast.setCrnNo(dto.getCrnNo());
//                            wrkMast.setStaNo(dto.getStaNo()); // 目标站
//                            wrkMast.setCrnNo(dto.getCrnNo());
                            wrkMast.setStaNo(liftStaProtocol.getStaNo());//目标站
                            wrkMast.setLocNo(sourceLocNo); // 目标库位 = 出库时的源库位
                            wrkMast.setShuttleNo(null); // 穿梭车清空
                            wrkMast.setLiftNo(null);// 提升机清空
                            wrkMast.setModiTime(new Date());
                            if (wrkMastMapper.updateById(wrkMast) == 0) {
                                throw new CoolException(wrkMast.getWrkNo() + "更新工作档数据状态失败");
@@ -532,14 +545,16 @@
                                throw new CoolException("修改库位状态失败");
                            }
                            // 更新站点信息 且 下发plc命令
                            staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                            staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            if (!result) {
                                News.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                            }
//                            // 更新站点信息 且 下发plc命令
//                            staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
//                            staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//                            boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                            if (!result) {
//                                News.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
//                            }
                            barcodeThread.setBarcode("");//清理条码
                        } else if (code == 500){
                            if (ledThread != null) {
@@ -550,10 +565,10 @@
                            }
                            News.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/loc/v1", JSON.toJSONString(param), response);
                        } else {
                            staProtocol.setWorkNo((short) 32002);
                            staProtocol.setStaNo(pickSta.getBackSta().shortValue());
                            devpThread.setPakMk(staProtocol.getSiteId(), false);
                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
//                            staProtocol.setWorkNo((short) 32002);
//                            staProtocol.setStaNo(pickSta.getBackSta().shortValue());
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            // led 异常显示
                            if (ledThread != null) {
@@ -690,38 +705,6 @@
                continue;
            }
        }
        // 根据输送线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;
                }
            }
        }
    }
//    /**
@@ -868,6 +851,10 @@
            BasDevp basDevp = basDevpService.selectById(wrkMast.getStaNo());
            if (basDevp == null) {
                return false;//出库站点不存在
            }
            if (!basDevp.getAutoing().equals("Y")) {
                return false;//不是自动状态
            }
            if (!basDevp.getOutEnable().equals("Y")) {
@@ -1168,6 +1155,12 @@
            //获取提升机命令
            NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, startSta, targetSta, wrkMast.getWrkNo());
            if (wrkMast.getIoType() == 53) {
                //拣料再回库,重新分配设备工作号
                Random random = new Random();
                int deviceWrk = Math.abs((liftCommand.getTaskNo().intValue() + random.nextInt(9999)));//获取设备工作号
                liftCommand.setTaskNo((short) deviceWrk);
            }
            ArrayList<NyLiftCommand> commands = new ArrayList<>();
            commands.add(liftCommand);
@@ -1208,16 +1201,27 @@
                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;//出库站点不存在
            }
            //获取源站对应的牛眼提升机站点编号(起点编号)
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(basDevp.getLiftNo(), Utils.getLev(wrkMast.getSourceLocNo()));
            if (liftStaProtocol == null) {
                return false;//找不到站点
            }
            Integer startSta = liftStaProtocol.getStaNo();
            NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol.getCurrentLocNo().equals(liftStaProtocol.getLocNo())) {
                //小车还在输送站点
                //调度小车避让
                boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkMast.getSourceLocNo()), wrkMast.getShuttleNo(), shuttleThread);
                if (!result) {
                    return false;
                }
            }
            if (!basDevp.getOutEnable().equals("Y")) {
@@ -1232,6 +1236,7 @@
            if (liftProtocol == null) {
                return false;
            }
            if (!liftProtocol.isIdle()) {
                return false;
            }
@@ -1244,13 +1249,6 @@
            if (liftWrkMast != 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());
@@ -1304,8 +1302,14 @@
                    && liftProtocol.getTaskNo() != 0
                    && !liftProtocol.getBusy()
            ) {
                BasLiftOpt basLiftOpt = basLiftOptService.selectByDeviceWrk(liftProtocol.getTaskNo().toString());
                int taskNo = liftProtocol.getTaskNo().intValue();
                if (basLiftOpt != null) {
                    taskNo = basLiftOpt.getWrkNo();
                }
                //将任务档标记为完成
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo324104(liftProtocol.getTaskNo().intValue());
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo324104(taskNo);
                if (wrkMast != null) {
                    switch (wrkMast.getWrkSts().intValue()) {
                        case 3://3.提升机搬运中 ==> 4.提升机搬运完成
@@ -1320,15 +1324,16 @@
                            wrkMast.setWrkSts(25L);
                            if (wrkMast.getIoType() == 11) {//库位移转
                                wrkMast.setWrkSts(4L);//4.提升机搬运完成
                            }else {
                                if (wrkMast.getMk() == null || !wrkMast.getMk().equals("Y")) {
                                    //不需要用到机械臂,直接转29.出库完成
                                    wrkMast.setWrkSts(29L);
                                }
                            }
                            if (liftProtocol.getToken().equals(wrkMast.getWrkNo())) {
                                //释放提升机令牌
                                liftProtocol.setToken(0);
                            }
                            if (wrkMast.getMk() == null || !wrkMast.getMk().equals("Y")) {
                                //不需要用到机械臂,直接转29.出库完成
                                wrkMast.setWrkSts(29L);
                            }
                            break;
@@ -1395,7 +1400,7 @@
                    continue;
                }
                boolean step4 = this.locToLocExecuteStep4(wrkMast);//调度车辆取货并运送到出库口
                boolean step4 = this.locToLocExecuteStep4(wrkMast);//调度车辆取货并运送到目标库位
                if (!step4) {
                    continue;
                }
@@ -1497,7 +1502,7 @@
            }
            //获取穿梭车最近且空闲的提升机输送站点
            LiftStaProtocol liftSta = shuttleDispatchUtils.getRecentLiftSta(shuttleThread.getSlave().getId());
            LiftStaProtocol liftSta = shuttleDispatchUtils.getRecentLiftSta(shuttleThread.getSlave().getId(), Utils.getLev(wrkMast.getLocNo()));
            if (liftSta == null) {
                return false;//没有可用且空闲的输送站点
            }
@@ -1543,14 +1548,47 @@
    private boolean locToLocExecuteStep3(WrkMast wrkMast) {
        Date now = new Date();
        if (wrkMast.getWrkSts() == 23) {//23.小车搬运完成
            //源站
            Integer sourceStaNo = wrkMast.getSourceStaNo();
            //目标站
            Integer staNo = wrkMast.getStaNo();
            if (sourceStaNo == null || staNo == null) {
                return false;//源站或目标站为空
            }
            int liftNo = staNo / 100;//获取提升机号
            //获取提升机线程
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo());
            LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, liftNo);
            if (liftThread == null) {
                return false;
            }
            LiftProtocol liftProtocol = liftThread.getLiftProtocol();
            if (liftProtocol == null) {
                return false;
            }
            //获取源站对应的输送站点
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(liftNo, Utils.getLev(wrkMast.getSourceLocNo()));
            if (liftStaProtocol == null) {
                return false;//找不到站点
            }
            if (!(liftStaProtocol.getModel() && !liftStaProtocol.getBusy() && liftStaProtocol.getHasTray())) {
                return false;//站点必须自动、空闲、有托盘
            }
            NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo());
            if (shuttleThread == null) {
                return false;
            }
            NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol.getCurrentLocNo().equals(liftStaProtocol.getLocNo())) {
                //小车还在输送站点
                //调度小车避让
                boolean result = Utils.searchEmptyGroupToMoveShuttle(Utils.getLev(wrkMast.getSourceLocNo()), wrkMast.getShuttleNo(), shuttleThread);
                if (!result) {
                    return false;
                }
            }
            if (!liftProtocol.isIdle()) {
@@ -1561,14 +1599,6 @@
            WrkMast wrkMast1 = wrkMastMapper.selectLiftWrkMast(liftProtocol.getLiftNo().intValue());
            if (wrkMast1 != null && wrkMast1.getWrkNo().intValue() != wrkMast.getWrkNo().intValue()) {
                return false;
            }
            //源站
            Integer sourceStaNo = wrkMast.getSourceStaNo();
            //目标站
            Integer staNo = wrkMast.getStaNo();
            if (sourceStaNo == null || staNo == null) {
                return false;//源站或目标站为空
            }
            //获取提升机命令
@@ -1605,13 +1635,17 @@
    private boolean locToLocExecuteStep4(WrkMast wrkMast) {
        if (wrkMast.getWrkSts() == 4) {//4.提升机搬运完成
            //获取目标站对应的输送站点
            BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), wrkMast.getLiftNo());
            if (targetBasDevp == null) {
                return false;//缺少站点信息
            LiftStaProtocol liftStaProtocol = NyLiftUtils.getLiftStaByLev(wrkMast.getLiftNo(), Utils.getLev(wrkMast.getLocNo()));
            if (liftStaProtocol == null) {
                return false;//找不到站点
            }
            if (!(liftStaProtocol.getModel() && !liftStaProtocol.getBusy() && liftStaProtocol.getHasTray())) {
                return false;//站点必须自动、空闲、有托盘
            }
            if (wrkMast.getShuttleNo() == null) {
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), targetBasDevp.getLocNo());//调度小车到目标输送站点进行取货
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftStaProtocol.getLocNo());//调度小车到目标输送站点进行取货
                return false;
            }
@@ -1629,14 +1663,14 @@
            }
            //判断小车是否到达目标输送站点
            if (!shuttleProtocol.getCurrentLocNo().equals(targetBasDevp.getLocNo())) {
            if (!shuttleProtocol.getCurrentLocNo().equals(liftStaProtocol.getLocNo())) {
                //小车不在目标输送站点
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), targetBasDevp.getLocNo(), wrkMast.getShuttleNo());//调度小车到目标输送站点进行取货
                shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), liftStaProtocol.getLocNo(), wrkMast.getShuttleNo());//调度小车到目标输送站点进行取货
                return false;
            }
            //小车已抵达目标输送站点,将货物搬运到目标库位
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), targetBasDevp.getLocNo(), wrkMast.getLocNo());
            NyShuttleOperaResult result = NyShuttleOperaUtils.getShuttleTransportCommands(wrkMast.getShuttleNo(), wrkMast.getWrkNo(), liftStaProtocol.getLocNo(), wrkMast.getLocNo());
            if (result == null) {//路径计算失败
                return false;
            }
@@ -2014,23 +2048,56 @@
                        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();
                        //向AGV发起组托请求
                        try {
                            HashMap<String, Object> param = new HashMap<>();
                            param.put("wrkNo", wrkMast.getWrkNo());
                            String response = new HttpHandler.Builder()
                                    .setUri(wmsUrl)
                                    .setPath("/rpc/replenishment")
                                    .setJson(JSON.toJSONString(param))
                                    .build()
                                    .doPost();
                            JSONObject jsonObject = JSON.parseObject(response);
                            Integer code = jsonObject.getInteger("code");
                            if (code.equals(200)) {//AGV组托成功
                                //覆盖工作档目标站
                                wrkMast.setStaNo(targetSta.intValue());
                                wrkMast.setShuttleNo(null);//释放小车
                                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;
                                }
                            }
                            continue;
                        } catch (Exception e) {
                            e.printStackTrace();
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        }
//                        //覆盖工作档目标站
//                        wrkMast.setStaNo(targetSta.intValue());
//                        wrkMast.setShuttleNo(null);//释放小车
//                        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;
//                        }
                    }
                }
            }
@@ -2039,30 +2106,147 @@
            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");
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol303.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                if (wrkDetls.isEmpty()) {
                    continue;
                }
                if (wrkMast.getInvWh() == null) {
                    wrkMast.setInvWh("Y");//标记已经下发机械臂任务
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        RobotUtils.sendTask(staProtocol303.getWorkNo().toString(), wrkDetls.size(), "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");
                //查询是否有工作档
                WrkMast wrkMast = wrkMastMapper.selectByWorkNo(staProtocol317.getWorkNo().intValue());
                if (wrkMast == null) {
                    continue;
                }
                List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                if (wrkDetls.isEmpty()) {
                    continue;
                }
                if (wrkMast.getInvWh() == null) {
                    wrkMast.setInvWh("Y");//标记已经下发机械臂任务
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        RobotUtils.sendTask(staProtocol317.getWorkNo().toString(), wrkDetls.size(), "317");
                    }
                }
            }
        }
    }
    /**
     * AGV补货(通知AGV取货)
     */
    public void agvRestockInto() {
        //检测309和312站是否自动、有物
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 获取入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            StaProtocol staProtocol309 = devpThread.getStation().get(309);
            StaProtocol staProtocol312 = devpThread.getStation().get(312);
            if (staProtocol309 == null || staProtocol312 == null) {
                continue;
            }
            if (staProtocol309.isAutoing() && staProtocol309.isLoading()) {
                // 获取条码扫描仪信息
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, 11);//308站条码器
                if (barcodeThread == null) {
                    continue;
                }
                String barcode = barcodeThread.getBarcode();
                if(!Cools.isEmpty(barcode)) {
                    //通知AGV取货
                    agvRestockCall("CS-301-001-01@3", barcode);
                }
            } else if (staProtocol312.isAutoing() && staProtocol312.isLoading()) {
                // 获取条码扫描仪信息
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, 12);//311站条码器
                if (barcodeThread == null) {
                    continue;
                }
                String barcode = barcodeThread.getBarcode();
                if(!Cools.isEmpty(barcode)) {
                    //通知AGV取货
                    agvRestockCall("CS-302-001-01@3", barcode);
                }
            }
        }
    }
    //通知AGV取货
    private boolean agvRestockCall(String staNo, String barcode) {
        try {
            HashMap<String, Object> param = new HashMap<>();
            param.put("devNo", staNo);
            param.put("containerCode", barcode);
            String response = new HttpHandler.Builder()
                    .setUri(wmsUrl)
                    .setPath("/rpc/start")
                    .setJson(JSON.toJSONString(param))
                    .build()
                    .doPost();
            JSONObject jsonObject = JSON.parseObject(response);
            Integer code = jsonObject.getInteger("code");
            if (code.equals(200)) {//呼叫AGV
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return false;
    }
    // 300站拣料
    public void pick300() {
        //检测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() != 29) {//29.出库完成
                    continue;
                }
                if (wrkMast.getMk() == null) {
                    Integer sourceStaNo = wrkMast.getSourceStaNo();//源站
                    Integer staNo = wrkMast.getStaNo();//目标站
                    //覆盖工作档目标站
                    wrkMast.setStaNo(sourceStaNo);
                    wrkMast.setSourceStaNo(staNo);
                    wrkMast.setMk("N");
                    if (wrkMastMapper.updateById(wrkMast) > 0) {
                        //向300站写入目标站
                        staProtocol = staProtocol.clone();
                        staProtocol.setStaNo(wrkMast.getStaNo().shortValue());//移动到目标站
                        boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                        try {
                            Thread.sleep(500);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
@@ -2362,7 +2546,16 @@
                }
            } else if (wrkCharge.getWrkSts() == 52) {
                //检测小车是否满电
                //获取满电阈值
                int maxPower = 95;
                EntityWrapper<Config> wrapper = new EntityWrapper<>();
                wrapper.eq("code", "chargeMaxValue");
                Config config = configService.selectOne(wrapper);
                if (config != null) {
                    maxPower = Integer.parseInt(config.getValue());
                }
                if (shuttleProtocol.getPowerPercent() < maxPower) {
                    continue;
                }
@@ -2444,8 +2637,6 @@
            if (!stepMoveLoc) {
                continue;
            }
//            this.shuttleMoveExecuteStepClearWrkMast(wrkMast);//清理111.小车移动完成
        }
    }
@@ -2618,7 +2809,8 @@
                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))));//更换随机任务号
                int deviceWrk = Math.abs((liftCommand.getTaskNo().intValue() + random.nextInt(9999)));//获取设备工作号
                liftCommand.setTaskNo((short) deviceWrk);//更换随机任务号
                ArrayList<NyLiftCommand> commands = new ArrayList<>();
                commands.add(liftCommand);
@@ -2940,6 +3132,33 @@
//            NavigateNode liftNode = new NavigateNode(basLift.getPoint$().getX(), basLift.getPoint$().getY());
//            liftNode.setZ(basLift.getPoint$().getZ());
            //小车已经在目标库位,直接认定小车移动任务完成
            if (shuttleProtocol.getCurrentLocNo().equals(wrkMast.getLocNo())) {
                if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) {
                    //释放小车令牌
                    shuttleProtocol.setToken(0);
                }
                wrkMast.setWrkSts(111L);//111.小车移动完成
                wrkMast.setLiftNo(null);//释放提升机
                wrkMast.setModiTime(now);
                wrkMastMapper.updateById(wrkMast);
                shuttleProtocol.setShuttleNo((short) 0);//释放小车
                shuttleProtocol.setToken(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());
                    }
                }
                return false;
            }
            //获取小车到目标库位命令
            NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo(), NavigationMapType.NORMAL.id);
            if (result == null) {
@@ -2980,69 +3199,6 @@
                MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand));
            }
        }
        return true;
    }
    /**
     * 小车迁移-清理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;
    }