CTC股道视图恢复中

This commit is contained in:
thesai 2022-06-15 00:29:36 +08:00
parent 6175a33da4
commit 8499b22642
9 changed files with 258 additions and 48 deletions

View File

@ -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<Map<String, Object>> list = new ArrayList<>();
for (TrackViewVO vo : ctcRepository.getTrackViewVOMap().values()) {
Map<String, Object> map = new HashMap<>();
map.put("stationCode", vo.getStationCode());
map.put("trackView", vo);
list.add(map);
}
SocketMessageVO<Object> message = SocketMessageFactory.buildCtcRouteSequenceMessage(simulation.getId(), list);
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
}
private void sendTrackViewMessage(Simulation simulation) {

View File

@ -26,6 +26,8 @@ public class CtcRepository {
*/
private final Map<String, RouteSequenceVO> routeSequenceVOMap = new HashMap<>();
private final Map<String, TrackViewVO> trackViewVOMap = new HashMap<>();
/**
* 全量运行计划
*/
@ -67,6 +69,8 @@ public class CtcRepository {
public void reset() {
routeSequenceMap.clear();
routeSequenceVOMap.clear();
// 编辑区清空
this.simulationRunPlanEditAreaMap.clear();
// 仿真运行数据直接清空

View File

@ -252,7 +252,7 @@ public class CtcStationRunPlanLog {
private String adjacentStatus;
/**
* 同意邻站发车邻站同意发车
* 同意邻站发车邻站同意发车0,1,2分别代表无状态发起预告/接到预告完成预告
*/
private String adjacentMessage;

View File

@ -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);
}

View File

@ -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<Object> 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);

View File

@ -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;
}

View File

@ -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<String, TrackInfo> sectionAndTrackInfo;
class TrackInfo {
public static class TrackInfo {
private boolean occupied;
private List<Line> 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 {

View File

@ -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<Simulati
this.repository.reset();
this.iscsRepository.reset();
this.ctcRepository.reset();
SimulationBuilder.generateRouteSequence(this); // TODO: 2022/6/14 重新考虑重置逻辑
this.getSimulationMembers().forEach(member -> member.setCommand(null));
this.planRunning = false;
if (!CollectionUtils.isEmpty(simulationConversationMap)) {

View File

@ -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<String, List<RouteSequence.Line>> 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<String, RouteSequence> 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;