大铁CTC逻辑(未完)

This commit is contained in:
joylink_zhangsai 2022-04-22 13:47:39 +08:00
parent fedf7b2e3f
commit 0c1e5f2268
25 changed files with 431 additions and 129 deletions

2
mvnw vendored
View File

@ -161,7 +161,7 @@ fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# traverses directory structure from mean work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {

View File

@ -13,6 +13,7 @@ public enum MapPrdTypeEnum {
BIG_SCREEN("07", "大屏工作站"),
RUN_PLAN_MAKE("08", "运行图编制工作站"),
DEPOT_IL("09", "车辆段联锁工作站"),
CTC("10", "CTC工作站")
;
private String code;

View File

@ -769,9 +769,9 @@ public class DraftMapController {
iDraftMapService.deleteOperationDefinition(mapId, code);
}
// //临时接口
// @PostMapping("/handle/ctc/{id}")
// public void handle(@PathVariable Long id) {
// iDraftMapService.handle(id);
// }
//临时接口
@PostMapping("/handle/ctc/{id}")
public void handle(@PathVariable Long id) {
iDraftMapService.handle(id);
}
}

View File

@ -5,8 +5,6 @@ import club.joylink.rtss.dao.MapSystemDAO;
import club.joylink.rtss.entity.MapSystem;
import club.joylink.rtss.entity.MapSystemExample;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.org.IOrgLessonService;
import club.joylink.rtss.services.org.IOrgService;
import club.joylink.rtss.services.org.IOrgUserService;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO;
@ -58,12 +56,6 @@ public class MapSystemService implements IMapSystemService {
@Autowired
private IOrgUserService iOrgUserService;
@Autowired
private IOrgService iOrgService;
@Autowired
private IOrgLessonService iOrgLessonService;
@Autowired
private IExamService iExamService;
@ -73,6 +65,12 @@ public class MapSystemService implements IMapSystemService {
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(iMapService.isExist(mapId),
String.format("id为[%s]的地图不存在", mapId));
for (MapPrdTypeEnum value : MapPrdTypeEnum.values()) {
if (MapPrdTypeEnum.CTC.equals(value)) {
MapVO mapDetail = iMapService.getMapDetail(mapId);
if (!mapDetail.getConfigVO().isHasCTC()) {
continue;
}
}
generate(mapId, value);
}
}

View File

@ -455,6 +455,11 @@ public class Operation {
*/
CTC_DEPARTURE_NOTICE,
/**
* CTC进路自触
*/
CTC_ROUTE_AUTO_TRIGGER,
//---------------------------- 改方辅助操作 -------------------------
/**
* 按下改方按钮

View File

@ -1,26 +1,145 @@
package club.joylink.rtss.simulation.cbtc.CTC;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationPlan;
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsRouteSelectService;
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Routing;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
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.plan.StationPlan;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
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.factory.SocketMessageFactory;
import club.joylink.rtss.websocket.StompMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.*;
@Component
public class CTCLogicLoop {
public static final String NAME = "CTC";
public static final int RATE = 1000;
@Autowired
@Qualifier(value = "atsPlanTrainRouteSelectServiceImpl")
private AtsRouteSelectService atsRouteSelectService;
@Autowired
private StompMessageService stompMessageService;
public void run(Simulation simulation) {
buildNewCtcStationPlan(simulation);
updateCtcStationPlan(simulation);
sendMessage(simulation);
}
private void sendMessage(Simulation simulation) {
CtcRepository ctcRepository = simulation.getCtcRepository();
List<BusyBoard> list = new ArrayList<>();
Map<String, Map<String, CtcStationPlan>> map = ctcRepository.getCtcStationPlanMap();
for (Map.Entry<String, Map<String, CtcStationPlan>> entry : map.entrySet()) {
String stationCode = entry.getKey();
BusyBoard busyBoard = new BusyBoard(stationCode);
list.add(busyBoard);
TrackView trackView = busyBoard.getTrackView();
RouteSequence routeSequence = busyBoard.getRouteSequence();
for (CtcStationPlan value : entry.getValue().values()) {
trackView.addLine(new TrackView.Line(value));
RouteSequence.Line receivingLine = RouteSequence.Line.buildReceivingLine(value);
if (receivingLine != null) {
receivingLine.setStartTime(simulation.getCorrectSystemTime().toLocalTime());
routeSequence.addLine(receivingLine);
}
RouteSequence.Line departureLine = RouteSequence.Line.buildDepartureLine(value);
if (departureLine != null) {
departureLine.setStartTime(simulation.getCorrectSystemTime().toLocalTime());
routeSequence.addLine(departureLine);
}
}
routeSequence.getLines().sort((o1, o2) -> o1.getPlanTime().isBefore(o2.getPlanTime()) ? -1 : 1);
}
if (!CollectionUtils.isEmpty(list)) {
SocketMessageVO<List<BusyBoard>> message = SocketMessageFactory.buildRailCtcMessage(simulation.getId(), list);
Set<String> userIds = simulation.getSimulationUserIds();
stompMessageService.sendToUser(userIds, message);
}
}
private void updateCtcStationPlan(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
CtcRepository ctcRepository = simulation.getCtcRepository();
Map<String, String> deleteMap = new HashMap<>();
for (Map<String, CtcStationPlan> ctcStationPlanMap : ctcRepository.getCtcStationPlanMap().values()) {
Collection<CtcStationPlan> ctcStationPlans = ctcStationPlanMap.values();
for (CtcStationPlan ctcStationPlan : ctcStationPlans) {
if (ctcStationPlan.getDeleteRemain() != 0) { //流程终止准备删除
int deleteRemain = ctcStationPlan.getDeleteRemain();
deleteRemain -= RATE;
if (deleteRemain <= 0) {
deleteMap.put(ctcStationPlan.getStationCode(), ctcStationPlan.getTripNumber());
}
}
/* 按接发车流程倒序检查 */
StationPlan receivingPlan = ctcStationPlan.getReceivingPlan();
boolean planRight = receivingPlan.isRight();
Section receivingSection = receivingPlan.getSection();
VirtualRealityTrain train = repository.getOnlineTrainBy(ctcStationPlan.getTrainInfo().getGroupNumber());
SectionPosition headPosition = train.getHeadPosition();
//发点
Signal departureSignal = receivingSection.getSignalOf(planRight); //发车信号机
if (headPosition.isAheadOf(departureSignal.getPosition(), planRight)) {
ctcStationPlan.updateProcess(CtcStationPlan.Process.FINISH);
ctcStationPlan.setDeleteRemain(CtcStationPlan.DEFAULT_REMAIN);
}
//发车进路办理
if (!ctcStationPlan.isDepartureRouteLock()) {
if (ctcStationPlan.getDepartureRoute().isLock()) {
ctcStationPlan.setDepartureRouteLock(true);
}
}
if (ctcStationPlan.isDepartureRouteLock()) {
ctcStationPlan.updateProcess(CtcStationPlan.Process.DEPARTURE);
}
//发预
if (ctcStationPlan.isDepartureNotice() && ctcStationPlan.getDeparturePlan() != null) { //邻站发车预告
CtcStationPlan departureCtcStationPlan = ctcRepository
.getCtcStationPlan(ctcStationPlan.getDeparturePlan().getStation().getCode(), ctcStationPlan.getTripNumber());
departureCtcStationPlan.updateProcess(CtcStationPlan.Process.RECEIVING);
}
//到点
Signal receivingSignal = receivingSection.getSignalOf(!planRight); //接车信号机
if (headPosition.isAheadOf(receivingSignal.getPosition(), planRight)) {
ctcStationPlan.setArrive(true);
}
//接车进路办理
if (!ctcStationPlan.isReceivingRouteLock()) {
if (ctcStationPlan.getReceivingRoute().isLock()) {
ctcStationPlan.setReceivingRouteLock(true);
}
}
if (ctcStationPlan.isReceivingRouteLock()) {
ctcStationPlan.updateProcess(CtcStationPlan.Process.ARRIVE);
}
//接预
if (ctcStationPlan.isReceivingNotice()) {
ctcStationPlan.updateProcess(CtcStationPlan.Process.RECEIVING_ROUTE);
}
}
}
for (Map.Entry<String, String> entry : deleteMap.entrySet()) {
ctcRepository.deleteCtcStationPlan(entry.getKey(), entry.getValue());
}
}
private void buildNewCtcStationPlan(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
CtcRepository ctcRepository = simulation.getCtcRepository();
List<TrainInfo> superviseTrainList = repository.getSuperviseTrainList();
@ -31,47 +150,47 @@ public class CTCLogicLoop {
}
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber());
VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber());
SectionPosition headPosition = train.getHeadPosition();
CtcStationPlan ctcStationPlan = new CtcStationPlan();
ctcStationPlan.setTripNumber(tripPlan.getTripNumber());
if (trainInfo.isParking()) {
//接车信息已完成
Section headSection = headPosition.getSection();
StationPlan currentStationPlan = tripPlan.queryStationPlan(headSection);
ctcStationPlan.setReceivingPlan(currentStationPlan);
ctcStationPlan.setReceivingRouteLock(true);
ctcStationPlan.setArrive(true);
//发车信息
StationPlan nextStationPlan = tripPlan.queryNextStationPlan(headSection);
ctcStationPlan.setDeparturePlan(nextStationPlan);
Signal signal = headSection.getSignalOf(tripPlan.isRight());
List<Routing> routings = repository.getRoutings(tripPlan.getStartSection(), tripPlan.getEndSection(), tripPlan.isRight());
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(routings);
Routing routing = routings.get(0);
StationPlan stationPlan = tripPlan.queryNextStationPlanByStationCode(trainInfo.getStationCode());
Section previousSection = train.getHeadPosition().getSection(); //前一个的停车区段
while (stationPlan != null) {
CtcStationPlan ctcStationPlan = new CtcStationPlan(trainInfo, stationPlan);
ctcRepository.addCtcStationPlan(ctcStationPlan);
Section headSection = train.getHeadPosition().getSection();
List<RoutePath> paths = repository.queryRoutePathsByEndAndContainsSection(stationPlan.getSection(), previousSection);
if (!CollectionUtils.isEmpty(paths)) {
/* 接车 */
if (headSection.equals(stationPlan.getSection())) { //到站了
ctcStationPlan.setReceivingNotice(true);
ctcStationPlan.setReceivingRouteLock(true);
ctcStationPlan.setArrive(true);
ctcStationPlan.updateProcess(CtcStationPlan.Process.ARRIVE);
} else { //没到站
RoutePath routePath = atsRouteSelectService.selectRoutePath(paths);
Route receivingRoute = routePath.getLastRoute();
ctcStationPlan.setReceivingRoute(receivingRoute);
ctcStationPlan.updateProcess(CtcStationPlan.Process.RECEIVING);
}
/* 发车 */
List<RoutePath> routePaths;
StationPlan nextStationPlan = tripPlan.queryNextStationPlan(stationPlan.getStation());
if (nextStationPlan != null) {
routePaths = repository.getRoutePaths(stationPlan.getSection(), nextStationPlan.getSection());
ctcStationPlan.setDeparturePlan(nextStationPlan);
} else {
routePaths = repository.getRoutePaths(stationPlan.getSection(), tripPlan.getEndSection());
}
RoutePath routePath = atsRouteSelectService.selectRoutePath(routePaths);
Route departureRoute = routePath.getFirstRoute();
ctcStationPlan.setDepartureRoute(departureRoute);
}
previousSection = stationPlan.getSection();
stationPlan = tripPlan.queryNextStationPlan(stationPlan.getStation());
}
}
}
// CtcRepository ctcRepository = new CtcRepository(); //添加到simulation中
// if (CollectionUtils.isEmpty(ctcRepository.getStationBusyBoardMap())) {
// List<TripPlan> allTripPlanList = simulation.getRepository().getAllTripPlanList();
// Map<Station, List<StationPlan>> stationPlanMap = allTripPlanList.stream()
// .flatMap(tripPlan -> tripPlan.getPlanList().stream())
// .collect(Collectors.groupingBy(StationPlan::getStation));
// for (Map.Entry<Station, List<StationPlan>> entry : stationPlanMap.entrySet()) {
// Station station = entry.getKey();
// List<StationPlan> plans = entry.getValue();
// BusyBoard busyBoard = new BusyBoard();
// busyBoard.setStationCode(station.getCode());
//
// ctcRepository.addBusyBoard(busyBoard);
// }
// }
}
public void addJobs(Simulation simulation) {
simulation.addJob(SimulationModule.CTC.name(), () -> this.run(simulation), SimulationModule.CTC.getRateMs());
simulation.addJob(NAME, () -> this.run(simulation), RATE);
}
}

