*
lsh
2025-04-27 44be6da8fc2740a7e81d5b878a894e318b6a5f8c
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -384,9 +384,28 @@
     */
    public void crnStnToOutStn() {
        for (CrnSlave crnSlave : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crnSlave.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) { continue; }
            BasCrnp basCrnp = basCrnpService.selectById(crnSlave.getId());
            if (basCrnp == null) {
                log.error("{}号堆垛机尚未在数据库进行维护!", crnSlave.getId());
                continue;
            }
            if (!crnSlave.getId().equals(crnProtocol.getLaneNo())){
                for (CrnSlave crnOther : slaveProperties.getCrn()) {
                    if (crnOther.getId().equals(crnProtocol.getLaneNo())){
                        crnSlave.updateCrnInStn(crnOther);
                    }
                }
            }
            // 遍历堆垛机出库站
            for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) {
                List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", crnSlave.getId()).eq("crn_stn", crnStn.getStaNo()));
                List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("CRN_NO", crnSlave.getId()).eq("LANE_NO", crnProtocol.getLaneNo()).eq("CRN_STN", crnStn.getStaNo()));
//                List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", crnSlave.getId()).eq("").eq("crn_stn", crnStn.getStaNo()));
                for (StaDesc staDesc : staDescs){
                    try{
                        // 获取堆垛机出库站信息
@@ -399,7 +418,7 @@
                        }
                        if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == 0)) {
                            // 查询工作档
                            TaskWrk taskWrk = taskWrkMapper.selectCrnStaWorking(crnSlave.getId(), staDesc.getStnNo().toString());
                            TaskWrk taskWrk = taskWrkMapper.selectCrnStaWorking(crnProtocol.getLaneNo(), staDesc.getStnNo().toString());
                            if (taskWrk == null) {
                                continue;
                            }
@@ -452,6 +471,14 @@
                continue;
            }
            if (!crn.getId().equals(crnProtocol.getLaneNo())){
                for (CrnSlave crnOther : slaveProperties.getCrn()) {
                    if (crnOther.getId().equals(crnProtocol.getLaneNo())){
                        crn.updateCrnInStn(crnOther);
                    }
                }
            }
            // 库位移转
            this.locToLoc(crn, crnProtocol);
@@ -488,7 +515,7 @@
     */
    public void crnStnToLoc(CrnSlave slave, CrnProtocol crnProtocol) throws IOException {
        for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) {
            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo()));
            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("CRN_NO", slave.getId()).eq("LANE_NO", crnProtocol.getLaneNo()).eq("CRN_STN", crnStn.getStaNo()));
            for (StaDesc staDesc : staDescs) {
                boolean flag = false;
                // 获取堆垛机入库站信息
@@ -514,7 +541,7 @@
                }
                // 获取工作状态为2(设备上走)的入库工作档
                TaskWrk taskWrk = taskWrkMapper.selectPakIn(slave.getId(), staProtocol.getWorkNo().intValue(), staDesc.getStnNo().toString());
                TaskWrk taskWrk = taskWrkMapper.selectPakIn(crnProtocol.getLaneNo(), staProtocol.getWorkNo().intValue(), staDesc.getStnNo().toString());
                if(null == taskWrk) {
                    continue;
                }
@@ -525,7 +552,7 @@
                }
                // 已经存在吊车执行任务时,则过滤
                if (taskWrkMapper.selectCrnWorking(slave.getId()) != null) {
                if (taskWrkMapper.selectCrnWorking(crnProtocol.getLaneNo()) != null) {
                    continue;
                }
@@ -573,7 +600,8 @@
                // 命令下发区 --------------------------------------------------------------------------
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(staDesc.getCrnNo()); // 堆垛机编号
                crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                crnCommand.setCrnNo(staDesc.getLaneNo()); // 堆垛机巷道编号
                crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 工作号
                crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
@@ -634,15 +662,17 @@
     * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库
     */
    public void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol){
        List<TaskWrk> taskWrksInitial = taskWrkMapper.selectPakOut(slave.getId(), null);
        List<TaskWrk> taskWrksInitial = taskWrkMapper.selectPakOut(crnProtocol.getLaneNo(), null);
        if (taskWrksInitial.size()==0){
            return;
        }
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo()));
            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("CRN_NO", slave.getId()).eq("LANE_NO", crnProtocol.getLaneNo()).eq("CRN_STN", crnStn.getStaNo()));
