diff --git a/src/main/java/club/joylink/rtss/constants/DirectionLabelEnum.java b/src/main/java/club/joylink/rtss/constants/DirectionLabelEnum.java index 3774642ce..6ed3ccfee 100644 --- a/src/main/java/club/joylink/rtss/constants/DirectionLabelEnum.java +++ b/src/main/java/club/joylink/rtss/constants/DirectionLabelEnum.java @@ -7,27 +7,14 @@ public enum DirectionLabelEnum { X, XF, XD, + XN, + XW, + XWN, S, SF, SD, + SDN, + SH, + SHN, NO; - - public static DirectionLabelEnum getLabel(String label) { - switch (label) { - case "X": - return DirectionLabelEnum.X; - case "XF": - return DirectionLabelEnum.XF; - case "XD": - return DirectionLabelEnum.XD; - case "S": - return DirectionLabelEnum.S; - case "SF": - return DirectionLabelEnum.SF; - case "SD": - return DirectionLabelEnum.SD; - default: - return DirectionLabelEnum.NO; - } - } } diff --git a/src/main/java/club/joylink/rtss/entity/DraftMapStationDirection.java b/src/main/java/club/joylink/rtss/entity/DraftMapStationDirection.java index 2b4b74be2..d363168d9 100644 --- a/src/main/java/club/joylink/rtss/entity/DraftMapStationDirection.java +++ b/src/main/java/club/joylink/rtss/entity/DraftMapStationDirection.java @@ -1,6 +1,7 @@ package club.joylink.rtss.entity; import club.joylink.rtss.constants.DirectionLabelEnum; +import club.joylink.rtss.simulation.cbtc.data.map.StationDirection; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.Getter; @@ -58,6 +59,21 @@ public class DraftMapStationDirection { */ private String signalCode; + /** + * 所属模式(自动闭塞、半自动闭塞) + */ + private StationDirection.DirectionRunModel runModel; + + /** + * 默认的接发状态 + */ + private StationDirection.ReceiveAndDeliverModel runStatus; + + /** + * 相对方向中的编码 + */ + private String relativeCode; + public void generateSectionList() { if (StringUtils.isEmpty(sectionsCode)) { sectionList = new ArrayList<>(0); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java index 83307f34b..e82cea446 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java @@ -755,6 +755,11 @@ public class Operation { */ Train_Load_Trip_Number_Train, + /** + * 大铁修改车次号 + */ + Train_Update_Trip_Number_Train, + //--------------------------- 司机 --------------------------- /** * 改变列车的牵引/制动力 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java index 443dd44fe..d39b2f933 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java @@ -399,7 +399,15 @@ public class TrainOperateHandler { * 大铁加载,指定车次列车 */ @OperateHandlerMapping(type = Operation.Type.Train_Load_Trip_Number_Train) - public void loadServiceNumberTrain(Simulation simulation, String tripNumber, String sectionCode, boolean right) { - atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, sectionCode, right); + public void loadServiceNumberTrain(Simulation simulation, String tripNumber, String sectionCode) { + atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, sectionCode); + } + + /** + * 大铁修改车次号 + */ + @OperateHandlerMapping(type = Operation.Type.Train_Update_Trip_Number_Train) + public void updateServiceNumberTrain(Simulation simulation, String tripNumber, String groupNumber) { + atsTrainLoadService.updateServiceNumberTrain(simulation, tripNumber, groupNumber); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java index 5c79df9cf..1494673c8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainLoadService.java @@ -26,6 +26,7 @@ import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService; import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -73,6 +74,9 @@ public class AtsTrainLoadService { @Autowired private CiApiService ciApiService; + @Autowired + private ATPService atpService; + public int getGivenTimeCouldLoadedTrainNumber(Simulation simulation, LocalTime time) { List list = this.getCurrentAllNeedLoadTrain(simulation, time); return list.size(); @@ -859,16 +863,12 @@ public class AtsTrainLoadService { * @param simulation 仿真实体 * @param tripNumber 车次号 * @param sectionCode 区段编号 - * @param right 上下行 */ - public void loadTripNumberTrain(Simulation simulation, String tripNumber, String sectionCode, boolean right) { + public void loadTripNumberTrain(Simulation simulation, String tripNumber, String sectionCode) { SimulationDataRepository repository = simulation.getRepository(); - boolean isExist = repository.getTrainInfoMap().values().stream() - .anyMatch(trainInfo -> tripNumber.equals(trainInfo.getTripNumber())); - if (isExist) { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, - String.format("车次[%s]的列车已经在运行中", tripNumber)); - } + validServiceNumber(simulation, tripNumber); + // 最后一位数字:偶数上行、奇数下行 + boolean right = (tripNumber.charAt(tripNumber.length() - 1) - 48) % 2 == 0; Optional virtualRealityTrainOptional = repository.getAllVrTrain().stream() .filter(trainInfo -> !repository.isVrTrainOnline(trainInfo.getGroupNumber())) .findFirst(); @@ -881,6 +881,53 @@ public class AtsTrainLoadService { trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain); } + /** + * 大铁修改车次列车 + * + * @param simulation 仿真实体 + * @param tripNumber 车次号 + * @param groupNumber 车组号 + */ + public void updateServiceNumberTrain(Simulation simulation, String tripNumber, String groupNumber) { + SimulationDataRepository repository = simulation.getRepository(); + validServiceNumber(simulation, tripNumber); + if (!repository.isVrTrainOnline(groupNumber)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, String.format("车组号[%s]的列车不存在", groupNumber)); + } + VirtualRealityTrain virtualRealityTrain = repository.getVRByCode(groupNumber, VirtualRealityTrain.class); + // 最后一位数字:偶数上行、奇数下行 + boolean right = (tripNumber.charAt(tripNumber.length() - 1) - 48) % 2 == 0; + if (!Objects.equals(right, virtualRealityTrain.isRight())) { + atpService.turnDirectionImmediately(virtualRealityTrain); + } + virtualRealityTrain.setTripNumber(tripNumber); + virtualRealityTrain.setRight(right); + TrainInfo trainInfo = TrainInfo.constructManualTrain(virtualRealityTrain); + trainInfo.tracking(virtualRealityTrain); + repository.addTrainInfo(trainInfo); + } + + /** + * 大铁操作车次前验证 + * + * @param simulation 仿真实体 + * @param tripNumber 车次号 + */ + private void validServiceNumber(Simulation simulation, String tripNumber) { + SimulationDataRepository repository = simulation.getRepository(); + boolean isExist = repository.getTrainInfoMap().values().stream() + .anyMatch(trainInfo -> tripNumber.equals(trainInfo.getTripNumber())); + if (isExist) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("车次[%s]的列车已经在运行中", tripNumber)); + } + int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48; + if (lastNum < 0 && lastNum > 9) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, + String.format("车次[%s]要以数字结尾", tripNumber)); + } + } + /** * 列车上线并构建ATS监控列车信息 * diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/assist/StationDirectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/assist/StationDirectionService.java index 26a398d57..3f8e4cb80 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/assist/StationDirectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/assist/StationDirectionService.java @@ -394,7 +394,10 @@ public class StationDirectionService { * @return 相对方向 */ private StationDirection getRelativeStationDirection(Simulation simulation, StationDirection stationDirection) { - StationDirection relativeStationDirection = null; + StationDirection relativeStationDirection = stationDirection.getRelativeStationDirection(); + if (relativeStationDirection != null) { + return relativeStationDirection; + } // 获取邻站实体 Optional adjacentStationOptional = getAdjacentStationOptional(simulation, stationDirection); if (adjacentStationOptional.isPresent()) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl2.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl2.java index f867cf62f..a402d95f9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl2.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl2.java @@ -188,7 +188,7 @@ public class CiApiServiceImpl2 implements CiApiService { station.getStationDirectionMap().values().stream() .filter(stationDirection -> route.getStart().getCode().equals(stationDirection.getSignal().getCode()) || route.getDestination().getCode().equals(stationDirection.getSignal().getCode())) - .forEach(stationDirection -> stationDirection.modifyRunStatus(route)) + .forEach(stationDirection -> stationDirection.modifyRunStatus()) ); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java index 980efaf72..1a7c40500 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/InterlockBuilder2.java @@ -1633,16 +1633,11 @@ public class InterlockBuilder2 { if (elementMap.containsKey(stationDirection.getCode())) { errMsgList.add("已经存在车站运行方向" + stationDirection.getCode()); } else { - StationDirection model = new StationDirection(stationDirection.getCode(), stationDirection.getCode(), stationDirection.getLabelEnum()); - Station station = (Station) elementMap.get(stationDirection.getStationCode()); - model.setStation(station); - // 注入区间数据 - if (!CollectionUtils.isEmpty(stationDirection.getSectionList())) { - List
sectionList = stationDirection.getSectionList() - .stream() - .map(sectionCode -> (Section) elementMap.get(sectionCode)) - .collect(Collectors.toList()); - model.setSectionList(sectionList); + StationDirection model; + if (stationDirection.getRunStatus() != null) { + model = new StationDirection(stationDirection); + } else { + model = new StationDirection(stationDirection.getCode(), stationDirection.getCode(), stationDirection.getLabelEnum()); } // 注入信号灯数据 if (!StringUtils.isEmpty(stationDirection.getSignalCode())) { @@ -1657,10 +1652,28 @@ public class InterlockBuilder2 { model.getDeliverRouteList().add((Route) elementMap.get(code)); }); } + // 注入区间数据 + if (!CollectionUtils.isEmpty(stationDirection.getSectionList())) { + List
sectionList = stationDirection.getSectionList().stream() + .map(sectionCode -> (Section) elementMap.get(sectionCode)) + .collect(Collectors.toList()); + model.setSectionList(sectionList); + } + model.modifyRunStatus(); + Station station = (Station) elementMap.get(stationDirection.getStationCode()); + model.setStation(station); station.getStationDirectionMap().put(model.getLabelEnum(), model); elementMap.put(model.getCode(), model); } }); + // 相对方向 + stationDirectionList.stream() + .filter(draftMapStationDirection -> elementMap.containsKey(draftMapStationDirection.getRelativeCode())) + .forEach(draftMapStationDirection -> { + StationDirection stationDirection = (StationDirection) elementMap.get(draftMapStationDirection.getCode()); + StationDirection relativeStationDirection = (StationDirection) elementMap.get(draftMapStationDirection.getRelativeCode()); + stationDirection.setRelativeStationDirection(relativeStationDirection); + }); } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java index 7a4b529ac..8955339a9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java @@ -578,7 +578,6 @@ public class CommandBO { Section section = train.getHeadPosition().getSection(); // 列车车头所在区段 boolean loop = true; Signal signal; - Switch switchObj; Section nextSection = section, targetSection = null; while (loop) { signal = isRight ? nextSection.getSignalToRight() : nextSection.getSignalToLeft(); // 方向信号机 @@ -611,6 +610,24 @@ public class CommandBO { return null; } } + }, + + /** + * 大铁、停车 + */ + Parking_Train(List.of(), SimulationMember.Type.DRIVER) { + @Override + public List buildStepList(Simulation simulation, SimulationMember targetMember, Map params) { + return Collections.emptyList(); + } + + @Override + public Step execute(Simulation simulation, CommandBO command) { + SimulationMember targetMember = command.getTargetMember(); + targetMember.setCommand(null); + // 设置目标位置 + return buildDriveStep(null); + } }; public enum ParamName { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/StationDirection.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/StationDirection.java index c33fa042d..e19a63fa7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/StationDirection.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/StationDirection.java @@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.data.map; import club.joylink.rtss.constants.DirectionLabelEnum; +import club.joylink.rtss.entity.DraftMapStationDirection; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -39,6 +40,11 @@ public class StationDirection extends MapNamedElement { */ private DirectionLabelEnum labelEnum; + /** + * 相对运行方向 + */ + private StationDirection relativeStationDirection; + /** * 指示灯实体 */ @@ -153,6 +159,14 @@ public class StationDirection extends MapNamedElement { this.currentRouteList = getNowRouteList(); } + public StationDirection(DraftMapStationDirection draftMapStationDirection) { + this(draftMapStationDirection.getCode(), draftMapStationDirection.getCode()); + this.labelEnum = draftMapStationDirection.getLabelEnum(); + this.runModel = draftMapStationDirection.getRunModel(); + this.defaultRunStatus = draftMapStationDirection.getRunStatus(); + this.runStatus = draftMapStationDirection.getRunStatus(); + } + public StationDirection(String code, String name) { super(code, name, DeviceType.STATION_DIRECTION); setDefaultAttribute(); @@ -183,7 +197,7 @@ public class StationDirection extends MapNamedElement { /** * 修改当前运行状态 */ - public void modifyRunStatus(Route route) { + public void modifyRunStatus() { // 自动模式 if (DirectionRunModel.A.equals(this.runModel)) { this.currentRouteList = getNowRouteList(); diff --git a/src/main/resources/mybatis/mapper/DraftMapStationDirectionDAO.xml b/src/main/resources/mybatis/mapper/DraftMapStationDirectionDAO.xml index 6f2ac1608..1d0e7f2f4 100644 --- a/src/main/resources/mybatis/mapper/DraftMapStationDirectionDAO.xml +++ b/src/main/resources/mybatis/mapper/DraftMapStationDirectionDAO.xml @@ -9,6 +9,9 @@ + + + @@ -74,7 +77,8 @@ - id, map_id, code, station_code, sections_code, label_enum, signal_code + id, map_id, code, station_code, sections_code, label_enum, + signal_code, run_model, run_status, relative_code