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 ec4c3026f..e8a51baef 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 @@ -122,7 +122,9 @@ public class ZCLogicLoop { return List.of(closedSection); // 如果车尾正常,从车头开始往前查找 Section section = headPosition.getSection(); - + MovementAuthority.End switchEnd = checkSwitch(tailSection, section, right); + if (switchEnd != null) + return List.of(switchEnd); // 检查列车当前所在进路是否锁闭 MovementAuthority.End end1 = this.checkRouteLock(simulation, section, tailSection, right, train); if (Objects.nonNull(end1)) { @@ -169,6 +171,10 @@ public class ZCLogicLoop { endList.add(unlockedOverlapEnd); } } + // 道岔 + MovementAuthority.End end = checkSwitch(section); + if (end != null) + endList.add(end); // 轨道尽头/问题道岔 Section temp = section.getNextRunningSectionOf(right); if (Objects.isNull(temp)) { // 到尽头 @@ -190,7 +196,7 @@ public class ZCLogicLoop { if (cs != null) endList.add(cs); - if (!CollectionUtils.isEmpty(endList)) { + if (!CollectionUtils.isEmpty(endList) && endList.size() == 1 && endList.get(0).getType().equals(MovementAuthority.EndType.CLOSED_SIGNAL)) { break; } @@ -212,6 +218,40 @@ public class ZCLogicLoop { return endList; } + private MovementAuthority.End checkSwitch(Section tailSection, Section headSection, boolean right) { + Section section = tailSection; + for (int i = 0; i < 10; i++) { + if (section.equals(headSection)) + break; + MovementAuthority.End end = checkSwitch(section); + if (end != null) + return end; + section = section.getNextRunningSectionOf(right); + } + return null; + } + + private MovementAuthority.End checkSwitch(Section section) { + Switch relSwitch = section.getRelSwitch(); + if (relSwitch != null) { + Route route = relSwitch.getRoute(); + if (relSwitch.isLoss()) { + return new MovementAuthority.End(section, MovementAuthority.EndType.FAULT_SWITCH); + } else if (route != null) { + List flsList = route.getFlsList(); + if (!CollectionUtils.isEmpty(flsList)) { + List fls = flsList.stream() + .filter(routeFls -> routeFls.getBase().getASwitch().equals(relSwitch)) + .collect(Collectors.toList()); + if (!routeService.isFlsCheckPass(fls)) { + return new MovementAuthority.End(section, MovementAuthority.EndType.FAULT_SWITCH); + } + } + } + } + return null; + } + private MovementAuthority.End checkClosedSection(Section section) { if (section.isClosed()) { return new MovementAuthority.End(section, MovementAuthority.EndType.CLOSED_SECTION); @@ -427,32 +467,20 @@ public class ZCLogicLoop { private MovementAuthority.End checkRouteLock(Simulation simulation, Section section, Section tailSection, boolean right, VirtualRealityTrain train) { SimulationDataRepository repository = simulation.getRepository(); // 判断前方是否有信号机(如果存在信号机,则不判断进路锁闭,以兼容现在列车加载到转换轨没有进路情况) - if (section.isTransferTrack()) { + Signal aheadSignal = section.getSignalOf(right); + if (Objects.nonNull(aheadSignal)) { return null; } -// Signal aheadSignal = section.getSignalOf(right); -// if (Objects.nonNull(aheadSignal)) { -// return null; -// } // 先查询是否是已排列的锁闭进路 List settingRoutes = repository.getSettingRoutes(); boolean lock = false; if (!CollectionUtils.isEmpty(settingRoutes)) { - boolean headRoute = false; - boolean tailRoute = false; for (Route route : settingRoutes) { - if (route.isRight() == right && (route.isRouteSection(section) || route.isRouteSection(tailSection))) { - if (route.isRouteSection(section)) - headRoute = true; - if (route.isRouteSection(tailSection)) - tailRoute = true; + if (route.isRouteSection(section) +// && !route.isSetting() + ) { lock = true; - List switches = screenSwitchesInFront(route, tailSection); - if (!this.checkRouteSwitchPosition(route, switches) || !this.isFlsCheckPass(route.getFlsList(), switches)) { - return new MovementAuthority.End(section, MovementAuthority.EndType.ROUTE_INTERLOCK_NOT_MET); - } - if (headRoute && tailRoute) - break; + break; } } } @@ -475,11 +503,68 @@ public class ZCLogicLoop { base = pre; } } - if (!lock && section.getSignalOf(right) == null) { + if (!lock) { // 未锁闭进路中,设置移动授权终点 return new MovementAuthority.End(section, MovementAuthority.EndType.UNLOCK_SECTION); } return null; + + +// SimulationDataRepository repository = simulation.getRepository(); +// // 判断前方是否有信号机(如果存在信号机,则不判断进路锁闭,以兼容现在列车加载到转换轨没有进路情况) +// if (section.isTransferTrack()) { +// return null; +// } +//// Signal aheadSignal = section.getSignalOf(right); +//// if (Objects.nonNull(aheadSignal)) { +//// return null; +//// } +// // 先查询是否是已排列的锁闭进路 +// List settingRoutes = repository.getSettingRoutes(); +// boolean lock = false; +// if (!CollectionUtils.isEmpty(settingRoutes)) { +// boolean headRoute = false; +// boolean tailRoute = false; +// for (Route route : settingRoutes) { +// if (route.isRight() == right && (route.isRouteSection(section) || route.isRouteSection(tailSection))) { +// if (route.isRouteSection(section)) +// headRoute = true; +// if (route.isRouteSection(tailSection)) +// tailRoute = true; +// lock = true; +// List switches = screenSwitchesInFront(route, tailSection); +// if (!this.checkRouteSwitchPosition(route, switches) || !this.isFlsCheckPass(route.getFlsList(), switches)) { +// return new MovementAuthority.End(section, MovementAuthority.EndType.ROUTE_INTERLOCK_NOT_MET); +// } +// if (headRoute && tailRoute) +// break; +// } +// } +// } +// if (!lock) { // 未找到锁闭进路,判断是否自动信号 +// Section base = section; +// int count = 0; +// while (Objects.nonNull(base) && count < 20) { +// ++count; +// // 向反方向查找,找信号机,判断是否自动信号 +// Section pre = base.getNextRunningSectionOf(!right); +// if (Objects.nonNull(pre)) { +// Signal signal = pre.getSignalOf(right); +// if (Objects.nonNull(signal)) { +// if (signal.isAutoSignal()) { +// lock = true; // 如果是自动信号,也相当于锁闭 +// } +// break; // 找到信号机,结束 +// } +// } +// base = pre; +// } +// } +// if (!lock && section.getSignalOf(right) == null) { +// // 未锁闭进路中,设置移动授权终点 +// return new MovementAuthority.End(section, MovementAuthority.EndType.UNLOCK_SECTION); +// } +// return null; } private boolean checkRouteSwitchPosition(Route route, List switches) { 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 6753a2c33..531a1bbf1 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 @@ -388,19 +388,19 @@ public class RouteService { for (Section section : sectionList) { if (section.isSwitchTrack()) { Switch relSwitch = section.getRelSwitch(); - relSwitch.getA().routeLocking(right); + relSwitch.getA().routeLocking(route, right); if (relSwitch.isNormalPosition()) { // 定位 - relSwitch.getB().routeLocking(right); + relSwitch.getB().routeLocking(route, right); relSwitch.getC().routeUnlocking(right); } else if (relSwitch.isReversePosition()) { // 反位 - relSwitch.getC().routeLocking(right); + relSwitch.getC().routeLocking(route, right); relSwitch.getB().routeUnlocking(right); } else { // 失表 - relSwitch.getB().routeLocking(right); - relSwitch.getC().routeLocking(right); + relSwitch.getB().routeLocking(route, right); + relSwitch.getC().routeLocking(route, right); } } else { - section.routeLocking(right); + section.routeLocking(route, right); } // log.debug(section.debugStr() + "因<预先锁闭>锁闭"); } @@ -412,7 +412,7 @@ public class RouteService { this.routeFlsControl(simulation, route.getFlsList()); if (config.isLockFirst()) { for (SwitchElement switchElement : switchList) { - switchElement.getASwitch().routeLock(); + switchElement.getASwitch().routeLock(route); } if (!CollectionUtils.isEmpty(route.getFlsList())) { for (RouteFls routeFls : route.getFlsList()) { @@ -660,7 +660,7 @@ public class RouteService { boolean right = route.getStart().isRight(); // 进路区段锁闭 for (Section section : route.getSectionList()) { - section.routeLocking(right); + section.routeLocking(route, right); if (section.isSwitchTrack()) { // 道岔锁闭 Switch relSwitch = section.getRelSwitch(); @@ -675,7 +675,7 @@ public class RouteService { // 道岔锁闭 for (SwitchElement element : route.getSwitchList()) { Switch aSwitch = element.getASwitch(); - aSwitch.routeLock(); + aSwitch.routeLock(route); } // 延续保护 @@ -1303,7 +1303,7 @@ public class RouteService { boolean right = route.getStart().isRight(); for (Section section : route.getSectionList()) { if (!section.isRouteLock()) { - section.routeLocking(right); + section.routeLocking(route, right); } } if (route.isOpen()) { 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 e57c86d04..e05b37046 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 @@ -1,6 +1,5 @@ package club.joylink.rtss.simulation.cbtc.data.map; -import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; @@ -173,6 +172,11 @@ public class Section extends MayOutOfOrderDevice { */ private boolean routeLock; + /** + * 锁闭该区段的进路 + */ + private Route route; + /** * 锁闭方向 */ @@ -253,6 +257,7 @@ public class Section extends MayOutOfOrderDevice { super.reset(); this.blockade = false; this.routeLock = false; + this.route = null; this.lockRight = false; this.overlapLock = false; this.ctOccupied = false; @@ -577,16 +582,18 @@ public class Section extends MayOutOfOrderDevice { /** * 进路锁闭(连同逻辑区段) */ - public void routeLocking(boolean right) { + public void routeLocking(Route route, boolean right) { //岔心锁闭 if (this.parent != null && this.parent.isCross()) { + this.parent.setRoute(route); this.parent.setRouteLock(true); this.parent.setLockRight(right); } + this.route = route; this.routeLock = true; this.lockRight = right; if (!CollectionUtils.isEmpty(this.logicList)) { - this.logicList.forEach(logic -> logic.routeLocking(right)); + this.logicList.forEach(logic -> logic.routeLocking(route, right)); } } @@ -600,11 +607,13 @@ public class Section extends MayOutOfOrderDevice { //岔心解锁 if (this.parent != null && this.parent.isCross()) { this.parent.setRouteLock(false); + this.parent.setRoute(null); // this.parent.setOverlapLock(false); this.parent.setLockRight(false); } //自身解锁 this.routeLock = false; + this.route = null; // this.overlapLock = false; this.lockRight = false; if (!CollectionUtils.isEmpty(this.logicList)) { @@ -615,6 +624,7 @@ public class Section extends MayOutOfOrderDevice { public void forceUnlocking() { this.routeLock = false; + this.route = null; this.overlapLock = false; this.lockRight = false; if (!isCross() && !CollectionUtils.isEmpty(this.logicList)) { @@ -836,6 +846,7 @@ public class Section extends MayOutOfOrderDevice { public void faultUnlock() { this.faultLock = false; this.routeLock = false; + this.route = null; this.overlapLock = false; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java index 64f53dde1..534f8cdcd 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java @@ -64,6 +64,11 @@ public class Switch extends MayOutOfOrderDevice { */ private boolean routeLock; + /** + * 锁闭该道岔的进路 + */ + private Route route; + /** * 是否进路侧防锁闭 */ @@ -140,6 +145,7 @@ public class Switch extends MayOutOfOrderDevice { this.singleLock = false; this.blockade = false; this.routeLock = false; + this.route = null; this.fpLock = false; this.overlapLock = false; this.masterGuideLock = false; @@ -252,12 +258,14 @@ public class Switch extends MayOutOfOrderDevice { this.c.setSpeedUpLimit(upLimitSpeed); } - public void routeLock() { + public void routeLock(Route route) { this.routeLock = true; + this.route = route; } public void routeUnlock() { this.routeLock = false; + this.route = null; } public void fpLock() { 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 ad22c08e7..e34e1fa0d 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 @@ -140,7 +140,12 @@ public class MovementAuthority { float offset = right ? Math.max(0, section.getLen() - 100) : Math.min(100, section.getLen()); return new SectionPosition(section, offset); } - case FAULT_SWITCH: + case FAULT_SWITCH: { + Section section = (Section) this.device; + float offset = right ? 0 : section.getLen(); + SectionPosition stopPosition = new SectionPosition(section, offset); + return CalculateService.calculateNextPositionByStartAndLen(stopPosition, !right, 100); + } case UNLOCK_SECTION: case FAULT_SECTION: case ROUTE_INTERLOCK_NOT_MET: diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java b/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java index e25a48bc5..4a23b4119 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java @@ -5,10 +5,8 @@ import club.joylink.rtss.simulation.cbtc.CI.service.RouteService; 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.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; -import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -41,7 +39,7 @@ public class DeviceStatusModifyTool { // 修改进路侧防到指定位置 this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList()); // 进路元素锁闭 - route.getSectionList().forEach(section -> section.routeLocking(route.getStart().isRight())); + route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight())); if (this.routeService.checkCanOverlapSet(simulation, route)) { SectionPath overlapPath = route.selectOverlapElement(); if (Objects.nonNull(overlapPath)) { @@ -86,7 +84,7 @@ public class DeviceStatusModifyTool { // 修改进路侧防到指定位置 this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList()); // 进路元素锁闭 - route.getSectionList().forEach(section -> section.routeLocking(route.getStart().isRight())); + route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight())); SectionPath overlapPath = route.selectOverlapElement(); if (Objects.nonNull(overlapPath)) { this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false); @@ -162,7 +160,7 @@ public class DeviceStatusModifyTool { } this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal()); if (routeLock) { - switchElement.getASwitch().routeLock(); + switchElement.getASwitch().routeLock(route); } else { // 延续保护锁闭 switchElement.getASwitch().overlapLock(); }