自动化立体仓库 - WCS系统
#
luxiaotao1123
2022-03-12 5d80e65274282610fd0387f733c9262985be12df
#
1个文件已修改
368 ■■■■ 已修改文件
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 368 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -610,6 +610,173 @@
    }
    /**
     * 出库  ===>>  库位到堆垛机站
     */
    public boolean locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol){
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            // 获取工作状态为11(生成出库ID)的出库工作档
            WrkMast wrkMast = wrkMastMapper.selectPakOutStep11(slave.getId(), crnStn.getStaNo());
            if (wrkMast == null) {
                continue;
            }
            // 工作档状态判断
            if (wrkMast.getIoType() < 100 || wrkMast.getSourceStaNo() == null){
                log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getIoType());
                continue;
            }
            // 获取源库位信息
            LocMast sourceSta = locMastService.selectById(wrkMast.getSourceLocNo());
            if (!sourceSta.getLocSts().equals("R") &&!sourceSta.getLocSts().equals("P")) {
                log.error("出库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), sourceSta.getLocSts());
                continue;
            }
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
                log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                continue;
            }
            // 判断堆垛机出库站状态
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() !=null && staDetl.getCanouting().equals("Y")
                    && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                // 命令下发区 --------------------------------------------------------------------------
                // 堆垛机控制过滤
                if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
                    continue;
                }
                // 最外层库位,直接堆垛机出库
                if (locMastService.isOutMost(wrkMast.getSourceLocNo())) {
                    // 已经存在吊车执行任务时,则过滤
                    if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                        continue;
                    }
                    // 堆垛机出库 命令下发区 --------------------------------------------------------------------------
                    CrnCommand crnCommand = new CrnCommand();
                    crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                    crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
                    crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                    crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                    crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
                    crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
                    crnCommand.setSourcePosZ(sourceSta.getLev1().shortValue());     // 源库位层
                    crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                    crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                    crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                    if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                        log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                    } else {
                        // 修改工作档状态 11.生成出库ID => 16.吊车出库中
                        Date now = new Date();
                        wrkMast.setWrkSts(16L);
                        wrkMast.setCrnStrTime(now);
                        wrkMast.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            log.error("修改工作档状态 11.生成出库ID => 16.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
                        }
                        return true;
                    }
                    // 不是最外层库位,需要使用穿梭车搬运后,再堆垛机出库
                } else {
                    // 当前组库位是否有穿梭车
                    Integer steNo = this.hasCarOfIdle(wrkMast.getLocNo());
                    // 有小车
                    if (steNo != null) {
                        if (wrkMast.getWrkSts() == 11L && wrkMast.getSteNo() == null) {
                            // 给穿梭车下发命令 让其将货物挪至堆垛机搬运点
                            SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, steNo);
                            SteProtocol steProtocol = steThread.getSteProtocol();
                            if (steProtocol == null) { continue; }
                            if (steProtocol.getStatusType().equals(SteStatusType.IDLE)) {
                                // 命令下发区 --------------------------------------------------------------------------
                                SteCommand steCommand = new SteCommand();
                                steCommand.setSteNo(steNo); // 穿梭车编号
                                steCommand.setTaskNo(wrkMast.getWrkNo()); // 工作号
                                steCommand.setTaskMode(SteTaskModeType.TO_B); // 任务模式:  去近点 等待堆垛机叉取
                                // todo:luxiaotao
                                if (!MessageQueue.offer(SlaveType.Ste, steNo, new Task(2, steCommand))) {
                                    log.error("穿梭车命令下发失败,穿梭车号={},任务数据={}", steNo, JSON.toJSON(steCommand));
                                } else {
                                    // 修改工作档状态 11.生成出库ID => 14.小车搬出库
                                    Date now = new Date();
                                    wrkMast.setWrkSts(14L);
                                    wrkMast.setSteNo(steNo);
                                    wrkMast.setCrnStrTime(now);
                                    wrkMast.setModiTime(now);
                                    if (wrkMastMapper.updateById(wrkMast) == 0) {
                                        log.error("修改工作档状态 11.生成出库ID => 14.小车搬出库 失败!!,工作号={}", wrkMast.getWrkNo());
                                    }
                                }
                            }
                        }
                        if (wrkMast.getWrkSts() == 15L) {
                            // 已经存在吊车执行任务时,则过滤
                            if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                                continue;
                            }
                            // 堆垛机出库 命令下发区 --------------------------------------------------------------------------
                            CrnCommand crnCommand = new CrnCommand();
                            crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                            crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
                            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                            crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                            crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
                            crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
                            crnCommand.setSourcePosZ(sourceSta.getLev1().shortValue());     // 源库位层
                            crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                            crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                            crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                            if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                                log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                            } else {
                                // 修改工作档状态 15.等待吊车 => 16.吊车出库中
                                Date now = new Date();
                                wrkMast.setWrkSts(16L);
                                wrkMast.setCrnStrTime(now);
                                wrkMast.setModiTime(now);
                                if (wrkMastMapper.updateById(wrkMast) == 0) {
                                    log.error("修改工作档状态 15.等待吊车 => 16.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
                                }
                                return true;
                            }
                        }
                        // 没有小车
                    } else {
                        if (wrkMast.getWrkSts() == 11L && wrkMast.getStaNo() == null) {
                            // 寻找最近的小车
                            SteThread steThread = queryIdleCar(wrkMast);
                            if (steThread != null) {
                                // 让小车等待搬运待续
                                this.letCarBeReady(wrkMast, steThread.getSlave().getId());
                            }
                        }
                        // 堆垛机搬运小车
                        if (wrkMast.getWrkSts() == 12L) {
                            this.carMoveIn(wrkMast, wrkMast.getSteNo(), crnProtocol);
                        }
                    }
                }
            }
        }
        return false;
    }
    /**
     * 当前库位组是否存在空闲小车
     */
    public Integer hasCarOfIdle(String locNo) {
@@ -622,6 +789,23 @@
                if (Utils.getGroupRow(locNo).equals(Utils.getGroupRow(steProtocol.getRow().intValue())) && steProtocol.getBay() == Utils.getBay(locNo) && steProtocol.getLev() == Utils.getLev(locNo)) {
                    return steProtocol.getSteNo().intValue();
                }
            }
        }
        return null;
    }
    /**
     * 查找当前库位最适合的穿梭车来作业
     */
    public SteThread queryIdleCar(WrkMast wrkMast) {
        Integer crnNo = wrkMast.getCrnNo();
        BasSte basSte = basSteService.findByCrnNo(crnNo);
        // 获取穿梭车信息
        SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, basSte.getSteNo());
        SteProtocol steProtocol = steThread.getSteProtocol();
        if (steProtocol != null) {
            if (steProtocol.getStatusType().equals(SteStatusType.IDLE)) {
                return steThread;
            }
        }
        return null;
