大铁:非常站控取消进路的自动触发逻辑;地图绘制增加配置,可配置线路是否有CTC/TDCS系统

This commit is contained in:
joylink_zhangsai 2022-07-18 16:34:21 +08:00
parent 32ae4fc71b
commit c2d04f684c
20 changed files with 104 additions and 45 deletions

View File

@ -67,7 +67,7 @@ public class MapSystemService implements IMapSystemService {
for (MapPrdTypeEnum value : MapPrdTypeEnum.values()) {
if (MapPrdTypeEnum.CTC.equals(value)) {
MapVO mapDetail = iMapService.getMapDetail(mapId);
if (!mapDetail.getConfigVO().isHasCTC()) {
if (!mapDetail.getConfigVO().isRailway()) {
continue;
}
}

View File

@ -829,7 +829,7 @@ public class RunPlanDraftService implements IRunPlanDraftService {
Map<String, List<RunPlanTripVO>> serviceMap = planVO.getTripList().stream().collect(Collectors.groupingBy(RunPlanTripVO::getServiceNumber));
serviceMap.forEach((s, trips) -> {
trips.sort(Comparator.comparing(RunPlanTripVO::getStartTime));
if (!map.getConfigVO().isHasCTC()) {
if (!map.getConfigVO().isRailway()) {
if(Objects.isNull(trips.get(0).getIsOutbound()) || !trips.get(0).getIsOutbound()){
errorList.add(String.format("服务号[%s]首班车次[%s]不是出库", s, trips.get(0).getTripNumber()));
}
@ -839,7 +839,7 @@ public class RunPlanDraftService implements IRunPlanDraftService {
if (departTime.isBefore(LocalTime.of(2, 0))) {
errorList.add(String.format("服务号[%s]首班车次发车时间[%s]过早应不早于02:00", s, departTime));
}
if (!map.getConfigVO().isHasCTC()) {
if (!map.getConfigVO().isRailway()) {
if(Objects.isNull(trips.get(trips.size() - 1).getIsInbound()) || !trips.get(trips.size() - 1).getIsInbound()){
errorList.add(String.format("服务号[%s]最后一班车次[%s]不是回库", s, trips.get(trips.size() - 1).getTripNumber()));
}

View File

@ -82,7 +82,7 @@ public class AtpSectionService {
SimulationDataRepository repository = simulation.getRepository();
MapConfig config = repository.getConfig();
boolean switchSingleHandle = config.isSwitchSingleHandle();
boolean isHasCTC = config.isHasCTC(); // 大铁逻辑
boolean isRailway = config.isRailway(); // 大铁逻辑
if (train.isCommunicable()) { // 通信车占用
// 车尾位置追加不确定性距离(速度*2)m
SectionPosition trainTailPosition = CalculateService
@ -111,7 +111,7 @@ public class AtpSectionService {
for (Section section : sectionList) {
if (section.isSwitchAxleCounterSection()) {
Section switchSection = section.getLogicList().get(0);
if (switchSingleHandle && isHasCTC) {
if (switchSingleHandle && isRailway) {
atpSectionList.addAll(handleSingleSwitchPosition(section, right));
} else {
atpSectionList.addAll(switchSection.getSwitchAxleSectionsBySwitchPosition());

View File

@ -75,7 +75,7 @@ public class GroundAtpApiServiceImpl implements GroundAtpApiService {
}
}));
// 大铁逻辑
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
// 非通信车占用
nctSectionMap.forEach(((train, sections) -> {
// 判断车头所在位置

View File

@ -83,7 +83,7 @@ public class AtsTrainMonitorService {
}
}
// ATS自动进路触发
if (!simulation.getRepository().getConfig().isHasCTC()) {
if (!simulation.getRepository().getConfig().isRailway()) {
this.atsTriggerRouteService.tryTrigger(simulation, trainInfo);
}
// // PIS语音自动触发

View File

@ -123,7 +123,7 @@ public class AtsTrainService {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
String.format("不存在车组号为[%s]的车次", groupNumber));
}
if (repository.getConfig().isHasCTC()) {// 大铁删除列车
if (repository.getConfig().isRailway()) {// 大铁删除列车
// if (!trainInfo.isStop()) {
// throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, String.format("列车[%s]未停稳的车次", groupNumber));
// }

View File

@ -206,7 +206,7 @@ public class CiApiServiceImpl2 implements CiApiService {
@Override
public void humanCancel(Simulation simulation, String routeCode) {
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(route.isApproachLock(),
"进路未接近锁闭,不能人解");
}
@ -216,7 +216,7 @@ public class CiApiServiceImpl2 implements CiApiService {
@Override
public void sectionFaultUnlock(Simulation simulation, String sectionCode) {
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
if (!section.isFaultLock()) {
return;
}
@ -406,7 +406,7 @@ public class CiApiServiceImpl2 implements CiApiService {
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception("signalCode和routeCode不能都为空");
}
// 判断是否要进行进路判断大铁可以不对进路判断
boolean firstCheck = config.isHasCTC() ? false : config.isGuideNeedRouteSettingFirst();
boolean firstCheck = config.isRailway() ? false : config.isGuideNeedRouteSettingFirst();
//条件检查
if (firstCheck) {
List<Route> routeList = signal.getRouteList();
@ -420,7 +420,7 @@ public class CiApiServiceImpl2 implements CiApiService {
// if (config.isSomeCommandNeedInit()) {
// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isInit(), signal.debugStr() + "未初始化");
// }
if (!simulation.getRepository().getConfig().isHasCTC()) {
if (!simulation.getRepository().getConfig().isRailway()) {
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isDefaultAspect(),
String.format("信号机[%s]需处于关闭状态", signal.getCode()));
}
@ -445,7 +445,7 @@ public class CiApiServiceImpl2 implements CiApiService {
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal, signal.getSignalModel().getGuideAspect());
} else if (!CollectionUtils.isEmpty(signal.getRouteList())) {
List<Route> collect;
if (config.isHasCTC()) { // 大铁配置引导进路
if (config.isRailway()) { // 大铁配置引导进路
collect = getCtcGuideRouteList(repository, signal);
if (collect == null) {
return;
@ -468,7 +468,7 @@ public class CiApiServiceImpl2 implements CiApiService {
}
}
}
if (repository.getConfig().isHasCTC() && signal.isHigherThanGuideLevel()) {
if (repository.getConfig().isRailway() && signal.isHigherThanGuideLevel()) {
Route lockedRoute = signal.getLockedRoute();
if (lockedRoute != null && lockedRoute.getFirstLogicSection().isOccupied()) {
signal.guideDelayStart();
@ -521,7 +521,7 @@ public class CiApiServiceImpl2 implements CiApiService {
Station deviceStation = station;
boolean restartFlag = Objects.nonNull(deviceStation.getRestartTime()) && deviceStation.getRestartTime().isBefore(LocalTime.now());
// 是否大铁设备
boolean hasCTCFlag = simulation.getRepository().getConfig().isHasCTC();
boolean hasCTCFlag = simulation.getRepository().getConfig().isRailway();
// 大铁异常提示语
String exceptionMsg = hasCTCFlag ? "无效操作:车站未下电" : "无效操作或连锁机重启过8分钟需手动解锁";
// 是否需要重启

View File

@ -50,7 +50,7 @@ public class CiLogic {
}
// 区间灯点灯逻辑
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
// 车站
simulation.getRepository().getStationList().stream().forEach(station -> {
// 允许自律状态刷新
@ -81,7 +81,7 @@ public class CiLogic {
signalControlService.controlLightOfSignal(simulation, signal);
//控制通过信号机的显示信号机前第一个区段被占用开红灯第二个区段被占用开黄灯否则开绿灯
if (signal.isPassingSignal()) {
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
boolean right = signal.isRight();
Section section = signal.getSection();
Section one = section.getNextSection(right);
@ -160,7 +160,7 @@ public class CiLogic {
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
start, start.getDefaultAspect());
if (config.isHasCTC()) //大铁线路暂时限制自动重开信号
if (config.isRailway()) //大铁线路暂时限制自动重开信号
start.setForbidden(true);
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());

View File

@ -173,7 +173,7 @@ public class CiService {
|| (!signal.isCbtcMode() && Signal.SignalFault.LIGHTING_UNIT_FAULT_HEAD.equals(signal.getFault())))
return level;
// 大铁情况下做判断
if (simulation.getRepository().getConfig().isHasCTC() && !Signal.SignalType.SHUNTING.equals(signal.getType())) {
if (simulation.getRepository().getConfig().isRailway() && !Signal.SignalType.SHUNTING.equals(signal.getType())) {
// 如果当前进路在列表中不存在则信号灯不开放
boolean isCanHandle = simulation.getRepository().getStationList().stream()
.filter(station -> station.getCode().equals(route.getStart().getStation().getCode())

View File

@ -131,7 +131,11 @@ public class CTCLogicLoop {
*/
private void routeSequenceTrigger(Simulation simulation) {
LocalDateTime correctSystemTime = simulation.getCorrectSystemTime();
for (RouteSequence routeSequence : simulation.getCtcRepository().getRouteSequenceMap().values()) {
SimulationDataRepository repository = simulation.getRepository();
for (Map.Entry<String, RouteSequence> entry : simulation.getCtcRepository().getRouteSequenceMap().entrySet()) {
String stationCode = entry.getKey();
Station station = repository.getByCode(stationCode, Station.class);
RouteSequence routeSequence = entry.getValue();
for (RouteSequence.Line line : routeSequence.getLines()) {
if (line.isTriggered())
continue;
@ -148,8 +152,10 @@ public class CTCLogicLoop {
continue;
}
}
if (line.isAutoTrigger() && correctSystemTime.toLocalTime().isAfter(line.getPlanTime())) {
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
if (!station.isInterlockControl()) { //非非常站控模式下才能自动触发进路
if (line.isAutoTrigger() && correctSystemTime.toLocalTime().isAfter(line.getPlanTime())) {
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
}
}
}
}
@ -323,8 +329,6 @@ public class CTCLogicLoop {
/**
* 运行计划发送变化事件
*
* @param simulation 仿真实体
*/
private void sendRunPlanChangeMessage(Simulation simulation) {
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap();

View File

@ -8,6 +8,8 @@ import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RouteSequenceVO;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.TrackViewVO;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import lombok.Getter;
@ -129,6 +131,7 @@ public class CtcRepository {
private final CopyOnWriteArrayList<Ticket> tickets = new CopyOnWriteArrayList<>();
public void reset(Simulation simulation) {
MapConfig config = simulation.getRepository().getConfig();
// 仿真运行数据直接清空
this.ctcZoneRepository.reset();
this.ctcEffectRepository.reset();
@ -146,8 +149,11 @@ public class CtcRepository {
dispatchCommandMap.clear();
stationRegisterMap.clear();
SimulationBuilder.buildCtcStationRunPlanLog(simulation);
SimulationBuilder.generateRouteSequence(simulation);
buildTrackViewData(simulation);
// SimulationBuilder.generateRouteSequence(simulation);
if (config.isHasCTC()) {
buildRouteSequence(simulation);
buildTrackViewData(simulation);
}
ticketIdGenerator = new AtomicInteger(0);
tickets.clear();
for (Station station : simulation.getRepository().getStationList()) {
@ -155,6 +161,33 @@ public class CtcRepository {
}
}
public void buildRouteSequence(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
AtomicInteger idGenerator = getRouteSequenceIdGenerator();
Map<String, List<RouteSequence.Line>> stationLineMap = new HashMap<>();
for (Station station : repository.getStationList()) {
stationLineMap.put(station.getCode(), new ArrayList<>());
}
for (CtcStationRunPlanLog plan : getAllRunPlanList()) {
List<RouteSequence.Line> lines = stationLineMap.get(plan.getStation().getCode());
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = plan.getArriveRunPlan();
if (arriveRunPlan != null) {
RouteSequence.Line line = RouteSequence.buildLine(arriveRunPlan, false, idGenerator);
lines.add(line);
}
CtcStationRunPlanLog.RunPlanItem departRunPlan = plan.getDepartRunPlan();
if (departRunPlan != null) {
RouteSequence.Line line = RouteSequence.buildLine(departRunPlan, true, idGenerator);
lines.add(line);
}
}
Map<String, RouteSequence> routeSequenceMap = getRouteSequenceMap();
for (Station station : repository.getStationList()) {
RouteSequence routeSequence = new RouteSequence(station, stationLineMap.get(station.getCode()));
routeSequenceMap.put(station.getCode(), routeSequence);
}
}
/**
* 构建占线板股道视图数据
*/

View File

@ -6,7 +6,6 @@ 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.Simulation;
import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -65,9 +64,11 @@ public class CTCService {
* 该方法应该在车务终端发送阶段计划之后调用
*/
public void regenerateRouteSequenceAndTrackView(Simulation simulation) {
SimulationBuilder.generateRouteSequence(simulation);
CtcRepository ctcRepository = simulation.getCtcRepository();
ctcRepository.buildTrackViewData(simulation);
if (simulation.getRepository().getConfig().isHasCTC()) {
CtcRepository ctcRepository = simulation.getCtcRepository();
ctcRepository.buildRouteSequence(simulation);
ctcRepository.buildTrackViewData(simulation);
}
}
/**

View File

@ -37,7 +37,7 @@ public class DeviceStatusServiceImpl implements DeviceStatusService {
private void initStationControlMode(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
MapConfig config = repository.getConfig();
if (!config.isHasCTC())
if (!config.isRailway())
return;
for (Station station : repository.getStationList()) {
station.setControlMode(Station.ControlMode.Local);

View File

@ -576,7 +576,7 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
}
this.repository.reset();
this.iscsRepository.reset();
if (this.repository.getConfig().isHasCTC()) {
if (this.repository.getConfig().isRailway()) {
this.ctcRepository.reset(this);
}
this.getSimulationMembers().forEach(member -> member.setCommand(null));

View File

@ -198,7 +198,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
iscsLogicLoop.addJob(simulation);
//////////////////////////////////////////////
// simulationRealDeviceConnectManager.addJobs(simulation);
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
ctcLogicLoop.addJobs(simulation);
}
}

View File

@ -19,6 +19,7 @@ import club.joylink.rtss.vo.client.iscs.device.IscsDeviceVO;
import club.joylink.rtss.vo.client.iscs.systemRes.IscsSystemResourcesVO;
import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO;
import club.joylink.rtss.vo.map.MapFunctionConfig;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.RealLineConfigVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
@ -46,7 +47,8 @@ public class SimulationBuilder {
simulation.setProject(buildParams.getLoginUserInfo().getProject());
}
// 线路配置参数
simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO()));
simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO(),
buildParams.getMap().getGraphDataNew().getMapFunctionConfig()));
simulation.getRepository().getConfig()
.setRouteLikeHa1(buildParams.getMap().getGraphDataNew().getGenerateConfig().isLikeHa1());
simulation.getRepository().getConfig()
@ -80,7 +82,7 @@ public class SimulationBuilder {
buildParams.getMap(), mapDataBuildResult.getErrMsgList());
if (!CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 存在数据异常
mapDataBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("地图数据异常:%s", errMsg)));
if (!buildParams.getMap().getConfigVO().isHasCTC()) {
if (!buildParams.getMap().getConfigVO().isRailway()) {
simulation.setMapDataError(true);
}
simulation.addDataErrMsgs(mapDataBuildResult.getErrMsgList());
@ -94,9 +96,9 @@ public class SimulationBuilder {
// 加载车辆段route path
loadDepotInOutRoutePath(simulation);
// CTC行车日志数据结构构建
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
buildCtcStationRunPlanLog(simulation);
generateRouteSequence(simulation);
// generateRouteSequence(simulation);
}
return simulation;
}
@ -318,7 +320,7 @@ public class SimulationBuilder {
RunPlanBuilder.RunPlanBuildResult runPlanBuildResult =
RunPlanBuilder.buildRunDiagram(simulation.getRepository().getDeviceMap(), runPlan);
simulation.setPlanLoaded(true);
if (!simulation.getRepository().getConfig().isHasCTC() && !CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常
if (!simulation.getRepository().getConfig().isRailway() && !CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常
runPlanBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("运行图数据异常:%s", errMsg)));
simulation.setPlanDataError(true);
simulation.addDataErrMsgs(runPlanBuildResult.getErrMsgList());
@ -330,7 +332,7 @@ public class SimulationBuilder {
List<String> errMsgList = checkRunPlanAndBuildLostRoutePaths(runPlanBuildResult.getServerTripMap(),
simulation.getRepository().getRoutePathMap());
if (!errMsgList.isEmpty()) {
if (!simulation.getRepository().getConfig().isHasCTC()) {
if (!simulation.getRepository().getConfig().isRailway()) {
simulation.setMapDataError(true);
}
simulation.addDataErrMsgs(errMsgList);
@ -463,11 +465,14 @@ public class SimulationBuilder {
return result;
}
public static MapConfig buildConfig(RealLineConfigVO configVO) {
public static MapConfig buildConfig(RealLineConfigVO configVO, MapFunctionConfig mapFunctionConfig) {
MapConfig mapConfig = new MapConfig();
if (Objects.nonNull(configVO)) {
mapConfig.copyConfigBy(configVO);
}
if (mapFunctionConfig != null) {
mapConfig.copyConfigBy(mapFunctionConfig);
}
return mapConfig;
}

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.data.map;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.vo.map.MapFunctionConfig;
import club.joylink.rtss.vo.map.RealLineConfigVO;
import lombok.Getter;
import lombok.Setter;
@ -229,10 +230,14 @@ public class MapConfig {
private boolean updateTripPlanByServiceNumber;
/**
* 有CTC系统大铁
* 大铁线路
*/
private boolean railway;
private boolean hasCTC;
private boolean hasTDCS;
private Set<SimulationMember.Type> needConfirmConnectMembers =
Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet());
@ -287,10 +292,17 @@ public class MapConfig {
setTripNumberIsUnique(configVO.isTripNumberIsUnique());
setStandTbStrategyIsInvalid(configVO.isStandTbStrategyIsInvalid());
setUpdateTripPlanByServiceNumber(configVO.isUpdateTripPlanByServiceNumber());
setHasCTC(configVO.isHasCTC());
setRailway(configVO.isRailway());
}
}
public void copyConfigBy(MapFunctionConfig mapFunctionConfig) {
if (mapFunctionConfig == null)
return;
this.hasCTC = mapFunctionConfig.isHasCTC();
this.hasTDCS = mapFunctionConfig.isHasTDCS();
}
public boolean isNoParkingServiceNumber(String serviceNumber) {
if (StringUtils.hasText(noParkingSM)) {
if (noParkingSM.contains("-")) {

View File

@ -524,6 +524,10 @@ public class Station extends MayOutOfOrderDevice {
}
}
public boolean isInterlockControl() {
return ControlMode.Interlock.equals(controlMode);
}
/**
* 获取该方向的正常站台
*/

View File

@ -49,7 +49,7 @@ public class MemberManager {
this.addRole(simulation, SimulationMember.Type.DEPOT_DISPATCHER, station.getName() + "调度", station);
}
// 大铁CTC
if (simulation.getRepository().getConfig().isHasCTC()) {
if (simulation.getRepository().getConfig().isRailway()) {
// this.addRole(simulation, SimulationMember.Type.RAIL_CTC, null, station);
this.addRole(simulation, SimulationMember.Type.STATION_ASSISTANT, null, station);
}

View File

@ -216,9 +216,9 @@ public class RealLineConfigVO {
private boolean updateTripPlanByServiceNumber;
/**
* 有CTC系统大铁
* 大铁线路
*/
private boolean hasCTC;
private boolean railway;
public static RealLineConfigVO parseJsonStr(String configData) {
if (StringUtils.hasText(configData)) {