|  |  |  | 
|---|
|  |  |  | package com.zy.acs.manager.core.service; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson.JSON; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
|---|
|  |  |  | import com.zy.acs.common.constant.RedisConstant; | 
|---|
|  |  |  | import com.zy.acs.common.utils.RedisSupport; | 
|---|
|  |  |  | import com.zy.acs.common.utils.GsonUtils; | 
|---|
|  |  |  | import com.zy.acs.common.utils.Utils; | 
|---|
|  |  |  | import com.zy.acs.framework.common.Cools; | 
|---|
|  |  |  | import com.zy.acs.framework.common.SnowflakeIdWorker; | 
|---|
|  |  |  | import com.zy.acs.framework.exception.CoolException; | 
|---|
|  |  |  | import com.zy.acs.manager.common.utils.MapDataUtils; | 
|---|
|  |  |  | import com.zy.acs.manager.core.constant.MapDataConstant; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.BlockVehicleDto; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.TaskPosDto; | 
|---|
|  |  |  | import com.zy.acs.manager.core.domain.TrafficJamDto; | 
|---|
|  |  |  | import com.zy.acs.manager.core.service.astart.DynamicNodeType; | 
|---|
|  |  |  | 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.NavigateNode; | 
|---|
|  |  |  | import com.zy.acs.manager.core.service.astart.RetreatNavigateNode; | 
|---|
|  |  |  | import com.zy.acs.manager.core.service.astart.WaveNodeType; | 
|---|
|  |  |  | import com.zy.acs.manager.core.service.astart.domain.DynamicNode; | 
|---|
|  |  |  | import com.zy.acs.manager.manager.entity.*; | 
|---|
|  |  |  | import com.zy.acs.manager.manager.enums.JamStateType; | 
|---|
|  |  |  | import com.zy.acs.manager.manager.enums.SegmentStateType; | 
|---|
|  |  |  | 
|---|
|  |  |  | import org.springframework.transaction.annotation.Transactional; | 
|---|
|  |  |  | import org.springframework.transaction.interceptor.TransactionAspectSupport; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.ArrayList; | 
|---|
|  |  |  | import java.util.Arrays; | 
|---|
|  |  |  | import java.util.Date; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  | import java.util.stream.Collectors; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * Wavefront | 
|---|
|  |  |  | 
|---|
|  |  |  | @Slf4j | 
|---|
|  |  |  | @Component | 
|---|
|  |  |  | public class TrafficService { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static final Integer MIN_SLICE_PATH_LENGTH = 3; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static final Integer timeoutDuration = 5 * 1000; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private final RedisSupport redis = RedisSupport.defaultRedisSupport; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private AgvService agvService; | 
|---|
|  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MainService mainService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MainLockWrapService mainLockWrapService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MapService mapService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MapDataDispatcher mapDataDispatcher; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private SnowflakeIdWorker snowflakeIdWorker; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private ActionService actionService; | 
|---|
|  |  |  | private AgvModelService agvModelService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private RetreatNavigateService retreatNavigateService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private AvoidWaveCalculator avoidWaveCalculator; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // todo | 
|---|
|  |  |  | //  1.故障 | 
|---|
|  |  |  | @Transactional | 
|---|
|  |  |  | public synchronized void trigger(Segment segment) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | 
|---|
|  |  |  | 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()) | 
|---|
|  |  |  | 
|---|
|  |  |  | .eq(Jam::getState, JamStateType.RUNNING.toString()) | 
|---|
|  |  |  | ) > 0) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // deprecate jam | 
|---|
|  |  |  | if (this.isJamBeDeprecatedByAvo(segment.getId())) { | 
|---|
|  |  |  | if (this.skipCurrSegment(segment)) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // execute ----------------------------------------------- | 
|---|
|  |  |  | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void callback(List<Segment> segmentList) { | 
|---|
|  |  |  | Date now = new Date(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | segmentList.stream().max(Comparator.comparingInt(Segment::getSerial)).ifPresent(segment -> { | 
|---|
|  |  |  | Segment nextSegment = segmentService.getNextStepOfInit(segment.getTravelId(), segment.getSerial()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (null != nextSegment) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | nextSegment.setState(SegmentStateType.WAITING.toString()); | 
|---|
|  |  |  | nextSegment.setUpdateTime(now); | 
|---|
|  |  |  | if (!segmentService.updateById(nextSegment)) { | 
|---|
|  |  |  | log.error("Segment [{}] 更新失败 !!!", nextSegment.getGroupId() + " - " + nextSegment.getSerial()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | travelService.checkFinish(segment.getTravelId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private List<String> checkoutPath(Agv agv, Code startCode, Code endCode, Segment segment) { | 
|---|
|  |  |  | Integer lev = null; | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  | // 避让解 | 
|---|
|  |  |  | List<String> lockPathList = mapService.checkoutPath(agvNo, startCode, endCode, true); | 
|---|
|  |  |  | List<String> lockPathList = mapService.checkoutPath(agvNo, startCode, endCode, true, blackPath, segment); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(lockPathList) && // 存在避让解 | 
|---|
|  |  |  | Math.abs(lockPathList.size() - unlockPathList.size()) <= Arrays.stream(mapDataDispatcher.getCodeMatrix(lev)).mapToInt(row -> row.length).sum() / 10 | 
|---|
|  |  |  | 
|---|
|  |  |  | pathList = lockPathList; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // preview path | 
|---|
|  |  |  | List<String> draftPath = new ArrayList<>(unlockPathList); | 
|---|
|  |  |  | if (blockSeverity.equals(BlockSeverityType.SEVERE)) { | 
|---|
|  |  |  | unlockPathList.remove(endCode.getData()); | 
|---|
|  |  |  | blackPath.addAll(unlockPathList); | 
|---|
|  |  |  | List<String> newUnlockPathList = mapService.checkoutPath(agvNo, startCode, endCode, false, blackPath, segment); | 
|---|
|  |  |  | if (!Cools.isEmpty(newUnlockPathList)) { | 
|---|
|  |  |  | draftPath = newUnlockPathList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 可走行路径集合计算 | 
|---|
|  |  |  | List<String> jamVehicleList = this.getSliceAndReturnJamVehicleList(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 (!Cools.isEmpty(jamVehicleList) && !pathList.get(pathList.size() - 1).equals(endCode.getData())) { | 
|---|
|  |  |  | String jamAgvNo = jamVehicleList.get(0); | 
|---|
|  |  |  | if (mapDataDispatcher.queryCodeListFromDynamicNode(null, jamAgvNo).size() > 1 && pathList.size() <= MIN_SLICE_PATH_LENGTH) { | 
|---|
|  |  |  | if (!pathList.get(pathList.size() - 1).equals(endCode.getData())) { | 
|---|
|  |  |  | assert !Cools.isEmpty(blockVehicleList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | boolean hasUnavoidableBlocks = blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable()); | 
|---|
|  |  |  | if (hasUnavoidableBlocks && pathList.size() <= MapDataConstant.MIN_SLICE_PATH_LENGTH) { | 
|---|
|  |  |  | log.info("AGV[{}] waiting in place, because the path list is too short...", agvNo); | 
|---|
|  |  |  | pathList.clear(); | 
|---|
|  |  |  | //                        return pathList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 无可走行路径 | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 阻塞车辆列表 | 
|---|
|  |  |  | assert !Cools.isEmpty(jamVehicleList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String jamAgvNo = jamVehicleList.get(0); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | boolean initJamCache = false; | 
|---|
|  |  |  | if (null == jam) { | 
|---|
|  |  |  | jam = new Jam(); | 
|---|
|  |  |  | jam.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); | 
|---|
|  |  |  | jam.setJamAgv(agv.getId()); | 
|---|
|  |  |  | jam.setJamCode(startCode.getId()); | 
|---|
|  |  |  | jam.setJamSeg(segment.getId()); | 
|---|
|  |  |  | jam.setStartTime(now); | 
|---|
|  |  |  | jam.setState(JamStateType.RUNNING.toString()); | 
|---|
|  |  |  | if (!jamService.save(jam)) { | 
|---|
|  |  |  | log.error("{}号车辆在{}定位被阻塞,记录阻塞状态失败!!!", agvNo, startCode.getData()); | 
|---|
|  |  |  | return pathList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | initJamCache = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | long previousTimestamp = jam.getStartTime().getTime(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // jam vehicle info | 
|---|
|  |  |  | Agv jamAgv = agvService.selectByUuid(jamAgvNo); | 
|---|
|  |  |  | String jamAgvCode = codeService.getById(agvDetailService.selectByAgvId(jamAgv.getId()).getRecentCode()).getData(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // jam vehicle dynamic on map matrix | 
|---|
|  |  |  | List<String> jamCodeList = mapDataDispatcher.queryCodeListFromDynamicNode(lev, jamAgvNo); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 路径阻塞 | 
|---|
|  |  |  | if (jamCodeList.size() > 1) { | 
|---|
|  |  |  | if (System.currentTimeMillis() - previousTimestamp > timeoutDuration) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(lockPathList)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | pathList = lockPathList; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" | 
|---|
|  |  |  | , agvNo, startCode.getData(), endCode.getData(), "路径阻塞超时"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.info("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】", agvNo, jamAgvNo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 车辆阻塞 | 
|---|
|  |  |  | 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 { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 已经通知车辆避让 | 
|---|
|  |  |  | if (!Cools.isEmpty(jam.getAvoAgv())) { | 
|---|
|  |  |  | assert !Cools.isEmpty(jam.getNotifyTime()); | 
|---|
|  |  |  | assert !Cools.isEmpty(blockVehicleList); | 
|---|
|  |  |  | Integer maxJamTimeoutFactor = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (System.currentTimeMillis() - jam.getNotifyTime().getTime() > timeoutDuration) { | 
|---|
|  |  |  | log.warn("{}号车辆阻塞时间过长!!!已通知避让车辆【{}】...", agvNo, jam.getAvoAgv$()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return pathList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // persist jam data | 
|---|
|  |  |  | jam = this.createOrUpdateJam(agv, startCode, segment, jam, draftPath); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | do { | 
|---|
|  |  |  | // ? has unAvoidable block vehicles | 
|---|
|  |  |  | if (blockVehicleList.stream().anyMatch(blockVehicleDto -> !blockVehicleDto.isAvoidable())) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 阻塞车辆正在作业,等待 ===>> 超过等待时间,绕路 | 
|---|
|  |  |  | List<Segment> runningSegList = segmentService.getByAgvAndState(jamAgv.getId(), SegmentStateType.RUNNING.toString()); | 
|---|
|  |  |  | if (!Cools.isEmpty(runningSegList)) { | 
|---|
|  |  |  | // set factor of jam timeout | 
|---|
|  |  |  | maxJamTimeoutFactor = 1; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (System.currentTimeMillis() - previousTimestamp > timeoutDuration) { | 
|---|
|  |  |  | // ? already do notify to avoid | 
|---|
|  |  |  | if (!Cools.isEmpty(jam.getAvoAgv()) | 
|---|
|  |  |  | && BlockVehicleDto.customContain(blockVehicleList, agvService.getById(jam.getAvoAgv()).getUuid())) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(lockPathList)) { | 
|---|
|  |  |  | pathList = lockPathList; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" | 
|---|
|  |  |  | , agvNo, startCode.getData(), endCode.getData(), "车辆阻塞超时"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.info("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】", agvNo, jamAgvNo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | maxJamTimeoutFactor = 5; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 判断下个任务是否为原地任务,如果是则等待 ===>> 超过等待时间,绕路;如果不是,让阻塞车辆避让 | 
|---|
|  |  |  | Segment waitingSeg = segmentService.getJustWaitingSeg(jamAgv.getId()); | 
|---|
|  |  |  | if (null != waitingSeg) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 如果阻塞车辆待执行任务处于原地,则不能通知它避让 | 
|---|
|  |  |  | if (waitingSeg.getEndNode().equals(codeService.selectByData(jamAgvCode).getId())) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (System.currentTimeMillis() - previousTimestamp > Math.max((timeoutDuration / 30), (5 * 1000))) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(lockPathList)) { | 
|---|
|  |  |  | pathList = lockPathList; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" | 
|---|
|  |  |  | , agvNo, startCode.getData(), endCode.getData(), "车辆阻塞超时"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.info("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】", agvNo, jamAgvNo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 通知阻塞车辆避让 | 
|---|
|  |  |  | if (this.notifyVehicleAvoid(jamAgvNo, jamAgvCode, unlockPathList, agvNo, jam)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (jam.getCycleAvo() == 1) { | 
|---|
|  |  |  | jam.setCycleCode(endCode.getId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | jam.setAvoAgv(jamAgv.getId()); | 
|---|
|  |  |  | jam.setNotifyTime(new Date()); | 
|---|
|  |  |  | if (!jamService.updateById(jam)) { | 
|---|
|  |  |  | //                                log.error("{}编号阻塞记录更新失败!!!", jam.getUuid()); | 
|---|
|  |  |  | throw new CoolException(jam.getUuid() + "编号阻塞记录更新失败!!!"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (System.currentTimeMillis() - previousTimestamp > timeoutDuration) { | 
|---|
|  |  |  | // select optimal block vehicle | 
|---|
|  |  |  | String blockAgvNo = this.checkoutBestSolutionOfBlocks(blockVehicleList, segment); | 
|---|
|  |  |  | if (Cools.isEmpty(blockAgvNo)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(lockPathList)) { | 
|---|
|  |  |  | pathList = lockPathList; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" | 
|---|
|  |  |  | , agvNo, startCode.getData(), endCode.getData(), "车辆阻塞超时"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | maxJamTimeoutFactor = 2; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.info("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】", agvNo, jamAgvNo); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // block vehicle info | 
|---|
|  |  |  | Agv blockAgv = agvService.selectByUuid(blockAgvNo); | 
|---|
|  |  |  | String blockAgvCode = codeService.getById(agvDetailService.selectByAgvId(blockAgv.getId()).getRecentCode()).getData(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // create new jam if already notify the avoid vehicle | 
|---|
|  |  |  | if (!Cools.isEmpty(jam.getAvoAgv(), jam.getAvoSeg()) && !blockAgv.getId().equals(jam.getAvoAgv())) { | 
|---|
|  |  |  | jam = this.setupNewJam(jam, agv, startCode, segment, draftPath); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | do { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 阻塞车辆正在原地作业,等待 ===>> 超过等待时间,绕路 | 
|---|
|  |  |  | 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); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!initJamCache) { | 
|---|
|  |  |  | jam.setDuration(System.currentTimeMillis() - jam.getStartTime().getTime()); | 
|---|
|  |  |  | if (!jamService.updateById(jam)) { | 
|---|
|  |  |  | log.error("{}编号阻塞记录更新失败!!!", jam.getUuid()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // handle jam timeout | 
|---|
|  |  |  | if (null != maxJamTimeoutFactor) { | 
|---|
|  |  |  | if (System.currentTimeMillis() - jam.getStartTime().getTime() > MapDataConstant.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)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (null != jam) { | 
|---|
|  |  |  | boolean beDeprecate = false; | 
|---|
|  |  |  | if (blockSeverity.equals(BlockSeverityType.SEVERE) && !Cools.isEmpty(jam.getJamPath())) { | 
|---|
|  |  |  | List<String> jamPath = GsonUtils.fromJsonToList(jam.getJamPath(), String.class); | 
|---|
|  |  |  | if (!this.comparePathLists(jamPath, pathList)) {    // jamPath >= pathList | 
|---|
|  |  |  | beDeprecate = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | jam.setEndTime(now); | 
|---|
|  |  |  | jam.setUpdateTime(now); | 
|---|
|  |  |  | jam.setState(JamStateType.FINISH.toString()); | 
|---|
|  |  |  | if (!jamService.updateById(jam)) { | 
|---|
|  |  |  | log.error("{}编号阻塞记录完成修改失败!!!", jam.getUuid()); | 
|---|
|  |  |  | jam.setState(beDeprecate ? JamStateType.DEPRECATED.toString() : JamStateType.FINISH.toString()); | 
|---|
|  |  |  | if (jamService.updateById(jam)) { | 
|---|
|  |  |  | if (beDeprecate) { | 
|---|
|  |  |  | // search previous jam that jamSeg from this segment | 
|---|
|  |  |  | List<Jam> previousJams = jamService.list(new LambdaQueryWrapper<Jam>() | 
|---|
|  |  |  | .eq(Jam::getJamSeg, segment.getId()) | 
|---|
|  |  |  | .eq(Jam::getState, JamStateType.FINISH.toString()) | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | for (Jam previousJam : previousJams) { | 
|---|
|  |  |  | previousJam.setState(JamStateType.DEPRECATED.toString()); | 
|---|
|  |  |  | previousJam.setUpdateTime(now); | 
|---|
|  |  |  | if (!jamService.updateById(previousJam)) { | 
|---|
|  |  |  | log.error("Jam[{}] failed to update!!!", previousJam.getUuid()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | log.error("Jam[{}] failed to update!!!", jam.getUuid()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // expired jam | 
|---|
|  |  |  | // deal expired jam | 
|---|
|  |  |  | for (Jam expiredJam : jamService.list(new LambdaQueryWrapper<Jam>() | 
|---|
|  |  |  | .eq(Jam::getJamAgv, agv.getId()) | 
|---|
|  |  |  | .eq(Jam::getState, JamStateType.RUNNING.toString()))) { | 
|---|
|  |  |  | expiredJam.setEndTime(now); | 
|---|
|  |  |  | expiredJam.setUpdateTime(now); | 
|---|
|  |  |  | expiredJam.setState(JamStateType.FINISH.toString()); | 
|---|
|  |  |  | expiredJam.setState(JamStateType.DEPRECATED.toString()); | 
|---|
|  |  |  | if (!jamService.updateById(expiredJam)) { | 
|---|
|  |  |  | log.error("{}编号阻塞记录完成修改失败!!!", expiredJam.getUuid()); | 
|---|
|  |  |  | log.error("Jam[{}] failed to update!!!", expiredJam.getUuid()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | return pathList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private List<String> getSliceAndReturnJamVehicleList(Integer lev, List<String> fullPathList, String agvNo, List<String> input) { | 
|---|
|  |  |  | List<String> jamVehicleList = new ArrayList<>(); | 
|---|
|  |  |  | private List<BlockVehicleDto> slicePathAndReturnBlockVehicleList(Integer lev, List<String> fullPathList, String agvNo, List<String> pathList) { | 
|---|
|  |  |  | List<BlockVehicleDto> blockVehicleList = new ArrayList<>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev); | 
|---|
|  |  |  | //        DynamicNode[][] dynamicMatrix = mapDataDispatcher.getDynamicMatrix(lev); | 
|---|
|  |  |  | String[][] waveMatrix = mapDataDispatcher.getWaveMatrix(lev); | 
|---|
|  |  |  | for (String code : fullPathList) { | 
|---|
|  |  |  | int[] node = mapDataDispatcher.getCodeMatrixIdx(lev, code); | 
|---|
|  |  |  | 
|---|
|  |  |  | List<String> waveNodeList = MapDataUtils.parseWaveNode(waveNode); | 
|---|
|  |  |  | List<String> otherWaveList = MapDataUtils.hasOtherWave(waveNodeList, agvNo); | 
|---|
|  |  |  | if (!Cools.isEmpty(otherWaveList)) { | 
|---|
|  |  |  | jamVehicleList.addAll(otherWaveList); | 
|---|
|  |  |  | for (String otherWave : otherWaveList) { | 
|---|
|  |  |  | if (1 < mapDataDispatcher.queryCodeListFromDynamicNode(lev, otherWave).size()) { | 
|---|
|  |  |  | blockVehicleList.add(new BlockVehicleDto(otherWave, false)); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | blockVehicleList.add(new BlockVehicleDto(otherWave, true)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | DynamicNode dynamicNode = dynamicMatrix[node[0]][node[1]]; | 
|---|
|  |  |  | String vehicle = dynamicNode.getVehicle(); | 
|---|
|  |  |  | assert !vehicle.equals(DynamicNodeType.BLOCK.val); | 
|---|
|  |  |  | if (!vehicle.equals(DynamicNodeType.ACCESS.val) && !vehicle.equals(agvNo)) { | 
|---|
|  |  |  | jamVehicleList.add(vehicle); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //            DynamicNode dynamicNode = dynamicMatrix[node[0]][node[1]]; | 
|---|
|  |  |  | //            String vehicle = dynamicNode.getVehicle(); | 
|---|
|  |  |  | //            assert !vehicle.equals(DynamicNodeType.BLOCK.val); | 
|---|
|  |  |  | //            if (!vehicle.equals(DynamicNodeType.ACCESS.val) && !vehicle.equals(agvNo)) { | 
|---|
|  |  |  | //                blockVehicleList.add(vehicle); | 
|---|
|  |  |  | //                break; | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | input.add(code); | 
|---|
|  |  |  | pathList.add(code); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (input.size() <= 1) { | 
|---|
|  |  |  | input.clear(); | 
|---|
|  |  |  | if (pathList.size() <= 1) { | 
|---|
|  |  |  | pathList.clear(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return jamVehicleList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private String hasEvent(String agvNo) { | 
|---|
|  |  |  | List<Agv> agvList = agvService.list(new LambdaQueryWrapper<>()); | 
|---|
|  |  |  | for (Agv agv : agvList) { | 
|---|
|  |  |  | if (agvNo.equals(agv.getUuid())) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String jamStr = redis.getValue(RedisConstant.AGV_TRAFFIC_JAM_FLAG, agv.getUuid()); | 
|---|
|  |  |  | if (!Cools.isEmpty(jamStr)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | TrafficJamDto jamDto = JSON.parseObject(jamStr, TrafficJamDto.class); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | return blockVehicleList.stream().distinct().collect(Collectors.toList()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * avoidPathList include wave node and dynamic node | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private boolean notifyVehicleAvoid(String agvNo, String agvPosCode, List<String> avoidPathList, String sponsor, Jam jam) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | assert avoidPathList.size() >= 2; | 
|---|
|  |  |  | Agv agv = agvService.selectByUuid(agvNo); | 
|---|
|  |  |  | if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { | 
|---|
|  |  |  | log.warn("{}号车辆避让失败,存在进行中任务!!!", agvNo); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int[] startMapIdx = mapDataDispatcher.getCodeMatrixIdx(null, agvPosCode); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | RetreatNavigateNode startNode = new RetreatNavigateNode(startMapIdx[0], startMapIdx[1], agvPosCode); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | assert avoidPathList.size() >= 2; | 
|---|
|  |  |  | RetreatNavigateNode finalNode = retreatNavigateService.execute(agvNo, startNode, avoidPathList, sponsor, jam); | 
|---|
|  |  |  | if (null == finalNode) { | 
|---|
|  |  |  | log.warn("{}号车辆避让失败,检索避让点失败!!!", agvNo); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Date now = new Date(); | 
|---|
|  |  |  | String endCodeData = finalNode.getCodeData(); | 
|---|
|  |  |  | Agv agv = agvService.selectByUuid(agvNo); | 
|---|
|  |  |  | Code endCode = codeService.selectByData(endCodeData); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | jam.setAvoCode(endCode.getId()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!Cools.isEmpty(segmentService.getByAgvAndState(agv.getId(), SegmentStateType.RUNNING.toString()))) { | 
|---|
|  |  |  | log.warn("{}号车辆避让失败,存在进行中任务!!!", agvNo); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<Segment> waitingSegList = segmentService.getByAgvAndState(agv.getId(), SegmentStateType.WAITING.toString()); | 
|---|
|  |  |  | if (!Cools.isEmpty(waitingSegList)) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (waitingSegList.size() > 1) { | 
|---|
|  |  |  | log.error("避让通知失败,{}号车辆存在多个等待中的Segment!!!", agvNo); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // revert | 
|---|
|  |  |  | Date now = new Date(); | 
|---|
|  |  |  | for (Segment seg : waitingSegList) { | 
|---|
|  |  |  | seg.setState(SegmentStateType.INIT.toString()); | 
|---|
|  |  |  | seg.setUpdateTime(now); | 
|---|
|  |  |  | 
|---|
|  |  |  | if (!segmentService.save(insertSeg)) { | 
|---|
|  |  |  | log.error("Segment [{}] 保存失败 !!!", segment.getTravelId() + " - " + segment.getSerial()); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | jam.setAvoSeg(insertSeg.getId()); | 
|---|
|  |  |  | jam.setAvoCode(endCode.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, 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)) { | 
|---|
|  |  |  | log.error("AGV[{}] failed to save jam", agv.getUuid()); | 
|---|
|  |  |  | throw new CoolException("failed to save jam"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | jam.setDuration(System.currentTimeMillis() - jam.getStartTime().getTime()); | 
|---|
|  |  |  | if (!jamService.updateById(jam)) { | 
|---|
|  |  |  | log.error("AGV[{}] failed to update jam", agv.getUuid()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return jam; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private Jam setupNewJam(Jam originJam, Agv agv, Code startCode, Segment segment, List<String> draftPath) { | 
|---|
|  |  |  | originJam.setUpdateTime(new Date()); | 
|---|
|  |  |  | originJam.setState(JamStateType.FINISH.toString()); | 
|---|
|  |  |  | if (!jamService.updateById(originJam)) { | 
|---|
|  |  |  | log.error("Jam[{}] failed to update", originJam.getUuid()); | 
|---|
|  |  |  | return originJam; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | return this.createOrUpdateJam( | 
|---|
|  |  |  | agv | 
|---|
|  |  |  | , startCode | 
|---|
|  |  |  | , segment | 
|---|
|  |  |  | , null | 
|---|
|  |  |  | , draftPath | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private List<String> getBlackPathList(List<Jam> unfinishedOriginJamByCurrAgv) { | 
|---|
|  |  |  | List<String> blackPathList = new ArrayList<>(); | 
|---|
|  |  |  | Integer lev = MapDataDispatcher.MAP_DEFAULT_LEV; | 
|---|
|  |  |  | 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(lev, 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())); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // the wave of first node | 
|---|
|  |  |  | Double avoidDistance = MapDataUtils.getVehicleWaveSafeDistance( | 
|---|
|  |  |  | agvModelService.getById(jamAgv.getAgvModel()).getDiameter(), | 
|---|
|  |  |  | MapDataConstant.MAX_DISTANCE_BETWEEN_ADJACENT_AGV_FACTOR | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | List<String> waveCodeList = mapService.getWaveScopeByCode(lev, firstCodeNode, avoidDistance) | 
|---|
|  |  |  | .stream().map(NavigateNode::getCodeData).distinct().collect(Collectors.toList()); | 
|---|
|  |  |  | list.addAll(waveCodeList); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | blackPathList.addAll(list); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return blackPathList.stream().distinct().collect(Collectors.toList()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private String checkoutBestSolutionOfBlocks(List<BlockVehicleDto> blockVehicleList, Segment segment) { | 
|---|
|  |  |  | assert !Cools.isEmpty(blockVehicleList); | 
|---|
|  |  |  | for (BlockVehicleDto blockVehicleDto : blockVehicleList) { | 
|---|
|  |  |  | if (!blockVehicleDto.isAvoidable()) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 当前vehicle正在进行避让作业 | 
|---|
|  |  |  | if (!Cools.isEmpty(jamService.getUnfinishedAvoSegByAvo(blockVehicleDto.getVehicle(), null))) { | 
|---|
|  |  |  | continue; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return blockVehicleDto.getVehicle(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public boolean comparePathLists(List<String> list1, List<String> list2) { | 
|---|
|  |  |  | if (list1.equals(list2)) { | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (list1.containsAll(list2)) { | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private boolean isJamBeDeprecatedByAvo(Long avoSeg) { | 
|---|
|  |  |  | return 0 < jamService.count(new LambdaQueryWrapper<Jam>() | 
|---|
|  |  |  | //                .eq(Jam::getAvoAgv, avoAgv) | 
|---|
|  |  |  | .eq(Jam::getAvoSeg, avoSeg) | 
|---|
|  |  |  | .eq(Jam::getState, JamStateType.DEPRECATED.toString()) | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private boolean skipCurrSegment(Segment currSegment) { | 
|---|
|  |  |  | currSegment.setState(SegmentStateType.FINISH.toString()); | 
|---|
|  |  |  | currSegment.setUpdateTime(new Date()); | 
|---|
|  |  |  | if (!segmentService.updateById(currSegment)) { | 
|---|
|  |  |  | log.error("Segment [{}] failed to update !!!", currSegment.getTravelId() + " - " + currSegment.getSerial()); | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | segmentService.processNext(Utils.singletonList(currSegment)); | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|