From 80d8b0ed5a43ba329c31b557fff81eceb42b022c Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期二, 26 十一月 2024 10:26:55 +0800 Subject: [PATCH] # --- zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java | 231 +++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 156 insertions(+), 75 deletions(-) diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java index fe6f6da..6ca2b01 100644 --- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java +++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/TrafficService.java @@ -1,6 +1,7 @@ package com.zy.acs.manager.core.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zy.acs.common.utils.GsonUtils; import com.zy.acs.common.utils.RedisSupport; import com.zy.acs.framework.common.Cools; import com.zy.acs.framework.common.SnowflakeIdWorker; @@ -8,6 +9,7 @@ import com.zy.acs.manager.common.utils.MapDataUtils; import com.zy.acs.manager.core.domain.BlockVehicleDto; import com.zy.acs.manager.core.domain.TaskPosDto; +import com.zy.acs.manager.core.domain.type.BlockSeverityType; import com.zy.acs.manager.core.service.astart.MapDataDispatcher; import com.zy.acs.manager.core.service.astart.RetreatNavigateNode; import com.zy.acs.manager.core.service.astart.WaveNodeType; @@ -55,6 +57,8 @@ @Autowired private MainService mainService; @Autowired + private MainLockWrapService mainLockWrapService; + @Autowired private MapService mapService; @Autowired private MapDataDispatcher mapDataDispatcher; @@ -91,10 +95,13 @@ if (!Cools.isEmpty(waitingSegList)) { for (Segment waitingSeg : waitingSegList) { if (!waitingSeg.getId().equals(segment.getId())) { +// log.error("AGV[{}] 浠诲姟寮傚父锛屾湇鍔″櫒閿欒锛侊紒锛�", agv.getUuid()); return; } } } + + // dead lane if (jamService.count(new LambdaQueryWrapper<Jam>() .eq(Jam::getJamAgv, agv.getId()) .eq(Jam::getJamSeg, segment.getId()) @@ -150,7 +157,7 @@ insertSeg.setPosType(TaskPosDto.PosType.MOVE.toString()); insertSeg.setState(SegmentStateType.WAITING.toString()); if (!segmentService.save(insertSeg)) { - log.error("Segment [{}] 淇濆瓨澶辫触 锛侊紒锛�", segment.getTravelId() + " - " + segment.getSerial()); + log.error("Segment [{}] failed to save 锛侊紒锛�", segment.getTravelId() + " - " + segment.getSerial()); } segmentList.add(insertSeg); @@ -193,14 +200,18 @@ String agvNo = agv.getUuid(); Date now = new Date(); Jam jam = jamService.getJam(agv.getId(), startCode.getId(), segment.getId()); + BlockSeverityType blockSeverity = BlockSeverityType.query(null == jam ? null : jam.getDuration()); + // judge avoid of jam + List<Jam> unfinishedOriginJamByCurrAgv = jamService.getUnfinishedOriginJamByAvo(agv.getId(), startCode.getId(), segment.getId()); + List<String> blackPath = this.getBlackPathList(unfinishedOriginJamByCurrAgv); // 缁撴灉闆� List<String> pathList = new ArrayList<>(); // 鏃犻殰纰嶈В - List<String> unlockPathList = mapService.checkoutPath(agvNo, startCode, endCode, false); + List<String> unlockPathList = mapService.checkoutPath(agvNo, startCode, endCode, false, blackPath, segment, null); // 閬胯瑙� - List<String> lockPathList = mapService.checkoutPath(agvNo, startCode, endCode, true); + List<String> lockPathList = mapService.checkoutPath(agvNo, startCode, endCode, true, blackPath, segment, null); if (!Cools.isEmpty(lockPathList) && // 瀛樺湪閬胯瑙� Math.abs(lockPathList.size() - unlockPathList.size()) <= Arrays.stream(mapDataDispatcher.getCodeMatrix(lev)).mapToInt(row -> row.length).sum() / 10 @@ -209,17 +220,27 @@ pathList = lockPathList; } else { + // preview path + List<String> draftPath = new ArrayList<>(unlockPathList); // 鍙蛋琛岃矾寰勯泦鍚堣绠� - List<BlockVehicleDto> blockVehicleList = this.slicePathAndReturnBlockVehicleList(lev, unlockPathList, agvNo, pathList); // jamAgvNo may was wave + List<BlockVehicleDto> blockVehicleList = this.slicePathAndReturnBlockVehicleList(lev, draftPath, agvNo, pathList); // jamAgvNo may was wave if (!Cools.isEmpty(pathList)) { if (!pathList.get(pathList.size() - 1).equals(endCode.getData())) { assert !Cools.isEmpty(blockVehicleList); - boolean hasUnavoidableBlocks = blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable()); + boolean hasUnavoidableBlocks = blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable()); if (hasUnavoidableBlocks && pathList.size() <= MIN_SLICE_PATH_LENGTH) { log.info("AGV[{}] waiting in place, because the path list is too short...", agvNo); + pathList.clear(); + } + + boolean hasCycleJam = blockVehicleList.stream().anyMatch( + blockVehicleDto -> null != jamService.getCycleJam(agv.getId(), segment.getId(), blockVehicleDto.getVehicle()) + ); + if (hasCycleJam) { + log.info("AGV[{}] waiting in place, because has cycle jam...", agvNo); pathList.clear(); } } @@ -227,94 +248,106 @@ // 鏃犲彲璧拌璺緞 } else { - assert !Cools.isEmpty(blockVehicleList); - Integer maxJamTimeoutFactor = null; - - // persist jam data - jam = this.createOrUpdateJam(agv, startCode, segment, jam); - - // ? has unAvoidable block vehicles - if (blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable())) { - - // set factor of jam timeout - maxJamTimeoutFactor = 1; + if (Cools.isEmpty(blockVehicleList)) { + log.warn("AGV[{}] can't reach to code: {}, because there is too many vehicle in the lane...", agvNo, endCode.getData()); } else { - // ? already do notify to avoid - if (!Cools.isEmpty(jam.getAvoAgv()) - && BlockVehicleDto.customContain(blockVehicleList, agvService.getById(jam.getAvoAgv()).getUuid())) { + assert !Cools.isEmpty(blockVehicleList); + Integer maxJamTimeoutFactor = null; - maxJamTimeoutFactor = 10; + // persist jam data + jam = this.createOrUpdateJam(agv, startCode, segment, jam, draftPath); + // ? has unAvoidable block vehicles + if (blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable())) { + + // set factor of jam timeout + maxJamTimeoutFactor = 1; } else { - // select optimal block vehicle - String blockAgvNo = blockVehicleList.stream() - .filter(BlockVehicleDto::isAvoidable) - .map(BlockVehicleDto::getVehicle) - .findFirst().orElse(null); + // ? already do notify to avoid + if (!Cools.isEmpty(jam.getAvoAgv()) + && BlockVehicleDto.customContain(blockVehicleList, agvService.getById(jam.getAvoAgv()).getUuid())) { - // block vehicle info - Agv blockAgv = agvService.selectByUuid(blockAgvNo); - String blockAgvCode = codeService.getById(agvDetailService.selectByAgvId(blockAgv.getId()).getRecentCode()).getData(); + maxJamTimeoutFactor = 10; - do { + } else { - // 闃诲杞﹁締姝e湪鍘熷湴浣滀笟锛岀瓑寰� ===>> 瓒呰繃绛夊緟鏃堕棿锛岀粫璺� - List<Segment> runningSegList = segmentService.getByAgvAndState(blockAgv.getId(), SegmentStateType.RUNNING.toString()); - if (!Cools.isEmpty(runningSegList)) { - maxJamTimeoutFactor = 1; - break; - } + // select optimal block vehicle + String blockAgvNo = this.checkoutBestSolutionOfBlocks(blockVehicleList); + if (Cools.isEmpty(blockAgvNo)) { - // 鍒ゆ柇涓嬩釜浠诲姟鏄惁涓哄師鍦颁换鍔★紝濡傛灉鏄垯绛夊緟 ===>> 瓒呰繃绛夊緟鏃堕棿锛岀粫璺紱濡傛灉涓嶆槸锛岃闃诲杞﹁締閬胯 - Segment waitingSeg = segmentService.getJustWaitingSeg(blockAgv.getId()); - if (null != waitingSeg && waitingSeg.getEndNode().equals(codeService.selectByData(blockAgvCode).getId())) { - maxJamTimeoutFactor = 1; - break; - } + maxJamTimeoutFactor = 2; - // notify block vehicle to avoid - if (this.notifyVehicleAvoid(blockAgvNo, blockAgvCode, unlockPathList, agvNo, jam)) { - if (jam.getCycleAvo() == 1) { - jam.setCycleCode(endCode.getId()); - } - jam.setAvoAgv(blockAgv.getId()); - jam.setNotifyTime(new Date()); - if (!jamService.updateById(jam)) { - throw new CoolException(jam.getUuid() + "-jam failed to update锛侊紒锛�"); - } } else { - maxJamTimeoutFactor = 1; + // block vehicle info + Agv blockAgv = agvService.selectByUuid(blockAgvNo); + String blockAgvCode = codeService.getById(agvDetailService.selectByAgvId(blockAgv.getId()).getRecentCode()).getData(); + + do { + + // 闃诲杞﹁締姝e湪鍘熷湴浣滀笟锛岀瓑寰� ===>> 瓒呰繃绛夊緟鏃堕棿锛岀粫璺� + List<Segment> runningSegList = segmentService.getByAgvAndState(blockAgv.getId(), SegmentStateType.RUNNING.toString()); + if (!Cools.isEmpty(runningSegList)) { + maxJamTimeoutFactor = 1; + break; + } + + // 鍒ゆ柇涓嬩釜浠诲姟鏄惁涓哄師鍦颁换鍔★紝濡傛灉鏄垯绛夊緟 ===>> 瓒呰繃绛夊緟鏃堕棿锛岀粫璺紱濡傛灉涓嶆槸锛岃闃诲杞﹁締閬胯 + List<Segment> waitingSegList = segmentService.getJustWaitingSeg(blockAgv.getId()); + if (null != waitingSegList + && waitingSegList.stream().anyMatch( + waitingSeg -> waitingSeg.getEndNode().equals(codeService.selectByData(blockAgvCode).getId()) + )) { + maxJamTimeoutFactor = 1; + break; + } + + // notify block vehicle to avoid + if (this.notifyVehicleAvoid(blockAgvNo, blockAgvCode, draftPath, agvNo, jam)) { + if (jam.getCycleAvo() == 1) { + jam.setCycleCode(endCode.getId()); + } + jam.setAvoAgv(blockAgv.getId()); + jam.setNotifyTime(new Date()); + if (!jamService.updateById(jam)) { + throw new CoolException(jam.getUuid() + "-jam failed to update锛侊紒锛�"); + } + } else { + + maxJamTimeoutFactor = 1; + } + + } while (false); } - } while (false); - } - - } - - // handle jam timeout - if (null != maxJamTimeoutFactor) { - if (System.currentTimeMillis() - jam.getStartTime().getTime() > MAX_JAM_TIMEOUT * maxJamTimeoutFactor) { - - if (!Cools.isEmpty(lockPathList)) { - - pathList = lockPathList; - } else { - log.error("{}鍙疯溅杈嗘绱{}] ===>> [{}]璺緞澶辫触锛屽師鍥狅細{}" - , agvNo, startCode.getData(), endCode.getData(), "璺緞闃诲瓒呮椂"); } - } else { - log.warn("{}鍙疯溅杈嗘鍦ㄧ瓑寰呬氦閫氬牭濉烇紝闃诲杞﹁締锛氥�恵}銆�" - , agvNo - , blockVehicleList.stream().map(BlockVehicleDto::getVehicle).collect(Collectors.toList()).toString() - ); + } + + // handle jam timeout + if (null != maxJamTimeoutFactor) { + if (System.currentTimeMillis() - jam.getStartTime().getTime() > MAX_JAM_TIMEOUT * maxJamTimeoutFactor) { + + if (!Cools.isEmpty(lockPathList)) { + + pathList = lockPathList; + } else { + log.error("{}鍙疯溅杈嗘绱{}] ===>> [{}]璺緞澶辫触锛屽師鍥狅細{}" + , agvNo, startCode.getData(), endCode.getData(), "璺緞闃诲瓒呮椂"); + } + } else { + log.warn("{}鍙疯溅杈嗘鍦ㄧ瓑寰呬氦閫氬牭濉烇紝闃诲杞﹁締锛氥�恵}銆�" + , agvNo + , blockVehicleList.stream().map(BlockVehicleDto::getVehicle).collect(Collectors.toList()).toString() + ); + } + } + } } - } if (!Cools.isEmpty(pathList)) { @@ -414,6 +447,10 @@ List<Segment> waitingSegList = segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString()); if (!Cools.isEmpty(waitingSegList)) { + if (waitingSegList.size() > 1) { + log.error("閬胯閫氱煡澶辫触锛寋}鍙疯溅杈嗗瓨鍦ㄥ涓瓑寰呬腑鐨凷egment锛侊紒锛�", agvNo); + return false; + } // revert Date now = new Date(); for (Segment seg : waitingSegList) { @@ -437,23 +474,26 @@ if (!segmentService.save(insertSeg)) { log.error("Segment [{}] 淇濆瓨澶辫触 锛侊紒锛�", segment.getTravelId() + " - " + segment.getSerial()); return false; + } else { + jam.setAvoSeg(insertSeg.getId()); } } else { - return mainService.buildMinorTask(agv, null, TaskTypeType.MOVE, endCodeData); + return mainLockWrapService.buildMinorTask(agv, TaskTypeType.MOVE, endCodeData, jam); } return true; } - private Jam createOrUpdateJam(Agv agv, Code startCode, Segment segment, Jam jam) { + private Jam createOrUpdateJam(Agv agv, Code startCode, Segment segment, Jam jam, List<String> jamPath) { if (jam == null) { jam = new Jam(); jam.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); jam.setJamAgv(agv.getId()); jam.setJamCode(startCode.getId()); jam.setJamSeg(segment.getId()); + jam.setJamPath(GsonUtils.toJson(jamPath)); jam.setStartTime(new Date()); jam.setState(JamStateType.RUNNING.toString()); if (!jamService.save(jam)) { @@ -469,4 +509,45 @@ return jam; } + private List<String> getBlackPathList(List<Jam> unfinishedOriginJamByCurrAgv) { + List<String> blackPathList = new ArrayList<>(); + if (!Cools.isEmpty(unfinishedOriginJamByCurrAgv)) { + for (Jam jam : unfinishedOriginJamByCurrAgv) { + if (!Cools.isEmpty(jam.getJamPath())) { + + List<String> list = GsonUtils.fromJsonToList(jam.getJamPath(), String.class); + + Agv jamAgv = agvService.getById(jam.getJamAgv()); + List<String> jamDynamicNodes = mapDataDispatcher.queryCodeListFromDynamicNode(null, jamAgv.getUuid()); + // jamDynamicNodes has sorted + String firstCodeNode = jamDynamicNodes.stream().findFirst().orElse(null); + + if (!Cools.isEmpty(firstCodeNode)) { + int idx = list.indexOf(firstCodeNode); + if (idx != -1) { + list = new ArrayList<>(list.subList(idx, list.size())); + } + } + + blackPathList.addAll(list); + } + } + } + return blackPathList.stream().distinct().collect(Collectors.toList()); + } + + private String checkoutBestSolutionOfBlocks(List<BlockVehicleDto> blockVehicleList) { + assert !Cools.isEmpty(blockVehicleList); + for (BlockVehicleDto blockVehicleDto : blockVehicleList) { + if (!blockVehicleDto.isAvoidable()) { + continue; + } + // 娌℃湁閬胯涓殑浠诲姟 + if (Cools.isEmpty(jamService.getUnfinishedAvoSegByAvo(blockVehicleDto.getVehicle(), null))) { + return blockVehicleDto.getVehicle(); + } + } + return null; + } + } -- Gitblit v1.9.1