@@ -777,173 +961,6 @@
        }
    }
    /**
     * 出库  ===>>  库位到堆垛机站
     */
    public boolean locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol){
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            // 获取工作状态为11(生成出库ID)的出库工作档
            WrkMast wrkMast = wrkMastMapper.selectPakOutStep11(slave.getId(), crnStn.getStaNo());
            if (wrkMast == null) {
                continue;
            }
            // 工作档状态判断
            if (wrkMast.getIoType() < 100 || wrkMast.getSourceStaNo() == null){
                log.error("查询工作档数据不符合条件--入出类型/站点, 工作号={},源库位={},入出类型={}", wrkMast.getWrkNo(), wrkMast.getSourceLocNo(), wrkMast.getIoType());
                continue;
            }
            // 获取源库位信息
            LocMast sourceSta = locMastService.selectById(wrkMast.getSourceLocNo());
            if (!sourceSta.getLocSts().equals("R") &&!sourceSta.getLocSts().equals("P")) {
                log.error("出库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), sourceSta.getLocSts());
                continue;
            }
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
            }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
                log.error("出库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                continue;
            }
            // 判断堆垛机出库站状态
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() !=null && staDetl.getCanouting().equals("Y")
                    && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                // 命令下发区 --------------------------------------------------------------------------
                // 堆垛机控制过滤
                if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
                    continue;
                }
                // 最外层库位,直接堆垛机出库
                if (locMastService.isOutMost(wrkMast.getSourceLocNo())) {
                    // 已经存在吊车执行任务时,则过滤
                    if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                        continue;
                    }
                    // 堆垛机出库 命令下发区 --------------------------------------------------------------------------
                    CrnCommand crnCommand = new CrnCommand();
                    crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                    crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
                    crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                    crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                    crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
                    crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
                    crnCommand.setSourcePosZ(sourceSta.getLev1().shortValue());     // 源库位层
                    crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                    crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                    crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                    if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                        log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                    } else {
                        // 修改工作档状态 11.生成出库ID => 16.吊车出库中
                        Date now = new Date();
                        wrkMast.setWrkSts(16L);
                        wrkMast.setCrnStrTime(now);
                        wrkMast.setModiTime(now);
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            log.error("修改工作档状态 11.生成出库ID => 16.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
                        }
                        return true;
                    }
                // 不是最外层库位,需要使用穿梭车搬运后,再堆垛机出库
                } else {
                    // 当前组库位是否有穿梭车
                    Integer steNo = this.hasCarOfIdle(wrkMast.getLocNo());
                    // 有小车
                    if (steNo != null) {
                        if (wrkMast.getWrkSts() == 11L && wrkMast.getSteNo() == null) {
                            // 给穿梭车下发命令 让其将货物挪至堆垛机搬运点
                            SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, steNo);
                            SteProtocol steProtocol = steThread.getSteProtocol();
                            if (steProtocol == null) { continue; }
                            if (steProtocol.getStatusType().equals(SteStatusType.IDLE)) {
                                // 命令下发区 --------------------------------------------------------------------------
                                SteCommand steCommand = new SteCommand();
                                steCommand.setSteNo(steNo); // 穿梭车编号
                                steCommand.setTaskNo(wrkMast.getWrkNo()); // 工作号
                                steCommand.setTaskMode(SteTaskModeType.TO_B); // 任务模式:  去近点 等待堆垛机叉取
                                // todo:luxiaotao
                                if (!MessageQueue.offer(SlaveType.Ste, steNo, new Task(2, steCommand))) {
                                    log.error("穿梭车命令下发失败,穿梭车号={},任务数据={}", steNo, JSON.toJSON(steCommand));
                                } else {
                                    // 修改工作档状态 11.生成出库ID => 14.小车搬出库
                                    Date now = new Date();
                                    wrkMast.setWrkSts(14L);
                                    wrkMast.setSteNo(steNo);
                                    wrkMast.setCrnStrTime(now);
                                    wrkMast.setModiTime(now);
                                    if (wrkMastMapper.updateById(wrkMast) == 0) {
                                        log.error("修改工作档状态 11.生成出库ID => 14.小车搬出库 失败!!,工作号={}", wrkMast.getWrkNo());
                                    }
                                }
                            }
                        }
                        if (wrkMast.getWrkSts() == 15L) {
                            // 已经存在吊车执行任务时,则过滤
                            if (wrkMastMapper.selectWorking(slave.getId()) != null) {
                                continue;
                            }
                            // 堆垛机出库 命令下发区 --------------------------------------------------------------------------
                            CrnCommand crnCommand = new CrnCommand();
                            crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                            crnCommand.setTaskNo(wrkMast.getWrkNo().shortValue()); // 工作号
                            crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                            crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                            crnCommand.setSourcePosX(sourceSta.getRow1().shortValue());     // 源库位排
                            crnCommand.setSourcePosY(sourceSta.getBay1().shortValue());     // 源库位列
                            crnCommand.setSourcePosZ(sourceSta.getLev1().shortValue());     // 源库位层
                            crnCommand.setDestinationPosX(crnStn.getRow().shortValue());     // 目标库位排
                            crnCommand.setDestinationPosY(crnStn.getBay().shortValue());     // 目标库位列
                            crnCommand.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                            if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
                                log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
                            } else {
                                // 修改工作档状态 15.等待吊车 => 16.吊车出库中
                                Date now = new Date();
                                wrkMast.setWrkSts(16L);
                                wrkMast.setCrnStrTime(now);
                                wrkMast.setModiTime(now);
                                if (wrkMastMapper.updateById(wrkMast) == 0) {
                                    log.error("修改工作档状态 15.等待吊车 => 16.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
                                }
                                return true;
                            }
                        }
                    // 没有小车
                    } else {
                        if (wrkMast.getWrkSts() == 11L && wrkMast.getStaNo() == null) {
                            // 寻找最近的小车
                            SteThread steThread = queryIdleCar(wrkMast);
                            if (steThread != null) {
                                // 让小车等待搬运待续
                                this.letCarBeReady(wrkMast, steThread.getSlave().getId());
                            }
                        }
                        // 堆垛机搬运小车
                        if (wrkMast.getWrkSts() == 12L) {
                            this.carMoveIn(wrkMast, wrkMast.getSteNo(), crnProtocol);
                        }
                    }
                }
            }
        }
        return false;
    }
    /**
     * 执行对工作档的完成操作
@@ -1135,23 +1152,6 @@
            }
        }
    }
    /**
     * 查找当前库位最适合的穿梭车来作业
     */
    public SteThread queryIdleCar(WrkMast wrkMast) {
        Integer crnNo = wrkMast.getCrnNo();
        BasSte basSte = basSteService.findByCrnNo(crnNo);
        // 获取穿梭车信息
        SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, basSte.getSteNo());
        SteProtocol steProtocol = steThread.getSteProtocol();
        if (steProtocol != null) {
            if (steProtocol.getStatusType().equals(SteStatusType.IDLE)) {
                return steThread;
            }
        }
        return null;
    }
    /**