diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java index 8ed28bccb..22940e3ae 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java @@ -86,9 +86,9 @@ public class AtpSectionService { for (VirtualRealityTrain train : onlineTrainList) { List
atpSectionList = trainAtpSectionMap.get(train.getGroupNumber()); List
physicalList = this.convert2PhysicalSectionList(atpSectionList); - if (train.isCBTC() && signal.containsApproachAtpSection(atpSectionList)) { //通信车在atp接近区段上 + if (train.isCommunicable() && signal.containsApproachAtpSection(atpSectionList)) { //通信车在atp接近区段上 approachMsg = SignalApproachMessage.ApproachMessage.CBTC; - } else if (!train.isCBTC() && signal.containsApproachPhysicalSection(physicalList)) { //非通信车在物理接近区段上 + } else if (!train.isCommunicable() && signal.containsApproachPhysicalSection(physicalList)) { //非通信车在物理接近区段上 approachMsg = SignalApproachMessage.ApproachMessage.NCT; nctApproachSignalMap.put(train, signal); } @@ -142,7 +142,7 @@ public class AtpSectionService { SimulationDataRepository repository = simulation.getRepository(); atpSectionList = CalculateService.getAtpSections(trainHeadPosition, trainTailPosition, right, repository.getConfig().isSwitchSingleHandle()); - if (train.isCBTC()) { // cbtc通信车占用 + if (train.isCommunicable()) { // 通信车占用 atpSectionList.forEach(atpSection -> atpSection.communicateTrainOccupy(right)); } else { // 非通信车 Set
collect = atpSectionList.stream().map(section -> { //找到列车占压区段所属的物理区段 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java index dbdbefd53..5021872f5 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java @@ -74,35 +74,13 @@ public class ZCLogicLoop { })); } //更新CBTC ma - if (headPosition.getSection().anyZcWorking()) { + if (train.isCommunicable()) { this.calculateMAOfCBTC(simulation, train, trainList); } -// //更新CBTC ma -// if (!deviceStation.getZc().isFault()) { //如果列车头所在区段所属设备集中站zc未故障 -// this.calculateMAOfCBTC(simulation, train, trainList); -// } } }); } - /** - * 为升级CM而强制更新ma(简单处理) - * @return 是否更新成功 - */ - public boolean updateCbtcMa4CM(Simulation simulation, VirtualRealityTrain train) { - RunLevel defaultRunLevel = simulation.getRepository().getConfig().getRunMode(); - if (RunLevel.CBTC.equals(defaultRunLevel)) { - List trainList = simulation.getRepository().getOnlineTrainList(); - SectionPosition headPosition = train.getHeadPosition(); - if (headPosition.getSection().anyZcWorking()) { - List endList = this.findMaEnd(simulation, train, trainList); - MovementAuthority ma = this.compareAndBuildMa(train, endList); - return onboardAtpApiService.ignoreDriveModeUpdateMA4CBTC(train, ma); - } - } - return false; - } - private void calculateMAOfCBTC(Simulation simulation, VirtualRealityTrain train, List trainList) { // 查找移动授权终端列表 @@ -154,13 +132,8 @@ public class ZCLogicLoop { // } //非通信车占用区段 if (section.isNonCbtcOccupy() && !section.isInvalid()) { - VirtualRealitySectionAxleCounter axle = section.getVirtualAxleCounter(); - if (axle == null && section.getParent() != null) - axle = section.getParent().getVirtualAxleCounter(); - if (axle == null || axle.getLeftCount() > 1 || axle.getRightCount() > 1) { //以计轴器计数为1作为是当前列车导致区段非通信车占用的判断依据 - endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_SECTION)); - return endList; - } + endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_SECTION)); + return endList; } //通信车占用区段 List
occupiedLogicSectionList = simulation.getRepository().queryTrainOccupyAtpSectionList(train.getGroupNumber()); @@ -236,7 +209,7 @@ public class ZCLogicLoop { if (trainEnd != null) endList.add(trainEnd); //非通信车占用区段 - if (temp.isNonCbtcOccupy() && !temp.isInvalid()) { + if (temp.isNctOccupied() && !temp.isInvalid()) { endList.add(new MovementAuthority.End(temp, MovementAuthority.EndType.NCT_OCCUPIED_SECTION)); } //检查关闭的区段 @@ -696,7 +669,7 @@ public class ZCLogicLoop { if (section.isStandTrack()) { List standList = section.getStandList(); for (Stand stand : standList) { - if (!stand.isInterlockRelease() && stand.isPsdOpen()) { + if (!stand.isPsdSafe()) { return new MovementAuthority.End(stand, MovementAuthority.EndType.OPENED_PSD, section); } if (stand.isClosed()) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java index 168c7fd95..3951699a0 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java @@ -1,9 +1,11 @@ package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; +import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService; import club.joylink.rtss.simulation.cbtc.ATP.ground.ZCLogicLoop; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; +import club.joylink.rtss.simulation.cbtc.CI.CILogicLoop; import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.ControlGear; @@ -39,6 +41,9 @@ public class DriverOperateHandler { @Autowired private ZCLogicLoop zcLogicLoop; + @Autowired + private GroundAtpApiService groundAtpApiService; + @OperateHandlerMapping(type = Operation.Type.Driver_Force_Change) public void changeTrainForce(Simulation simulation, String groupNumber, Float percent) { Objects.requireNonNull(percent); @@ -114,28 +119,12 @@ public class DriverOperateHandler { public void changeTrainDriveMode(Simulation simulation, String groupNumber, DriveMode driveMode) { VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); switch (driveMode) { - case CM: { - if (!train.isAtpOn()) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, - String.format("列车[%s]ATP未开启,无法升级CM驾驶模式", train.getGroupNumber())); - } - if (zcLogicLoop.updateCbtcMa4CM(simulation, train)) { - train.useCMMode(); - } - break; - } + case AM: + case CM: case RM: { - if (!train.isAtpOn()) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, - String.format("列车[%s]ATP未开启,无法升级RM驾驶模式", train.getGroupNumber())); - } - train.useRMMode(); + train.setPreDriveMode(driveMode); break; } - case NRM: - ATPService.cutOffAtp(train); -// train.useNRMMode(); - break; } } 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 40f12518c..c07d97036 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 @@ -752,8 +752,8 @@ public class AtsRouteSettingService { ++count; Signal signal = base.getSignalOf(right); if (Objects.isNull(signal) || !signal.isClose() || - (!train.isCtcLevel() && signal.isVirtual())) { - // 指定方向信号机不存在,或已经开放,或非CTC列车碰到虚拟信号机,继续往下找 + (!train.isCommunication() && signal.isVirtual())) { + // 指定方向信号机不存在,或已经开放,或非通信车碰到虚拟信号机,继续往下找 base = base.getNextRunningSectionOf(right); continue; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java index 6bc8dd0c3..33efda296 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java @@ -593,7 +593,7 @@ public class AtsTrainLoadService { Section end = viaSectionList.get(i); // 取相邻两区段的路径单元,查询进路 RoutePath routePath = this.selectDefaultRoutePath(repository, start, end); - Route route = routePath.queryRouteContainsSection(train.getRunLevel(), headSection, repository.getConfig()); + Route route = routePath.queryRouteContainsSection(train.isCommunicable(), headSection, repository.getConfig()); if (Objects.nonNull(route)) { // 排列好进路 this.deviceStatusModifyTool.openRouteDirect(simulation, route); 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 d04243db7..8ab0aa41f 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 @@ -308,8 +308,7 @@ public class AtsTrainService { if (!sections.get(0).equals(headSection)) { sections.add(0, headSection); } - SectionPath headPath = new SectionPath(selectRouting.isRight(), null, sections, null); - supervisedTrain.setHeadPath(headPath); + supervisedTrain.setHctPath(new SectionRunPath(sections, selectRouting.isRight())); break; default: throw new SimulationException(SimulationExceptionType.System_Fault, String.format("无法识别的目的地码类型[%s]", destinationCodeDefinition.getType())); @@ -675,7 +674,7 @@ public class AtsTrainService { } break; case OTHER: - List
path = train.getHeadPath().getSectionList(); + List
path = train.getHctPath().getSections(); if (path != null) { int index = path.indexOf(headSection); if (index == -1) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsHeadTrainRouteSelectServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsHeadTrainRouteSelectServiceImpl.java index 859866d0c..5614d6a3c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsHeadTrainRouteSelectServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsHeadTrainRouteSelectServiceImpl.java @@ -2,19 +2,10 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.ars; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; -import club.joylink.rtss.simulation.cbtc.data.map.DestinationCodeDefinition; import club.joylink.rtss.simulation.cbtc.data.map.Route; -import club.joylink.rtss.simulation.cbtc.data.map.Section; -import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; -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.vo.TrainInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.Comparator; -import java.util.List; /** * 头码车进路选择 @@ -28,45 +19,6 @@ public class AtsHeadTrainRouteSelectServiceImpl extends AtsRouteSelectService { return null; } SimulationDataRepository repository = simulation.getRepository(); - // 基础检查 - Boolean right = trainInfo.getRight(); - if (right == null) - return null; - DestinationCodeDefinition dcd = repository.getDestinationCodeDefinition(trainInfo.getDestinationCode()); - Object[] results = queryTriggerRoutes(repository, trainInfo.getHeadPath().getSectionList(), trainInfo, null, trainInfo.getHeadPath().isRight()); - return filterRoutes(repository, trainInfo, results, dcd); - } - - private Route filterRoutes(SimulationDataRepository repository, TrainInfo trainInfo, Object[] results, DestinationCodeDefinition dcd) { - if (results == null) - return null; - List triggers = (List) results[0]; - if (CollectionUtils.isEmpty(triggers)) - return null; - Route route; - if (triggers.size() == 1) { - route = triggers.get(0); - } else { - route = triggers.stream().min(Comparator.comparingInt(Route::getReverseSwitchQuantity)).get(); - } - return route; - } - - private boolean isConflicting(SimulationDataRepository repository, TrainInfo trainInfo, Route route) { - if (!trainInfo.isPlanTrain()) - return false; - TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); - Section start = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); - for (StationPlan stationPlan : tripPlan.getPlanList()) { - if (!stationPlan.isFinished()) { - List routePaths = repository.getRoutePaths(start, stationPlan.getSection()); - RoutePath routePath = selectRoutePath(routePaths); - if (routePath.isConflictWith(route)) { - return true; - } - } - start = stationPlan.getSection(); - } - return false; + return queryTriggerRoutes(repository, trainInfo.getHctPath().getSections(), trainInfo, null); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsPlanTrainRouteSelectServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsPlanTrainRouteSelectServiceImpl.java index 1314a7d44..74a509699 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsPlanTrainRouteSelectServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsPlanTrainRouteSelectServiceImpl.java @@ -8,7 +8,6 @@ import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; 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.StationTurnBackStrategyOption; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -44,13 +43,12 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService { LocalDateTime systemTime = simulation.getSystemTime(); // 根据车次计划查找可触发进路列表 // Object[] results = this.queryByStationPlan(repository, systemTime, trainInfo, tripPlan); - Object[] results = queryByStationPlan2(repository, systemTime, trainInfo, tripPlan); + Route route = queryByStationPlan(repository, systemTime, trainInfo, tripPlan); // 根据计划筛选需触发进路 - Route route = filterRoutes(simulation, trainInfo, tripPlan, results); - return route; + return filterRoutes(simulation, trainInfo, tripPlan, route); } - private Object[] queryByStationPlan2(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) { + private Route queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) { // 计划时间 List planList = tripPlan.getPlanList(); LocalTime startTime = tripPlan.getStartTime(); @@ -66,9 +64,9 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService { } List
targetList = tripPlan.getPlanList().stream().map(StationPlan::getSection).collect(Collectors.toList()); if (tripPlan.isBehindTurnBack()) { - return queryTriggerRoutes(repository, targetList, trainInfo, tripPlan.getEndSection(), tripPlan.isRight()); + return queryTriggerRoutes(repository, targetList, trainInfo, tripPlan.getEndSection()); } else { - return queryTriggerRoutes(repository, targetList, trainInfo, null, tripPlan.isRight()); + return queryTriggerRoutes(repository, targetList, trainInfo, null); } } @@ -77,25 +75,16 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService { * @param simulation * @param trainInfo * @param tripPlan - * @param results + * @param route * @return */ private Route filterRoutes(Simulation simulation, - TrainInfo trainInfo, TripPlan tripPlan, Object[] results) { - if (results == null) { - return null; - } - List triggerList = (List) results[0]; - if (CollectionUtils.isEmpty(triggerList)) { + TrainInfo trainInfo, TripPlan tripPlan, Route route) { + if (route == null) { return null; } SimulationDataRepository repository = simulation.getRepository(); // 先选取需要征用的进路 - boolean turnBack = (boolean) results[1]; - Route route = this.filter(repository, trainInfo, tripPlan, triggerList, turnBack); - if (route == null) { - return null; - } log.debug(String.format("列车[%s]筛选出的进路为:[%s]", trainInfo.getGroupNumber(), route.getName())); if (route.isCheckConflict() && route.getConflictAlarm() == null) { ConflictInfo conflictInfo = this.checkConflict(repository, trainInfo, tripPlan, route); @@ -432,147 +421,147 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService { return route; } - /** - * @return (List)[0]: 可触发的进路;(Boolean)[1]:是否需要折返 - */ - private Object[] queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) { - Route route = null; - Object[] result = new Object[3]; - result[1] = false; - result[2] = false; - List triggerList = null; - // 获取列车上一停靠站台轨和下一计划达到轨道,结合列车位置,查询需要办理的进路 - if (trainInfo.getPlanStandTrack() == null) { // 列车下一计划存在 - return null; - } - // 计划时间 - List planList = tripPlan.getPlanList(); - LocalTime startTime = tripPlan.getStartTime(); - for (StationPlan stationPlan : planList) { - if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())) { - break; - } - startTime = stationPlan.getLeaveTime(); - } - if (!systemTime.toLocalTime().plusSeconds(50).isAfter(startTime)) { - log.debug(String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber())); - return null; - } - Section planTrack = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);//下一计划 - Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段 - if (!planTrack.isSamePhysical(section.getCode())) { - List routePathList = repository.queryRoutePathsByEnd(planTrack); - routePathList = routePathList.stream() - .filter(routePath -> routePath.containsSection(section)) - .collect(Collectors.toList()); - result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); - } - if (!((boolean) result[1]) && !((boolean) result[2])) { // 不存在未开放进路,且不存在未接近的信号机 - // 判断配置是否列车停站才触发接下来的进路 - MapConfig config = repository.getConfig(); - if (config.isSignalOpenAfterParking() && !trainInfo.isParking()) { - return null; - } else { - if (tripPlan.isLastPlanStationSection(planTrack)) { - //是计划的终点站 - if (tripPlan.isBehindTurnBack()) { - // 是站后折返 - triggerList = this.queryAccordingTbStrategy(repository, trainInfo, tripPlan); - Object[] rs = {triggerList, true}; - return rs; - } else if (!tripPlan.getEndSection().equals(tripPlan.getLastStationPlan().getSection())) { - // 备用车 - List routePathList = repository.getRoutePaths(tripPlan.getLastStationPlan().getSection(), - tripPlan.getEndSection()); - result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); - } - } else { - StationPlan nextStationPlan = tripPlan.queryNextStationPlan(planTrack); - if (nextStationPlan != null) { - // 下一计划车站存在 - List routePathList = repository.getRoutePaths(planTrack, nextStationPlan.getSection()); - result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); - } - } - } - } - triggerList = (List) result[0]; - Object[] rs = {triggerList, false}; - return rs; - } +// /** +// * @return (List)[0]: 可触发的进路;(Boolean)[1]:是否需要折返 +// */ +// private Object[] queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) { +// Route route = null; +// Object[] result = new Object[3]; +// result[1] = false; +// result[2] = false; +// List triggerList = null; +// // 获取列车上一停靠站台轨和下一计划达到轨道,结合列车位置,查询需要办理的进路 +// if (trainInfo.getPlanStandTrack() == null) { // 列车下一计划存在 +// return null; +// } +// // 计划时间 +// List planList = tripPlan.getPlanList(); +// LocalTime startTime = tripPlan.getStartTime(); +// for (StationPlan stationPlan : planList) { +// if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())) { +// break; +// } +// startTime = stationPlan.getLeaveTime(); +// } +// if (!systemTime.toLocalTime().plusSeconds(50).isAfter(startTime)) { +// log.debug(String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber())); +// return null; +// } +// Section planTrack = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);//下一计划 +// Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段 +// if (!planTrack.isSamePhysical(section.getCode())) { +// List routePathList = repository.queryRoutePathsByEnd(planTrack); +// routePathList = routePathList.stream() +// .filter(routePath -> routePath.containsSection(section)) +// .collect(Collectors.toList()); +// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); +// } +// if (!((boolean) result[1]) && !((boolean) result[2])) { // 不存在未开放进路,且不存在未接近的信号机 +// // 判断配置是否列车停站才触发接下来的进路 +// MapConfig config = repository.getConfig(); +// if (config.isSignalOpenAfterParking() && !trainInfo.isParking()) { +// return null; +// } else { +// if (tripPlan.isLastPlanStationSection(planTrack)) { +// //是计划的终点站 +// if (tripPlan.isBehindTurnBack()) { +// // 是站后折返 +// triggerList = this.queryAccordingTbStrategy(repository, trainInfo, tripPlan); +// Object[] rs = {triggerList, true}; +// return rs; +// } else if (!tripPlan.getEndSection().equals(tripPlan.getLastStationPlan().getSection())) { +// // 备用车 +// List routePathList = repository.getRoutePaths(tripPlan.getLastStationPlan().getSection(), +// tripPlan.getEndSection()); +// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); +// } +// } else { +// StationPlan nextStationPlan = tripPlan.queryNextStationPlan(planTrack); +// if (nextStationPlan != null) { +// // 下一计划车站存在 +// List routePathList = repository.getRoutePaths(planTrack, nextStationPlan.getSection()); +// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList); +// } +// } +// } +// } +// triggerList = (List) result[0]; +// Object[] rs = {triggerList, false}; +// return rs; +// } - private boolean isTriggerTurnBackRoute(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) { - Section eaStandSection = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class); - Section arriveStandSection = repository.getByCode(trainInfo.getActualArriveStandTrack(), Section.class); - if (tripPlan.isBehindTurnBack()) {// 是站后折返计划 - Section lastStationSection = tripPlan.getLastStationPlan().getSection(); - if (lastStationSection.isSamePhysical(arriveStandSection.getCode())) { - // 列车达到计划终点站 - return true; - } else if (lastStationSection.isSamePhysical(eaStandSection.getCode())) { - // 预计到达为终点站,再判断是否到达折返始端信号机触发范围 - List list = repository.getRoutePaths(lastStationSection, tripPlan.getEndSection()); - boolean right = list.get(0).isRight(); - Signal signal = lastStationSection.getSignalOf(right); +// private boolean isTriggerTurnBackRoute(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) { +// Section eaStandSection = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class); +// Section arriveStandSection = repository.getByCode(trainInfo.getActualArriveStandTrack(), Section.class); +// if (tripPlan.isBehindTurnBack()) {// 是站后折返计划 +// Section lastStationSection = tripPlan.getLastStationPlan().getSection(); +// if (lastStationSection.isSamePhysical(arriveStandSection.getCode())) { +// // 列车达到计划终点站 +// return true; +// } else if (lastStationSection.isSamePhysical(eaStandSection.getCode())) { +// // 预计到达为终点站,再判断是否到达折返始端信号机触发范围 +// List list = repository.getRoutePaths(lastStationSection, tripPlan.getEndSection()); +// boolean right = list.get(0).isRight(); +// Signal signal = lastStationSection.getSignalOf(right); +// +// return true; +// } +// } +// return false; +// } - return true; - } - } - return false; - } - - private List queryAccordingTbStrategy(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) { - Section standSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); - if (!standSection.isRouteLock()) { - - } - Station station = standSection.getStation(); - StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy(); - Section tbSection = tripPlan.getEndSection(); - Route tbRoute = null; - List
tbSectionList = new ArrayList<>(); - if (Objects.isNull(strategy)) { - tbSectionList.add(tbSection); - } else { - switch (strategy.getType()) { - // 按计划 - case NONE: { - tbSectionList.add(tbSection); - break; - } - // 仅某个折返轨 - case ONLY: { - tbSectionList.add(strategy.getSectionList().get(0)); - break; - } - // 折返轨等价 - case FIRST: - case EQUAL: { - tbSectionList.addAll(strategy.getSectionList()); - break; - } - } - } - List list = repository.getRoutePaths(standSection, tbSection); - boolean right = list.get(0).isRight(); - Signal signal = standSection.getSignalOf(right); - if (!this.isApproachSignal(repository, trainInfo, signal)) { - return null; - } - List routeList = signal.getRouteList(); - List tbRouteList = new ArrayList<>(); - for (Route route : routeList) { - if (route.isTurnBack()) { - tbRouteList.add(route); - } - } - if (!tbRouteList.isEmpty()) { - routeList = tbRouteList; - } - routeList = routeList.stream() - .filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route)) - .filter(route -> route.containSameSection(tbSectionList)) - .collect(Collectors.toList()); - return routeList; - } +// private List queryAccordingTbStrategy(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) { +// Section standSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); +// if (!standSection.isRouteLock()) { +// +// } +// Station station = standSection.getStation(); +// StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy(); +// Section tbSection = tripPlan.getEndSection(); +// Route tbRoute = null; +// List
tbSectionList = new ArrayList<>(); +// if (Objects.isNull(strategy)) { +// tbSectionList.add(tbSection); +// } else { +// switch (strategy.getType()) { +// // 按计划 +// case NONE: { +// tbSectionList.add(tbSection); +// break; +// } +// // 仅某个折返轨 +// case ONLY: { +// tbSectionList.add(strategy.getSectionList().get(0)); +// break; +// } +// // 折返轨等价 +// case FIRST: +// case EQUAL: { +// tbSectionList.addAll(strategy.getSectionList()); +// break; +// } +// } +// } +// List list = repository.getRoutePaths(standSection, tbSection); +// boolean right = list.get(0).isRight(); +// Signal signal = standSection.getSignalOf(right); +// if (!this.isApproachSignal(repository, trainInfo, signal)) { +// return null; +// } +// List routeList = signal.getRouteList(); +// List tbRouteList = new ArrayList<>(); +// for (Route route : routeList) { +// if (route.isTurnBack()) { +// tbRouteList.add(route); +// } +// } +// if (!tbRouteList.isEmpty()) { +// routeList = tbRouteList; +// } +// routeList = routeList.stream() +// .filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route)) +// .filter(route -> route.containSameSection(tbSectionList)) +// .collect(Collectors.toList()); +// return routeList; +// } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsRouteSelectService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsRouteSelectService.java index 3183b1e50..6860aacae 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsRouteSelectService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/ars/AtsRouteSelectService.java @@ -1,8 +1,10 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.ars; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; @@ -23,53 +25,45 @@ public abstract class AtsRouteSelectService { * 查询需要触发的进路 * * @param turnBackSection 站后折返的折返轨 - * @param right 计划运行方向 + * @return */ - public Object[] queryTriggerRoutes(SimulationDataRepository repository, List
targetList, - TrainInfo trainInfo, Section turnBackSection, boolean right) { + public Route queryTriggerRoutes(SimulationDataRepository repository, List
targetList, + TrainInfo trainInfo, Section turnBackSection) { + if (trainInfo.getPlanStandTrack() == null) { + return null; + } + //寻找通向计划区段的进路 + Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); Section headSection = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); - Object[] result = {null, false, false}; + List routePaths = repository.queryRoutePathsByEndAndContainsSection(planSection, headSection); + int index = targetList.indexOf(planSection); + if (index == -1) { + return null; + } + Section nextPlanSection = null; //下一个计划区段 + if (index < targetList.size() - 1) { + nextPlanSection = targetList.get(index + 1); + } + Route route = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths, nextPlanSection); + if (route != null) { //有进路未触发 + return route; + } + //通向计划区段的进路已全部办理,根据条件尝试向下一个计划区段或站后折返轨办理进路 MapConfig config = repository.getConfig(); - Section targetSection = null; - Section nextTarget = null; - //选择目标区段 - for (int i = targetList.size() - 1; i >= 0; i--) { - Section target = targetList.get(i); - List routePaths = repository.queryRoutePathsByEndAndContainsSection(target, headSection); - routePaths.removeIf(routePath -> routePath.isRight() != right); - if (!CollectionUtils.isEmpty(routePaths)) { - result = queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths); - targetSection = target; - if (i < targetList.size() - 1) { - nextTarget = targetList.get(i + 1); + if (!config.isSignalOpenAfterParking() || (headSection.equals(planSection) && trainInfo.isParking())) { //不需要停站就可以开放信号机或者已经在计划区段停站(可以继续向前办理进路) + if (nextPlanSection != null) { //计划区段路径未跑完 + routePaths = repository.queryRoutePaths(planSection, nextPlanSection); + if (!CollectionUtils.isEmpty(routePaths)) { + return this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths, nextPlanSection); } + } else if (turnBackSection != null) { //站后折返 + return queryTriggerRoutes4TurnBack(repository, planSection, turnBackSection, trainInfo); } } - //选择进路 - boolean noRoute2Trigger = result != null && !(boolean) result[1] && !(boolean) result[2]; - if (targetSection != null) { - if (!config.isSignalOpenAfterParking()) { - if (noRoute2Trigger) { - if (nextTarget != null) { - List routePaths = repository.queryRoutePathsByEndAndContainsSection(nextTarget, headSection); - routePaths.removeIf(routePath -> routePath.isRight() != right); - result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths); - } else if (turnBackSection != null) { - List triggerRoutes = queryTriggerRoutes4TurnBack(repository, targetSection, turnBackSection, trainInfo); - return new Object[]{triggerRoutes, true}; - } - } - } else { - if (nextTarget == null && targetSection.equals(headSection) && trainInfo.isParking()) { - List triggerRoutes = queryTriggerRoutes4TurnBack(repository, targetSection, turnBackSection, trainInfo); - return new Object[]{triggerRoutes, true}; - } - } - } - return result; + return null; } - public List queryTriggerRoutes4TurnBack(SimulationDataRepository repository, Section standSection, Section tbSection, TrainInfo trainInfo) { + public Route queryTriggerRoutes4TurnBack(SimulationDataRepository repository, Section standSection, Section tbSection, TrainInfo trainInfo) { Station station = standSection.getStation(); StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy(); List
tbSectionList = new ArrayList<>(); @@ -115,7 +109,24 @@ public abstract class AtsRouteSelectService { .filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route)) .filter(route -> route.containSameSection(tbSectionList)) .collect(Collectors.toList()); - return routeList; + Route route = null; + for (Route temp : routeList) { + List
sectionList = temp.getSectionList(); + boolean trainOccupy = false; + for (Section rs : sectionList) { + if (rs.isOccupied()) { + trainOccupy = true; + break; + } + } + if (trainOccupy) { + continue; + } else { + route = temp; + break; + } + } + return route; } /** @@ -134,24 +145,11 @@ public abstract class AtsRouteSelectService { return pathList.get(0); } - public Object[] queryTriggerRoutesOfRoutePath(SimulationDataRepository repository, - TrainInfo trainInfo, List routePathList) { - Boolean right = trainInfo.getRight(); + public Route queryTriggerRoutesOfRoutePath(SimulationDataRepository repository, + TrainInfo trainInfo, List routePathList, Section nextPlanSection) { Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段 - Section logicSection = repository.getByCode(trainInfo.getSection(), Section.class); - return queryTriggers(repository, trainInfo, routePathList, right, section, logicSection); - } - - public Object[] queryTriggers(SimulationDataRepository repository, TrainInfo trainInfo, List routePathList, - Boolean right, Section section, Section logicSection) { - Object[] result = new Object[3]; // 结果,0为可触发的进路列表,1为是否存在未触发的进路,2为是否存在未接近的信号机 + Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); //列车计划区段 List triggerList = new ArrayList<>(); - result[0] = triggerList; - result[1] = false; - result[2] = false; - if (logicSection.isSwitchAxleCounterSection() || logicSection.isCross()) { - logicSection = section; - } if (!routePathList.isEmpty()) { RoutePath routePath = this.selectRoutePath(routePathList); // 查找可以触发的进路列表 @@ -164,7 +162,6 @@ public abstract class AtsRouteSelectService { continue; } if (signal.hasCiAutoTriggerRoute() || signal.hasFleetModeRoute()) { - result[2] = true; // 存在联锁自动触发进路或联锁自动进路 break; } if (!ctcLevel && signal.isVirtual()) { @@ -172,15 +169,15 @@ public abstract class AtsRouteSelectService { } if (this.isApproachSignal(repository, trainInfo, signal)) { // 是信号机接近区段 - if (signal.isNormalOpen()) { //如果信号机已经正常开放,继续查询下一个 + if (signal.isNormalOpen()) { if (routePath.isPathRoute(signal.getLockedRoute())) { continue; } else { - result[2] = true; // 非路径进路办理 + // 非路径进路办理 break; } } else { - result[1] = true; + //筛选可触发的进路 for (Route route : routePath.getRouteList()) { TrainInfo other = repository.querySameStartTriggerRouteTrain(trainInfo, route); if (other != null) { // 已经有在排列中的进路,结束 @@ -192,15 +189,40 @@ public abstract class AtsRouteSelectService { triggerList.add(route); } } + //选择要触发的进路 + if (triggerList.size() == 1) { + return triggerList.get(0); + } else if (triggerList.size() > 1) { + if (planSection.equals(triggerList.get(0).getLastRouteSection()) && nextPlanSection != null) { + // 进路是计划站台轨,根据后续计划筛选 + List routePaths = repository.getRoutePaths(planSection, nextPlanSection); + for (Route temp : triggerList) { + if (routePaths.get(0).containsAllSections(temp.getOverlap().getFirstPath().getSectionList())) { + return temp; + } + } + } else { + // 取第一个延续保护道岔定位的 + for (Route temp : triggerList) { + List switchList = temp.getOverlap().getFirstPath().getSwitchList(); + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(switchList, + String.format("列车[%s]过滤进路异常:进路不是延续保护差异进路[%s]", + trainInfo.getGroupNumber(), + triggerList.stream().map(Route::getName).collect(Collectors.joining(",")))); + if (switchList.get(0).isNormal()) { + return temp; + } + } + } + } } } else { // 列车未接近此信号机 - result[2] = true; } break; } } - return result; + return null; } protected boolean isApproachSignal(SimulationDataRepository repository, TrainInfo trainInfo, Signal signal) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/stage/AtsHeadTrainStageService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/stage/AtsHeadTrainStageService.java index 722990861..b34dcc48f 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/stage/AtsHeadTrainStageService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/stage/AtsHeadTrainStageService.java @@ -6,14 +6,12 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.*; -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.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.List; @@ -45,7 +43,6 @@ public class AtsHeadTrainStageService implements AtsStageService { DestinationCodeDefinition dcd = repository.findDestinationCodeDefinition(trainInfo.getDestinationCode()); if (dcd == null) return; - SectionPosition headPosition = repository.buildHeadPositionOfTrainInfo(trainInfo); if (Objects.equals(dcd.getSection(), parkSection)) { // 列车到达目的地 trainInfo.finishPlanPrepareInbound(); @@ -64,7 +61,7 @@ public class AtsHeadTrainStageService implements AtsStageService { if (Objects.equals(dcd.getSection(), parkSection)) { handleArriveDestination(simulation, trainInfo); } else { - this.updateNextTarget(simulation, trainInfo); + this.updatePlanSection(simulation, trainInfo); } } @@ -74,13 +71,13 @@ public class AtsHeadTrainStageService implements AtsStageService { if (Objects.equals(dcd.getSection(), parkSection)) { handleArriveDestination(simulation, trainInfo); } else { - this.updateNextTarget(simulation, trainInfo); + this.updatePlanSection(simulation, trainInfo); } } @Override public void handlePassStand(Simulation simulation, TrainInfo trainInfo) { - this.updateNextTarget(simulation, trainInfo); + this.updatePlanSection(simulation, trainInfo); } /** @@ -92,92 +89,53 @@ public class AtsHeadTrainStageService implements AtsStageService { } } - private void updateNextTarget(Simulation simulation, TrainInfo trainInfo) { - boolean right = trainInfo.getRight(); + private void updatePlanSection(Simulation simulation, TrainInfo trainInfo) { + if (!StringUtils.hasText(trainInfo.getPlanStandTrack())) + return; + boolean planRight = trainInfo.getHctPath().isRight(); SimulationDataRepository repository = simulation.getRepository(); SectionPosition headPosition = repository.buildHeadPositionOfTrainInfo(trainInfo); + Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); //如果还未到达目标轨 Section headSection = headPosition.getSection(); - if (StringUtils.hasText(trainInfo.getEstimatedArriveStandTrack())) { - Section target = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class); - if (!target.equals(headSection) && target.isAheadOf(repository, headSection, right)) { - return; - } + if (!planSection.equals(headSection) && planSection.isAheadOf(repository, headSection, planRight)) { + return; } //寻找目标区段 - Section nextTarget = queryNextTarget(simulation, headPosition.getSection(), trainInfo, right); - if (nextTarget == null) + Section nextPlanSection = queryNextPlanSection(simulation, trainInfo); + if (nextPlanSection == null) return; //判断调头 - if (!nextTarget.isAheadOf(repository, headSection, right)) {//下一目标区段不在当前车头方向的前方 + Boolean trainRight = trainInfo.getRight(); + if (!nextPlanSection.isAheadOf(repository, headSection, trainRight)) {//下一计划区段不在当前车头方向的前方 atpService.turnDirectionImmediately(repository.getOnlineTrainBy(trainInfo.getGroupNumber())); //调头 } - //更新预计到站 - SectionPosition stopPosition = new SectionPosition(nextTarget, nextTarget.getStopPointByDirection(right)); - Float distance = CalculateService.calculateDistance(headPosition, stopPosition, right); + //更新计划到站 + SectionPosition stopPosition = new SectionPosition(nextPlanSection, nextPlanSection.getStopPointByDirection(planRight)); + Float distance = CalculateService.calculateDistance(headPosition, stopPosition, planRight); int runningTime; if (distance != null) { runningTime = (int) (distance / (45 / 3.6)); } else { runningTime = 180; } - trainInfo.updatePlanInfo(nextTarget, null, null); -// trainInfo.updateEstimatedArriveInfo(nextTarget, simulation.getSystemTime().toLocalTime().plusSeconds(runningTime)); - boolean jump = this.atsStandService.isJump(nextTarget, trainInfo.getGroupNumber()); - onboardAtpApiService.updateNextArriveInfo(simulation, trainInfo.getGroupNumber(), nextTarget, true, runningTime, jump); + trainInfo.updatePlanInfo(nextPlanSection, null, null); + boolean jump = this.atsStandService.isJump(nextPlanSection, trainInfo.getGroupNumber()); + onboardAtpApiService.updateNextArriveInfo(simulation, trainInfo.getGroupNumber(), nextPlanSection, true, runningTime, jump); } - public static Section queryNextTarget(Simulation simulation, Section headSection, TrainInfo trainInfo, Boolean right) { - SimulationDataRepository repository = simulation.getRepository(); - List
targetList = trainInfo.getHeadPath().getSectionList(); - for (int i = targetList.size() - 1; i >= 0; i--) { - Section target = targetList.get(i); - List routePaths = repository.queryRoutePathsByEndAndContainsSection(target, headSection); - if (!CollectionUtils.isEmpty(routePaths)) { - return target; - } + public static Section queryNextPlanSection(Simulation simulation, TrainInfo trainInfo) { + if (trainInfo.getPlanStandTrack() == null) { + return null; + } + SimulationDataRepository repository = simulation.getRepository(); + List
targetList = trainInfo.getHctPath().getSections(); + Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); + int index = targetList.indexOf(planSection); + if (index == -1 || index == targetList.size() - 1) { + return null; + } else { + return targetList.get(index + 1); } - return null; - - -// SimulationDataRepository repository = simulation.getRepository(); -// String dc = trainInfo.getDestinationCode(); -// List routings = repository.queryRoutingByDestCode(dc); -// Section nextSection = null; -// if (!CollectionUtils.isEmpty(routings)) { //目的地码在区段上 -// for (Routing routing : routings) { -// if (headSection.isTurnBackTrack()) { //是折返轨,不限制方向 -// nextSection = routing.queryNextSection(headSection); -// if (nextSection != null) -// break; -// for (Section s : routing.getAllSections()) { -// List routePaths = repository.queryRoutePathsByEndAndContainsSection(s, headSection); -// if (!CollectionUtils.isEmpty(routePaths)) { -// if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == routing.isRight())) { -// return s; -// } -// } -// } -// } else { //不是折返轨,必须和列车同向 -// if (routing.isRight() == right) { -// nextSection = routing.queryNextSection(headSection); -// if (nextSection != null) -// break; -// for (Section s : routing.getAllSections()) { -// List routePaths = repository.queryRoutePathsByEndAndContainsSection(s, headSection); -// if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == right)) { -// return s; -// } -// } -// } -// } -// } -// } else { -// DestinationCodeDefinition dcd = repository.findDestinationCodeDefinition(dc); -// if (dcd == null) -// return null; -// nextSection = AtsTrainService.findNextTarget4HeadTrain(simulation, trainInfo, repository, headSection, headSection.getStation(), dcd); -// } -// return nextSection; } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java index 9cfcd2307..03be59ebf 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java @@ -280,15 +280,18 @@ public class RouteService { // 进路内区段占用检查 List
sectionList = route.getSectionList(); for (Section section : sectionList) { - if (section.isOccupied() && !section.isPreReset()) { - if (section.isSwitchTrack()) { - if (!section.getRelSwitch().isPreReset()) { - return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section); - } - } else { - return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section); - } + if (section.isOccupied()) { + return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section); } +// if (section.isOccupied() && !section.isPreReset()) { +// if (section.isSwitchTrack()) { +// if (!section.getRelSwitch().isPreReset()) { +// return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section); +// } +// } else { +// return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section); +// } +// } } // 延续保护检查 RouteOverlap overlap = route.getOverlap(); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java index b2975b136..a352902c7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java @@ -186,7 +186,7 @@ public class CommandBO { if (!train.isStopAtThePosition(driveStep.getTargetPosition())) { //如果列车没停到目标位置 if (!train.isStop()) return buildDriverForceChangeOperationStep(train.getGroupNumber(), -1); - if (!DriveMode.RM.equals(train.getDriveMode())) + if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode()) return buildDriverDriveModeChangeOperationStep(train.getGroupNumber(), DriveMode.RM); if (train.isEB()) return buildReleaseEBStep(train); @@ -305,7 +305,7 @@ public class CommandBO { // command.getTargetMember().setCommand(null); // } } else { - if (!DriveMode.RM.equals(train.getDriveMode())) { + if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode()) { return buildDriverDriveModeChangeOperationStep(train.getGroupNumber(), DriveMode.RM); } if (train.isSignalEB()) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionRunPath.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionRunPath.java new file mode 100644 index 000000000..369eabfd8 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionRunPath.java @@ -0,0 +1,17 @@ +package club.joylink.rtss.simulation.cbtc.data.map; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class SectionRunPath { + private List
sections; + + private boolean right; + + public SectionRunPath(List
sections, boolean right) { + this.sections = sections; + this.right = right; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/PSDStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/PSDStatus.java index b79c42610..b4cb13ecf 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/PSDStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/PSDStatus.java @@ -38,7 +38,7 @@ public class PSDStatus extends DeviceStatus { public PSDStatus(PSD psd) { super(psd.getCode(), psd.getDeviceType()); - this.close = psd.isClose(); + this.close = psd.isCloseAndLock(); // this.lock = psd.isLock(); this.interlockRelease = psd.isInterlockRelease(); this.noStatus = psd.isNoStatus(); @@ -49,8 +49,8 @@ public class PSDStatus extends DeviceStatus { PSD psd = (PSD) device; PSDStatusVO status = (PSDStatusVO)statusVO; boolean change = false; - if (!Objects.equals(this.close, psd.isClose())) { - this.close = psd.isClose(); + if (!Objects.equals(this.close, psd.isCloseAndLock())) { + this.close = psd.isCloseAndLock(); status.setClose(this.close); change = true; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/RoutePath.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/RoutePath.java index 94a2206ac..800f01b36 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/RoutePath.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/RoutePath.java @@ -253,7 +253,7 @@ public class RoutePath { return new SectionPosition(section, offset); } - public Route queryRouteContainsSection(RunLevel runLevel, Section section, MapConfig config) { + public Route queryRouteContainsSection(boolean communication, Section section, MapConfig config) { for (Signal signal : this.signalList) { List routeList = signal.getRouteList(); if (CollectionUtils.isEmpty(routeList)) { @@ -261,11 +261,11 @@ public class RoutePath { } for (Route route : routeList) { if (config.isRouteLikeHa1()) { - if (Objects.equals(runLevel, RunLevel.CBTC)) { // ctc级别列车找ATP进路 + if (communication) { // 通信车找ATP进路 if (!route.isAtp()) { continue; } - } else { // 非CTC列车找地面进路 + } else { // 非通信车找地面进路 if (!route.isGround()) { continue; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/TrainInfo.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/TrainInfo.java index df52e82d4..f0caa795a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/TrainInfo.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/TrainInfo.java @@ -206,7 +206,7 @@ public class TrainInfo extends MapElement { * 头码车的区段路径 */ @Setter - private SectionPath headPath; + private SectionRunPath hctPath; /** * 下令停车 @@ -244,29 +244,21 @@ public class TrainInfo extends MapElement { */ @Setter private String turnBackStatus = NON; - /** - * 无折返 - */ + /** 无折返 */ public static String NON = "NON"; - /** - * 初始化 - */ + /** 初始化 */ public static String INIT = "INIT"; - /** - * 开往折返轨 - */ + /** 开往折返轨 */ public static String TO = "TO"; - /** - * 到达折返轨停稳 - */ + /** 到达折返轨停稳 */ public static String STOP = "STOP"; - /** - * 开出折返轨 - */ + /** 开出折返轨 */ public static String EXIT = "EXIT"; /** ATS为此列车触发的进路 */ private Map atsTriggerRouteMap = new ConcurrentHashMap<>(); + private boolean communication; + public TrainInfo(String groupNumber) { super(groupNumber, DeviceType.TRAIN); this.groupNumber = groupNumber; @@ -383,7 +375,7 @@ public class TrainInfo extends MapElement { this.offsetp = headPosition.getPercent(); if (headPosition.getSection().isSwitchTrack()) { this.section = headPosition.getSection().getParent().getCode(); - } else if (this.isCtcLevel()) { + } else if (this.isCommunication()) { this.section = headPosition.getLogicSection().getCode(); } else { this.section = headPosition.getSection().getCode(); @@ -408,6 +400,7 @@ public class TrainInfo extends MapElement { } else if (speed != 0 && this.turnBackStatus.equals(STOP)) { this.turnBackStatus = EXIT; } + this.communication = train.isCommunication(); } public boolean isCtcLevel() { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java index 95d10b361..371d7967d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java @@ -99,7 +99,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { /** * 车载服务通讯是否正常在线 */ - private boolean online; + private boolean communication; /** * 列车运行级别 @@ -111,6 +111,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice { */ private DriveMode driveMode; + /** + * 预选驾驶模式 + */ + private DriveMode preDriveMode; + /** * 服务号 */ @@ -400,6 +405,12 @@ public class VirtualRealityTrain extends VirtualRealityDevice { */ private int runningTime; + public void setCommunication(boolean communication) { + if (Fault.COMMUNICATION_ABNORMAL.equals(this.fault) && communication) + return; + this.communication = communication; + } + public void setRunType(RunType runType) { this.runType = runType; switch (runType) { @@ -446,8 +457,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice { @Override public void reset() { + this.communication = true; this.runLevel = null; this.driveMode = null; + this.preDriveMode = null; this.serviceNumber = null; this.tripNumber = null; this.destinationCode = null; @@ -569,11 +582,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice { } private void init() { + this.communication = true; this.jump = false; this.hold = false; this.standParkedTrainActivity = null; this.runLevel = RunLevel.CBTC; this.driveMode = DriveMode.AM; + this.preDriveMode = DriveMode.AM; this.speed = 0; this.atoSpeed = 0; this.atpSpeed = 0; @@ -713,8 +728,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice { // this.setSignalEB(false); this.setAtoOn(false); this.setDriveMode(DriveMode.RM); + setCommunication(false); //断开通信 // this.lossPosition(); - this.setCbtcMaMiss(); //通信断开 +// this.setCbtcMaMiss(); //通信断开 // this.lastTwoPassedResponders.clear(); // if (RunLevel.CBTC.equals(this.runLevel)) { // this.setCbtcMaMiss(); @@ -728,7 +744,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { public void useCMMode() { if (!this.isAtpOn()) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATP", this.getCode())); + return; } this.atoOn = false; this.driveMode = DriveMode.CM; @@ -736,12 +752,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice { public void useAMMode() { if (!atoOn) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATO", this.getCode())); + return; } if (!this.isAtpOn()) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATP", this.getCode())); + return; } this.driveMode = DriveMode.AM; + setCommunication(true); } public void useNRMMode() { @@ -755,9 +772,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { return; } this.driveMode = DriveMode.NRM; - if (RunLevel.CBTC.equals(this.runLevel)) { - this.setCbtcMaMiss(); - } + setCommunication(false); } public void setITCMode() { @@ -1113,13 +1128,15 @@ public class VirtualRealityTrain extends VirtualRealityDevice { public boolean isCommunicable() { Section section = headPosition.getSection(); - Station deviceStation = section.getDeviceStation(); - if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault - || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault() - || !section.anyZcWorking()) { - return false; - } - return true; + return communication && section.anyZcWorking(); + +// Station deviceStation = section.getDeviceStation(); +// if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault +// || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault() +// || !section.anyZcWorking()) { +// return false; +// } +// return true; } public boolean isCMMode() { @@ -1135,26 +1152,27 @@ public class VirtualRealityTrain extends VirtualRealityDevice { * 通信异常 */ COMMUNICATION_ABNORMAL { -// @Override -// public boolean apply(MapElement device) { -// VirtualRealityTrain train = (VirtualRealityTrain) device; -// if (Objects.equals(this, train.getFault())) { -// return false; -// } -// train.setFault(this); -// train.lossPosition(); -// return true; -// } + @Override + public boolean apply(MapElement device) { + if (super.apply(device)) { + VirtualRealityTrain train = (VirtualRealityTrain) device; + train.setCommunication(false); + return true; + } + return false; + } }, /** 驾驶异常 */ DRIVE_FAULT { @Override public boolean apply(MapElement device) { - super.apply(device); - VirtualRealityTrain train = (VirtualRealityTrain) device; - train.emergencyBreak(); //暂时就在这里直接处理,可能正常应该是ATP的责任 - return true; + if (super.apply(device)) { + VirtualRealityTrain train = (VirtualRealityTrain) device; + train.emergencyBreak(); //暂时就在这里直接处理,可能正常应该是ATP的责任 + return true; + } + return false; } }, diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java index 8e8c2c61f..77537eee8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java @@ -49,9 +49,10 @@ public class ATOService { } if (Objects.nonNull(train.getMa())) { train.setAtoOn(true); - if (DriveMode.CM.equals(train.getDriveMode())) { - train.useAMMode(); - } + train.setPreDriveMode(DriveMode.AM); +// if (DriveMode.CM.equals(train.getDriveMode())) { +// train.useAMMode(); +// } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java index db93a734d..73d750008 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java @@ -3,10 +3,7 @@ package club.joylink.rtss.simulation.cbtc.onboard.ATP; import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService; import club.joylink.rtss.simulation.cbtc.ATS.AtsApiService; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.constant.ControlGear; -import club.joylink.rtss.simulation.cbtc.constant.RunLevel; -import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; -import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; +import club.joylink.rtss.simulation.cbtc.constant.*; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Stand; @@ -109,6 +106,7 @@ public class ATPLogicLoop { private void onboardLogicRun2(Simulation simulation, VirtualRealityTrain train) { this.runLevelControl(simulation, train); + this.driveModeControl(simulation, train); boolean right = train.isRight(); SectionPosition headPosition = train.getHeadPosition(); @@ -183,6 +181,33 @@ public class ATPLogicLoop { this.atoService.ATO(train); } + private void driveModeControl(Simulation simulation, VirtualRealityTrain train) { + DriveMode preDriveMode = train.getPreDriveMode(); + DriveMode driveMode = train.getDriveMode(); + if (preDriveMode.equals(driveMode)) + return; + switch (preDriveMode) { + case AM: + train.setCommunication(true); //恢复列车通信 + if (train.isCMMode() && train.isAtoOn()) { + train.useAMMode(); + } + break; + case CM: + train.setCommunication(true); //恢复列车通信 + if (!train.isCbtcMaMiss() || !train.isItcMaMiss()) { //CBTC或ITC的移动授权未丢失 + Float distance = ATOService.calculateDistanceOfMa(train.getHeadPosition(), train.isRight(), train.getMa()); + if (distance != null && distance > 0) { //移动授权的距离为正 + train.useCMMode(); + } + } + break; + case RM: + train.useRMMode(); + break; + } + } + private void updateRunningTime(VirtualRealityTrain train) { if (train.isParkingAt()) { train.setRunningTime(0); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiService.java index e5517301e..1c3009490 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiService.java @@ -16,11 +16,6 @@ public interface OnboardAtpApiService { */ void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma); - /** - * 忽略驾驶模式更新CBTC移动授权 - */ - boolean ignoreDriveModeUpdateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma); - void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma); /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiServiceImpl.java index 72546b20c..f7ff792c8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/OnboardAtpApiServiceImpl.java @@ -37,30 +37,10 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService { if (!train.isAtpOn()) { return; } - if (train.getFault() == VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL) { //列车通信故障 - return; - } - if (train.isRMMode() || train.isNRMMode()) - return; - if (train.isCBTC()) { + if (train.isCommunication()) { this.ATPService.updateMA(train, ma); + train.setCbtcMaMissDuration(0); } - train.setCbtcMaMissDuration(0); - } - - @Override - public boolean ignoreDriveModeUpdateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma) { - if (ma == null) - return false; - if (!train.isAtpOn()) { - return false; - } - if (train.getFault() == VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL) { //列车通信故障 - return false; - } - this.ATPService.updateMA(train, ma); - train.setCbtcMaMissDuration(0); - return true; } @Override @@ -70,7 +50,7 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService { if (!train.isAtpOn()) { return; } - if (!train.isCBTC()) { + if (!train.isCommunication()) { this.ATPService.updateMA(train, ma); train.setItcMaMissDuration(0); } diff --git a/src/main/java/club/joylink/rtss/vo/map/display/DisplayVO.java b/src/main/java/club/joylink/rtss/vo/map/display/DisplayVO.java index 460f85215..12cca72b4 100644 --- a/src/main/java/club/joylink/rtss/vo/map/display/DisplayVO.java +++ b/src/main/java/club/joylink/rtss/vo/map/display/DisplayVO.java @@ -13,4 +13,7 @@ public class DisplayVO { private List stationCodeList; private List elementList; + + /** 可切换显示的车站 */ + private List switchStationCodeList; }