diff --git a/src/main/java/club/joylink/rtss/services/script/ScriptSimulationService.java b/src/main/java/club/joylink/rtss/services/script/ScriptSimulationService.java index e46c96a6d..2ae9118d2 100644 --- a/src/main/java/club/joylink/rtss/services/script/ScriptSimulationService.java +++ b/src/main/java/club/joylink/rtss/services/script/ScriptSimulationService.java @@ -261,7 +261,7 @@ public class ScriptSimulationService implements IScriptSimulationService { Simulation simulation = groupSimulationCache.getSimulationByGroup(group); SimulationMember member = simulation.getSimulationMemberByUserId(user.getId()); if (!SimulationMember.Type.DRIVER.equals(member.getType())) { - throw new SimulationException(SimulationExceptionType.Invalid_Operation, "非司机角色不能点击托管"); + throw new SimulationException(SimulationExceptionType.Invalid_Operation, "非司机角色不能使用"); } VirtualRealityTrain train = (VirtualRealityTrain) member.getDevice(); SectionPosition targetPosition = CalculateService.calculatePositionOfNextStopPoint(train); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SignalOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SignalOperateHandler.java index d4e22c8b8..f8f719191 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SignalOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SignalOperateHandler.java @@ -223,8 +223,8 @@ public class SignalOperateHandler { * @param signalCode */ @OperateHandlerMapping(type = Operation.Type.Signal_Set_CI_Auto_Trigger) - public void setCiAutoTrigger(Simulation simulation, String signalCode) { - atsRouteService.setCiAutoTrigger(simulation, signalCode); + public void setCiAutoTrigger(Simulation simulation, String signalCode, List routeCodeList) { + atsRouteService.setCiAutoTrigger(simulation, signalCode, routeCodeList); } /** @@ -234,8 +234,8 @@ public class SignalOperateHandler { * @param signalCode */ @OperateHandlerMapping(type = Operation.Type.Signal_Cancel_CI_Auto_Trigger) - public void cancelCiAutoTrigger(Simulation simulation, String signalCode) { - atsRouteService.cancelCiAutoTrigger(simulation, signalCode); + public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List routeCodeList) { + atsRouteService.cancelCiAutoTrigger(simulation, signalCode, routeCodeList); } // /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java index 64e259680..d1343cf12 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java @@ -62,16 +62,7 @@ public class StationOperateHandler { */ @OperateHandlerMapping(type = Operation.Type.Station_Open_Auto_Setting) public void openAutoSetting(Simulation simulation, String stationCode) { - SimulationDataRepository repository = simulation.getRepository(); - Station station = repository.getByCode(stationCode, Station.class); - List routeList = repository.getRouteList(); - for (Route route : routeList) { - if (Objects.equals(route.getInterlockStation(), station)) { - if (!route.isAtsControl()) { - route.setAtsControl(true); - } - } - } + this.atsStationService.openAutoSetting(simulation, stationCode); } /** @@ -79,16 +70,7 @@ public class StationOperateHandler { */ @OperateHandlerMapping(type = Operation.Type.Station_Close_Auto_Setting) public void closeAutoSetting(Simulation simulation, String stationCode) { - SimulationDataRepository repository = simulation.getRepository(); - Station station = repository.getByCode(stationCode, Station.class); - List routeList = repository.getRouteList(); - for (Route route : routeList) { - if (Objects.equals(route.getInterlockStation(), station)) { - if (route.isAtsControl()) { - route.setAtsControl(false); - } - } - } + this.atsStationService.closeAutoSetting(simulation, stationCode); } /** @@ -193,7 +175,12 @@ public class StationOperateHandler { @OperateHandlerMapping(type = Operation.Type.Station_CIArea_Close_AllSignal) public void closeCIAreaAllSignal(Simulation simulation, String stationCode){ SimulationDataRepository repository = simulation.getRepository(); - repository.getSignalList().stream().filter(s -> Objects.equals(stationCode,s.getInterlockStation().getCode())).forEach(signal -> ciApiService.blockadeSignal(simulation, signal.getCode())); + repository.getSignalList().stream() + .filter(s -> Objects.equals(stationCode,s.getInterlockStation().getCode())) + .forEach(signal -> { + ciApiService.blockadeSignal(simulation, signal.getCode()); + ciApiService.closeSignal(simulation, signal.getCode()); + }); } /**交出控制权/下放站控*/ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteService.java index fd5daeb39..a08fce7b9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteService.java @@ -71,11 +71,13 @@ public class AtsRouteService { } List routes = routeCodeList.stream().map(routeCode -> repository.getByCode(routeCode, Route.class)).collect(Collectors.toList()); if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { - Signal start = routes.get(0).getStart(); - String startSignalCode = start.getCode(); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(routes.stream().allMatch(route -> route.getStart().getCode().equals(startSignalCode)), - "所选进路的始端信号机不同,处理逻辑未知"); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(start.isHumanControl(), String.format("信号机[%s]需处于人工控状态", start.getCode())); + routes.stream() + .map(Route::getStart) + .distinct() + .forEach(signal -> + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertNotTrue(signal.isCiControl(), + String.format("信号机[%s]需处于人工控状态", signal.getCode()))); } if (CollectionUtils.isEmpty(checkConflictList)) { routes.forEach(route -> route.setAtsControl(true)); @@ -90,7 +92,7 @@ public class AtsRouteService { } else if (StringUtils.hasText(signalCode)) { Signal signal = repository.getByCode(signalCode, Signal.class); if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isHumanControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode())); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode())); } List routeList = signal.getRouteList(); if (!CollectionUtils.isEmpty(routeList)) { @@ -172,21 +174,38 @@ public class AtsRouteService { /** * 设置联锁自动触发 */ - public void setCiAutoTrigger(Simulation simulation, String signalCode) { - Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); - if (simulation.getRepository().getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isHumanControl(), String.format("信号机[%s]需处于人工控", signal.getCode())); + public void setCiAutoTrigger(Simulation simulation, String signalCode, List routeCodeList) { + SimulationDataRepository repository = simulation.getRepository(); + List routeList; + if (StringUtils.hasText(signalCode)) { + Signal signal = repository.getByCode(signalCode, Signal.class); + if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode())); + } + routeList = signal.getRouteList(); + } else { + routeList = routeCodeList.stream() + .map(code -> repository.getByCode(code, Route.class)) + .collect(Collectors.toList()); + if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { + routeList.stream() + .map(Route::getStart) + .distinct() + .forEach(signal -> + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertNotTrue(signal.isAtsControl(), + String.format("信号机[%s]需处于人工控", signal.getCode()))); + } } - List routeList = signal.getRouteList(); if (!CollectionUtils.isEmpty(routeList)) { routeList.stream().filter(Route::isArs).forEach(route -> { if (route.isFleetMode()) { throw new SimulationException(SimulationExceptionType.Operation_Conflict, String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode())); } - if (route.isCiControl()) { - throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode())); - } +// if (route.isCiControl()) { +// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode())); +// } }); for (Route route : routeList) { // route.setAtsControl(false); @@ -199,9 +218,17 @@ public class AtsRouteService { /** * 取消联锁自动触发 */ - public void cancelCiAutoTrigger(Simulation simulation, String signalCode) { - Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); - List routeList = signal.getRouteList(); + public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List routeCodes) { + List routeList; + SimulationDataRepository repository = simulation.getRepository(); + if (StringUtils.hasText(signalCode)) { + Signal signal = repository.getByCode(signalCode, Signal.class); + routeList = signal.getRouteList(); + } else { + routeList = routeCodes.stream() + .map(code -> repository.getByCode(code, Route.class)) + .collect(Collectors.toList()); + } if (!CollectionUtils.isEmpty(routeList)) { for (Route route : routeList) { if (route.isCiControl()) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java index 4c4230df4..b93f4f0e7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java @@ -7,10 +7,7 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.command.OperationMessage; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; -import club.joylink.rtss.simulation.cbtc.data.map.Route; -import club.joylink.rtss.simulation.cbtc.data.map.Signal; -import club.joylink.rtss.simulation.cbtc.data.map.Station; -import club.joylink.rtss.simulation.cbtc.data.map.Switch; +import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.status.StationStatus; import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption; import club.joylink.rtss.simulation.cbtc.data.vo.ControlTransferReplyVO; @@ -284,6 +281,13 @@ public class AtsStationService { } else { deviceStation = station.getDeviceStation(); } + List dispatchers = simulation.querySimulationMembersOfRole(SimulationMember.Type.DISPATCHER); + if (!CollectionUtils.isEmpty(dispatchers)) { + boolean allDispatchersAreRobots = dispatchers.stream().allMatch(SimulationMember::isRobot); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertTrue(allDispatchersAreRobots, + String.format("车站[%s]控制权未交出", deviceStation.debugStr())); + } SimulationDataRepository repository = simulation.getRepository(); Set stations = repository.getStationsByDeviceStations(deviceStation); if (member.isDispatcher()) { @@ -298,19 +302,14 @@ public class AtsStationService { Station station = repository.getByCode(stationCode, Station.class); if (!station.isInterlock()) { throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("车站不是联锁站")); + "车站不是联锁站"); } List routeList = repository.getRouteList(); - for (Route route : routeList) { - if (Objects.equals(route.getInterlockStation(), station)) { - route.setAtsControl(false); - if (!route.isArs() || route.isFleetMode() || route.isCiControl()) { - continue; - } - route.setFleetMode(false); - route.setCiControl(true); - } - } + List routeCodes = routeList.stream() + .filter(route -> Objects.equals(route.getInterlockStation(), station)) + .map(MapElement::getCode) + .collect(Collectors.toList()); + atsRouteService.setCiAutoTrigger(simulation, null, routeCodes); } public void cancelCiAutoTrigger(Simulation simulation, String stationCode) { @@ -318,14 +317,14 @@ public class AtsStationService { Station station = repository.getByCode(stationCode, Station.class); if (!station.isInterlock()) { throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("车站不是联锁站")); + "车站不是联锁站"); } List routeList = repository.getRouteList(); - for (Route route : routeList) { - if (Objects.equals(route.getInterlockStation(), station)) { - route.setCiControl(false); - } - } + List routeCodes = routeList.stream() + .filter(route -> Objects.equals(route.getInterlockStation(), station)) + .map(MapElement::getCode) + .collect(Collectors.toList()); + atsRouteService.cancelCiAutoTrigger(simulation, null, routeCodes); } /** @@ -505,4 +504,26 @@ public class AtsStationService { station.setRestartTime(LocalTime.now()); Station.Fault.INTERLOCK_MACHINE_FAULT.fix(station); } + + public void openAutoSetting(Simulation simulation, String stationCode) { + SimulationDataRepository repository = simulation.getRepository(); + Station station = repository.getByCode(stationCode, Station.class); + List routeList = repository.getRouteList(); + List routeCodes = routeList.stream() + .filter(route -> Objects.equals(route.getInterlockStation(), station)) + .map(MapElement::getCode) + .collect(Collectors.toList()); + atsRouteService.setRouteAtsControl(simulation, null, routeCodes, null); + } + + public void closeAutoSetting(Simulation simulation, String stationCode) { + SimulationDataRepository repository = simulation.getRepository(); + Station station = repository.getByCode(stationCode, Station.class); + List routeList = repository.getRouteList(); + List routeCodes = routeList.stream() + .filter(route -> Objects.equals(route.getInterlockStation(), station)) + .map(MapElement::getCode) + .collect(Collectors.toList()); + atsRouteService.setRouteHumanControl(simulation, null, routeCodes); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java index 07621b1fe..91e2740bc 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java @@ -248,10 +248,20 @@ public class CiApiServiceImpl implements CiApiService { // section.debugStr() + "未锁闭,无需解锁"); List lockedRouteList = simulation.getRepository().queryAllLockedRoute(); Route lockedRoute = null; - for (Route route : lockedRouteList) { - if (route.containSection(section)) { - lockedRoute = route; - break; + if (section.isRouteLock()) { + lockedRoute = section.getRoute(); +// for (Route route : lockedRouteList) { +// if (route.containSection(section)) { +// lockedRoute = route; +// break; +// } +// } + } else if (section.isOverlapLock()) { + for (Route route : lockedRouteList) { + if (route.overlapContainSection(section)) { + lockedRoute = route; + break; + } } } this.sectionService.sectionFaultUnlock(simulation, section, lockedRoute); @@ -260,12 +270,24 @@ public class CiApiServiceImpl implements CiApiService { @Override public void switchSectionFaultUnlock(Simulation simulation, String switchCode) { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); + if (!aSwitch.isLocked()) + return; List lockedRouteList = simulation.getRepository().queryAllLockedRoute(); Route lockedRoute = null; - for (Route route : lockedRouteList) { - if (route.isRouteSwitch(aSwitch)) { - lockedRoute = route; - break; + if (aSwitch.isRouteLock()) { + lockedRoute = aSwitch.getRoute(); +// for (Route route : lockedRouteList) { +// if (route.isRouteSwitch(aSwitch)) { +// lockedRoute = route; +// break; +// } +// } + } else if (aSwitch.isOverlapLock()) { + for (Route route : lockedRouteList) { + if (route.overlapContainSwitch(aSwitch)) { + lockedRoute = route; + break; + } } } this.switchService.switchFaultUnlock(simulation, aSwitch, lockedRoute); 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 b9f81f3e9..24f8a947f 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 @@ -1287,10 +1287,7 @@ public class RouteService { } relSwitch.routeUnlock(); // 侧防解锁 - RouteFls routeFls = route.getRouteFlsOfSwitch(relSwitch); - if (routeFls != null && !routeFls.getBase().getASwitch().isRouteLock() && !routeFls.getBase().getASwitch().isOverlapLock()) { - routeFls.unlock(); - } + route.unlockRouteFlsOfSwitch(relSwitch); //检查道岔的联动道岔和计轴关联道岔是否可以解锁 for (SwitchElement switchElement : route.getSwitchList()) { if (switchElement.getASwitch().equals(relSwitch)) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java index aef63f836..ab630f882 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java @@ -1,6 +1,7 @@ package club.joylink.rtss.simulation.cbtc.CI.service; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.data.map.Route; import club.joylink.rtss.simulation.cbtc.data.map.Section; @@ -8,6 +9,7 @@ import club.joylink.rtss.simulation.cbtc.data.map.Signal; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; import org.springframework.util.CollectionUtils; import java.util.List; @@ -22,6 +24,8 @@ public class SectionService { @Autowired private SignalService signalService; + @Autowired + private RouteService routeService; /** * 封锁(封锁后,包含区段的进路不能排列) @@ -59,11 +63,12 @@ public class SectionService { if (route.isOpen()) { signalService.close(simulation, route.getStart()); } - if (route.isApproachLock()) { + if (routeService.isApproachLock(simulation.getRepository(), route) || section.isOverlapLock()) { // 区段延时解锁 - section.setDelayTime(route.getDelayReleaseTime() * 1000); + int delayTime = route.getDelayReleaseTime() * 1000; + section.delayUnlock(delayTime); if (section.isShowLogic()) { - section.getLogicList().forEach(ls -> ls.setDelayTime(route.getDelayReleaseTime() * 1000)); + section.getLogicList().forEach(ls -> ls.delayUnlock(delayTime)); } return; } else { @@ -89,7 +94,7 @@ public class SectionService { public void delayUnlock(Simulation simulation, Section section) { int remainTime = section.getDelayTime(); if (remainTime > 0) { - remainTime -= SimulationModule.CI.getRateS(); + remainTime -= SimulationConstants.CI_LOOP_RATE; if (remainTime <= 0) { List routeList = simulation.getRepository().queryAllLockedRoute(); Route lockedRoute = null; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java index 0394700ef..8ecd0b884 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java @@ -3,11 +3,9 @@ package club.joylink.rtss.simulation.cbtc.CI.service; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.communication.vo.ControllableDevice; import club.joylink.rtss.simulation.cbtc.communication.vo.SwitchTurn; +import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; -import club.joylink.rtss.simulation.cbtc.data.map.Route; -import club.joylink.rtss.simulation.cbtc.data.map.Signal; -import club.joylink.rtss.simulation.cbtc.data.map.Switch; -import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement; +import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; import club.joylink.rtss.simulation.cbtc.event.RouteModeChangeEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationDeviceControlEvent; @@ -36,6 +34,12 @@ public class SwitchService { @Autowired private SignalService signalService; + @Autowired + private RouteService routeService; + + @Autowired + private SectionService sectionService; + /** * 控制室外道岔转动(道岔转动指令下达) * @param simulation @@ -151,32 +155,54 @@ public class SwitchService { if (route.isOpen()) { signalService.close(simulation, route.getStart()); } - if (route.isApproachLock()) { - // 区段延时解锁 + if (routeService.isApproachLock(simulation.getRepository(), route) || aSwitch.isOverlapLock()) { + // 延时解锁 aSwitch.setDelayTime(route.getDelayReleaseTime() * 1000); + aSwitch.getAllSections().forEach(section -> { + if (section.isLocked()) + sectionService.sectionFaultUnlock(simulation, section, route); + }); return; } else { - Signal start = route.getStart(); route.setLock(false); + Signal start = route.getStart(); if (start.getLockedRoute() == route) { start.setLockedRoute(null); } } } + this.faultUnlock(aSwitch, route); + } + + public void faultUnlock(Switch aSwitch, Route route) { + aSwitch.faultUnlock(); aSwitch.sectionFaultUnlock(); + if (route != null) { + route.unlockRouteFlsOfSwitch(aSwitch); //进路中该道岔对应的侧防解除锁闭 + RouteOverlap overlap = route.getOverlap(); + if (overlap != null) { + for (SectionPath sectionPath : overlap.getPathList()) { + overlap.unlockFlsOfSwitch(sectionPath.getFlsList(), aSwitch); //延续保护中该道岔的侧防解除锁闭 + } + } + } } public void delayUnlock(Simulation simulation, Switch aSwitch) { int remainTime = aSwitch.getDelayTime(); if (remainTime > 0) { - remainTime -= SimulationModule.CI.getRateMs(); + remainTime -= SimulationConstants.CI_LOOP_RATE; if (remainTime <= 0) { List routeList = simulation.getRepository().queryAllLockedRoute(); Route lockedRoute = null; - for (Route route : routeList) { - if (route.isRouteSwitch(aSwitch)) { - lockedRoute = route; - break; + if (aSwitch.isRouteLock()) { + lockedRoute = aSwitch.getRoute(); + } else { + for (Route route : routeList) { + if (route.overlapContainSwitch(aSwitch)) { + lockedRoute = route; + break; + } } } if (Objects.nonNull(lockedRoute)) { @@ -186,7 +212,7 @@ public class SwitchService { start.setLockedRoute(null); } } - aSwitch.sectionFaultUnlock(); + this.faultUnlock(aSwitch, lockedRoute); aSwitch.setDelayTime(0); } else { aSwitch.setDelayTime(remainTime); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/UserConfigDataBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/UserConfigDataBuilder.java index dadc8e8bb..8ab0f91ca 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/UserConfigDataBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/UserConfigDataBuilder.java @@ -28,6 +28,9 @@ public class UserConfigDataBuilder { Function.identity())); } List runLevelList = map.getLogicDataNew().getRunLevelList(); + if (CollectionUtils.isEmpty(runLevelList)) { + errMsgList.add("无默认运行等级数据"); + } for (MapStationRunLevelVO vo : runLevelList) { String key = StationRunLevel.buildKey(vo.getStartSectionCode(), vo.getEndSectionCode()); voMap.putIfAbsent(key, new RunPlanRunlevelVO(vo)); @@ -52,9 +55,6 @@ public class UserConfigDataBuilder { stationRunLevel.setL5(vo.getL5()); runLevelMap.putIfAbsent(stationRunLevel.buildKey(), stationRunLevel); } - if (CollectionUtils.isEmpty(runLevelMap)) { - errMsgList.add("无运行等级数据"); - } repository.setRunLevelMap(runLevelMap); } @@ -66,6 +66,9 @@ public class UserConfigDataBuilder { .collect(Collectors.toMap(RunPlanParkingTimeVO::getSectionCode, Function.identity())); } List parkingTimeList = map.getLogicDataNew().getParkingTimeList(); + if (CollectionUtils.isEmpty(parkingTimeList)) { + errMsgList.add("无默认停站时间数据"); + } for (MapStationParkingTimeVO vo : parkingTimeList) { voMap.putIfAbsent(vo.getSectionCode(), new RunPlanParkingTimeVO(vo)); } @@ -75,9 +78,6 @@ public class UserConfigDataBuilder { StationParkTime stationParkTime = new StationParkTime(section, vo.getParkingTime()); parkTimeMap.putIfAbsent(section.getCode(), stationParkTime); } - if (CollectionUtils.isEmpty(parkTimeMap)) { - errMsgList.add("无停站时间数据"); - } repository.setParkTimeMap(parkTimeMap); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java index 9f2e98678..0daa7f92e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java @@ -625,6 +625,30 @@ public class Route extends MapNamedElement { return null; } + public void unlockRouteFlsOfSwitch(Switch relSwitch) { + RouteFls routeFls = this.getRouteFlsOfSwitch(relSwitch); + if (routeFls != null && !routeFls.getBase().getASwitch().isRouteLock() && !routeFls.getBase().getASwitch().isOverlapLock()) { + routeFls.unlock(); + } + } + + /** + * 延续保护包含该道岔 + */ + public boolean overlapContainSwitch(Switch aSwitch) { + RouteOverlap overlap = this.getOverlap(); + if (overlap == null) + return false; + return overlap.containSwitch(aSwitch); + } + + public boolean overlapContainSection(Section section) { + RouteOverlap overlap = this.getOverlap(); + if (overlap == null) + return false; + return overlap.containSection(section); + } + /** * 进路检查失败原因 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java index 0438091f4..c47358512 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java @@ -106,14 +106,7 @@ public class RouteOverlap extends MapNamedElement { for (SwitchElement element : path.getSwitchList()) { Switch aSwitch = element.getASwitch(); aSwitch.overlapUnLock(); - if (!CollectionUtils.isEmpty(flsList)) { - for (RouteFls routeFls : flsList) { - if (routeFls.getBase().getASwitch().equals(aSwitch) && - !aSwitch.isRouteLock()) { - routeFls.unlock(); - } - } - } + unlockFlsOfSwitch(flsList, aSwitch); } } } @@ -123,6 +116,17 @@ public class RouteOverlap extends MapNamedElement { this.releasing = false; } + public void unlockFlsOfSwitch(List flsList, Switch aSwitch) { + if (!CollectionUtils.isEmpty(flsList)) { + for (RouteFls routeFls : flsList) { + if (routeFls.getBase().getASwitch().equals(aSwitch) && + !aSwitch.isRouteLock()) { + routeFls.unlock(); + } + } + } + } + /** * 延时解锁 */ @@ -148,6 +152,9 @@ public class RouteOverlap extends MapNamedElement { return false; } + /** + * 包含反位道岔 + */ public boolean containRpSwitch() { for (SectionPath sectionPath : this.pathList) { if (sectionPath.containRpSwitch()) { @@ -268,4 +275,12 @@ public class RouteOverlap extends MapNamedElement { this.signal.setOverlapLock(lock); this.lock = lock; } + + public boolean containSection(Section section) { + return this.selectPath().containSection(section); + } + + public boolean containSwitch(Switch aSwitch) { + return this.selectPath().containSwitch(aSwitch); + } } 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 5ce8e9938..03f90c562 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 @@ -423,15 +423,19 @@ public class Section extends MayOutOfOrderDevice { return Objects.hash(getCode()); } + public void setCtOccupied(boolean ctOccupied) { + this.ctOccupied = ctOccupied; + if (!ctOccupied && AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault())) { + AxleFault.CBTC_OCCUPIED_FAULT.fix(this); + } + } + /** * 区段列车出清 */ public void clearOccupy() { - if (AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault())) { - return; - } synchronized (this) { - this.ctOccupied = false; + setCtOccupied(false); this.setNctOccupied(false); if (!CollectionUtils.isEmpty(this.logicList)) { for (Section section : this.logicList) { @@ -740,7 +744,7 @@ public class Section extends MayOutOfOrderDevice { } public boolean isLocked() { - return this.routeLock || this.overlapLock; + return this.routeLock || this.overlapLock || this.faultLock; } /** @@ -758,7 +762,7 @@ public class Section extends MayOutOfOrderDevice { public void communicateTrainOccupy(boolean right) { this.trainRight = right; - this.ctOccupied = true; + setCtOccupied(true); } public void setNctOccupied(boolean nctOccupied) { @@ -772,7 +776,7 @@ public class Section extends MayOutOfOrderDevice { this.trainRight = right; this.setNctOccupied(true); // this.nctOccupied = true; - this.ctOccupied = false; + setCtOccupied(false); } public boolean isOccupiedOn(boolean right) { @@ -908,11 +912,17 @@ public class Section extends MayOutOfOrderDevice { } } + public void delayUnlock(int delayTime) { + setDelayTime(delayTime); + setDelayUnlock(true); + } + public void faultUnlock() { this.faultLock = false; this.routeLock = false; this.route = null; this.overlapLock = false; + this.delayUnlock = false; } public boolean isLockedOn(boolean right) { @@ -1208,6 +1218,10 @@ public class Section extends MayOutOfOrderDevice { if (this.equals(section.getFault())) return false; section.setFault(this); + Section parent = section.getParent(); + if (parent != null && parent.isAxleCounter()) { + VirtualRealitySectionAxleCounter.Fault.FAULT.apply(parent.getVirtualAxleCounter()); + } section.setCtOccupied(true); return true; } @@ -1216,11 +1230,15 @@ public class Section extends MayOutOfOrderDevice { public void fix(MayOutOfOrderDevice device) { if (this.equals(device.getFault())) { Section section = (Section) device; - section.setCtOccupied(false); section.setFault(null); + section.setCtOccupied(false); if (section.isSwitchTrack()) { section.getRelSwitch().getAllSections().forEach(section1 -> section1.setCtOccupied(false)); } + Section parent = section.getParent(); + if (parent != null && parent.isAxleCounter()) { + VirtualRealitySectionAxleCounter.Fault.FAULT.fix(parent.getVirtualAxleCounter()); + } } } }, diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java index 6d90394aa..8e22d5417 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/SectionPath.java @@ -94,6 +94,9 @@ public class SectionPath { return this.sectionList.get(this.sectionList.size()-1); } + /** + * 包含反位道岔 + */ public boolean containRpSwitch() { if (!CollectionUtils.isEmpty(this.switchList)) { for (SwitchElement switchElement : this.switchList) { @@ -154,4 +157,12 @@ public class SectionPath { SwitchElement element = this.getSwitchElement(relSwitch); return element.isNormal(); } + + public boolean containSection(Section section) { + return this.sectionList.contains(section); + } + + public boolean containSwitch(Switch aSwitch) { + return this.switchList.stream().anyMatch(se -> Objects.equals(se.getASwitch(), aSwitch)); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java index e9d64487c..b4183db3c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java @@ -492,6 +492,22 @@ public class Signal extends MayOutOfOrderDevice { } } + public boolean isAtsControl() { + if (!CollectionUtils.isEmpty(routeList)) { + return routeList.stream().allMatch(Route::isAtsControl); + } else { + return false; + } + } + + public boolean isCiControl() { + if (!CollectionUtils.isEmpty(routeList)) { + return routeList.stream().allMatch(Route::isCiControl); + } else { + return false; + } + } + public void fpLock() { this.fpl = true; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java index 68dc0584a..50de80f97 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java @@ -288,6 +288,10 @@ public class Station extends MayOutOfOrderDevice { this.controlMode = ControlMode.None; } + public boolean isSurrenderControl() { + return this.controlMode == ControlMode.None; + } + public void occControl() { this.controlMode = ControlMode.Center; } 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 ac6f3a896..fe267068c 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 @@ -4,9 +4,11 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; /** * 道岔 @@ -460,6 +462,25 @@ public class Switch extends MayOutOfOrderDevice { return toNormal; } + /** + * 获取道岔关联的计轴关联的所有区段 + */ + public List
getAllAxleSections() { + Section parent = this.getA().getParent(); + List relSwitchList = parent.getRelSwitchList(); + return relSwitchList.stream() + .flatMap(aSwitch -> aSwitch.getAllSections().stream()) + .distinct() + .collect(Collectors.toList()); + } + + public void faultUnlock() { + setRouteLock(false); + setOverlapLock(false); + setFpLock(false); + setRoute(null); + } + /** * 联锁征用(进路/延续保护/侧防等) * @param normal