View File

@ -4,6 +4,8 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationPlan;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import org.springframework.stereotype.Component;
@Component
@ -29,4 +31,10 @@ public class CTCService {
CtcStationPlan ctcStationPlan = ctcRepository.findCtcStationPlan(stationCode, tripNumber);
ctcStationPlan.setDepartureNotice(true);
}
public void routeAutoTrigger(Simulation simulation, String routeCode, boolean trigger) {
SimulationDataRepository repository = simulation.getRepository();
Route route = repository.getRoute(routeCode);
route.setCtcControl(trigger);
}
}

View File

@ -10,10 +10,14 @@ public class BusyBoard {
/**
* 股道视图
*/
private TrackView trackView;
private TrackView trackView = new TrackView();
/**
* 进路序列
*/
private RouteSequence routeSequence;
private RouteSequence routeSequence = new RouteSequence();
public BusyBoard(String stationCode) {
this.stationCode = stationCode;
}
}

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import lombok.Getter;
import org.springframework.util.CollectionUtils;
@ -8,22 +9,12 @@ import java.util.concurrent.ConcurrentHashMap;
@Getter
public class CtcRepository {
private final Map<String, BusyBoard> stationBusyBoardMap = new ConcurrentHashMap<>();
/**
* k - stationCode
* k-tripNumber
*/
private final Map<String, Map<String, CtcStationPlan>> ctcStationPlanMap = new ConcurrentHashMap<>();
public void addBusyBoard(BusyBoard busyBoard) {
stationBusyBoardMap.put(busyBoard.getStationCode(), busyBoard);
}
public BusyBoard getBusyBoard(String stationCode) {
return stationBusyBoardMap.get(stationCode);
}
public void addCtcStationPlan(CtcStationPlan stationPlan) {
Map<String, CtcStationPlan> map = ctcStationPlanMap.computeIfAbsent(stationPlan.getReceivingPlan().getStation().getCode(),
(k) -> new ConcurrentHashMap<>());
@ -42,4 +33,21 @@ public class CtcRepository {
return ctcStationPlanMap.entrySet().stream()
.anyMatch(entry -> entry.getValue().containsKey(tripNumber));
}
public CtcStationPlan getCtcStationPlan(String stationCode, String tripNumber) {
CtcStationPlan plan = findCtcStationPlan(stationCode, tripNumber);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(plan);
return plan;
}
public void deleteCtcStationPlan(String stationCode, String tripNumber) {
Map<String, CtcStationPlan> map = ctcStationPlanMap.get(stationCode);
if (!CollectionUtils.isEmpty(map)) {
map.remove(tripNumber);
}
}
public void reset() {
this.ctcStationPlanMap.clear();
}
}

View File

@ -2,6 +2,8 @@ package club.joylink.rtss.simulation.cbtc.CTC.data;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@ -11,7 +13,7 @@ import lombok.Setter;
@Getter
@Setter
public class CtcStationPlan {
private String tripNumber;
private TrainInfo trainInfo;
/**
* 该车站的接车计划
@ -23,11 +25,6 @@ public class CtcStationPlan {
*/
private StationPlan departurePlan;
/**
* 邻站的发车预告
*/
private boolean adjacentDepartureNotice;
private boolean receivingNotice;
private Route receivingRoute;
@ -50,20 +47,60 @@ public class CtcStationPlan {
private boolean departure;
@Getter
public enum Process {
RECEIVING_NOTICE("接预"), //接预
RECEIVING_ROUTE("接路"), //接路
ARRIVE("到点"), //到点
DEPARTURE_NOTICE("发预"), //发预
DEPARTURE_ROUTE("发路"), //发路
DEPARTURE("发点"), //发点
;
@Setter(AccessLevel.NONE)
private Process process;
private final String name;
/**
* 删除倒计时流程终止后10秒删除
*/
private int deleteRemain;
public static final int DEFAULT_REMAIN = 10 * 1000;
Process(String name) {
this.name = name;
public CtcStationPlan(TrainInfo trainInfo, StationPlan receivingPlan) {
this.trainInfo = trainInfo;
this.receivingPlan = receivingPlan;
}
public String getTripNumber() {
return trainInfo.getTripNumber();
}
public void updateProcess(Process process) {
if (this.process == null) {
this.process = process;
} else {
if (this.process.ordinal() < process.ordinal()) {
this.process = process;
}
}
}
public String getStationCode() {
return receivingPlan.getStation().getCode();
}
public enum Process {
RECEIVING, //准备接车
RECEIVING_ROUTE, //办理接车进路
ARRIVE, //列车到达通过报点
DEPARTURE, //发车进路办理发车报点
FINISH //流程终止
}
// @Getter
// public enum Mean {
// RECEIVING_NOTICE("接预"), //接预
// RECEIVING_ROUTE("接路"), //接路
// ARRIVE("到点"), //到点
// DEPARTURE_NOTICE("发预"), //发预
// DEPARTURE_ROUTE("发路"), //发路
// DEPARTURE("发点"), //发点
// ;
//
// private final String name;
//
// Mean(String name) {
// this.name = name;
// }
// }
}

View File

@ -1,26 +1,31 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
/**
* 进路序列
*/
@Getter
@Setter
public class RouteSequence {
/**
* 进路序列模式可修改/只读
*/
private String mode;
private boolean readOnly;
private List<Line> lines;
private List<Line> lines = new ArrayList<>();
public void addLine(Line line) {
this.lines.add(line);
}
@Getter
@Setter
@Builder
public static class Line {
/**
* 车次
@ -32,10 +37,10 @@ public class RouteSequence {
*/
private String trackName;
/**
* 自触
*/
private boolean autoTrigger;
// /**
// * 自触
// */
// private boolean autoTrigger;
/**
* 类型
@ -55,6 +60,32 @@ public class RouteSequence {
/**
* 序列描述大概是进路名称吧
*/
private String routeName;
private String routeCode;
public static Line buildReceivingLine(CtcStationPlan plan) {
if (plan.getReceivingRoute() != null) {
Line line = new Line();
line.tripNumber = plan.getTripNumber();
line.trackName = plan.getReceivingPlan().getSection().getName();
line.type = "接车";
line.planTime = plan.getReceivingPlan().getArriveTime();
line.routeCode = plan.getReceivingRoute().getCode();
return line;
}
return null;
}
public static Line buildDepartureLine(CtcStationPlan plan) {
if (plan.getDepartureRoute() != null) {
Line line = new Line();
line.tripNumber = plan.getTripNumber();
line.trackName = plan.getReceivingPlan().getSection().getName();
line.type = "发车";
line.planTime = plan.getReceivingPlan().getLeaveTime();
line.routeCode = plan.getDepartureRoute().getCode();
return line;
}
return null;
}
}
}

View File

@ -1,19 +1,23 @@
package club.joylink.rtss.simulation.cbtc.CTC.data;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
public class TrackView {
private List<Line> lines = new ArrayList<>();
public void addLine(Line line) {
this.lines.add(line);
}
@Getter
@Setter
@Builder
public static class Line {
/**
* 轨道名
@ -38,12 +42,26 @@ public class TrackView {
/**
* 接发车流程
*/
private Process process;
private CtcStationPlan.Process process;
/**
* 接预发预等按钮
* 接预
*/
private List<Button> buttons;
private boolean receivingNotice;
private boolean receivingRouteLock;
private String receivingRouteCode;
private boolean arrive;
private boolean departureNotice;
private boolean departureRouteLock;
private String departureRouteCode;
private boolean departure;
/**
* 预计到达时间
@ -64,15 +82,29 @@ public class TrackView {
* 计划发车时间
*/
private LocalTime planDepartureTime;
public Line(CtcStationPlan plan) {
this.trackName = plan.getReceivingPlan().getSection().getName();
this.tripNumber = plan.getTripNumber();
// this.trainType =
// this.trainDistanceInfo
this.process = plan.getProcess();
this.receivingNotice = plan.isReceivingNotice();
this.receivingRouteLock = plan.isReceivingRouteLock();
this.receivingRouteCode = plan.getReceivingRoute() == null ? null : plan.getReceivingRoute().getCode();
this.arrive = plan.isArrive();
this.departureNotice = plan.isDepartureNotice();
this.departureRouteLock = plan.isDepartureRouteLock();
this.departureRouteCode = plan.getDepartureRoute() == null ? null : plan.getDepartureRoute().getCode();
this.departure = plan.isDeparture();
}
}
@Getter
enum Process {
RECEIVING_BLOCK(""), //办理接车闭塞
enum Mean {
RECEIVING_NOTICE("接预"), //接预
RECEIVING_ROUTE("接路"), //接路
ARRIVE("到点"), //到点
DEPARTURE_BLOCK(""), //办理发车闭塞
DEPARTURE_NOTICE("发预"), //发预
DEPARTURE_ROUTE("发路"), //发路
DEPARTURE("发点"), //发点
@ -80,7 +112,7 @@ public class TrackView {
private final String name;
Process(String name) {
Mean(String name) {
this.name = name;
}
}
@ -96,7 +128,9 @@ public class TrackView {
/**
* 按钮代表的流程
*/
private Process process;
private Mean mean;
private String routeCode;
/**
* 按钮的颜色
@ -104,7 +138,8 @@ public class TrackView {
private Color color;
}
enum Color {
@Getter
public enum Color {
GREY,
YELLOW,
RED,

View File

@ -31,4 +31,8 @@ public class BusyBoardOperateHandler {
ctcService.departureNotice(simulation, stationCode, tripNumber);
}
@OperateHandlerMapping(type = Operation.Type.CTC_ROUTE_AUTO_TRIGGER)
public void routeAutoTrigger(Simulation simulation, String routeCode, boolean trigger) {
ctcService.routeAutoTrigger(simulation, routeCode, trigger);
}
}

View File

@ -575,6 +575,7 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
}
this.repository.reset();
this.iscsRepository.reset();
this.ctcRepository.reset();
this.getSimulationMembers().forEach(member -> member.setCommand(null));
this.planRunning = false;
if (!CollectionUtils.isEmpty(simulationConversationMap)) {

View File

@ -241,18 +241,16 @@ public class InterlockBuilder2 {
// ------------站间运行等级end-------------
// ------------目的地码start-------------
long start = System.currentTimeMillis();
InterlockBuilder2.checkAndBuildDestinationCodeDefinition(elementMap, logicData.getDestinationCodeDefinitionList(), mapDataBuildResult.getDestinationMap(), errMsgList);
InterlockBuilder2.log.info("目的地码构建耗时:" + (System.currentTimeMillis() - start));
// ------------目的地码end-------------
// 处理指示灯按钮逻辑信息
InterlockBuilder2.buildAssistIndicatorAndButtonLogic(elementMap, errMsgList, logicData.getIndicatorButtonVOList());
// 根据站间运行等级数据构建路径单元
if (!errMsgList.isEmpty()) {
return;
}
// if (!errMsgList.isEmpty()) {
// return;
// }
InterlockBuilder2.buildRoutePathFromStationRunLevel(stationRunLevelList, mapDataBuildResult, errMsgList);
// buildParkTimes(logicData, elementMap, mapDataBuildResult.getParkTimeMap(), errMsgList);
}
@ -1049,11 +1047,26 @@ public class InterlockBuilder2 {
private static void buildRoutePathFromStationRunLevel(List<StationRunLevel> stationRunLevelList,
SimulationBuilder.SimulationDeviceBuildResult buildResult,
List<String> errMsgList) {
long start = System.currentTimeMillis();
Map<String, List<RoutePath>> routePathMap = buildResult.getRoutePathMap();
Map<String, MapElement> deviceMap = buildResult.getDeviceMap();
List<Section> sections = deviceMap.values().stream()
.filter(device -> device instanceof Section)
.map(device -> (Section) device)
.filter(Section::isFunctionTrack)
.collect(Collectors.toList());
for (int i = 0; i < sections.size(); i++) {
Section start = sections.get(i);
for (int j = 0; j < sections.size() && i != j; j++) {
Section end = sections.get(j);
List<RoutePath> routePaths = CalculateService.queryRoutePathsOnDirection(start, end, true, 100);
if (!CollectionUtils.isEmpty(routePaths)) {
routePathMap.put(routePaths.get(0).getKey(), routePaths);
}
}
}
if (CollectionUtils.isEmpty(stationRunLevelList)) {
return;
}
Map<String, List<RoutePath>> routePathMap = buildResult.getRoutePathMap();
for (StationRunLevel runLevel : stationRunLevelList) {
Section startSection = runLevel.getStartSection();
Section endSection = runLevel.getEndSection();
@ -1082,7 +1095,6 @@ public class InterlockBuilder2 {
}
}
}
System.out.println("用时" + (System.currentTimeMillis() - l));
}
// /**

View File

@ -28,10 +28,8 @@ public class UserConfigDataBuilder {
Function.identity()));
}
List<MapStationRunLevelVO> runLevelList = map.getLogicDataNew().getRunLevelList();
if (!repository.getConfig().isHasCTC()) {
if (CollectionUtils.isEmpty(runLevelList)) {
errMsgList.add("无默认运行等级数据");
}
if (CollectionUtils.isEmpty(runLevelList)) {
errMsgList.add("无默认运行等级数据");
}
for (MapStationRunLevelVO vo : runLevelList) {
String key = StationRunLevel.buildKey(vo.getStartSectionCode(), vo.getEndSectionCode());
@ -68,10 +66,8 @@ public class UserConfigDataBuilder {
.collect(Collectors.toMap(RunPlanParkingTimeVO::getSectionCode, Function.identity()));
}
List<MapStationParkingTimeVO> parkingTimeList = map.getLogicDataNew().getParkingTimeList();
if (!repository.getConfig().isHasCTC()) {
if (CollectionUtils.isEmpty(parkingTimeList)) {
errMsgList.add("无默认停站时间数据");
}
if (CollectionUtils.isEmpty(parkingTimeList)) {
errMsgList.add("无默认停站时间数据");
}
for (MapStationParkingTimeVO vo : parkingTimeList) {
voMap.putIfAbsent(vo.getSectionCode(), new RunPlanParkingTimeVO(vo));

View File

@ -59,11 +59,6 @@ public enum SimulationModule {
CATENARY(SimulationConstants.POWER_SUPPLY_STATUS_UPDATE_RATE),
ROBOT(SimulationConstants.ROBOT_LOGIC_LOOP_RATE),
/**
* 大铁CTC系统
*/
CTC(SimulationConstants.ATS_LOOP_RATE),
;
/** 执行频率-单位ms */

View File

@ -387,6 +387,13 @@ public class SimulationDataRepository {
return getListByType(MapElement.DeviceType.ROUTE, Route.class);
}
public Route getRoute(String routeCode) {
Route route = getByCode(routeCode, Route.class);
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(route,
String.format("code为[%s]的进路不存在", routeCode));
return route;
}
public List<RouteOverlap> getRouteOverlapList() {
return getListByType(MapElement.DeviceType.OVERLAP, RouteOverlap.class);
}

View File

@ -136,6 +136,10 @@ public class Route extends MapNamedElement {
private boolean checkConflict;
/** 冲突告警 */
private AtsAlarm conflictAlarm;
/**
* 大铁CTC自动触发
*/
private boolean ctcControl;
/** 按计划执行 */
public static final int Conflict_Handle_Way_1 = 1;
/** 执行冲突进路 */

View File

@ -63,4 +63,8 @@ public class StationPlan {
public void finish() {
this.finished = true;
}
public boolean isRight() {
return this.plan.isRight();
}
}

View File

@ -68,6 +68,11 @@ public class RouteStatus extends DeviceStatus {
@JsonDeserialize(using = Boolean2NumDeserializer.class)
private boolean checkConflict;
/**
* 大铁CTC自动触发
*/
private boolean ctcControl;
public RouteStatus(Route route) {
super(route.getCode(), route.getDeviceType());
this.atsControl = route.isAtsControl();
@ -80,6 +85,7 @@ public class RouteStatus extends DeviceStatus {
this.canceling = route.isDelayUnlocking();
this.normalUnlock = route.isNormalUnlock();
this.checkConflict = route.isCheckConflict();
this.ctcControl = route.isCtcControl();
}
@Override
@ -95,6 +101,7 @@ public class RouteStatus extends DeviceStatus {
statusVO.setCanceling(canceling);
statusVO.setNormalUnlock(normalUnlock);
statusVO.setCheckConflict(checkConflict);
statusVO.setCtcControl(ctcControl);
return statusVO;
}
@ -153,6 +160,11 @@ public class RouteStatus extends DeviceStatus {
status.setCheckConflict(this.checkConflict);
change = true;
}
if (!Objects.equals(this.ctcControl, route.isCtcControl())) {
this.ctcControl = route.isCtcControl();
status.setCtcControl(this.ctcControl);
change = true;
}
// if (!Objects.equals(this.conflict, route.isConflict())) {
// this.conflict = route.isConflict();
// this.conflictDesc = route.getConflictDesc();

View File

@ -480,4 +480,16 @@ public class RoutePath {
}
return route;
}
public Route getRoute(int index) {
return routeList.get(index);
}
public Route getLastRoute() {
return getRoute(routeList.size() - 1);
}
public Route getFirstRoute() {
return getRoute(0);
}
}

View File

@ -53,6 +53,9 @@ public class RouteStatusVO extends DeviceStatusVO {
@JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean checkConflict;
@JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean ctcControl;
public RouteStatusVO(Route route) {
super(route.getCode(), route.getDeviceType());
}

View File

@ -47,8 +47,8 @@ public enum WebSocketMessageType {
/** 仿真-设备状态消息 */
Simulation_DeviceStatus,
/** CTC系统的状态消息 */
Simulation_CtcStatus,
/** 大铁CTC系统的状态消息 */
Simulation_RailCtcStatus,
/** 仿真-IBP状态消息 */
Simulation_IbpStatus,
/** 仿真-PSL盘状态消息 */

View File

@ -1,6 +1,7 @@
package club.joylink.rtss.vo.client.factory;
import club.joylink.rtss.constants.BusinessConsts.WebSocketSubscribeTopic;
import club.joylink.rtss.simulation.cbtc.CTC.data.BusyBoard;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.communication.vo.TrainPosition;
import club.joylink.rtss.simulation.cbtc.conversation.Conversation;
@ -82,6 +83,7 @@ public class SocketMessageFactory {
case Simulation_User:
case Simulation_Member:
case Simulation_DeviceStatus:
case Simulation_RailCtcStatus:
case Simulation_IbpStatus:
case Simulation_PslStatus:
case Simulation_AutoFault_Trigger:
@ -383,4 +385,8 @@ public class SocketMessageFactory {
RunPlanEChartsDataVO eChartsDataVO = new RunPlanEChartsDataVO(changeTrips);
return build(WebSocketMessageType.Simulation_Trip_Plan_Change, simulationId, eChartsDataVO);
}
public static SocketMessageVO<List<BusyBoard>> buildRailCtcMessage(String simulationId, List<BusyBoard> list) {
return build(WebSocketMessageType.Simulation_RailCtcStatus, simulationId, list);
}
}