diff --git a/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java b/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java index dd283b859..1102df8ec 100644 --- a/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java +++ b/src/main/java/club/joylink/rtss/exception/BusinessExceptionAssertEnum.java @@ -30,12 +30,13 @@ public enum BusinessExceptionAssertEnum implements BusinessExceptionAssert { SIMULATION_PERMISSION_NOT_AVAILABLE(10014, "simulation permission not available"), UNSUPPORTED_FILE_FORMAT(10015, "unsupported file format"), OPERATION_REPEAT(10016, "operation repeat"), + SIMULATION_EXCEPTION_FOR_SHOW(10017, ""), //错误信息用于展示给仿真用户 DATA_ERROR(11000, "data error"), CI_GENERATE_ERROR(11001, "ci data generate error"), MAP_PASSENGER_FLOW_DATA_ERROR(11002, "map passenger flow data error"), - DATA_UNIQUE_PROPERTY_REPEAT(10013, "data unique property repeat"), + DATA_UNIQUE_PROPERTY_REPEAT(11013, "data unique property repeat"), DATA_INVALID(11004, "data invalid"), DATA_BEEN_USED(11005, "data has been used"), DATA_STATE_INCORRECT(11007, "data state incorrect"), diff --git a/src/main/java/club/joylink/rtss/services/DraftMapService.java b/src/main/java/club/joylink/rtss/services/DraftMapService.java index 8f6247c75..bc6c253d4 100644 --- a/src/main/java/club/joylink/rtss/services/DraftMapService.java +++ b/src/main/java/club/joylink/rtss/services/DraftMapService.java @@ -1534,6 +1534,7 @@ public class DraftMapService implements IDraftMapService { case NON_OPERATION: case LAST_NON_OPERATION: BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotNull(definitionVO.getSectionCode(), "目标区段必须选择"); + break; case OTHER: break; } diff --git a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java index 5dc7e3e08..0b53ac0a1 100644 --- a/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java +++ b/src/main/java/club/joylink/rtss/services/draftData/DraftMapCiDataGeneratorImpl.java @@ -182,6 +182,12 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { .filter(mapElement -> MapElement.DeviceType.SECTION.equals(mapElement.getDeviceType())) .map(mapElement -> (Section) mapElement) .collect(Collectors.toList()); + // 所有车站 + List stationList = deviceMap.values().stream() + .filter(mapElement -> MapElement.DeviceType.STATION.equals(mapElement.getDeviceType())) + .map(mapElement -> (Station) mapElement) + .sorted(Comparator.comparingInt(Station::getSn)) + .collect(Collectors.toList()); Map> overlapMap = new HashMap<>(); List approachList = new ArrayList<>(); @@ -296,58 +302,6 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { // // 生成交路数据 // List generateRoutingList = this.generateRoutings(deviceMap, generatedRouteList, autoSignalList, errorList); - -// // 获取所有转换轨或者折返轨 -// List
sectionList = deviceMap.values().stream() -// .filter(mapElement -> mapElement.getDeviceType().equals(MapElement.DeviceType.SECTION)) -// .map(mapElement -> ((Section) mapElement)).filter(section -> section.isTurnBackTrack() || section.isTransferTrack()) -// .collect(Collectors.toList()); -// CodeGenerator routingCodeGenerator = new CodeGenerator("Routing"); -// //交路生成 -// List generatedRoutingList = new ArrayList<>(); -// int size = sectionList.size(); -// log.info(String.format("共有折返轨和转换轨[%s]个", size)); -// for (int i = 0; i < size - 1; i++) { -// Section startSection = sectionList.get(i); -// for (int j = i + 1; j < size; j++) { -// Section endSection = sectionList.get(j); -// //站台轨之间反向暂不生成 -// if(startSection.isNormalStandTrack() && endSection.isNormalStandTrack()){ -// boolean noNeed = startSection.getStandList().stream() -// .filter(stand -> !stand.isSmall()) -// .anyMatch(stand -> { -// for (Stand stand1 : endSection.getStandList()) { -// if (!stand1.isSmall() && !Objects.equals(stand1.isRight(), stand.isRight())) { -// return true; -// } -// } -// return false; -// }); -// if(noNeed) continue; -// } -// // 同一车站间不生成 -// if (Objects.equals(startSection.getStation(), endSection.getStation())) { -// continue; -// } -// //生成交路 -// MapRoutingDataVO routingData = generateRouting(errorList, -// routingCodeGenerator, startSection, endSection); -// if (Objects.nonNull(routingData)) { -// generatedRoutingList.add(routingData); -// } -// //生成上面交路的回路 -// MapRoutingDataVO routingDataLoop = generateRouting(errorList, routingCodeGenerator, endSection, startSection); -// if (Objects.nonNull(routingDataLoop)) { -// if(Objects.nonNull(routingData)){ -// routingDataLoop.setCode(routingData.getCode() + "-LOOP"); -// routingDataLoop.setName(routingData.getName() + "-LOOP"); -// } -// generatedRoutingList.add(routingDataLoop); -// } -// -// } -// } - //站间运行等级生成 List generatedStationRunLevelList = new ArrayList<>(); // generateRunLevel(deviceMap, errorList, generateRoutingList, generatedStationRunLevelList); @@ -355,21 +309,132 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator { //目的地码生成 List destinationCodeDefinitionList = new ArrayList<>(); - if (!CollectionUtils.isEmpty(sectionList)) { - for (Section section : sectionList) { - String destinationCode = section.getDestinationCode(); - if (!StringUtils.hasText(destinationCode)) { + if (config.isGenerateDestination()) { + String code = null; + DestinationCodeDefinition.Type type = null; + String description = null; + Section startSection = null; + Section section = null; + Boolean right = null; + List
necessarySections = null; + Station leftStation = null; + Boolean leftFrontTurnBack = null; + Station rightStation = null; + Boolean rightFrontTurnBack = null; + + int codeNum = 1; + for (int i = 0; i < stationList.size(); i++) { + leftStation = stationList.get(i); + if (CollectionUtils.isEmpty(leftStation.getTurnBackList())) //没有折返轨的略过 continue; + if (i == stationList.size() - 1) + break; + + List
leftTbSections = queryAfterTurnBackList(leftStation, false); + leftTbSections.addAll(queryFrontTurnBackList(stationList, leftStation, false)); + for (Section startTbSection : leftTbSections) { + for (int j = stationList.size() - 1; j >= 0; j--) { + rightStation = stationList.get(j); + if (leftStation.equals(rightStation)) { + break; + } + List
rightTbSections = queryAfterTurnBackList(rightStation, true); + rightTbSections.addAll(queryFrontTurnBackList(stationList, rightStation, true)); + for (Section endTbSection : rightTbSections) { + code = String.format("%03d", codeNum++); + type = DestinationCodeDefinition.Type.NORMAL_OPERATION; + description = String.format("%s-%s", leftStation.getName(), rightStation.getName()); + necessarySections = List.of(startTbSection, endTbSection); + leftFrontTurnBack = startTbSection.isNormalStandTrack(); + rightFrontTurnBack = endTbSection.isNormalStandTrack(); + destinationCodeDefinitionList.add( + new DestinationCodeDefinition(code, type, description, startSection, section, right, necessarySections, + leftStation, leftFrontTurnBack, rightStation, rightFrontTurnBack, null, null) + ); + } + } + } + } + } else { + if (!CollectionUtils.isEmpty(sectionList)) { + for (Section section : sectionList) { + String destinationCode = section.getDestinationCode(); + if (!StringUtils.hasText(destinationCode)) { + continue; + } + destinationCodeDefinitionList.add(new DestinationCodeDefinition(destinationCode, DestinationCodeDefinition.Type.OTHER, section)); } - destinationCodeDefinitionList.add(new DestinationCodeDefinition(destinationCode, DestinationCodeDefinition.Type.OTHER, section)); } } + return new CiGenerateResult(errorList, approachList, autoSignalList, generatedRouteList, generatedOverlapList, flsList, generateCycleList, generatedStationRunLevelList, destinationCodeDefinitionList); } + /** + * 筛选站后折返轨(优先右行站台折返) + * @param stations 所有车站 + * @param right 是否是右端车站 + */ + private List
queryFrontTurnBackList(List stations, Station station, boolean right) { + List
turnBackList = station.getTurnBackList(); + if (CollectionUtils.isEmpty(turnBackList) || CollectionUtils.isEmpty(station.getAllNormalStands())) { + return new ArrayList<>(); + } + int sn; + if (right) { + sn = station.getSn() - 1; + } else { + sn = station.getSn() + 1; + } + Station adjacentStation = stations.stream().filter(sta -> sta.getSn() == sn).limit(1).findAny().get(); + if (CollectionUtils.isEmpty(adjacentStation.getAllNormalStands())) { + return new ArrayList<>(); + } + Section leftStandTrack = station.getNormalStand(false).get(0).getSection(); + Section rightStandTrack = station.getNormalStand(true).get(0).getSection(); + Section adjacentLeftStandTrack = adjacentStation.getNormalStand(false).get(0).getSection(); + Section adjacentRightStandTrack = adjacentStation.getNormalStand(true).get(0).getSection(); + List
tbSections = new ArrayList<>(); + if (right) { + if (rightStandTrack.isTurnBackTrack() + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(rightStandTrack, adjacentLeftStandTrack, false))) { + tbSections.add(rightStandTrack); + } + if (leftStandTrack.isTurnBackTrack() + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentRightStandTrack, leftStandTrack, true))) { + tbSections.add(leftStandTrack); + } + } else { + if (rightStandTrack.isTurnBackTrack() + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(adjacentLeftStandTrack, rightStandTrack, false))) { + tbSections.add(rightStandTrack); + } + if (leftStandTrack.isTurnBackTrack() + && !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(leftStandTrack, adjacentRightStandTrack, true))) { + tbSections.add(leftStandTrack); + } + } + return tbSections; + } + + /** + * 筛选站前折返轨 + * @param right 是否是右端车站 + */ + private List
queryAfterTurnBackList(Station station, boolean right) { + List
turnBackList = station.getTurnBackList(); + if (CollectionUtils.isEmpty(turnBackList)) { + return new ArrayList<>(); + } + Section standTrack = station.getNormalStand(right).get(0).getSection(); + return turnBackList.stream().filter(section -> !section.isNormalStandTrack()) + .filter(section -> !CollectionUtils.isEmpty(CalculateService.queryRoutePathsOnDirection(standTrack, section, right))) + .collect(Collectors.toList()); + } + private Collection generateRouteLikeHa1(Signal signal, CodeGenerator routeCodeGenerator, Map> overlapMap, CodeGenerator overlapCodeGenerator, diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java index 79b1b8c60..4be510510 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -73,6 +74,27 @@ public class GroundAtpApiServiceImpl implements GroundAtpApiService { } // 判断是否要将ARB设为非通信车占用 this.atpSectionService.judgeFaultSectionAsNctOccupied(nctApproachSignalMap); + // 根据道岔的位置修改道岔区段的占用(暂时只处理因故障导致的占用) + repository.getSwitchList().stream().filter(aSwitch -> Section.AxleFault.CBTC_OCCUPIED_FAULT.equals(aSwitch.getA().getFault())) + .forEach(aSwitch -> { + List
allSections = aSwitch.getAllSections(); + if (aSwitch.isLoss()) { + allSections.forEach(section -> section.setCtOccupied(true)); + } else { + List
sections = Arrays.asList(aSwitch.getA(), aSwitch.getNextSectionOnBaseSection(aSwitch.getA())); + for (Section section : sections) { + if (section != null) { + section.setCtOccupied(true); + } + } + allSections.forEach(section -> { + if (!sections.contains(section)) { + section.setCtOccupied(false); + } + }); + } + }); + // 发送区段状态 this.atsApiService.handleDeviceStatus(simulation, repository.getSectionList()); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/AtsOperationDispatcher.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/AtsOperationDispatcher.java index 8ba562de3..d7a641582 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/AtsOperationDispatcher.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/AtsOperationDispatcher.java @@ -1,5 +1,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.operation; +import club.joylink.rtss.exception.BusinessException; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.event.SimulationOperationEvent; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; @@ -43,6 +45,12 @@ public class AtsOperationDispatcher { try { result = handlerMethod.execute(simulation, params, member); } catch (Exception e) { + if (e instanceof BusinessException) { + BusinessException be = (BusinessException) e; + if (BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.getCode() == be.getCode()) { + throw e; + } + } throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, String.format("操作【%s】执行失败:%s", operate, e.getMessage()), e); } 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 eea1c314e..68abb1851 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 @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; @@ -8,8 +9,6 @@ import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.map.Route; import club.joylink.rtss.simulation.cbtc.data.status.RouteStatus; -import club.joylink.rtss.simulation.cbtc.exception.SimulationException; -import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -35,10 +34,7 @@ public class SignalOperateHandler { @OperateHandlerMapping(type = Operation.Type.Signal_Set_Route) public void settingRoute(Simulation simulation, String routeCode) { Route.CheckFailMessage checkResult = this.ciApiService.routeSettingCheck(simulation, routeCode); - if (Objects.nonNull(checkResult)) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - checkResult.toJson()); - } + BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.assertNull(checkResult, "进路排列失败,被联锁逻辑取消"); this.ciApiService.settingRoute(simulation, routeCode); } 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 ea23f0244..59768939d 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 @@ -179,7 +179,14 @@ public class StationOperateHandler { @OperateHandlerMapping(type = Operation.Type.Station_Close_AllSignal) public void closeAllSignal(Simulation simulation, String stationCode){ SimulationDataRepository repository = simulation.getRepository(); - repository.getSignalList().stream().filter(s -> Objects.equals(stationCode,s.getStation().getCode())).forEach(signal -> ciApiService.blockadeSignal(simulation, signal.getCode())); + repository.getSignalList().stream() + .filter(s -> s.getStation() != null && Objects.equals(stationCode, s.getStation().getCode())) + .forEach(signal -> { + ciApiService.blockadeSignal(simulation, signal.getCode()); + if (signal.getLockedRoute() != null) { + ciApiService.closeSignal(simulation, signal.getCode()); + } + }); } /**关区信号*/ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SwitchOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SwitchOperateHandler.java index b188813f9..482755b6b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SwitchOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SwitchOperateHandler.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler; @@ -38,10 +39,8 @@ public class SwitchOperateHandler { @OperateHandlerMapping(type = Operation.Type.Switch_Turn) public void turn(Simulation simulation, String switchCode) { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); - if (!aSwitch.canTurn()) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - "道岔锁闭或占用,无法转动"); - } + BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.assertTrue(!aSwitch.isLocked(), + String.format("联锁操作被取消,道岔%s被锁定", aSwitch.getName())); this.ciApiService.turn(simulation, switchCode); } 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 6419bed24..da5e54e82 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 @@ -9,7 +9,6 @@ import club.joylink.rtss.simulation.cbtc.data.support.SignalApproachMessage; import club.joylink.rtss.simulation.cbtc.data.support.TrainStopMessage; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter; -import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import lombok.extern.slf4j.Slf4j; @@ -87,7 +86,7 @@ public class CiApiServiceImpl implements CiApiService { } Optional routeOptional = simulation.getRepository().getSettingRoutes().stream() .filter(route -> route.getStart().equals(signal)).limit(1).findAny(); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(routeOptional.isPresent(),"信号机不是已排进路的始端信号机"); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(routeOptional.isPresent(), "信号机不是已排进路的始端信号机"); // settingRoute(simulation, routeOptional.get().getCode()); Route lockedRoute = signal.getLockedRoute(); if (Objects.isNull(lockedRoute)) { @@ -107,15 +106,17 @@ public class CiApiServiceImpl implements CiApiService { @Override public void turn(Simulation simulation, String switchCode) { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); - if (aSwitch.isReversePosition()) { + boolean toNormal = aSwitch.judgeTurnToNormal(); + aSwitch.setLastTurnToNormal(toNormal); + if (toNormal) { if (!this.switchService.turn2NormalPosition(simulation, aSwitch)) { log.info(String.format("道岔[%s(%s)]锁闭,不能进行定操", aSwitch.getName(), aSwitch.getCode())); - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,"道岔锁闭,不能进行定操"); + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行定操"); } } else { if (!this.switchService.turn2ReversePosition(simulation, aSwitch)) { log.info(String.format("道岔[%s(%s)]锁闭,不能进行反操", aSwitch.getName(), aSwitch.getCode())); - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,"道岔锁闭,不能进行反操"); + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行反操"); } } } @@ -125,7 +126,7 @@ public class CiApiServiceImpl implements CiApiService { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); if (!this.switchService.turn2NormalPosition(simulation, aSwitch)) { log.info(String.format("道岔[%s(%s)]锁闭,不能进行定操", aSwitch.getName(), aSwitch.getCode())); - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,"道岔锁闭,不能进行定操"); + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行定操"); } } @@ -134,7 +135,7 @@ public class CiApiServiceImpl implements CiApiService { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); if (!this.switchService.turn2ReversePosition(simulation, aSwitch)) { log.info(String.format("道岔[%s(%s)]锁闭,不能进行反操", aSwitch.getName(), aSwitch.getCode())); - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,"道岔锁闭,不能进行反操"); + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行反操"); } } @@ -512,7 +513,7 @@ public class CiApiServiceImpl implements CiApiService { } @Override - public void powerOnUnlock(Simulation simulation, Station station){ + public void powerOnUnlock(Simulation simulation, Station station) { if (!station.isCentralized()) { station = station.getDeviceStation(); } @@ -520,14 +521,15 @@ public class CiApiServiceImpl implements CiApiService { if (Objects.nonNull(deviceStation.getRestartTime()) && deviceStation.getRestartTime().isBefore(LocalTime.now()) && ((Simulation.FunctionalType.LESSON.equals(simulation.getBuildParams().getFunctionalType()) - ||Simulation.FunctionalType.EXAM.equals(simulation.getBuildParams().getFunctionalType())) - ?true: deviceStation.getRestartTime().plusMinutes(8).isAfter(LocalTime.now()))) { + || Simulation.FunctionalType.EXAM.equals(simulation.getBuildParams().getFunctionalType())) + ? true : deviceStation.getRestartTime().plusMinutes(8).isAfter(LocalTime.now()))) { List
sections = simulation.getRepository().getSectionList(); sections.stream().filter(section -> Objects.equals(section.getDeviceStation(), deviceStation)).forEach(Section::faultUnlock); return; } - throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("无效操作或连锁机重启过8分钟需手动解锁"); + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("无效操作或连锁机重启过8分钟需手动解锁"); } + @Override public void standEB(Simulation simulation, Stand stand) { if (stand.getEsp() == null) @@ -545,14 +547,13 @@ public class CiApiServiceImpl implements CiApiService { @Override public void switchForceTurn(Simulation simulation, String switchCode, Boolean normal) { Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(aSwitch.isSectionOccupied(), "道岔未被占用,不能使用强转"); + BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.assertTrue(!aSwitch.isLocked() && aSwitch.isSectionOccupied(), + String.format("对%s强行转岔操作被联锁逻辑取消", aSwitch.getName())); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!aSwitch.isLocked(), String.format("道岔[%s]锁闭,无法转动", aSwitch.getCode())); - VirtualRealitySwitch vrSwitch = aSwitch.getVirtualSwitch(); if (normal == null) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(vrSwitch.isLoss(), "道岔不在定反位,不能转动"); - normal = vrSwitch.isReverse(); + normal = aSwitch.judgeTurnToNormal(); } - vrSwitch.startSetting(normal); + switchService.controlSwitch(simulation, aSwitch, normal); } @Override diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java index 3519e9c7c..d42e41682 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java @@ -34,10 +34,10 @@ public class SignalService { public void blockade(Simulation simulation, Signal signal) { if(!signal.isBlockade()) { signal.setBlockade(true); -// if (signal.getLockedRoute() != null) { -// signal.setReblockade(true); -// log.debug(signal.debugStr() + "因信号机封锁且有锁闭的进路而重复封锁"); -// } + if (signal.getLockedRoute() != null) { + signal.setReblockade(true); + log.debug(signal.debugStr() + "因信号机封锁且有锁闭的进路而重复封锁"); + } } } 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 dc9a7a6d2..71413a06b 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 @@ -20,6 +20,7 @@ import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Objects; +import java.util.Random; import java.util.stream.Collectors; /** @@ -41,7 +42,14 @@ public class SwitchService { * @param aSwitch * @param toNormal */ - private void controlSwitch(Simulation simulation, Switch aSwitch, boolean toNormal) { + public void controlSwitch(Simulation simulation, Switch aSwitch, boolean toNormal) { + if (simulation.getRepository().getConfig().isSwitchTurnOperationCanRecoverSplitFault()) { + if (new Random().nextInt(5) == 0) { + Switch.SwitchFault.SPLIT.fix(aSwitch); + Switch.SwitchFault.NORMAL_SPLIT.fix(aSwitch); + Switch.SwitchFault.REVERSE_SPLIT.fix(aSwitch); + } + } VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch(); if ((virtualSwitch.isNormal() && toNormal) || (virtualSwitch.isReverse() && !toNormal)) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java index 1f6bd4e78..56a8f149d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java @@ -866,6 +866,7 @@ public class MapDeviceBuilder { } else { signal.setDeviceStation(deviceStation); } + signal.setStation((Station) elementMap.get(signalVO.getBelongStationCode())); // 所属车站 Station station = (Station) elementMap.get(signalVO.getBelongStationCode()); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java index aa8c80a15..e913d4690 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java @@ -201,6 +201,11 @@ public class MapConfig { */ private boolean stationPreResetBeforeAxlePreReset; + /** + * 道岔转动操作可以使失表故障恢复 + */ + private boolean switchTurnOperationCanRecoverSplitFault; + private Set needConfirmConnectMembers = Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet()); @@ -242,6 +247,7 @@ public class MapConfig { setBlockadeCommandOnlyValidInStandbyMode(configVO.isBlockadeCommandOnlyValidInStandbyMode()); setSomeCommandNeedInit(configVO.isSwitchBlockadeCommandNeedInit()); setStationPreResetBeforeAxlePreReset(configVO.isStationPreResetBeforeAxlePreReset()); + setSwitchTurnOperationCanRecoverSplitFault(configVO.isSwitchTurnOperationCanRecoverSplitFault()); } } 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 beb921716..280c1b311 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 @@ -391,6 +391,9 @@ public class Section extends MayOutOfOrderDevice { * 区段列车出清 */ public void clearOccupy() { + if (AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault())) { + return; + } synchronized (this){ this.ctOccupied = false; if (this.isAxleCounter()) { @@ -1029,12 +1032,19 @@ public class Section extends MayOutOfOrderDevice { section.setFault(this); return true; } + }, + CBTC_OCCUPIED_FAULT{ @Override - public void fix(MayOutOfOrderDevice device) { + public boolean apply(MayOutOfOrderDevice device) { Section section = (Section) device; + if (!CollectionUtils.isEmpty(section.getLogicList())) + return false; if (this.equals(section.getFault())) - section.setFault(null); + return false; + section.setFault(this); + section.setCtOccupied(true); + return true; } } } 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 10988c836..49c3edf96 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 @@ -129,6 +129,11 @@ public class Switch extends MayOutOfOrderDevice { */ private boolean init; + /** + * 上一次是否是将道岔转向定位 + */ + private Boolean lastTurnToNormal; + @Override public void reset() { super.reset(); @@ -148,6 +153,7 @@ public class Switch extends MayOutOfOrderDevice { this.interlockReserve = false; this.blockadeInvalid = false; this.init = false; + this.lastTurnToNormal = null; } /** @@ -407,10 +413,23 @@ public class Switch extends MayOutOfOrderDevice { return !this.isNormalPosition() && !this.isReversePosition(); } - public void forceUnlock() { - this.routeLock = false; - this.overlapLock = false; - this.fpLock = false; + /** + * 判断道岔转动的方向 + */ + public boolean judgeTurnToNormal() { + boolean toNormal; + if (this.reversePosition) { + toNormal = true; + } else if (this.normalPosition) { + toNormal = false; + } else { + if (this.lastTurnToNormal != null) { + toNormal = !this.lastTurnToNormal; + } else { + toNormal = true; + } + } + return toNormal; } public enum SwitchFault implements DeviceFault { @@ -493,7 +512,7 @@ public class Switch extends MayOutOfOrderDevice { /** * 计轴故障 */ - AXLE_FAULT{ + AXLE_FAULT { @Override public boolean apply(MayOutOfOrderDevice device) { Switch aSwitch = (Switch) device; @@ -507,6 +526,23 @@ public class Switch extends MayOutOfOrderDevice { Section section = aSwitch.getA().getParent(); Section.AxleFault.FAULT.fix(section); } + }, + + /** + * 通信车占用故障 + */ + CBTC_OCCUPIED_FAULT { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Switch aSwitch = (Switch) device; + return Section.AxleFault.CBTC_OCCUPIED_FAULT.apply(aSwitch.getA()); + } + + @Override + public void fix(MayOutOfOrderDevice device) { + Switch aSwitch = (Switch) device; + Section.AxleFault.CBTC_OCCUPIED_FAULT.fix(aSwitch.getA()); + } } } } diff --git a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java index 61388bf74..06872fd3b 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java @@ -140,6 +140,11 @@ public class RealLineConfigVO { */ private boolean stationPreResetBeforeAxlePreReset; + /** + * 道岔转动操作可以使失表故障恢复 + */ + private boolean switchTurnOperationCanRecoverSplitFault; + public static RealLineConfigVO parseJsonStr(String configData) { if (StringUtils.hasText(configData)) { return JsonUtils.read(configData, RealLineConfigVO.class); diff --git a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapCiGenerateConfig.java b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapCiGenerateConfig.java index e4a25c568..960d54057 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapCiGenerateConfig.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapCiGenerateConfig.java @@ -69,6 +69,9 @@ public class MapCiGenerateConfig { @ApiModelProperty(value = "若生成进路信号按钮,进路信号按钮是否取最近的一个信号机") private boolean getNearlySignal; + @ApiModelProperty("是否生成目的地码定义(泰雷兹式)") + private boolean generateDestination; + // @ApiModelProperty(value = "是否分开生成ATP联锁和地面信号联锁") // private boolean apartGroundAndAtp; diff --git a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapDestinationCodeDefinitionVO.java b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapDestinationCodeDefinitionVO.java index bdadf8a98..f58fd91cc 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapDestinationCodeDefinitionVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapDestinationCodeDefinitionVO.java @@ -73,6 +73,9 @@ public class MapDestinationCodeDefinitionVO { vo.code = definition.getCode(); vo.type = definition.getType(); vo.description = definition.getDescription(); + if (definition.getStartSection() != null) { + vo.startSectionCode = definition.getStartSection().getCode(); + } if (definition.getSection() != null) { vo.sectionCode = definition.getSection().getCode(); } @@ -80,6 +83,18 @@ public class MapDestinationCodeDefinitionVO { if (!CollectionUtils.isEmpty(definition.getNecessarySections())) { vo.runPath =definition.getNecessarySections().stream().map(MapElement::getCode).collect(Collectors.toList()); } + if (definition.getLeftStation() != null) { + vo.stationACode = definition.getLeftStation().getCode(); + } + if (definition.getLeftFrontTurnBack() != null) { + vo.stationAFrontTurnBack = definition.getLeftFrontTurnBack(); + } + if (definition.getRightStation() != null) { + vo.stationBCode = definition.getRightStation().getCode(); + } + if (definition.getRightFrontTurnBack() != null) { + vo.stationBFrontTurnBack = definition.getRightFrontTurnBack(); + } return vo; }