| | |
| | | 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.PathDto; |
| | | 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 org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | import com.zy.acs.common.utils.News; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | |
| | | // } |
| | | // } |
| | | // if (null == endCode) { |
| | | // log.warn("AGV[{}] failed to search destination,there hadn't any idle funSta,TaskTypeType:{}", segment.getAgvId(), FuncStaType.STANDBY); |
| | | // News.warn("AGV[{}] failed to search destination,there hadn't any idle funSta,TaskTypeType:{}", segment.getAgvId(), FuncStaType.STANDBY); |
| | | // return; |
| | | // } |
| | | // |
| | | // segment.setState(SegmentStateType.INIT.toString()); |
| | | // segment.setUpdateTime(now); |
| | | // if (!segmentService.updateById(segment)) { |
| | | // log.error("Segment [{}] failed to update !!!", segment.getGroupId() + " - " + segment.getSerial()); |
| | | // News.error("Segment [{}] failed to update !!!", segment.getGroupId() + " - " + segment.getSerial()); |
| | | // return; |
| | | // } |
| | | // |
| | |
| | | // insertSeg.setState(SegmentStateType.WAITING.toString()); |
| | | // insertSeg.setMemo(MapDataConstant.RESOLVE_DEADLOCK); |
| | | // if (!segmentService.save(insertSeg)) { |
| | | // log.error("Segment [{}] failed to save !!!", segment.getTravelId() + " - " + segment.getSerial()); |
| | | // News.error("Segment [{}] failed to save !!!", segment.getTravelId() + " - " + segment.getSerial()); |
| | | // return; |
| | | // } |
| | | // return; |
| | |
| | | if (!Cools.isEmpty(waitingSegList)) { |
| | | for (Segment waitingSeg : waitingSegList) { |
| | | if (!waitingSeg.getId().equals(segment.getId())) { |
| | | // log.error("AGV[{}] 任务异常,服务器错误!!!", agv.getUuid()); |
| | | // News.error("AGV[{}] 任务异常,服务器错误!!!", agv.getUuid()); |
| | | return; |
| | | } |
| | | } |
| | |
| | | // ArrayList<List<TaskPosDto>> list = JSON.parseObject(travel.getTaskContent(), new TypeReference<ArrayList<List<TaskPosDto>>>() {}); |
| | | |
| | | // * sync wave scope |
| | | if (!avoidWaveCalculator.calcWaveScope()) { |
| | | log.error("failed to calculate avoid wave matrix ..."); |
| | | if (!avoidWaveCalculator.calcWaveScope(agvModelService.getByAgvId(agv.getId()))) { |
| | | News.error("failed to calculate avoid wave matrix ..."); |
| | | return; |
| | | } |
| | | |
| | |
| | | segment.setState(SegmentStateType.INIT.toString()); |
| | | segment.setUpdateTime(now); |
| | | if (!segmentService.updateById(segment)) { |
| | | log.error("Segment [{}] failed to update !!!", segment.getGroupId() + " - " + segment.getSerial()); |
| | | News.error("Segment [{}] failed to update !!!", segment.getGroupId() + " - " + segment.getSerial()); |
| | | } |
| | | segmentList.clear(); |
| | | |
| | |
| | | insertSeg.setPosType(TaskPosDto.PosType.MOVE.toString()); |
| | | insertSeg.setState(SegmentStateType.WAITING.toString()); |
| | | if (!segmentService.save(insertSeg)) { |
| | | log.error("Segment [{}] failed to save !!!", segment.getTravelId() + " - " + segment.getSerial()); |
| | | News.error("Segment [{}] failed to save !!!", insertSeg.getTravelId() + " - " + insertSeg.getSerial()); |
| | | } |
| | | segmentList.add(insertSeg); |
| | | |
| | |
| | | interrupt = true; |
| | | } else { |
| | | if (nextStep.getEndNode() == endNode) { |
| | | |
| | | segmentList.add(nextStep); |
| | | // remove sta action seg |
| | | if (!nextStep.getPosType().equals(TaskPosDto.PosType.ORI_STA.toString()) |
| | | && !nextStep.getPosType().equals(TaskPosDto.PosType.DEST_STA.toString())) { |
| | | segmentList.add(nextStep); |
| | | } |
| | | } else { |
| | | interrupt = true; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | mapService.lockPath(null, pathList, agv.getUuid()); |
| | | |
| | | // startTime = System.currentTimeMillis(); |
| | | mainService.generateAction(segment.getAgvId(), segmentList, pathList, now); |
| | | List<PathDto> pathDtoList = mainService.generateAction(segment.getAgvId(), segmentList, pathList, now); |
| | | // System.out.println("generateAction: " + (System.currentTimeMillis() - startTime)); |
| | | |
| | | mapService.lockPath(null, pathDtoList, agv.getUuid()); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("TrafficService.trigger", e); |
| | | News.error("TrafficService.trigger", e); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | |
| | | throw new RuntimeException("trigger method caught an exception", e); |
| | | } |
| | | } |
| | | |
| | |
| | | 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> blackPath = this.getBlackPathList(agvNo, unfinishedOriginJamByCurrAgv); |
| | | |
| | | // 结果集 |
| | | List<String> pathList = new ArrayList<>(); |
| | |
| | | |
| | | 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); |
| | | // News.info("AGV[{}] waiting in place, because the path list is too short...", agvNo); |
| | | pathList.clear(); |
| | | } |
| | | |
| | |
| | | blockVehicleDto -> null != jamService.getCycleJam(agv.getId(), segment.getId(), blockVehicleDto.getVehicle()) |
| | | ); |
| | | if (hasCycleJam) { |
| | | log.info("AGV[{}] waiting in place, because has cycle jam...", agvNo); |
| | | News.info("AGV[{}] waiting in place, because has cycle jam...", agvNo); |
| | | pathList.clear(); |
| | | } |
| | | } |
| | |
| | | } else { |
| | | |
| | | if (Cools.isEmpty(blockVehicleList)) { |
| | | log.warn("AGV[{}] can't reach to code: {}, because there is too many vehicle in the lane...", agvNo, endCode.getData()); |
| | | News.warn("AGV[{}] can't reach to code: {}, because there is too many vehicle in the lane...", agvNo, endCode.getData()); |
| | | } else { |
| | | |
| | | assert !Cools.isEmpty(blockVehicleList); |
| | |
| | | |
| | | pathList = lockPathList; |
| | | } else { |
| | | log.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" |
| | | News.error("{}号车辆检索[{}] ===>> [{}]路径失败,原因:{}" |
| | | , agvNo, startCode.getData(), endCode.getData(), "路径阻塞超时"); |
| | | } |
| | | } else { |
| | | log.warn("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】" |
| | | , agvNo |
| | | , blockVehicleList.stream().map(BlockVehicleDto::getVehicle).collect(Collectors.toList()).toString() |
| | | ); |
| | | // News.warn("{}号车辆正在等待交通堵塞,阻塞车辆:【{}】" |
| | | // , agvNo |
| | | // , blockVehicleList.stream().map(BlockVehicleDto::getVehicle).collect(Collectors.toList()).toString() |
| | | // ); |
| | | } |
| | | } |
| | | |
| | |
| | | previousJam.setState(JamStateType.DEPRECATED.toString()); |
| | | previousJam.setUpdateTime(now); |
| | | if (!jamService.updateById(previousJam)) { |
| | | log.error("Jam[{}] failed to update!!!", previousJam.getUuid()); |
| | | News.error("Jam[{}] failed to update!!!", previousJam.getUuid()); |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | log.error("Jam[{}] failed to update!!!", jam.getUuid()); |
| | | News.error("Jam[{}] failed to update!!!", jam.getUuid()); |
| | | } |
| | | } |
| | | // deal expired jam |
| | |
| | | expiredJam.setUpdateTime(now); |
| | | expiredJam.setState(JamStateType.DEPRECATED.toString()); |
| | | if (!jamService.updateById(expiredJam)) { |
| | | log.error("Jam[{}] failed to update!!!", expiredJam.getUuid()); |
| | | News.error("Jam[{}] failed to update!!!", expiredJam.getUuid()); |
| | | } |
| | | } |
| | | |
| | |
| | | private boolean notifyVehicleAvoid(String agvNo, String agvPosCode, List<String> avoidPathList, String sponsor, Jam jam) { |
| | | Long agvId = agvService.getAgvId(agvNo); |
| | | if (!Cools.isEmpty(segmentService.getByAgvAndState(agvId, SegmentStateType.RUNNING.toString()))) { |
| | | log.warn("{}号车辆避让失败,存在进行中任务!!!", agvNo); |
| | | News.warn("{}号车辆避让失败,存在进行中任务!!!", agvNo); |
| | | return false; |
| | | } |
| | | |
| | |
| | | assert avoidPathList.size() >= 2; |
| | | RetreatNavigateNode finalNode = retreatNavigateService.execute(agvNo, startNode, avoidPathList, sponsor, jam); |
| | | if (null == finalNode) { |
| | | log.warn("{}号车辆避让失败,检索避让点失败!!!", agvNo); |
| | | News.warn("{}号车辆避让失败,检索避让点失败!!!", agvNo); |
| | | return false; |
| | | } |
| | | |
| | |
| | | if (!Cools.isEmpty(waitingSegList)) { |
| | | |
| | | if (waitingSegList.size() > 1) { |
| | | log.error("避让通知失败,{}号车辆存在多个等待中的Segment!!!", agvNo); |
| | | News.error("避让通知失败,{}号车辆存在多个等待中的Segment!!!", agvNo); |
| | | return false; |
| | | } |
| | | // revert |
| | |
| | | seg.setState(SegmentStateType.INIT.toString()); |
| | | seg.setUpdateTime(now); |
| | | if (!segmentService.updateById(seg)) { |
| | | log.error("Segment [{}] 更新失败 !!!", seg.getTravelId() + " - " + seg.getSerial()); |
| | | News.error("Segment [{}] 更新失败 !!!", seg.getTravelId() + " - " + seg.getSerial()); |
| | | } |
| | | } |
| | | Segment segment = waitingSegList.get(0); |
| | |
| | | insertSeg.setPosType(TaskPosDto.PosType.MOVE.toString()); |
| | | insertSeg.setState(SegmentStateType.WAITING.toString()); |
| | | if (!segmentService.save(insertSeg)) { |
| | | log.error("Segment [{}] 保存失败 !!!", segment.getTravelId() + " - " + segment.getSerial()); |
| | | News.error("Segment [{}] 保存失败 !!!", segment.getTravelId() + " - " + segment.getSerial()); |
| | | return false; |
| | | } else { |
| | | jam.setAvoSeg(insertSeg.getId()); |
| | |
| | | jam.setStartTime(new Date()); |
| | | jam.setState(JamStateType.RUNNING.toString()); |
| | | if (!jamService.save(jam)) { |
| | | log.error("AGV[{}] failed to save jam", agv.getUuid()); |
| | | News.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()); |
| | | News.error("AGV[{}] failed to update jam", agv.getUuid()); |
| | | } |
| | | } |
| | | return jam; |
| | |
| | | originJam.setUpdateTime(new Date()); |
| | | originJam.setState(JamStateType.FINISH.toString()); |
| | | if (!jamService.updateById(originJam)) { |
| | | log.error("Jam[{}] failed to update", originJam.getUuid()); |
| | | News.error("Jam[{}] failed to update", originJam.getUuid()); |
| | | return originJam; |
| | | } else { |
| | | return this.createOrUpdateJam( |
| | |
| | | } |
| | | } |
| | | |
| | | private List<String> getBlackPathList(List<Jam> unfinishedOriginJamByCurrAgv) { |
| | | private List<String> getBlackPathList(String agvNo, 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())) { |
| | | if (Cools.isEmpty(unfinishedOriginJamByCurrAgv)) { |
| | | return blackPathList; |
| | | } |
| | | |
| | | List<String> list = GsonUtils.fromJsonToList(jam.getJamPath(), String.class); |
| | | AgvModel agvModel = agvModelService.getByAgvNo(agvNo); |
| | | double bufferRadius = MapDataUtils.buildFootprint(agvModel).maxExtent(); |
| | | |
| | | Agv jamAgv = agvService.getById(jam.getJamAgv()); |
| | | List<String> jamDynamicNodes = mapService.queryCodeListFromDynamicNode(lev, jamAgv.getUuid()); |
| | | // jamDynamicNodes has sorted |
| | | String firstCodeNode = jamDynamicNodes.stream().findFirst().orElse(null); |
| | | for (Jam jam : unfinishedOriginJamByCurrAgv) { |
| | | if (!Cools.isEmpty(jam.getJamPath())) { |
| | | |
| | | if (!Cools.isEmpty(firstCodeNode)) { |
| | | int idx = list.indexOf(firstCodeNode); |
| | | if (idx != -1) { |
| | | list = new ArrayList<>(list.subList(idx, list.size())); |
| | | List<String> list = GsonUtils.fromJsonToList(jam.getJamPath(), String.class); |
| | | |
| | | // 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); |
| | | } else { |
| | | // 如果被阻塞车辆已经不在原来的阻塞路径中,考虑避让车走行时不需要把之前的阻塞路径加入黑名单 |
| | | list = new ArrayList<>(); |
| | | } |
| | | String jamAgvNo = agvService.getAgvNo(jam.getJamAgv()); |
| | | List<String> jamDynamicNodes = mapService.queryCodeListFromDynamicNode(lev, jamAgvNo); |
| | | // 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 |
| | | AgvModel jamAgvModel = agvModelService.getByAgvNo(jamAgvNo); |
| | | Double avoidDistance = MapDataUtils.buildFootprint(jamAgvModel).maxExtent() + bufferRadius; |
| | | List<String> waveCodeList = mapService.getWaveScopeByCode(lev, firstCodeNode, avoidDistance) |
| | | .stream().map(NavigateNode::getCodeData).distinct().collect(Collectors.toList()); |
| | | list.addAll(waveCodeList); |
| | | } else { |
| | | // 如果被阻塞车辆已经不在原来的阻塞路径中,考虑避让车走行时不需要把之前的阻塞路径加入黑名单 |
| | | list = new ArrayList<>(); |
| | | } |
| | | |
| | | blackPathList.addAll(list); |
| | | } |
| | | |
| | | blackPathList.addAll(list); |
| | | } |
| | | } |
| | | |
| | | return blackPathList.stream().distinct().collect(Collectors.toList()); |
| | | } |
| | | |
| | |
| | | if (!blockVehicleDto.isAvoidable()) { |
| | | continue; |
| | | } |
| | | Long agvId = agvService.getAgvId(blockVehicleDto.getVehicle()); |
| | | // 当前vehicle正在进行避让作业 |
| | | if (!Cools.isEmpty(jamService.getUnfinishedAvoSegByAvo(blockVehicleDto.getVehicle(), null))) { |
| | | if (!Cools.isEmpty(jamService.getUnfinishedAvoSegByAvo(agvId, null))) { |
| | | continue; |
| | | } |
| | | // 当前vehicle正在进行滚筒输送线等待 |
| | | if (travelService.hasRollerWaiting(agvId)) { |
| | | continue; |
| | | } |
| | | // if (segmentService.isRollerWaiting(agvId)) { |
| | | // continue; |
| | | // } |
| | | return blockVehicleDto.getVehicle(); |
| | | } |
| | | return null; |
| | |
| | | return false; |
| | | } |
| | | if (jamList.size() > 1) { |
| | | log.error("AvoSeg[id = {}] seg data has exception, result in two jams", avoSeg); |
| | | News.error("AvoSeg[id = {}] seg data has exception, result in two jams", avoSeg); |
| | | } |
| | | Jam jam = jamList.get(0); |
| | | if (jam.getState().equals(JamStateType.DEPRECATED.toString())) { |
| | |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | } |