diff --git a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java index 3a387029d..d1758b8ca 100644 --- a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java +++ b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java @@ -11,7 +11,6 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO; import club.joylink.rtss.simulation.cbtc.communication.vo.fault.DeviceFaultInfo; import club.joylink.rtss.simulation.cbtc.data.status.IbpStatus; -import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vo.SimulationVO; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; @@ -306,9 +305,9 @@ public class SimulationV1Controller { return groupSimulationService.getLog(group, queryVO); } - @ApiOperation("查询进路路径") - @GetMapping("/{group}/queryRoutePaths") - public List queryRoutePaths(@PathVariable String group, String groupNumber, String standCode, String signalCode) { + @ApiOperation("查询区段路径") + @GetMapping("/{group}/querySectionPaths") + public List> querySectionPaths(@PathVariable String group, String groupNumber, String standCode, String signalCode) { return simulationSupportService.queryRoutePaths(group, groupNumber, standCode, signalCode); } } diff --git a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java index 35f31376f..12b913fdb 100644 --- a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java +++ b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java @@ -400,20 +400,20 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { List
tbSections = new ArrayList<>(); if (right) { if (rightStandTrack.isTurnBackTrack() - && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(rightStandTrack, adjacentLeftStandTrack, false))) { + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(rightStandTrack, adjacentLeftStandTrack, false, 10))) { tbSections.add(rightStandTrack); } if (leftStandTrack.isTurnBackTrack() - && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentRightStandTrack, leftStandTrack, true))) { + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentRightStandTrack, leftStandTrack, true, 10))) { tbSections.add(leftStandTrack); } } else { if (rightStandTrack.isTurnBackTrack() - && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentLeftStandTrack, rightStandTrack, false))) { + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentLeftStandTrack, rightStandTrack, false, 10))) { tbSections.add(rightStandTrack); } if (leftStandTrack.isTurnBackTrack() - && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(leftStandTrack, adjacentRightStandTrack, true))) { + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(leftStandTrack, adjacentRightStandTrack, true, 10))) { tbSections.add(leftStandTrack); } } @@ -431,7 +431,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { } Section standTrack = station.getNormalStand(right).get(0).getSection(); return turnBackList.stream().filter(section -> !section.isNormalStandTrack()) - .filter(section -> !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(standTrack, section, right))) + .filter(section -> !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(standTrack, section, right, 10))) .collect(Collectors.toList()); } @@ -1404,10 +1404,10 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { runLevelVO.setEndSectionCode(endSection.getCode()); runLevelVO.setEndStationCode(endSection.getStation().getCode()); runLevelVO.setRight(right); - List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right); + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right, 10); if (CollectionUtils.isEmpty(routePaths)) { // 未找到,反方向再找 - routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, !right); + routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, !right, 10); if (!CollectionUtils.isEmpty(routePaths)) { log.info(String.format("站间运行等级[%s]与交路[%s]方向相反,实际为[%s]", String.format("%s(%s(%s))->%s(%s(%s))", @@ -1463,7 +1463,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { adjacentSections.forEach(endSection -> { //验证是否是进路路径的站间 - List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right); + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right, 10); if (CollectionUtils.isEmpty(routePaths)) { log.warn(String.format("站间运行等级数据生成失败:没有找到[%s(%s) ——> %s(%s)]对应方向[%s]的进路路径可达的站间", startSection.getStation().getName(), startSection.getName(), endSection.getStation().getName(), endSection.getName(), right ? "右向" : "左向")); diff --git a/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java index 22079e229..7f0689a3b 100644 --- a/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java +++ b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java @@ -4,17 +4,18 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.CalculateService; +import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Signal; import club.joylink.rtss.simulation.cbtc.data.map.Stand; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; -import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.List; +import java.util.stream.Collectors; /** * 仿真运行支持 @@ -24,7 +25,7 @@ public class SimulationSupportService { @Autowired private GroupSimulationService groupSimulationService; - public List queryRoutePaths(String group, String groupNumber, String standCode, String signalCode) { + public List> queryRoutePaths(String group, String groupNumber, String standCode, String signalCode) { Simulation simulation = groupSimulationService.getSimulationByGroup(group); Section destination; if (StringUtils.hasText(standCode)) { @@ -39,7 +40,10 @@ public class SimulationSupportService { VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); Section startSection = train.getHeadPosition().getSection(); - List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, destination, train.isRight()); - return RoutePathVO.convert(routePaths); + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, destination, train.isRight(), 10); + return routePaths.stream() + .map(routePath -> CalculateService.selectUniqueRoutes(routePath, false) + .stream().map(MapElement::getCode).collect(Collectors.toList())) + .collect(Collectors.toList()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java index 64b710df2..8edd6be1b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java @@ -13,7 +13,6 @@ import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.TrainLoadParam2; -import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; @@ -322,8 +321,8 @@ public class TrainOperateHandler { * 排列进路到(站台/信号机)【泰雷兹】 */ @OperateHandlerMapping(type = Operation.Type.Train_Set_Route) - public void setRouteTo(Simulation simulation, RoutePathVO routePath) { - atsTrainService.setRouteTo(simulation, routePath); + public void setRouteTo(Simulation simulation, List routes) { + atsTrainService.setRouteTo(simulation, routes); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java index 394c7cf54..e68d29479 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java @@ -95,9 +95,9 @@ public class AtsRouteSettingService { return destDefinition.queryNextRoute(headSection); } else if (train.getEstimatedArriveStandTrack() != null) { Section targetSection = repository.getByCode(train.getEstimatedArriveStandTrack(), Section.class); - routePaths = CalculateService.queryRoutePathsOnDirection(headSection, targetSection, true); + routePaths = CalculateService.queryRoutePathsOnDirection(headSection, targetSection, true, 10); if (CollectionUtils.isEmpty(routePaths)) { - routePaths = CalculateService.queryRoutePathsOnDirection(headSection, targetSection, false); + routePaths = CalculateService.queryRoutePathsOnDirection(headSection, targetSection, false, 10); } } else { // 目的地定义存在,根据目的地定义查询路径,办理进路 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java index 2dbf1012c..db2fc40fb 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java @@ -13,7 +13,6 @@ import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption; -import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; @@ -516,7 +515,7 @@ public class AtsTrainService { Section tbSection = strategy.getSectionList().get(0); switch (strategy.getType()) { case FIRST: - List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, tbSection, standRight); + List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, tbSection, standRight, 10); if (routePaths.stream().anyMatch(path -> !path.isOccupied())) { nextTarget = tbSection; } @@ -533,7 +532,7 @@ public class AtsTrainService { if (section.isNormalStandTrack()) { continue; } - List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, section, standRight); + List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, section, standRight, 10); if (routePaths.stream().anyMatch(path -> !path.isOccupied())) { nextTarget = section; break; @@ -564,7 +563,7 @@ public class AtsTrainService { break; } nextTarget = adjacentStation.getNormalStand(!standRight).get(0).getSection(); - if (CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(headSection, nextTarget, standRight))) { + if (CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(headSection, nextTarget, standRight, 10))) { nextTarget = adjacentStation.getNormalStand(standRight).get(0).getSection(); } } else { @@ -583,7 +582,7 @@ public class AtsTrainService { if (nextTarget == null) { nextTarget = headStation.getNormalStand(destinationRight).get(0).getSection(); if (!headSection.equals(nextTarget)) { - List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, nextTarget, destinationRight); + List routePaths = CalculateService.queryRoutePathsOnDirection(headSection, nextTarget, destinationRight, 10); if (!CollectionUtils.isEmpty(routePaths)) { break; } @@ -894,8 +893,8 @@ public class AtsTrainService { /** * 排列进路到(站台/信号机) */ - public void setRouteTo(Simulation simulation, RoutePathVO routePath) { - routePath.getRouteList().forEach(routeCode -> ciApiService.settingRoute(simulation, routeCode)); + public void setRouteTo(Simulation simulation, List routes) { + routes.forEach(code -> ciApiService.settingRoute(simulation, code)); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java index 07d37c946..4e0e4755b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java @@ -602,15 +602,14 @@ public class InterlockBuilder2 { runPath = new ArrayList<>(); routes = new ArrayList<>(); //从左端车站开始选择路径 - startSection4RoutePath = screeningSection4DestinationCode(leftStation, leftFrontTurnBack, necessarySectionSet, true); + startSection4RoutePath = selectSection4DestinationCode(leftStation, leftFrontTurnBack, necessarySectionSet, true); runPath.add(startSection4RoutePath); - endSection4RoutePath = screeningSection4DestinationCode(rightStation, rightFrontTurnBack, necessarySectionSet, false); + endSection4RoutePath = selectSection4DestinationCode(rightStation, rightFrontTurnBack, necessarySectionSet, false); //查询并添加路径 RoutePath optimalPath = CalculateService.queryLeastSwitchRoutePath(startSection4RoutePath, endSection4RoutePath, necessarySectionSet, true); BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(optimalPath, String.format("从%s到%s的路径未找到", startSection4RoutePath.debugStr(), endSection4RoutePath.debugStr())); runPath.addAll(optimalPath.getSectionList()); - routes.addAll(optimalPath.getRouteList()); //寻找反向的路径 Section t = startSection4RoutePath; startSection4RoutePath = endSection4RoutePath; @@ -620,7 +619,9 @@ public class InterlockBuilder2 { BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(optimalPath2, String.format("从%s到%s的路径未找到", startSection4RoutePath.debugStr(), endSection4RoutePath.debugStr())); runPath.addAll(optimalPath2.getSectionList()); - routes.addAll(optimalPath2.getRouteList()); + //添加进路 + routes.addAll(CalculateService.selectUniqueRoutes(optimalPath, true)); + routes.addAll(CalculateService.selectUniqueRoutes(optimalPath2, true)); break; } case LAST_OPERATION: @@ -630,19 +631,37 @@ public class InterlockBuilder2 { if (!StringUtils.hasText(description)) { errMsgList.add(String.format("目的地码[%s]没有描述", code)); } - if (startSection == null || right == null) { - errMsgList.add(String.format("单向目的地码[%s]没有起始区段或方向", code)); - continue; - } if (section == null) { errMsgList.add(String.format("单向目的地码[%s]没有目标区段", code)); continue; } - RoutePath routePath = CalculateService.queryLeastSwitchRoutePath(startSection, section, necessarySections, right); - BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(routePath, - String.format("从%s到%s的路径未找到", startSection.debugStr(), section.debugStr())); - runPath = new ArrayList<>(routePath.getSectionList()); - routes = new ArrayList<>(routePath.getRouteList()); + if (startSection != null) { + List
sectionPath = new ArrayList<>(); + sectionPath.add(startSection); + sectionPath.addAll(necessarySections); + sectionPath.add(section); + runPath = new ArrayList<>(); + routes = new ArrayList<>(); + for (int i = 0; i < sectionPath.size() - 1; i++) { + Section start = sectionPath.get(i); + Section end = sectionPath.get(i + 1); + RoutePath routePath; + if (right == null) { + routePath = CalculateService.queryLeastSwitchRoutePath(start, end, null, true); + if (routePath == null) { + routePath = CalculateService.queryLeastSwitchRoutePath(start, end, null, false); + } + } else { + routePath = CalculateService.queryLeastSwitchRoutePath(start, end, null, right); + } + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(routePath, + String.format("从%s到%s的路径未找到", startSection.debugStr(), section.debugStr())); + runPath.add(start); + runPath.addAll(routePath.getSectionList()); + routes.addAll(routePath.getRouteList()); + } + runPath.add(section); + } } case OTHER: if (section == null) { @@ -665,7 +684,7 @@ public class InterlockBuilder2 { * @param preferredSections 优先区段 * @param right 站前折返时是否优先选择右向站台轨 */ - private static Section screeningSection4DestinationCode(Station station, Boolean ftb, Set
preferredSections, boolean right) { + private static Section selectSection4DestinationCode(Station station, Boolean ftb, Set
preferredSections, boolean right) { Section section; if (ftb) { Optional
selectedSectionOptional = preferredSections.stream() @@ -850,7 +869,7 @@ public class InterlockBuilder2 { Section startSection = runLevel.getStartSection(); Section endSection = runLevel.getEndSection(); boolean right = runLevel.isRight(); - List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right); + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, right, 10); if (CollectionUtils.isEmpty(routePaths)) { errMsgList.add(String.format("站间运行等级[%s]无法找到路径", runLevel.debugStr(), startSection.debugStr(), endSection.debugStr())); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java index 5158ee005..c522bc4d2 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java @@ -157,10 +157,10 @@ public class SimulationBuilder { String key = RoutePath.buildKey(start, end); if (!routePathMap.containsKey(key)) { // 路径不存在,尝试构建 - List routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight()); + List routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight(), 10); if (CollectionUtils.isEmpty(routePaths)) { // 计划方向路径未找到,反向尝试 - routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight()); + routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight(), 10); } if (CollectionUtils.isEmpty(routePaths)) { // 依然未找到 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java index 2f95cf0e4..2bf9f5269 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java @@ -635,11 +635,11 @@ public class CalculateService { return false; } - public static List queryRoutePathsOnDirection(Section start, Section end, Boolean right) { + public static List queryRoutePathsOnDirection(Section start, Section end, Boolean right, int iterTimes) { List list = new ArrayList<>(); List warnList = new ArrayList<>(); RoutePath routePath = new RoutePath(start, end, right); - queryRoutePaths(0, start, routePath, list, warnList); + queryRoutePaths(0, iterTimes, start, routePath, list, warnList); if (!CollectionUtils.isEmpty(list)) { for (RoutePath path : list) { path.calculateDistance(); @@ -659,7 +659,7 @@ public class CalculateService { * @param preferredSections 优先经过这些区段,可以为null */ public static RoutePath queryLeastSwitchRoutePath(Section startSection, Section endSection, Collection
preferredSections, boolean toRight) { - List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, toRight); + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, endSection, toRight, 100); if (CollectionUtils.isEmpty(routePaths)) { return null; } else { @@ -691,18 +691,18 @@ public class CalculateService { } return optimalPath; } - return routePaths.stream().min(Comparator.comparingDouble(RoutePath::getLength)).orElse(null); + return routePaths.stream().min(Comparator.comparingInt(RoutePath::getSwitchQuantity)).orElse(null); } } - private static void queryRoutePaths(int iter, Section section, RoutePath routePath, + private static void queryRoutePaths(int iter, int iterTimes, Section section, RoutePath routePath, List list, List warnList) { if (section == null) { warnList.add(String.format("进路路径[%s]未找到,找到的最后区段为[%s],下一区段为null", routePath.debugStr(), routePath.getLastSection().debugStr())); return; } - if (iter > 100) { + if (iter > iterTimes) { warnList.add(String.format("进路路径[%s]未找到:迭代100次,最后区段为[%s]", routePath.debugStr(), routePath.getLastSection().debugStr())); return; @@ -721,20 +721,20 @@ public class CalculateService { } else { // 添加并进行迭代 routePath.addSection(next); - queryRoutePaths(iter + 1, next, routePath, list, warnList); + queryRoutePaths(iter + 1, iterTimes, next, routePath, list, warnList); } } else if (section.isSwitchTrack()) { // 道岔区段 Switch relSwitch = section.getRelSwitch(); if (relSwitch.isA(section)) { RoutePath path1 = routePath.cloneNew(); path1.addSection(relSwitch.getB()); - queryRoutePaths(iter + 1, relSwitch.getB(), path1, list, warnList); + queryRoutePaths(iter + 1, iterTimes, relSwitch.getB(), path1, list, warnList); RoutePath path2 = routePath.cloneNew(); path2.addSection(relSwitch.getC()); - queryRoutePaths(iter + 1, relSwitch.getC(), path2, list, warnList); + queryRoutePaths(iter + 1, iterTimes, relSwitch.getC(), path2, list, warnList); } else { routePath.addSection(relSwitch.getA()); - queryRoutePaths(iter + 1, relSwitch.getA(), routePath, list, warnList); + queryRoutePaths(iter + 1, iterTimes, relSwitch.getA(), routePath, list, warnList); } } else { warnList.add(String.format("区段[%s]的[%s]区段不存在", @@ -760,7 +760,7 @@ public class CalculateService { list.add(routePath); } else { routePath.addSections(sectionList); - queryRoutePaths(iter + 1, route.getLastRouteSection(), routePath, list, warnList); + queryRoutePaths(iter + 1, iterTimes, route.getLastRouteSection(), routePath, list, warnList); } return; } @@ -823,7 +823,7 @@ public class CalculateService { } else { for (RoutePath clone : iterList) { Section next = clone.getLastSection(); - queryRoutePaths(iter + 1, next, clone, list, warnList); + queryRoutePaths(iter + 1, iterTimes, next, clone, list, warnList); } } } else { @@ -845,7 +845,7 @@ public class CalculateService { for (Section next : sectionList) { routePath.addSection(next); if (next.getSignalOf(right) != null) { - queryRoutePaths(iter + 1, next, routePath, list, warnList); + queryRoutePaths(iter + 1, iterTimes, next, routePath, list, warnList); break; } } @@ -1113,7 +1113,7 @@ public class CalculateService { // if (distance == null) { // return null; // } - List routePaths = queryRoutePathsOnDirection(train.getHeadPosition().getSection(), target, right); + List routePaths = queryRoutePathsOnDirection(train.getHeadPosition().getSection(), target, right, 10); if (CollectionUtils.isEmpty(routePaths)) { return null; } @@ -1157,6 +1157,46 @@ public class CalculateService { return atoSpeed; } + /** + * 筛选唯一进路。 + * 进路路径的sectionList中可能包含同一信号机下的多个进路,本方法将筛选掉多余的进路 + * + * @param routePath + * @param tb 是否要在进路路径的终点区段折返 + * @return + */ + public static List selectUniqueRoutes(RoutePath routePath, boolean tb) { + List routes = new ArrayList<>(); + List routeList = routePath.getRouteList(); + List
runPath = new ArrayList<>(); + runPath.add(routePath.getStart()); + runPath.addAll(routePath.getSectionList()); + runPath.add(routePath.getEnd()); + for (int i = 0; i < routeList.size(); i++) { + Route route = routeList.get(i); + Route last = i > 0 ? routeList.get(i - 1) : null; + if (last == null) { + routes.add(route); + } else { + if (last.getStart().equals(route.getStart())) { + if (last.getLastRouteSection().equals(routePath.getEnd())) { //进路到达目的地折返轨,优先选择折返进路 + if (!Objects.equals(tb, last.isTurnBack())) { + routes.set(routes.size() - 1, route); + } + } else { //优先选择非折返且无延续保护或延续保护在路径上的 + if (last.isTurnBack() || + (last.getOverlap() != null && !runPath.containsAll(last.getOverlap().getPathList().get(0).getSectionList()))) { + routes.set(routes.size() - 1, route); + } + } + } else { + routes.add(route); + } + } + } + return routes; + } + /** * 计算加速段的时间 */ @@ -1195,4 +1235,5 @@ public class CalculateService { return acceleratedDistance + varyingAcceleratedDistance; } + } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java index 280c1b311..5d2c70be7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java @@ -1046,6 +1046,18 @@ public class Section extends MayOutOfOrderDevice { section.setCtOccupied(true); return true; } + + @Override + public void fix(MayOutOfOrderDevice device) { + if (this.equals(device.getFault())) { + Section section = (Section) device; + section.setCtOccupied(false); + section.setFault(null); + if (section.isSwitchTrack()) { + section.getRelSwitch().getAllSections().forEach(section1 -> section1.setCtOccupied(false)); + } + } + } } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java index 69a615ab8..44a6ff3d7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java @@ -48,6 +48,14 @@ public class MovementAuthority { end.getEndPosition()); } + @Override + public String toString() { + return "MovementAuthority{" + + "end=" + end + + ", protectSpeedCurve=" + protectSpeedCurve + + '}'; + } + @Getter public static class End { MapNamedElement device; @@ -75,10 +83,12 @@ public class MovementAuthority { @Override public String toString() { - return String.format("End{" + - "device=[%s(%s)]" + - ", type=[%s]" + - '}', this.device.getName(), this.device.getCode(), this.type); + return "End{" + + "device=" + device + + ", type=" + type + + ", baseSection=" + baseSection + + ", endPosition=" + endPosition + + '}'; } private SectionPosition computeEndPosition(boolean right) {