From 1590a7cbccc86e976ce181a94403a5f2a71b2b9b Mon Sep 17 00:00:00 2001 From: joylink_zhangsai <1021828630@qq.com> Date: Mon, 26 Apr 2021 13:25:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E9=93=81=E4=BB=BF=E7=9C=9F=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=AE=9E=E7=8E=B0=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessExceptionAssertEnum.java | 1 + .../rtss/simulation/rt/ATS/bo/AtsSignal.java | 16 +- .../rtss/simulation/rt/CIL/CilApiService.java | 76 ++- .../simulation/rt/CIL/CilLogicService.java | 4 + .../rt/CIL/CilRouteLogicService.java | 582 +++++++----------- .../rt/CIL/CilSectionLogicService.java | 72 +++ .../rt/CIL/CilSignalLogicService.java | 83 ++- .../rt/CIL/CilSwitchLogicService.java | 25 + .../simulation/rt/CIL/bo/CilRepository.java | 14 + .../rtss/simulation/rt/CIL/bo/CilRoute.java | 2 + .../rtss/simulation/rt/CIL/bo/CilSection.java | 22 +- .../rtss/simulation/rt/CIL/bo/CilSignal.java | 20 +- .../rtss/simulation/rt/CIL/bo/CilSwitch.java | 21 + .../rtss/simulation/rt/SRD/SrdApiService.java | 47 +- .../rt/operation/SectionOperationHandler.java | 21 + .../rt/operation/SignalOperationHandler.java | 31 +- .../rt/operation/SwitchOperationHandler.java | 29 + 17 files changed, 634 insertions(+), 432 deletions(-) create mode 100644 src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSectionLogicService.java create mode 100644 src/main/java/club/joylink/rtss/simulation/rt/operation/SectionOperationHandler.java diff --git a/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java b/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java index 1102df8ec..13edfa8be 100644 --- a/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java +++ b/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java @@ -31,6 +31,7 @@ public enum BusinessExceptionAssertEnum implements BusinessExceptionAssert { UNSUPPORTED_FILE_FORMAT(10015, "unsupported file format"), OPERATION_REPEAT(10016, "operation repeat"), SIMULATION_EXCEPTION_FOR_SHOW(10017, ""), //错误信息用于展示给仿真用户 + OPERATION_FAIL(10018, "操作失败"), DATA_ERROR(11000, "data error"), diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java index e51efef27..5a606b754 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java @@ -5,6 +5,7 @@ import lombok.Getter; import java.util.Arrays; import java.util.List; +import java.util.Objects; @Getter public class AtsSignal extends AtsDevice { @@ -14,6 +15,8 @@ public class AtsSignal extends AtsDevice { boolean bl; boolean rbl; int level; + String lrId; + int delayTime; public AtsSignal(String id, String name) { super(id, name); @@ -22,7 +25,8 @@ public class AtsSignal extends AtsDevice { @Override List buildMessage() { return Arrays.asList(this.id, this.signalAspect, - this.convert(this.logic), this.convert(this.forceLight), this.convert(this.bl), this.convert(this.rbl), this.level); + this.convert(this.logic), this.convert(this.forceLight), this.convert(this.bl), this.convert(this.rbl), + this.level, this.lrId, this.delayTime); } public boolean applyChange(CilSignal cilSignal) { @@ -58,6 +62,16 @@ public class AtsSignal extends AtsDevice { stateList.set(6, this.level); change = true; } + if (!Objects.equals(this.lrId, cilSignal.getLrId())) { + this.lrId = cilSignal.getLrId(); + stateList.set(7, this.lrId); + change = true; + } + if (!Objects.equals(this.delayTime, cilSignal.getDelayTime())) { + this.delayTime = cilSignal.getDelayTime(); + stateList.set(8, this.delayTime); + change = true; + } return change; } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilApiService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilApiService.java index 7224cd61a..c8abd82a6 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilApiService.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.rt.CIL; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.rt.CIL.bo.CilRepository; import club.joylink.rtss.simulation.rt.CIL.bo.CilRoute; import club.joylink.rtss.simulation.rt.CIL.bo.CilSignal; @@ -19,6 +20,12 @@ public class CilApiService { @Autowired private CilRouteLogicService cilRouteLogicService; + @Autowired + private CilSignalLogicService cilSignalLogicService; + + @Autowired + private CilSectionLogicService cilSectionLogicService; + /** * 转动道岔 * @@ -55,20 +62,77 @@ public class CilApiService { return cilRouteLogicService.setRoute(simulation, cilRoute); } - public boolean cancelRoute(RtSimulation simulation, String id) { - return cilRouteLogicService.cancelRoute(simulation, id); + public boolean cancelRoute(RtSimulation simulation, String signalId) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSignal cilSignal = cilRepository.getSignalById(signalId); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertHasText(cilSignal.getLrId()); + return cilRouteLogicService.cancelRoute(simulation, cilSignal.getLrId()); } public boolean setGuide(RtSimulation simulation, String signalId, String routeId) { + //2021-04-25 16:09:13 比较复杂,延后吧 CommonRepository commonRepository = simulation.getRepository(CommonRepository.NAME, CommonRepository.class); CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); - CilRoute cilRoute; + CilSignal cilSignal = null; if (StringUtils.hasText(signalId)) { - cilRoute = cilRepository.getRouteById(cilRepository.getSignalById(signalId).getLrId()); + cilSignal = cilRepository.getSignalById(signalId); + BusinessExceptionAssertEnum.OPERATION_FAIL.assertHasText(cilSignal.getLrId(), "信号机无已锁闭的进路"); } else if (StringUtils.hasText(routeId)) { - cilRoute = cilRepository.getRouteById(routeId); + //大铁线路没有,暂时不管 + } else { + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("参数缺失"); } - + BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(cilSignal.sufficientLevel(CilSignal.GUIDE, false), "引导开放条件不满足"); + cilSignalLogicService.UpdateSignalDisplay(simulation, cilSignal, CilSignal.GUIDE, false); return true; } + + public void signalReopen(RtSimulation simulation, String signalId) { + cilSignalLogicService.reopen(simulation, signalId); + } + + public void humanCancel(RtSimulation simulation, String signalId) { + //检查 + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSignal cilSignal = cilRepository.getSignalById(signalId); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertHasText(cilSignal.getLrId(), "信号机无已办理进路"); + CilRoute cilRoute = cilRepository.getRouteById(cilSignal.getLrId()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilRoute.isDelayUnlocking(), "进路已在延时解锁中"); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilRoute.isTrainIn(), "进路非空闲状态"); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(cilSignalLogicService.isApproachOccupied(simulation, signalId), + "进路未接近锁闭"); + //关闭信号 + cilSignalLogicService.UpdateSignalDisplay(simulation, cilSignal, CilSignal.RED, false); + //设置延时解锁 + cilSignal.initDelayTime(); + cilRoute.setDelayUnlocking(true); + } + + public void blockadeSwitch(RtSimulation simulation, String id) { + cilSwitchLogicService.blockadeSwitch(simulation, id); + } + + public void unblockSwitch(RtSimulation simulation, String id) { + cilSwitchLogicService.unblockSwitch(simulation, id); + } + + public void singleLockSwitch(RtSimulation simulation, String id) { + cilSwitchLogicService.singleLockSwitch(simulation, id); + } + + public void singleUnlockSwitch(RtSimulation simulation, String id) { + cilSwitchLogicService.singleUnlockSwitch(simulation, id); + } + + public void blockadeSignal(RtSimulation simulation, String signalId) { + cilSignalLogicService.blockadeSignal(simulation, signalId); + } + + public void unblockSignal(RtSimulation simulation, String signalId) { + cilSignalLogicService.unblockSignal(simulation, signalId); + } + + public void sectionFaultUnlock(RtSimulation simulation, String id) { + cilSectionLogicService.sectionFaultUnlock(simulation, id); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java index cd019d498..d4914133b 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java @@ -31,6 +31,9 @@ public class CilLogicService { @Autowired private AtsApiService atsApiService; + @Autowired + private CilSectionLogicService cilSectionLogicService; + public void buildRepository(RtSimulation rtSimulation, MapVO mapVO) { CilRepository cilRepository = CilRepositoryBuilder.buildFrom(mapVO); rtSimulation.addRepository(cilRepository); @@ -78,6 +81,7 @@ public class CilLogicService { private void mainLogic(RtSimulation rtSimulation, CilRepository cilRepository) { this.cilRouteLogicService.routeLogic(rtSimulation, cilRepository); + this.cilSectionLogicService.mainLogic(rtSimulation, cilRepository); } private void sendState2Ats(RtSimulation rtSimulation, CilRepository cilRepository) { diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java index ec61b4f31..7205e7727 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java @@ -1,6 +1,7 @@ package club.joylink.rtss.simulation.rt.CIL; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.data.map.Signal; import club.joylink.rtss.simulation.rt.CIL.bo.*; import club.joylink.rtss.simulation.rt.RtSimulation; import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal; @@ -24,6 +25,9 @@ public class CilRouteLogicService { List supervisedRouteList = cilRepository.getSupervisedRouteList(); for (CilRoute cilRoute : supervisedRouteList) { this.settingProgress(rtSimulation, cilRoute, cilRepository.getConfig()); + if (cilRoute.isDelayUnlocking()) { + this.delayUnlockingProgress(rtSimulation, cilRoute, cilRepository.getConfig()); + } // switch (cilRoute.getStage()) { // case CilRoute.STAGE_SETTING: // this.settingProgress(rtSimulation, cilRoute, cilRepository.getConfig()); @@ -35,6 +39,20 @@ public class CilRouteLogicService { } } + /** + * 检查进路能否开放信号 + */ + public boolean canOpenSignal(RtSimulation rtSimulation, String routeId) { + CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class); + CilRoute cilRoute = cilRepository.getRouteById(routeId); + if (cilRoute.isTrainIn()) + return false; + CommonRepository commonRepository = rtSimulation.getRepository(CommonRepository.NAME, CommonRepository.class); + CommonRoute commonRoute = commonRepository.getRouteById(cilRoute.getId()); + CilSignal cilSignal = cilRepository.getSignalById(commonRoute.getStart().getId()); + return cilSignal.sufficientLevel(commonRoute.getSignalAspect(), false); + } + /** * 排列进路接口,包括办理冲突检查和选出延续保护及一些初始化工作 * @@ -43,13 +61,29 @@ public class CilRouteLogicService { * @return 是否办理 */ public boolean setRoute(RtSimulation rtSimulation, CilRoute cilRoute) { + /* 检查 */ CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class); - if (cilRepository.isSupervised(cilRoute.getId())) { - return false; - } + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilRepository.isSupervised(cilRoute.getId()), "进路已经办理"); CommonRepository commonRepository = rtSimulation.getRepository(CommonRepository.NAME, CommonRepository.class); CommonRoute commonRoute = commonRepository.getRouteById(cilRoute.getId()); - // 检查 + // 道岔检查 + List spList = commonRoute.getPathElement().getSpList(); + if (!CollectionUtils.isEmpty(spList)) { + for (SwitchPosition switchPosition : spList) { + CommonSwitch commonSwitch = switchPosition.getCommonSwitch(); + CilSwitch cilSwitch = cilRepository.getSwitchById(commonSwitch.getId()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilSwitch.isBl(), "进路内道岔封锁"); + } + } + //信号机检查 + CilSignal cilSignal = cilRepository.getSignalById(commonRoute.getStart().getId()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilSignal.isBl(), "进路内始端信号机封锁"); + //区段检查 + for (CommonSection commonSection : commonRoute.getPathElement().getSectionList()) { + CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilSection.isAxcOccupy(), "区段占用"); + } + /* 初始化 */ // 延续保护选择 this.selectRouteOverlap(cilRepository, commonRoute, cilRoute); // 其他初始化 @@ -111,6 +145,8 @@ public class CilRouteLogicService { // 进路解锁 cancelRouteLockAndCancelRouteUse(cilRepository, commonRoute); cilRoute.setLock(false); + //信号机可以自动开放 + cilRoute.setCanAutoOpen(true); return true; } @@ -159,45 +195,6 @@ public class CilRouteLogicService { } } } - - -// CilOverlap commonOverlap = cilRoute.getOverlap(); -// if (commonOverlap != null) { -// List pathElementList = commonOverlap.getPathElementList(); -// BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionNotEmpty(pathElementList); -// if (pathElementList.size() == 1) { -// commonOverlap.updateSelectedPath(pathElementList.get(0)); -// } else { // 多于一个,筛选(暂时选择逻辑为所有道岔在指定位置,若无,取直向) -// CilRoutePathElement straight = null; -// CilRoutePathElement selected = null; -// for (CilRoutePathElement cilRoutePathElement : pathElementList) { -// boolean select = true; -// boolean line = true; // 是否直向 -// List switchPositionList = cilRoutePathElement.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// if (!cilSwitchPosition.isNormalPosition()) { -// line = false; -// } -// if (!cilSwitchPosition.isOnPosition()) { -// select = false; -// break; -// } -// } -// if (line) { -// straight = cilRoutePathElement; -// } -// if (select) { -// selected = cilRoutePathElement; -// break; -// } -// } -// if (selected != null) { -// commonOverlap.updateSelectedPath(selected); -// } else { -// commonOverlap.updateSelectedPath(straight); -// } -// } -// } } private void settingProgress(RtSimulation rtSimulation, CilRoute cilRoute, CilConfig config) { @@ -210,65 +207,63 @@ public class CilRouteLogicService { TrackWay pathElement = commonRoute.getPathElement(); CommonSignal commonSignal = commonRoute.getStart(); CilSignal cilSignal = cilRepository.getSignalById(commonSignal.getId()); - // 进路内的设备转动、锁闭 - if (!cilRoute.isLock()) { - cilSwitchLogicService.tryTurn(rtSimulation, pathElement.getSpList()); // 转动道岔 - boolean allLock = try2RouteLockSwitches(cilRepository, cilRoute, pathElement.getSpList()); // 锁闭道岔 - if (allLock) { + if (cilRoute.isCanAutoOpen()) { //2021-04-25 14:47:06 这个判断条件可能不合理。能自动开放信号就应该尝试锁闭进路相关的设备吗? + // 进路内的设备转动、锁闭 + if (!cilRoute.isLock()) { + cilSwitchLogicService.tryTurn(rtSimulation, pathElement.getSpList()); // 转动道岔 + boolean allLock = try2RouteLockSwitches(cilRepository, cilRoute, pathElement.getSpList()); // 锁闭道岔 + if (allLock) { // if (!config.isLockFirst()) { - routeLockSections(cilRepository, commonRoute, pathElement.getSectionList()); + routeLockSections(cilRepository, commonRoute); // } - cilRoute.setLock(true); + } } - } - // 侧防设备转动、锁闭 - if (!cilRoute.isFl()) { //进路未侧防锁闭 - List flsList = pathElement.getFlsList(); + // 侧防设备转动、锁闭 + List flsList = commonRoute.getFlsList(); if (!CollectionUtils.isEmpty(flsList)) { //进路侧防不为空 - boolean allSwitchLocked = true; - for (CommonFls commonFls : flsList) { - SwitchPosition target = commonFls.getTarget(); - if (commonRoute.getPathElement().isContainSwitchPosition(target.getCommonSwitch().getId(), target.isNormal())) { //进路包含侧防所防护的道岔位置 - List firstLevelList = commonFls.getFirstLevelList(); - for (CommonFls.FlsElement commonFlsElement : firstLevelList) { - //侧防信号机关闭并锁闭 - CilSignal flsSignal = cilRepository.getSignalById(commonFlsElement.getPs().getId()); - cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, flsSignal, CilSignal.RED, true); - //侧防道岔转动 - cilSwitchLogicService.tryTurn(rtSimulation, cilRepository, commonFlsElement.getPp().getCommonSwitch(), commonFlsElement.getPp().getPosition()); - cilSwitchLogicService.tryTurn(rtSimulation, cilRepository, commonFlsElement.getPae().getCommonSwitch(), commonFlsElement.getPae().getPosition()); - //侧防设备锁闭 - boolean allLock = commonFlsElement.lock(cilRepository); - if (!allLock) { - allSwitchLocked = false; + if (!cilRoute.isFl()) { //进路未侧防锁闭 + for (CommonFls commonFls : flsList) { + SwitchPosition target = commonFls.getTarget(); + if (commonRoute.getPathElement().isContainSwitchPosition(target.getCommonSwitch().getId(), target.isNormal())) { //进路包含侧防所防护的道岔位置 + List firstLevelList = commonFls.getFirstLevelList(); + for (CommonFls.FlsElement commonFlsElement : firstLevelList) { + //侧防道岔转动 + cilSwitchLogicService.tryTurn(rtSimulation, cilRepository, commonFlsElement.getPp().getCommonSwitch(), commonFlsElement.getPp().getPosition()); + cilSwitchLogicService.tryTurn(rtSimulation, cilRepository, commonFlsElement.getPae().getCommonSwitch(), commonFlsElement.getPae().getPosition()); + //侧防设备锁闭 + commonFlsElement.lock(cilRepository); } } } } - if (allSwitchLocked) { //进路侧防锁闭,信号机级别改为ATP级 - cilRoute.setFl(true); - } } - } - // 延续保护设备转动、锁闭 - if (!cilRoute.isOl()) { - CommonOverlap commonOverlap = commonRoute.getOverlap(); + // 延续保护设备转动、锁闭 CilOverlap overlap = cilRoute.getOverlap(); if (overlap != null) { - TrackWay selectedPath = overlap.getSelectedPath(); - if (selectedPath != null) { - cilSwitchLogicService.tryTurn(rtSimulation, selectedPath.getSpList()); - boolean allSwitchesLocked = try2OverlapLockSwitches(cilRepository, overlap, pathElement.getSpList()); // 锁闭道岔 - if (allSwitchesLocked) { + CommonOverlap commonOverlap = commonRoute.getOverlap(); + if (!cilRoute.isOl()) { + TrackWay selectedPath = overlap.getSelectedPath(); + if (selectedPath != null) { + cilSwitchLogicService.tryTurn(rtSimulation, selectedPath.getSpList()); + boolean allSwitchesLocked = try2OverlapLockSwitches(cilRepository, overlap, pathElement.getSpList()); // 锁闭道岔 + if (allSwitchesLocked) { // if (!config.isLockFirst()) { overlapLockSections(cilRepository, commonOverlap.getStart().isRight(), overlap.getSelectedPath().getSectionList()); // } + } } } } } - - //判断信号级别并尝试开放信号 + //检查联锁条件并设置对应锁闭状态 + cilRoute.setLock(isRoutePassInterlockingCheck(cilRepository, commonRoute)); + if (!CollectionUtils.isEmpty(commonRoute.getFlsList())) { + cilRoute.setFl(isFlsPassInterlockingCheck(cilRepository, commonRoute)); + } + if (cilRoute.getOverlap() != null && cilRoute.getOverlap().getSelectedPath() != null) { + cilRoute.setFl(isOverlapPassInterlockingCheck(cilRepository, commonRoute, cilRoute.getOverlap())); + } + //判断信号级别 if (cilRoute.isLock()) { if (cilRoute.isFl() || CollectionUtils.isEmpty(commonRoute.getFlsList())) { if (cilRoute.isOl() || cilRoute.getOverlap() == null) { @@ -280,6 +275,7 @@ public class CilRouteLogicService { cilSignal.updateLevel(CilSignal.LEVEL_2); } } + //开放信号 // boolean routeCtcMode = cilRoute.getCilServer().isCtcMode(); boolean routeCtcMode = true; if (cilRoute.isCanAutoOpen()) { @@ -287,58 +283,117 @@ public class CilRouteLogicService { cilRoute.setCanAutoOpen(false); cilSignal.setLrId(cilRoute.getId()); } else { - cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, commonRoute.getSignalAspect(), routeCtcMode); + if (canOpenSignal(rtSimulation, cilRoute.getId())) { + cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, commonRoute.getSignalAspect(), routeCtcMode); + } } } - //持续监视 + //持续监视,如果当前信号级别不满足显示状态,关闭信号 if (!cilSignal.isForbidAspect()) { - if (!cilRoute.isLock()) { //进路主体未锁闭 - cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); - } else if (!CollectionUtils.isEmpty(pathElement.getFlsList()) || !cilRoute.isFl()) { //有侧防,但是侧防未锁闭 - if (cilSignal.getSignalAspect() != CilSignal.LEVEL_2) { //信号机不是引导信号 - cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); - } + if (!cilSignal.sufficientLevel(cilSignal.getSignalAspect(), false)) { + cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.RED, routeCtcMode); } - if (cilRoute.getOverlap() != null && !cilRoute.isOl()) { //进路延续保护没有锁闭 - if (cilSignal.getSignalAspect() != CilSignal.LEVEL_1 && !cilSignal.isLogic()) { //信号机是物理点灯且不是引导信号 - cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); - } - } - } - - -// if (config.isLockFirst()) { -// // 预先锁闭进路区段 -// this.lockRouteDevices(cilRoute); -// } -// // 进路道岔征用 -// this.turnSwitch(rtSimulation, cilRoute); -// if (!config.isLockFirst()) { -// // 检查道岔是否到位,到位锁闭进路,否则返回 -// boolean onPosition = this.checkSwitchOnPosition(cilRoute); -// if (onPosition) { -// this.lockRouteDevices(cilRoute); +// if (!cilRoute.isLock()) { //进路主体未锁闭 +// cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); +// } else if (!CollectionUtils.isEmpty(pathElement.getFlsList()) && !cilRoute.isFl()) { //有侧防,但是侧防未锁闭 +// if (cilSignal.getSignalAspect() != CilSignal.GUIDE) { //信号机不是引导信号 +// cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); +// } // } -// } -// int level = this.levelCheck(cilRoute); -// // 根据级别和模式控制信号显示 -// this.controlSignalAspectByLevel(rtSimulation, cilRoute, level); +// if (cilRoute.getOverlap() != null && !cilRoute.isOl()) { //进路延续保护没有锁闭 +// if (cilSignal.getSignalAspect() != CilSignal.GUIDE && !cilSignal.isLogic()) { //信号机是物理点灯且不是引导信号 +// cilSignalLogicService.try2UpdateSignalDisplay(rtSimulation, cilSignal, CilSignal.LEVEL_1, routeCtcMode); +// } +// } + } } -// private void lock(CilRepository cilRepository, CommonFls.FlsElement commonFlsElement) { -// if (this.pp != null) { -// CilSwitch cilSwitch = cilRepository.getSwitchById(pp.getCommonSwitch().getId()); -// if (pp.getPosition() == cilSwitch.getPosition()) { -// cilSwitch.flankLock(); -// } -// } -// if (this.pae != null) { -// CilSwitch cilSwitch = cilRepository.getSwitchById(pae.getCommonSwitch().getId()); -// if (pae.getPosition() == cilSwitch.getPosition()) { -// cilSwitch.flankLock(); -// } -// } -// } + /** + * 进路是否能通过联锁检查 + */ + private boolean isRoutePassInterlockingCheck(CilRepository cilRepository, CommonRoute commonRoute) { + TrackWay pathElement = commonRoute.getPathElement(); + List sectionList = pathElement.getSectionList(); + String routeId = commonRoute.getId(); + if (!CollectionUtils.isEmpty(sectionList)) { + for (CommonSection commonSection : sectionList) { + CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); + if (!cilSection.isRouteLockBy(routeId)) { + return false; + } + } + } + List spList = pathElement.getSpList(); + if (!CollectionUtils.isEmpty(spList)) { + for (SwitchPosition switchPosition : spList) { + CilSwitch cilSwitch = cilRepository.getSwitchById(switchPosition.getCommonSwitch().getId()); + if (!cilSwitch.isRouteLockOnPosition(routeId, switchPosition.getPosition())) { + return false; + } + } + } + return true; + } + + /** + * 侧防能否通过联锁检查 + */ + private boolean isFlsPassInterlockingCheck(CilRepository cilRepository, CommonRoute commonRoute) { + TrackWay pathElement = commonRoute.getPathElement(); + List flsList = pathElement.getFlsList(); + for (CommonFls commonFls : flsList) { + List flsElements = commonFls.getFirstLevelList(); + if (pathElement.isContainSwitchPosition(commonFls.getTarget().getCommonSwitch().getId(), commonFls.getTarget().isNormal())) { + for (CommonFls.FlsElement flsElement : flsElements) { + SwitchPosition pp = flsElement.getPp(); + if (pp != null) { + CilSwitch cilSwitch = cilRepository.getSwitchById(pp.getCommonSwitch().getId()); + if (!cilSwitch.isFlankLockOnPosition(pp.getPosition())) { + return false; + } + } + CommonSignal ps = flsElement.getPs(); + if (ps != null) { + CilSignal cilSignal = cilRepository.getSignalById(ps.getId()); + if (!cilSignal.isForbidAspect() || !cilSignal.isFl()) { + return false; + } + } + SwitchPosition pae = flsElement.getPae(); + if (pae != null) { + CilSwitch cilSwitch = cilRepository.getSwitchById(pae.getCommonSwitch().getId()); + if (!cilSwitch.isFlankLockOnPosition(pae.getPosition())) { + return false; + } + } + } + } + } + return true; + } + + public boolean isOverlapPassInterlockingCheck(CilRepository cilRepository, CommonRoute commonRoute, CilOverlap overlap) { + TrackWay path = overlap.getSelectedPath(); + List sectionList = path.getSectionList(); + if (!CollectionUtils.isEmpty(sectionList)) { + for (CommonSection commonSection : sectionList) { + CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); + if (!cilSection.isOl()) { + return false; + } + } + } + List spList = path.getSpList(); + if (!CollectionUtils.isEmpty(spList)) { + for (SwitchPosition switchPosition : spList) { + CilSwitch cilSwitch = cilRepository.getSwitchById(switchPosition.getCommonSwitch().getId()); + if (!cilSwitch.isOverlapLockOnPosition(switchPosition.getPosition())) { + return false; + } + } + } + return true; + } private boolean try2OverlapLockSwitches(CilRepository cilRepository, CilOverlap overlap, List switchPositionList) { boolean flag = true; @@ -380,7 +435,7 @@ public class CilRouteLogicService { cilSwitch.cancelRouteLock(); cilSwitch.cancelRouteUse(); } - for (CommonSection commonSection : pathElement.getSectionList()) { + for (CommonSection commonSection : pathElement.getAllSectionList()) { CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); cilSection.cancelRouteLock(); } @@ -393,7 +448,7 @@ public class CilRouteLogicService { // 进路内区段锁闭 TrackWay pathElement = commonRoute.getPathElement(); if (pathElement != null) { - routeLockSections(cilRepository, commonRoute, pathElement.getSectionList()); + routeLockSections(cilRepository, commonRoute); } // 延续保护区段锁闭 CommonOverlap commonOverlap = commonRoute.getOverlap(); @@ -406,22 +461,26 @@ public class CilRouteLogicService { } } - private void routeLockSections(CilRepository cilRepository, CommonRoute commonRoute, List sections) { - if (!CollectionUtils.isEmpty(sections)) { - for (CommonSection commonSection : sections) { + private void routeLockSections(CilRepository cilRepository, CommonRoute commonRoute) { + if (commonRoute.getPathElement() == null) + return; + List sections = commonRoute.getPathElement().getAllSectionList(); + if (CollectionUtils.isEmpty(sections)) + return; + + for (CommonSection commonSection : sections) { // CommonSwitch belongSwitch = commonSection.getBelongSwitch(); // if (belongSwitch != null) { // continue; // } - List relateList = commonSection.getRelateList(); - if (relateList.isEmpty()) { - CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); + List relateList = commonSection.getRelateList(); + if (relateList.isEmpty()) { + CilSection cilSection = cilRepository.getSectionById(commonSection.getId()); + cilSection.lockByRoute(commonRoute); + } else { + for (CommonSection section : relateList) { + CilSection cilSection = cilRepository.getSectionById(section.getId()); cilSection.lockByRoute(commonRoute); - } else { - for (CommonSection section : relateList) { - CilSection cilSection = cilRepository.getSectionById(section.getId()); - cilSection.lockByRoute(commonRoute); - } } } } @@ -435,233 +494,6 @@ public class CilRouteLogicService { return switchPositions.stream().allMatch(sp -> sp.getCilSwitch().getPosition() == sp.getPosition()); } -// private boolean checkSwitchOnPosition(CilRoute cilRoute) { -// boolean onPosition = true; -// // 检查进路内道岔 -// CilRoutePathElement pathElement = cilRoute.getPathElement(); -// List switchPositionList = pathElement.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// if (!cilSwitchPosition.isOnPosition()) { -// onPosition = false; -// break; -// } -// } -// if (!cilRoute.isPreparedForCtc()) { -// // 如果是为非CTC车准备的进路,还需检查延续保护 -// CilOverlap overlap = cilRoute.getOverlap(); -// CilRoutePathElement selectedPath = overlap.getSelectedPath(); -// List overlapSwitchPositionList = selectedPath.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : overlapSwitchPositionList) { -// if (!cilSwitchPosition.isOnPosition()) { -// onPosition = false; -// break; -// } -// } -// } -// return onPosition; -// } - -// private void controlSignalAspectByLevel(RtSimulation rtSimulation, CilRoute cilRoute, int level) { -// CilSignal start = cilRoute.getStart(); -// start.updateLevel(level); -// Integer aspect = null; -// switch (level) { -// case CilSignal.LEVEL_1: -// case CilSignal.LEVEL_2: { -// if (!cilRoute.isPreparedForCtc() || start.isForceLight()) { -// if (start.getSignalAspect() != CilSignal.RED) { -// aspect = SrSignal.RED; -// } -// } else { -// if (!start.isLogic()) { -// aspect = SrSignal.OFF; -// } else { -// start.setAspect(CilSignal.RED); -// } -// } -// break; -// } -// case CilSignal.LEVEL_3: { -// if (cilRoute.isPreparedForCtc()) { -// if (start.isForceLight()) { -// if (start.getSignalAspect() != cilRoute.getSignalAspect()) { -// aspect = cilRoute.getSignalAspect(); -// } -// } else { -// if (!start.isLogic()) { -// aspect = SrSignal.OFF; -// } else { -// start.setAspect(cilRoute.getSignalAspect()); -// } -// } -// } -// break; -// } -// case CilSignal.LEVEL_4: { -// if (!cilRoute.isPreparedForCtc() || start.isForceLight()) { -// if (start.getSignalAspect() != cilRoute.getSignalAspect()) { -// aspect = cilRoute.getSignalAspect(); -// } -// } else { -// if (!start.isLogic()) { -// aspect = SrSignal.OFF; -// } else { -// start.setAspect(cilRoute.getSignalAspect()); -// } -// } -// break; -// } -// } -// if (aspect != null) { -// this.srdApiService.changeSignalLight(rtSimulation, start.getId(), aspect); -// } -// } - -// private int levelCheck(CilRoute cilRoute) { -// int level = CilSignal.LEVEL_1; -// // 进路内道岔检查 -// CilRoutePathElement pathElement = cilRoute.getPathElement(); -// List switchPositionList = pathElement.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// if (!cilSwitchPosition.isOnPosition() || !cilSwitchPosition.getCilSwitch().isRl()) { -// return level; -// } -// } -// // 进路区段检查 -// List sectionList = pathElement.getSectionList(); -// for (CilSection section : sectionList) { -// if (!section.isRl()) { -// return level; -// } -// } -// // 进路内道岔到位,达到引导级别 -// level = CilSignal.LEVEL_2; -// // 进路侧防检查 -// List flsList = pathElement.getFlsList(); -// for (CilFls cilFls : flsList) { -// List firstLevelList = cilFls.getFirstLevelList(); -// for (CilFls.FlsElement flsElement : firstLevelList) { -// CilSwitchPosition pp = flsElement.getPp(); -// if (pp != null && !pp.isOnPosition()) { -// return level; -// } -// CilSwitchPosition pae = flsElement.getPae(); -// if (pae != null && !pae.isOnPosition()) { -// return level; -// } -// CilSignal ps = flsElement.getPs(); -// if (ps != null && !ps.isForbidAspect()) { -// return level; -// } -// } -// } -// // 进路侧防满足,达到移动闭塞信号级别 -// level = CilSignal.LEVEL_3; -// // 进路空闲情况,延续保护检查 -// -// return level; -// } - -// /** -// * 进路征用并转换道岔 -// * -// * @param rtSimulation -// * @param cilRoute -// * @return 是否所有道岔已经转换到位 -// */ -// private void turnSwitch(RtSimulation rtSimulation, CilRoute cilRoute) { -// // 进路内道岔 -// CilRoutePathElement pathElement = cilRoute.getPathElement(); -// List switchPositionList = pathElement.getSwitchPositionList(); -// boolean onPosition = true; -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// this.turnSwitch(rtSimulation, cilSwitchPosition); -// } -// // 进路侧防道岔 -// List flsList = pathElement.getFlsList(); -// for (CilFls cilFls : flsList) { -// List firstLevelList = cilFls.getFirstLevelList(); -// for (CilFls.FlsElement flsElement : firstLevelList) { -// CilSwitchPosition pp = flsElement.getPp(); -// if (pp != null) { -// this.turnSwitch(rtSimulation, pp); -// } -// CilSwitchPosition pae = flsElement.getPae(); -// if (pae != null) { -// this.turnSwitch(rtSimulation, pae); -// } -// } -// } -// // 延续保护道岔 -// // 延续保护侧防道岔 -// } - - // private void lockRouteDevices(CilRoute cilRoute) { -// CilRoutePathElement pathElement = cilRoute.getPathElement(); -// this.routeLockPathDevices(cilRoute, pathElement); -// // 延续保护锁闭 -// CilOverlap overlap = cilRoute.getOverlap(); -// if (overlap != null) { -// CilRoutePathElement selectedPath = overlap.getSelectedPath(); -// if (selectedPath != null) { -// this.overlapLockPathDevices(overlap, selectedPath); -// } -// } -// } - -// private void routeLockPathDevices(CilRoute cilRoute, CilRoutePathElement pathElement) { -// // 进路内道岔锁闭 -// List switchPositionList = pathElement.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch(); -// cilSwitch.getA().lockByRoute(cilRoute); -// if (cilSwitchPosition.isOnPosition()) { -// cilSwitch.lockByRoute(cilRoute); -// if (cilSwitch.isNormalPosition()) { -// cilSwitch.getB().lockByRoute(cilRoute); -// } else { -// cilSwitch.getC().lockByRoute(cilRoute); -// } -// } else { -// cilSwitch.getB().lockByRoute(cilRoute); -// cilSwitch.getC().lockByRoute(cilRoute); -// } -// } -// // 进路侧防道岔锁闭 -// List flsList = pathElement.getFlsList(); -// for (CilFls cilFls : flsList) { -// List firstLevelList = cilFls.getFirstLevelList(); -// for (CilFls.FlsElement flsElement : firstLevelList) { -// flsElement.lock(); -// } -// } -// // 进路内区段锁闭 -// routeLockSections(cilRoute, pathElement.getSectionList()); -// } - -// private void overlapLockPathDevices(CilOverlap overlap, CilRoutePathElement pathElement) { -// // 进路内道岔锁闭 -// List switchPositionList = pathElement.getSwitchPositionList(); -// for (CilSwitchPosition cilSwitchPosition : switchPositionList) { -// CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch(); -// cilSwitch.getA().lockByOverlap(overlap); -// if (cilSwitchPosition.isOnPosition()) { -// cilSwitch.lockByOverlap(overlap); -// if (cilSwitch.isNormalPosition()) { -// cilSwitch.getB().lockByOverlap(overlap); -// } else { -// cilSwitch.getC().lockByOverlap(overlap); -// } -// } else { -// cilSwitch.getB().lockByOverlap(overlap); -// cilSwitch.getC().lockByOverlap(overlap); -// } -// } -// // 进路内区段锁闭 -// List sectionList = pathElement.getSectionList(); -// overlapLockSections(overlap, sectionList); -// } - private void overlapLockSections(CilRepository cilRepository, boolean right, List sectionList) { for (CommonSection commonSection : sectionList) { CommonSwitch belongSwitch = commonSection.getBelongSwitch(); @@ -679,4 +511,16 @@ public class CilRouteLogicService { } } + private void delayUnlockingProgress(RtSimulation rtSimulation, CilRoute cilRoute, CilConfig config) { + CommonRepository commonRepository = rtSimulation.getRepository(CommonRepository.NAME, CommonRepository.class); + CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class); + CommonRoute commonRoute = commonRepository.getRouteById(cilRoute.getId()); + CilSignal cilSignal = cilRepository.getSignalById(commonRoute.getStart().getId()); + cilSignal.updateDelayTime(); + if (cilSignal.getDelayTime() == 0) { + cancelRoute(rtSimulation, cilRoute.getId()); //取消进路 + cilRoute.setDelayUnlocking(false); //取消进路的延时解锁状态 + } + } + } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSectionLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSectionLogicService.java new file mode 100644 index 000000000..c9b6f9757 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSectionLogicService.java @@ -0,0 +1,72 @@ +package club.joylink.rtss.simulation.rt.CIL; + +import club.joylink.rtss.simulation.rt.CIL.bo.CilRepository; +import club.joylink.rtss.simulation.rt.CIL.bo.CilSection; +import club.joylink.rtss.simulation.rt.RtSimulation; +import club.joylink.rtss.simulation.rt.repo.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +@Component +public class CilSectionLogicService { + + @Autowired + private CilSignalLogicService cilSignalLogicService; + + public void mainLogic(RtSimulation rtSimulation, CilRepository cilRepository) { + //延时解锁 + List sections = cilRepository.getDelayUnlockingSections(); + if (!CollectionUtils.isEmpty(sections)) { + sections.forEach(section -> delayUnlockingProgress(cilRepository, section)); + } + } + + public void sectionFaultUnlock(RtSimulation simulation, String id) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CommonRepository commonRepository = simulation.getRepository(CommonRepository.NAME, CommonRepository.class); + CilSection section = cilRepository.getSectionById(id); + /* 判断延时解锁 */ + if (section.isRl()) { //2021-04-26 09:22:55 后续需要补充延续保护解锁的逻辑 + String routeId = section.getRouteId(); + CommonRoute commonRoute = commonRepository.getRouteById(routeId); + CommonSignal commonStartSignal = commonRoute.getStart(); + if (cilSignalLogicService.isApproachOccupied(simulation, commonStartSignal.getId())) { //接近锁闭 + List routeSections = commonRoute.getPathElement().getAllSectionList(); + boolean completeLock = true; //进路区段完整锁闭 + boolean occupy = false; //进路区段有占用 + for (CommonSection routeSection : routeSections) { + CilSection cilSection = cilRepository.getSectionById(routeSection.getId()); + if (cilSection.isDelayUnlocking()) //有区段正在延时解锁的时候,区故解操作无效 + return; + if (!cilSection.isRouteLockBy(routeId)) { //区段未进路锁闭 + completeLock = false; + break; + } + if (cilSection.isAxcOccupy()) { + occupy = true; + } + } + if (completeLock && occupy) { + section.initDelayTime(); + cilRepository.addDelayUnlockingSections(section); + return; + } + } + } + //不延时,直接解锁 + section.cancelRouteLock(); + section.cancelOverlapLock(); + } + + public void delayUnlockingProgress(CilRepository cilRepository, CilSection cilSection) { + cilSection.updateDelayTime(); + if (cilSection.getDelayTime() == 0) { + cilRepository.removeDelayUnlockingSection(cilSection.getId()); + cilSection.cancelRouteLock(); + cilSection.cancelOverlapLock(); + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSignalLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSignalLogicService.java index 6dda203b0..28e38203d 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSignalLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSignalLogicService.java @@ -1,16 +1,19 @@ package club.joylink.rtss.simulation.rt.CIL; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.rt.CIL.bo.CilRepository; import club.joylink.rtss.simulation.rt.CIL.bo.CilRoute; import club.joylink.rtss.simulation.rt.CIL.bo.CilSignal; import club.joylink.rtss.simulation.rt.RtSimulation; import club.joylink.rtss.simulation.rt.SRD.SrdApiService; import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal; -import club.joylink.rtss.simulation.rt.repo.CommonRepository; +import club.joylink.rtss.simulation.rt.repo.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import java.util.List; import java.util.Optional; @Component @@ -19,22 +22,46 @@ public class CilSignalLogicService { @Autowired private SrdApiService srdApiService; - public void reopen(RtSimulation rtSimulation, String signalId) { -// CommonRepository commonRepository = null; // TODO: 2021/4/20 -// CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class); -// CilSignal signal = cilRepository.getSignalById(signalId); -// BusinessExceptionAssertEnum.OPERATION_REPEAT.assertEquals(CilSignal.RED, signal.getSignalAspect(), "信号已开,无需重开"); -// -// Optional routeOptional = cilRepository.getSupervisedRouteList().stream().filter(route -> signal.equals(route.getStart())).limit(1).findAny(); -// if (routeOptional.isEmpty()) { -// throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("无已排列进路,无法重开"); -// } else { -// CilRoute route = routeOptional.get(); -//// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(); -// } + @Autowired + private CilRouteLogicService cilRouteLogicService; + + /** + * 信号机接近区段占用 + */ + public boolean isApproachOccupied(RtSimulation simulation, String signalId) { + CommonRepository commonRepository = simulation.getRepository(CommonRepository.NAME, CommonRepository.class); + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CommonSignal commonSignal = commonRepository.getSignalById(signalId); + List approachList = commonSignal.getApproachList(); + if (!CollectionUtils.isEmpty(approachList)) { + for (TrackWay trackWay : approachList) { + List sectionList = trackWay.getSectionList(); + if (!CollectionUtils.isEmpty(sectionList)) { + for (CommonSection commonSection : sectionList) { + if (cilRepository.getSectionById(commonSection.getId()).isAxcOccupy()) { + return true; + } + } + } + } + } + return false; } - public void try2UpdateSignalDisplay(RtSimulation rtSimulation, CilSignal signal, int aspect, boolean ctcMode) { + public void reopen(RtSimulation rtSimulation, String signalId) { + CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class); + CommonRepository commonRepository = rtSimulation.getRepository(CommonRepository.NAME, CommonRepository.class); + CilSignal cilSignal = cilRepository.getSignalById(signalId); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(cilSignal.isForbidAspect(), + "信号未关闭,无需重开"); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertHasText(cilSignal.getLrId(), "无已办理的进路"); + CommonRoute commonRoute = commonRepository.getRouteById(cilSignal.getLrId()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(cilRouteLogicService.canOpenSignal(rtSimulation, commonRoute.getId()), + "联锁条件不满足,无法重开"); + UpdateSignalDisplay(rtSimulation, cilSignal, commonRoute.getSignalAspect(), false); + } + + public boolean try2UpdateSignalDisplay(RtSimulation rtSimulation, CilSignal signal, int aspect, boolean ctcMode) { // TODO: 2021/4/20 因信号机缺少表示虚拟信号机的字段,故缺少对虚拟信号机的检查 // boolean logic = !signal.isUta() && ctcMode && !signal.isForceLight(); // if (signal.sufficientLevel(aspect, logic)) { @@ -47,20 +74,22 @@ public class CilSignalLogicService { if (signal.sufficientLevel(aspect, false)) { srdApiService.changeSignalLight(rtSimulation, signal.getId(), aspect); } + return true; } public void UpdateSignalDisplay(RtSimulation rtSimulation, CilSignal signal, int aspect, boolean ctcMode) { - // TODO: 2021/4/20 因信号机缺少表示虚拟信号机的字段,故缺少对虚拟信号机的检查 -// boolean logic = !signal.isUta() && ctcMode && !signal.isForceLight(); -// if (signal.sufficientLevel(aspect, logic)) { -// if (logic) { -// signal.setAspect(aspect); -// } else { -// srdApiService.changeSignalLight(rtSimulation, signal.getId(), aspect); -// } -// } - if (signal.sufficientLevel(aspect, false)) { - srdApiService.changeSignalLight(rtSimulation, signal.getId(), aspect); - } + BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(try2UpdateSignalDisplay(rtSimulation, signal, aspect, ctcMode)); + } + + public void blockadeSignal(RtSimulation simulation, String signalId) { + CilRepository repository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSignal signal = repository.getSignalById(signalId); + signal.setBl(true); + } + + public void unblockSignal(RtSimulation simulation, String signalId) { + CilRepository repository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSignal signal = repository.getSignalById(signalId); + signal.setBl(false); } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSwitchLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSwitchLogicService.java index 8f1d9874e..6e3e83697 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSwitchLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilSwitchLogicService.java @@ -59,4 +59,29 @@ public class CilSwitchLogicService { } } } + + public void blockadeSwitch(RtSimulation simulation, String id) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSwitch cilSwitch = cilRepository.getSwitchById(id); + cilSwitch.setBl(true); + } + + public void unblockSwitch(RtSimulation simulation, String id) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSwitch cilSwitch = cilRepository.getSwitchById(id); + cilSwitch.setBl(false); + } + + public void singleLockSwitch(RtSimulation simulation, String id) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSwitch cilSwitch = cilRepository.getSwitchById(id); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(cilSwitch.isLost(), "道岔失表,无法单锁"); + cilSwitch.setSl(true); + } + + public void singleUnlockSwitch(RtSimulation simulation, String id) { + CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class); + CilSwitch cilSwitch = cilRepository.getSwitchById(id); + cilSwitch.setSl(false); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java index cff511545..8157ca787 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java @@ -15,6 +15,7 @@ public class CilRepository extends SimulationRepository { CilConfig config; Map sectionMap; + Map delayUnlockingSectionMap; // 延时解锁区段 Map switchMap; Map signalMap; Map standMap; @@ -33,6 +34,7 @@ public class CilRepository extends SimulationRepository { public CilRepository() { super(NAME); this.sectionMap = new HashMap<>(); + this.delayUnlockingSectionMap = new HashMap<>(); this.switchMap = new HashMap<>(); this.signalMap = new HashMap<>(); this.standMap = new HashMap<>(); @@ -120,4 +122,16 @@ public class CilRepository extends SimulationRepository { public CilRoute removeSupervisedRoute(String routeId) { return this.supervisedRouteMap.remove(routeId); } + + public void addDelayUnlockingSections(CilSection cilSection) { + this.delayUnlockingSectionMap.put(cilSection.getId(), cilSection); + } + + public List getDelayUnlockingSections() { + return new ArrayList<>(this.delayUnlockingSectionMap.values()); + } + + public CilSection removeDelayUnlockingSection(String sectionId) { + return this.delayUnlockingSectionMap.remove(sectionId); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java index 61b8df6a5..1bad8a9cf 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java @@ -56,6 +56,8 @@ public class CilRoute extends CilDevice { private boolean canAutoOpen = true; // 是否可以自动开放信号(初始应该为true,进路办理完毕,开放信号之后为false,代表不能自动重开信号) @Setter private boolean trainIn; //列车进入进路 + @Setter + private boolean delayUnlocking; //延时解锁中 diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java index 8e640ddfb..be8390c15 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java @@ -1,9 +1,10 @@ package club.joylink.rtss.simulation.rt.CIL.bo; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.rt.CIL.CilLogicService; import club.joylink.rtss.simulation.rt.repo.CommonRoute; -import club.joylink.rtss.simulation.rt.repo.CommonSection; import lombok.Getter; +import lombok.NonNull; import java.util.ArrayList; import java.util.List; @@ -11,6 +12,7 @@ import java.util.Objects; @Getter public class CilSection extends CilDevice { + public static final int DEFAULT_DELAY_TIME = 30 * 1000; CilSection parent; List relateList = new ArrayList<>(); // 关联的子区段,顺序 @@ -22,6 +24,7 @@ public class CilSection extends CilDevice { boolean rl; // 进路锁闭 boolean lr; // 进路锁闭方向,true-右向,false-左向 boolean ol; // 延续保护锁闭 + int delayTime; //延时解锁时间/ms public CilSection(String id, String name) { super(id, name); @@ -46,6 +49,7 @@ public class CilSection extends CilDevice { public void cancelRouteLock() { this.rl = false; + this.routeId = null; } public void lockByOverlap(boolean right) { @@ -61,4 +65,20 @@ public class CilSection extends CilDevice { public void cancelOverlapLock() { this.ol = false; } + + public boolean isRouteLockBy(@NonNull String routeId) { + return rl && routeId.equals(this.routeId); + } + + public void initDelayTime() { + this.delayTime = DEFAULT_DELAY_TIME; + } + + public void updateDelayTime() { + this.delayTime = Math.max(delayTime - CilLogicService.CilMainLogicRate, 0); + } + + public boolean isDelayUnlocking() { + return this.delayTime != 0; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java index 2e8ee853c..3416aa043 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java @@ -1,6 +1,7 @@ package club.joylink.rtss.simulation.rt.CIL.bo; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.rt.CIL.CilLogicService; import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal; import lombok.Getter; import lombok.Setter; @@ -9,6 +10,7 @@ import java.util.List; @Getter public class CilSignal extends CilDevice { + public static final int DEFAULT_DELAY_TIME = 30 * 1000; boolean right; List approachList; @@ -29,6 +31,7 @@ public class CilSignal extends CilDevice { public static final int HS = 12; // 红闪 boolean logic; boolean forceLight; // 强制点灯 + @Setter boolean bl; // 封锁 boolean rbl; // 重复封锁 @@ -40,9 +43,10 @@ public class CilSignal extends CilDevice { public static final int LEVEL_3 = 3; //ATP级 public static final int LEVEL_4 = 4; //主信号级 - boolean fl; //侧防锁闭(侧防锁闭后不能排列任何以此为始端信号机的进路) + boolean fl; //侧防锁闭(侧防锁闭后信号机不能开放) @Setter String lrId; //锁闭进路的id + int delayTime; //信号机延时解锁倒计时/ms public CilSignal(String id, String name) { super(id, name); @@ -90,6 +94,12 @@ public class CilSignal extends CilDevice { // default: // throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception(String.format("未知的显示状态[%s]", aspect)); // } + if (aspect == RED) { + return true; + } + if (aspect == GUIDE) { + return level == LEVEL_2 || level == LEVEL_3 || level == LEVEL_4; + } return level == LEVEL_4; } @@ -100,4 +110,12 @@ public class CilSignal extends CilDevice { public void cancelFlankLock() { this.fl = false; } + + public void initDelayTime() { + this.delayTime = DEFAULT_DELAY_TIME; + } + + public void updateDelayTime() { + this.delayTime = Math.max(this.delayTime - CilLogicService.CilMainLogicRate, 0); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java index 3a08b9fbe..fed0a8dbf 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java @@ -2,6 +2,8 @@ package club.joylink.rtss.simulation.rt.CIL.bo; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; import java.util.Objects; @@ -20,7 +22,9 @@ public class CilSwitch extends CilDevice { int routeUseToPosition; // 进路征用到位置, 0 为未征用 + @Setter boolean bl; // 封锁 + @Setter boolean sl; // 单锁 String routeId; // 锁闭进路的id boolean rl; // 进路锁闭 @@ -43,6 +47,10 @@ public class CilSwitch extends CilDevice { return REVERSE == this.position; } + public boolean isLost() { + return LOST == this.position; + } + public void setSections(CilSection a, CilSection b, CilSection c) { this.a = a; this.b = b; @@ -74,6 +82,7 @@ public class CilSwitch extends CilDevice { public void cancelRouteLock() { this.rl = false; + this.routeId = null; } public void lockByOverlap(CilOverlap overlap) { @@ -99,4 +108,16 @@ public class CilSwitch extends CilDevice { public boolean isLocked() { return sl || rl || ol || fl; } + + public boolean isRouteLockOnPosition(@NonNull String routeId, int position) { + return rl && routeId.equals(this.routeId) && position == this.position; + } + + public boolean isFlankLockOnPosition(int position) { + return fl && position == this.position; + } + + public boolean isOverlapLockOnPosition(int position) { + return ol && position == this.position; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java index d0a485c37..cf716f523 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java @@ -71,30 +71,31 @@ public class SrdApiService { LocalDateTime systemTime = rtSimulation.getSystemTime(); if (aspect >= 5 && aspect <= 12) { //2021-04-23 10:41:52 临时 srSignal.open(systemTime, aspect); - } - switch (aspect) { - case SrSignal.OFF:{ - srSignal.close(systemTime); - break; + } else { + switch (aspect) { + case SrSignal.OFF:{ + srSignal.close(systemTime); + break; + } + case SrSignal.RED:{ + srSignal.openRed(systemTime); + break; + } + case SrSignal.GREEN:{ + srSignal.openGreen(systemTime); + break; + } + case SrSignal.YELLOW: { + srSignal.openYellow(systemTime); + break; + } + case SrSignal.GUIDE: { + srSignal.openGuide(systemTime); + break; + } + default: + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("无效的信号机显示:[%s]", aspect)); } - case SrSignal.RED:{ - srSignal.openRed(systemTime); - break; - } - case SrSignal.GREEN:{ - srSignal.openGreen(systemTime); - break; - } - case SrSignal.YELLOW: { - srSignal.openYellow(systemTime); - break; - } - case SrSignal.GUIDE: { - srSignal.openGuide(systemTime); - break; - } - default: - throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("无效的信号机显示:[%s]", aspect)); } change = true; } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/operation/SectionOperationHandler.java b/src/main/java/club/joylink/rtss/simulation/rt/operation/SectionOperationHandler.java new file mode 100644 index 000000000..bbe9f9cfc --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/operation/SectionOperationHandler.java @@ -0,0 +1,21 @@ +package club.joylink.rtss.simulation.rt.operation; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; +import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.operation.SimulationOperationController; +import club.joylink.rtss.simulation.operation.SimulationOperationMapping; +import club.joylink.rtss.simulation.rt.CIL.CilApiService; +import club.joylink.rtss.simulation.rt.RtSimulation; +import org.springframework.beans.factory.annotation.Autowired; + +@SimulationOperationController() +public class SectionOperationHandler { + @Autowired + private CilApiService cilApiService; + + @SimulationOperationMapping("Section_Fault_Unlock") + public void sectionFaultUnlock(RtSimulation simulation, String id) { + this.cilApiService.sectionFaultUnlock(simulation, id); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/operation/SignalOperationHandler.java b/src/main/java/club/joylink/rtss/simulation/rt/operation/SignalOperationHandler.java index e77781d50..3ae43e2d3 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/operation/SignalOperationHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/operation/SignalOperationHandler.java @@ -3,29 +3,52 @@ package club.joylink.rtss.simulation.rt.operation; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.Route; import club.joylink.rtss.simulation.operation.SimulationOperationController; import club.joylink.rtss.simulation.operation.SimulationOperationMapping; import club.joylink.rtss.simulation.rt.CIL.CilApiService; import club.joylink.rtss.simulation.rt.RtSimulation; import org.springframework.beans.factory.annotation.Autowired; +import java.util.Objects; + @SimulationOperationController() public class SignalOperationHandler { @Autowired private CilApiService cilApiService; @SimulationOperationMapping("Signal_Set_Route") - public boolean setRoute(RtSimulation simulation, String id) { - return this.cilApiService.setRoute(simulation, id); + public boolean setRoute(RtSimulation simulation, String routeId) { + return this.cilApiService.setRoute(simulation, routeId); } @SimulationOperationMapping("Signal_Cancel_Route") - public boolean cancelRoute(RtSimulation simulation, String id) { - return this.cilApiService.cancelRoute(simulation, id); + public boolean cancelRoute(RtSimulation simulation, String signalId) { + return this.cilApiService.cancelRoute(simulation, signalId); + } + + @SimulationOperationMapping("Signal_Human_Release_Route") + public void humanCancel(RtSimulation simulation, String signalId) { + this.cilApiService.humanCancel(simulation, signalId); + } + + @SimulationOperationMapping("Signal_Reopen_Signal") + public void reopenSignal(RtSimulation simulation, String signalId) { + this.cilApiService.signalReopen(simulation, signalId); } @SimulationOperationMapping("Signal_Set_Guide") public boolean setGuide(RtSimulation simulation, String signalId, String routeId) { return this.cilApiService.setGuide(simulation, signalId, routeId); } + + @SimulationOperationMapping("Signal_Block") + public void block(RtSimulation simulation, String signalId) { + this.cilApiService.blockadeSignal(simulation, signalId); + } + + @SimulationOperationMapping("Signal_Unblock") + public void unblock(RtSimulation simulation, String signalId) { + this.cilApiService.unblockSignal(simulation, signalId); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/operation/SwitchOperationHandler.java b/src/main/java/club/joylink/rtss/simulation/rt/operation/SwitchOperationHandler.java index 61d3b0625..a0078f9a0 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/operation/SwitchOperationHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/operation/SwitchOperationHandler.java @@ -1,11 +1,18 @@ package club.joylink.rtss.simulation.rt.operation; +import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; +import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; +import club.joylink.rtss.simulation.cbtc.data.map.Switch; import club.joylink.rtss.simulation.operation.SimulationOperationController; import club.joylink.rtss.simulation.operation.SimulationOperationMapping; import club.joylink.rtss.simulation.rt.CIL.CilApiService; import club.joylink.rtss.simulation.rt.RtSimulation; import org.springframework.beans.factory.annotation.Autowired; +import java.util.Objects; + @SimulationOperationController() public class SwitchOperationHandler { @Autowired @@ -26,4 +33,26 @@ public class SwitchOperationHandler { this.cilApiService.turnSwitchToReverse(simulation, id); } + @SimulationOperationMapping("Switch_Single_Lock") + public void singleLockSwitch(RtSimulation simulation, String id) { + this.cilApiService.singleLockSwitch(simulation, id); + } + + @SimulationOperationMapping("Switch_Single_Unlock") + public void singleUnlockSwitch(RtSimulation simulation, String id) { + this.cilApiService.singleUnlockSwitch(simulation, id); + } + + /**道岔封锁l*/ + @SimulationOperationMapping("Switch_Block") + public void blockadeSwitch(RtSimulation simulation, String id) { + this.cilApiService.blockadeSwitch(simulation, id); + } + + /**道岔解锁l*/ + @SimulationOperationMapping("Switch_Unblock") + public void unblockSwitch(RtSimulation simulation, String id) { + this.cilApiService.unblockSwitch(simulation, id); + } + }