From 8499b22642edb24c05bd1a209ad1f42e2db12f99 Mon Sep 17 00:00:00 2001 From: thesai <1021828630@qq.com> Date: Wed, 15 Jun 2022 00:29:36 +0800 Subject: [PATCH] =?UTF-8?q?CTC=E8=82=A1=E9=81=93=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simulation/cbtc/CTC/CTCLogicLoop.java | 74 ++++++++- .../cbtc/CTC/data/CtcRepository.java | 4 + .../cbtc/CTC/data/CtcStationRunPlanLog.java | 2 +- .../cbtc/CTC/data/RouteSequence.java | 41 +++-- .../cbtc/CTC/data/RouteSequenceVO.java | 8 +- .../simulation/cbtc/CTC/data/TrackView.java | 11 ++ .../simulation/cbtc/CTC/data/TrackViewVO.java | 155 ++++++++++++++++-- .../rtss/simulation/cbtc/Simulation.java | 2 + .../cbtc/build/SimulationBuilder.java | 9 +- 9 files changed, 258 insertions(+), 48 deletions(-) create mode 100644 src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackView.java diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java index 14ee38c1b..9512e1145 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java @@ -3,11 +3,15 @@ package club.joylink.rtss.simulation.cbtc.CTC; import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsRouteSelectService; import club.joylink.rtss.simulation.cbtc.CI.CiApiService; -import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository; -import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; -import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; -import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequenceVO; +import club.joylink.rtss.simulation.cbtc.CTC.data.*; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +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.support.SectionPosition; +import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.vo.client.SocketMessageVO; import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.ctc.CtcRunPlanVO; @@ -18,6 +22,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -39,7 +44,8 @@ public class CTCLogicLoop { private CiApiService ciApiService; public void run(Simulation simulation) { - + updateRunPlanLog(simulation); + routeSequenceTrigger(simulation); } public void sendMessage(Simulation simulation) { @@ -52,8 +58,64 @@ public class CTCLogicLoop { sendAllRouteSequenceMessage(simulation); } - private void sendAllTrackViewMessage(Simulation simulation) { + /** + * 进路序列自触 + */ + private void routeSequenceTrigger(Simulation simulation) { + LocalDateTime correctSystemTime = simulation.getCorrectSystemTime(); + for (RouteSequence routeSequence : simulation.getCtcRepository().getRouteSequenceMap().values()) { + for (RouteSequence.Line line : routeSequence.getLines()) { + if (line.isAutoTrigger()) { + if (line.getRoute() != null && correctSystemTime.toLocalTime().isAfter(line.getPlanTime())) { + ciApiService.settingRoute(simulation, line.getRouteCode()); + } + } + } + } + } + /** + * 更新行车日志状态 + */ + private void updateRunPlanLog(Simulation simulation) { + SimulationDataRepository repository = simulation.getRepository(); + CtcRepository ctcRepository = simulation.getCtcRepository(); + for (TrainInfo trainInfo : repository.getSuperviseTrainList()) { + VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); + SectionPosition headPosition = train.getHeadPosition(); + Section headSection = headPosition.getSection(); + Station station = headSection.getStation(); + CtcStationRunPlanLog runPlan = ctcRepository.getRunPlan(station.getCode(), trainInfo.getServiceNumber()); + // 接车计划到点:列车占压区段与接车计划股道一致,且列车是停站状态 + CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); + if (arriveRunPlan != null) { + if (headSection.equals(arriveRunPlan.getTrackSection()) && train.isParkingAt()) { + arriveRunPlan.setActualTime(simulation.getCorrectSystemTime().toLocalTime().toString()); + } + } + // 发车计划发点:列车位置越过出站信号机 + CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan(); + if (departRunPlan != null) { + Section trackSection = departRunPlan.getTrackSection(); + Signal signal = trackSection.getSignalOf(departRunPlan.isRight()); + if (headPosition.isAheadOf(signal.getPosition(), departRunPlan.isRight())) { + departRunPlan.setActualTime(simulation.getCorrectSystemTime().toLocalTime().toString()); + } + } + } + } + + private void sendAllTrackViewMessage(Simulation simulation) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + List> list = new ArrayList<>(); + for (TrackViewVO vo : ctcRepository.getTrackViewVOMap().values()) { + Map map = new HashMap<>(); + map.put("stationCode", vo.getStationCode()); + map.put("trackView", vo); + list.add(map); + } + SocketMessageVO message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), list); + stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); } private void sendTrackViewMessage(Simulation simulation) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java index cfff14a4a..9106db37f 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java @@ -26,6 +26,8 @@ public class CtcRepository { */ private final Map routeSequenceVOMap = new HashMap<>(); + private final Map trackViewVOMap = new HashMap<>(); + /** * 全量运行计划 */ @@ -67,6 +69,8 @@ public class CtcRepository { public void reset() { + routeSequenceMap.clear(); + routeSequenceVOMap.clear(); // 编辑区清空 this.simulationRunPlanEditAreaMap.clear(); // 仿真运行数据直接清空 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java index 8a4d5f08c..94c0e8e2c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java @@ -252,7 +252,7 @@ public class CtcStationRunPlanLog { private String adjacentStatus; /** - * 同意邻站发车、邻站同意发车 + * 同意邻站发车、邻站同意发车(0,1,2分别代表无状态、发起预告/接到预告、完成预告) */ private String adjacentMessage; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java index dc4e82e9d..8bc28cd32 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequence.java @@ -70,29 +70,34 @@ public class RouteSequence { public static Line buildLine(CtcStationRunPlanLog.RunPlanItem item, boolean departure) { Section trackSection = item.getTrackSection(); - if (trackSection == null) - return null; boolean right = item.isRight(); Signal startSignal; Signal endSignal; - if (departure) { //发车 - startSignal = trackSection.getSignalOf(right); //股道的同向信号机作为发车进路的起始信号机 - if (startSignal == null || !startSignal.isShunting2()) //没有出站信号机的股道不生成进路序列 - return null; - endSignal = item.getStationDirection().getSignal(); - } else { //接车 - startSignal = item.getStationDirection().getSignal(); - endSignal = trackSection.getSignalOf(!right); //股道的反向信号机作为接车进路终点信号机 - if (endSignal == null || !endSignal.isShunting2()) - return null; + Route route = null; + if (trackSection != null) { + if (departure) { //发车 + startSignal = trackSection.getSignalOf(right); //股道的同向信号机作为发车进路的起始信号机 + if (startSignal == null || !startSignal.isShunting2()) //没有出站信号机的股道不生成进路序列 + startSignal = null; + endSignal = item.getStationDirection().getSignal(); + } else { //接车 + startSignal = item.getStationDirection().getSignal(); + Signal tempEndSignal = trackSection.getSignalOf(!right); + if (tempEndSignal == null || !tempEndSignal.isShunting2()) + endSignal = null; + else + endSignal = tempEndSignal; //股道的反向信号机作为接车进路终点信号机 + } + if (startSignal != null && endSignal != null) { + route = startSignal.getRouteList().stream() + .filter(r -> Objects.equals(r.getDestination(), endSignal)) + .findAny().orElse(null); + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(route, + String.format("车次[%s]的[%s]进路找不到", item.getTripNumber(), departure ? "发车" : "接车")); + } } - Route route = startSignal.getRouteList().stream() - .filter(r -> Objects.equals(r.getDestination(), endSignal)) - .findAny().orElse(null); - BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(route, - String.format("车次[%s]的[%s]进路找不到", item.getTripNumber(), departure ? "发车" : "接车")); - LocalTime planTime = item.getPlanTime().minusMinutes(9); int id = idGenerator.getAndIncrement(); + LocalTime planTime = item.getPlanTime().minusMinutes(9); return new Line(String.valueOf(id), item, false, departure, planTime, planTime, route); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java index 792c58c62..83ca97131 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/RouteSequenceVO.java @@ -30,7 +30,9 @@ public class RouteSequenceVO { public RouteSequenceVO(RouteSequence routeSequence) { this.stationCode = routeSequence.getStationCode(); this.readOnly = routeSequence.isReadOnly(); - this.lines = routeSequence.getLines().stream().map(LineVO::new).collect(Collectors.toList()); + this.lines = routeSequence.getLines().stream() + .filter(line -> line.getRoute() != null) //没有进路的不发送 + .map(LineVO::new).collect(Collectors.toList()); this.idLineMap = lines.stream().collect(Collectors.toMap(LineVO::getId, Function.identity())); } @@ -51,6 +53,10 @@ public class RouteSequenceVO { } List properties = new ArrayList<>(); for (RouteSequence.Line line : routeSequence.getLines()) { + // TODO: 2022/6/14 需要考虑修改股道之后,对应的进路序列删除的逻辑 + if (line.getRoute() == null) { + continue; + } LineVO vo = findLine(line.getId()); if (vo == null) { vo = new LineVO(line); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackView.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackView.java new file mode 100644 index 000000000..ddd67cdf2 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackView.java @@ -0,0 +1,11 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TrackView { + private CtcStationRunPlanLog runPlan; + +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackViewVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackViewVO.java index 86b804c1b..2b11853c7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackViewVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/TrackViewVO.java @@ -1,10 +1,11 @@ package club.joylink.rtss.simulation.cbtc.CTC.data; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.springframework.util.StringUtils; -import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -16,12 +17,14 @@ public class TrackViewVO { private Map sectionAndTrackInfo; - class TrackInfo { + public static class TrackInfo { private boolean occupied; private List lines; } + @Getter + @Setter class Line { private String tripNumber; @@ -29,35 +32,155 @@ public class TrackViewVO { private String trainDistanceInfo; - private Process process; +// private Process process; - private boolean receivingNotice; +// private boolean receivingNotice; private boolean receivingRouteLock; - private String receivingRouteCode; + @JsonIgnore + private RouteSequence.Line receivingRoute; - private boolean receivingRouteAutoTrigger; +// private boolean arrive; - private boolean arrive; - - private boolean departureNotice; +// private boolean departureNotice; private boolean departureRouteLock; - private String departureRouteCode; + @JsonIgnore + private RouteSequence.Line departureRoute; - private boolean departureRouteAutoTrigger; +// private boolean departure; - private boolean departure; +// private LocalDateTime arriveTime; +// +// private LocalDateTime departureTime; +// +// private LocalDateTime planArriveTime; +// +// private LocalDateTime planDepartureTime; - private LocalDateTime arriveTime; + public Process getProcess() { + if (isDeparture()) { + return Process.FINISH; + } + if (departureRouteLock) { + return Process.DEPARTURE; + } + if (isDepartureNotice()) { + return Process.DEPARTURE_ROUTE; + } + if (isArrive()) { + return Process.DEPARTURE_BLOCK; + } + if (receivingRouteLock) { + return Process.ARRIVE; + } + if (isReceivingNotice()) { + return Process.RECEIVING_ROUTE; + } + if (receivingRoute != null) { + if (CtcStationRunPlanLog.RunPlanItem.WAIT.equals(receivingRoute.getItem().getAdjacentMessage())) { + return Process.RECEIVING; + } + } + return Process.RECEIVING_BLOCK; + } - private LocalDateTime departureTime; + public String getReceivingRouteCode() { + if (receivingRoute != null) { + return receivingRoute.getRouteCode(); + } else { + return null; + } + } - private LocalDateTime planArriveTime; + public String getDepartureRouteCode() { + if (departureRoute != null) { + return departureRoute.getRouteCode(); + } else { + return null; + } + } - private LocalDateTime planDepartureTime; + public boolean getReceivingRouteAutoTrigger() { + if (receivingRoute == null) { + return false; + } else { + return receivingRoute.isAutoTrigger(); + } + } + + public boolean getDepartureRouteAutoTrigger() { + if (departureRoute == null) { + return false; + } else { + return departureRoute.isAutoTrigger(); + } + } + + public boolean isReceivingNotice() { + if (receivingRoute != null) { + if (CtcStationRunPlanLog.RunPlanItem.FINISH.equals(receivingRoute.getItem().getAdjacentMessage())) { + return true; + } + } + return false; + } + + /** + * 已经完成发预? + */ + public boolean isDepartureNotice() { + if (departureRoute != null) { + if (CtcStationRunPlanLog.RunPlanItem.FINISH.equals(departureRoute.getItem().getAdjacentMessage())) { + return true; + } + } + return false; + } + + public boolean isArrive() { + if (receivingRoute != null) { + if (StringUtils.hasText(receivingRoute.getItem().getActualTime())) { + return true; + } + } + return false; + } + + public boolean isDeparture() { + if (departureRoute != null) { + if (StringUtils.hasText(departureRoute.getItem().getActualTime())) { + return true; + } + } + return false; + } + + public String getArriveTime() { + if (receivingRoute ==null) + return null; + return receivingRoute.getItem().getActualTime(); + } + + public String getPlanArriveTime() { + if (receivingRoute == null) + return null; + return receivingRoute.getItem().getPlanTime().toString(); + } + + public String getDepartureTime() { + if (departureRoute ==null) + return null; + return departureRoute.getItem().getActualTime(); + } + + public String getPlanDepartureTime() { + if (departureRoute == null) + return null; + return departureRoute.getItem().getPlanTime().toString(); + } } enum Process { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java b/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java index 1a6593938..c2ba98d8a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java @@ -6,6 +6,7 @@ import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.simulation.cbtc.ATS.data.SimulationLog; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository; import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder; import club.joylink.rtss.simulation.cbtc.command.VoiceCommandBO; import club.joylink.rtss.simulation.cbtc.competition.CompetitionBO; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; @@ -576,6 +577,7 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation member.setCommand(null)); this.planRunning = false; if (!CollectionUtils.isEmpty(simulationConversationMap)) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java index 9be71e0e6..2ab42c145 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java @@ -110,7 +110,7 @@ public class SimulationBuilder { return simulation; } - private static void generateRouteSequence(Simulation simulation) { + public static void generateRouteSequence(Simulation simulation) { SimulationDataRepository repository = simulation.getRepository(); CtcRepository ctcRepository = simulation.getCtcRepository(); Map> stationLineMap = new HashMap<>(); @@ -122,14 +122,12 @@ public class SimulationBuilder { CtcStationRunPlanLog.RunPlanItem arriveRunPlan = plan.getArriveRunPlan(); if (arriveRunPlan != null) { RouteSequence.Line line = RouteSequence.buildLine(arriveRunPlan, false); - if (line != null) - lines.add(line); + lines.add(line); } CtcStationRunPlanLog.RunPlanItem departRunPlan = plan.getDepartRunPlan(); if (departRunPlan != null) { RouteSequence.Line line = RouteSequence.buildLine(departRunPlan, true); - if (line != null) - lines.add(line); + lines.add(line); } } Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); @@ -419,7 +417,6 @@ public class SimulationBuilder { * @param arriveFlag 到达 * @param stationPlan 运行计划 * @param ctcRunPlanParam 参数实体 - * @param adjacentStationCode 邻站编码 */ private static void initRunPlanParam(boolean arriveFlag, StationPlan stationPlan, CtcRunPlanParam ctcRunPlanParam, Station adjacentStation) { StationDirection.ReceiveAndDeliverModel defaultRunStatus;