//            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", crnProtocol.getLaneNo()).eq("crn_stn", crnStn.getStaNo()));
            for (StaDesc staDesc : staDescs){
                // 获取工作状态为11(生成出库ID)的出库工作档
                List<TaskWrk> taskWrks = taskWrkMapper.selectPakOut(slave.getId(),staDesc.getStnNo().toString());
                List<TaskWrk> taskWrks = taskWrkMapper.selectPakOut(crnProtocol.getLaneNo(),staDesc.getStnNo().toString());
                for (TaskWrk taskWrk : taskWrks){
                    if (taskWrk == null) {
                        continue;
@@ -679,12 +709,13 @@
                        }
                        // 已经存在吊车执行任务时,则过滤
                        if (taskWrkMapper.selectCrnWorking(slave.getId()) != null) {
                        if (taskWrkMapper.selectCrnWorking(crnProtocol.getLaneNo()) != null) {
                            break;
                        }
                        CrnCommand command = new CrnCommand();
                        command.setCrnNo(taskWrk.getCrnNo()); // 堆垛机编号
                        command.setCrnNo(slave.getId()); // 堆垛机编号
                        command.setLaneNo(crnProtocol.getLaneNo()); // 堆垛机编号
                        command.setTaskNo(taskWrk.getWrkNo().shortValue()); // 工作号
                        command.setAckFinish((short) 0);  // 任务完成确认位
                        command.setTaskMode(CrnTaskModeType.PAKIN); // 任务模式
@@ -696,7 +727,7 @@
                        command.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                        command.setCommand((short)1);
                        if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(2, command),false)) {
                            log.error("堆垛机命令生成失败,堆垛机号={},任务数据={}", taskWrk.getCrnNo(), JSON.toJSON(command));
                            log.error("堆垛机命令生成失败,堆垛机号={},巷道={},任务数据={}",slave.getId(), taskWrk.getCrnNo(), JSON.toJSON(command));
                            throw new CoolException("堆垛机命令生成失败");
                        }else{
                            try{
@@ -755,7 +786,7 @@
            // 获取工作状态为11(生成出库ID)的移库工作档
            List<TaskWrk> taskWrks = taskWrkMapper.selectList(
                    new EntityWrapper<TaskWrk>()
                    .eq("CRN_NO",slave.getId())
                    .eq("CRN_NO",crnProtocol.getLaneNo())
                    .eq("WRK_STS",11)
                    .eq("IO_TYPE",3)
                    .orderBy("IO_PRI",false));
@@ -775,7 +806,7 @@
                }
                // 已经存在吊车执行任务时,则过滤
                if (taskWrkMapper.selectCrnWorking(slave.getId()) != null) {
                if (taskWrkMapper.selectCrnWorking(crnProtocol.getLaneNo()) != null) {
                    continue;
                }
@@ -796,6 +827,7 @@
                // 1.堆垛机开始移动
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                crnCommand.setLaneNo(crnProtocol.getLaneNo()); // 堆垛机编号
                crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 工作号
                crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
@@ -863,12 +895,20 @@
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) { continue; }
            if (!crn.getId().equals(crnProtocol.getLaneNo())){
                for (CrnSlave crnOther : slaveProperties.getCrn()) {
                    if (crnOther.getId().equals(crnProtocol.getLaneNo())){
                        crn.updateCrnInStn(crnOther);
                    }
                }
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (!Cools.isEmpty(crnProtocol.getTaskFinish()) && crnProtocol.getTaskFinish() == 0 && crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                //获取入库待确认工作档
                TaskWrk taskWrk = taskWrkMapper.selectCrnNoInWorking(crn.getId(),crnProtocol.getTaskNo().intValue());
                TaskWrk taskWrk = taskWrkMapper.selectCrnNoInWorking(crnProtocol.getLaneNo(),crnProtocol.getTaskNo().intValue());
                if (Cools.isEmpty(taskWrk)&&crnProtocol.getTaskNo() !=999) {
                    log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
                    log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},巷道号={},工作号={}", crn.getId(),crnProtocol.getLaneNo(), crnProtocol.getTaskNo());
                    continue;
                }
                Thread.sleep(300);
@@ -1183,74 +1223,7 @@
        return false;
    }
    public boolean deviceRgvDetection(Integer startSta,RgvSlave rgvSlave,Integer endSta){
        BasDevpPosition basDevpPositionStartSta = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", startSta));
        if (basDevpPositionStartSta == null){
            return false;
        }
        BasDevpPosition basDevpPositionEndSta = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", endSta));
        if (basDevpPositionEndSta == null){
            return false;
        }
        DevpThread devpThreadEnd = (DevpThread) SlaveConnection.get(SlaveType.Devp, basDevpPositionEndSta.getPlcId());
        StaProtocol staProtocolEnd = devpThreadEnd.getStation().get(endSta);
        if (staProtocolEnd == null){
            return false;
        }
        // 判断是否满足放货条件
        if (!staProtocolEnd.isAutoing() || staProtocolEnd.isLoading()) {
            return false;
        }
        if (!rgvDetection(rgvSlave)){
            return false;
        }
        //  a当前  b  other
        //  b可用
            //  b无任务
                    //  半边区域内全任务
                    //  半边区域内取货任务
                    //  半边区域内放货任务
                //切换B
                    //  半边区域内全任务
                    //  半边区域内取货任务
                    //  半边区域内放货任务
            //b 有任务
                //  可用区域任务
                //  可用区域任务内取货任务
                    //
         // b禁用
            // 全区域任务  就近取货
        return false;
    }
    public synchronized void taskStart() {
        for (RgvSlave rgvSlave : slaveProperties.getRgv()) {
            try{
                if (rgvDetection(rgvSlave)){
                    for (RgvSlave.RgvStn inSta : rgvSlave.getRgvInSta()){
                        TaskWrk taskWrk = deviceDetection(inSta);
                        if (taskWrk!=null){
                            if (deviceRgvDetection(inSta.getStaNo(),rgvSlave,taskWrk.getTargetPointConvert())){
                                RgvProtocol rgvStatus = RgvStatusCache.getRgvStatus(rgvSlave.getId());
                            }
                        }
                    }
                }
            } catch (Exception e){
                log.error("任务生成失败===》异常信息:{}",e.getMessage());
            }
        }
    }
    public synchronized void DevpTaskNoRun() {
        for (RgvSlave rgvSlave : slaveProperties.getRgv()) {
            try{
                if (rgvDetection(rgvSlave)){
@@ -1272,69 +1245,130 @@
                        }
                    }
                    if (taskWrkList.isEmpty() || staList.isEmpty()) continue;
                    boolean sign = false;
                    if (rgvOtherStatusEnable(rgvSlave)){
                        //分成上下两部分任务
                        List<Integer>[] avoidRange = RouteUtils.avoidRange(staList, basDevpPositions);
                        List<Integer>[] avoidRange = RouteUtils.gradeRange(staList, basDevpPositions,itSmall);
                        List<Integer> rangeListSou = avoidRange[itSmall ? 0 : 1];
                        List<Integer> rangeListSouOther = avoidRange[itSmall ? 1 : 0];
                        //就近排序
                        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(rgvSlave.getId());
                        List<Integer> rangeList = RouteUtils.SortNearby(rangeListSou, rgvProtocol.RgvPos, basDevpPositions);
                        List<Integer> rangeListOther = RouteUtils.SortNearby(rangeListSouOther, rgvProtocol.RgvPos, basDevpPositions);
                        if (taskNoNow.equals("无")){ //b 无任务
                                //所属部分就进取货
                                //  半边区域内全任务
                            boolean sign = false;
                        //所属部分就进取货
                        //筛选范围内任务
                        //就近排序
                        //筛选在范围任务
                        Long[][] avoidedRange = new TrackRangeUtils().avoidRangeArr(rgvSlave, trackEntireLength, trackBenchmark, avoidDistance);
                        List<Integer> belongToRange = RouteUtils.SortNearby(RouteUtils.belongToRange(rangeList, avoidedRange[0], basDevpPositions), rgvProtocol.RgvPos, basDevpPositions);
                        for (Integer staNoNow : belongToRange){
                            for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                if (rgvStn.getStaNo().equals(staNoNow)){
                                    TaskWrk taskWrk = deviceDetection(rgvStn);
                                    if (taskWrk!=null){
                                        BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", taskWrk.getTargetPointConvert()));
                                        if (RouteUtils.CheckIfItIsWithinTheRange(rangeList,basDevpPosition.getPlcPosition(),basDevpPositions,itSmall)){
                                            sign = taskGenerate(rgvSlave,rgvStn,0);
                                        }
                                    }
                                    break;
                                }
                            }
                            if (sign){
                                break;
                            }
                        }
                        if (!sign){
                            //  筛选范围内取货任务
                            for (Integer staNoNow : belongToRange){
                                for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                    if (rgvStn.getStaNo().equals(staNoNow)){
                                        sign = taskGenerate(rgvSlave,rgvStn,0);
                                        break;
                                    }
                                }
                                if (sign){
                                    break;
                                }
                            }
                        }
                        if (!sign){
                            for (Integer staNoNow : rangeList){
                                for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                    if (rgvStn.getStaNo().equals(staNoNow)){
                                        TaskWrk taskWrk = deviceDetection(rgvStn);
                                        if (taskWrk!=null){
                                            BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", taskWrk.getTargetPointConvert()));
                                            if (RouteUtils.CheckIfItIsWithinTheRange(rangeList,basDevpPosition.getPlcPosition(),basDevpPositions,itSmall)){
                                                sign = taskGenerate(rgvSlave,rgvStn,0);
                                            }
                                        }
                                    }
                                }
                            }
                            if (!sign){
                                //  半边区域内取货任务
                                for (Integer staNoNow : rangeList){
                                    for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                        if (rgvStn.getStaNo().equals(staNoNow)){
                                            sign = taskGenerate(rgvSlave,rgvStn,0);
                                            break;
                                        }
                                    }
                                    if (sign){
                                        break;
                                    }
                                }
                                if (sign){
                                    break;
                                }
                            }
                            if (!sign){
                                //  半边区域内放货任务
                                for (Integer staNoNow : rangeListOther){
                                    for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                        if (rgvStn.getStaNo().equals(staNoNow)){
                                            break;
                                        }
                                    }
                                    if (sign){
                        }
                        if (!sign){
                            //  半边区域内取货任务
                            for (Integer staNoNow : rangeList){
                                for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                    if (rgvStn.getStaNo().equals(staNoNow)){
                                        sign = taskGenerate(rgvSlave,rgvStn,0);
                                        break;
                                    }
                                }
                                if (sign){
                                    break;
                                }
                            }
                            //切换B
                            continue;
                        } else {//b 有任务
                                //  可用区域任务
                                //  可用区域任务内取货任务
                                //切换B
                            continue;
                        }
                        if (!sign){
                            //  半边区域内放货任务
                            for (Integer staNoNow : rangeListOther){
                                for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                    if (rgvStn.getStaNo().equals(staNoNow)){
                                        TaskWrk taskWrk = deviceDetection(rgvStn);
                                        if (taskWrk!=null){
                                            BasDevpPosition basDevpPosition = basDevpPositionService.selectOne(new EntityWrapper<BasDevpPosition>().eq("DEV_NO", taskWrk.getTargetPointConvert()));
                                            if (RouteUtils.CheckIfItIsWithinTheRange(rangeList,basDevpPosition.getPlcPosition(),basDevpPositions,itSmall)){
                                                sign = taskGenerate(rgvSlave,rgvStn,0);
                                            }
                                        }
                                        break;
                                    }
                                }
                                if (sign){
                                    break;
                                }
                            }
                        }
                    } else {
                        //可用区域就近取货
                        //就近排序
                        RgvProtocol rgvProtocol = RgvStatusCache.getRgvStatus(rgvSlave.getId());
                        List<Integer> rangeList = RouteUtils.SortNearby(staList, rgvProtocol.RgvPos, basDevpPositions);
                        //  半边区域内取货任务
                        for (Integer staNoNow : rangeList){
                            for (RgvSlave.RgvStn rgvStn : rgvSlave.getRgvInSta()){
                                if (rgvStn.getStaNo().equals(staNoNow)){
                                    sign = taskGenerate(rgvSlave,rgvStn,0);
                                    break;
                                }
                            }
                            if (sign){
                                break;
                            }
                        }
                    }
                }
            } catch (Exception e){