加载备用车时可以选择预选模式;“多延续保护生成多条进路”联锁生成配置下也支持触发式延续保护;线路设置增加两个配置(但不生效)

This commit is contained in:
joylink_zhangsai 2023-10-27 10:09:46 +08:00
parent 18cfe99905
commit 2f2ec98029
15 changed files with 160 additions and 60 deletions

View File

@ -67,6 +67,9 @@ public class OperateMethod {
JsonUtils.getCollectionType(parameter.getType(), actualClass));
} else if (parameter.getType().isEnum()) {
Object o = param.get(parameter.getName());
if (o == null) {
continue;
}
Object[] enumConstants = parameter.getType().getEnumConstants();
for (Object enumConstant : enumConstants) {
if (enumConstant.toString().equals(o.toString())) {

View File

@ -17,8 +17,6 @@ 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.support.TrainLoadParam2;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.data.vo.VirtualRealityTrainVO;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
@ -264,8 +262,9 @@ public class TrainOperateHandler {
* 加载备用车
*/
@OperateHandlerMapping(type = Operation.Type.Train_Load_Spare_Train)
public void loadSpareTrain(Simulation simulation, String groupNumber, String sectionCode, boolean right) {
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, sectionCode, right);
public void loadSpareTrain(Simulation simulation, String groupNumber, String sectionCode, boolean right,
VirtualRealityTrain.PreselectionMode preselectionMode) {
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, sectionCode, right, preselectionMode);
}
/**

View File

@ -832,7 +832,8 @@ public class AtsTrainLoadService {
/**
* 在区段上加载指定车组号的列车
*/
public void loadSpareTrain(Simulation simulation, String groupNumber, String sectionCode, boolean right) {
public void loadSpareTrain(Simulation simulation, String groupNumber, String sectionCode, boolean right,
VirtualRealityTrain.PreselectionMode preselectionMode) {
SimulationDataRepository repository = simulation.getRepository();
if (!simulation.getRepository().getConfig().isHandleDepot() && repository.isVrTrainOnline(groupNumber)) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
@ -841,7 +842,7 @@ public class AtsTrainLoadService {
// 判断列车是否在派班计划中且后面要上线运行
}
VirtualRealityTrain virtualRealityTrain = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain, preselectionMode);
}
/**
@ -863,7 +864,7 @@ public class AtsTrainLoadService {
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
// 设置列车车次
virtualRealityTrain.setTripNumber(tripNumber);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain, null);
}
/**
@ -934,14 +935,15 @@ public class AtsTrainLoadService {
/**
* 列车上线并构建ATS监控列车信息
*
* @param simulation 仿真实体
* @param sectionCode 区段编码
* @param right 运行方向
* @param repository 数据实体
* @param train 列车
* @param simulation 仿真实体
* @param sectionCode 区段编码
* @param right 运行方向
* @param repository 数据实体
* @param train 列车
* @param preselectionMode
*/
private void trainOnline(Simulation simulation, String sectionCode, boolean right, SimulationDataRepository repository
, VirtualRealityTrain train) {
, VirtualRealityTrain train, VirtualRealityTrain.PreselectionMode preselectionMode) {
Section section = repository.getByCode(sectionCode, Section.class);
if (!section.isPhysical()) {
section = section.getParent();
@ -953,13 +955,15 @@ public class AtsTrainLoadService {
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
// 列车上线并构建ATS监控列车信息
manualTrainOnlineAndSupervise(simulation, train, headPosition, right);
manualTrainOnlineAndSupervise(simulation, train, headPosition, right, preselectionMode);
}
/**
* 人工车上线并监控
*/
private void manualTrainOnlineAndSupervise(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, boolean right) {
private void manualTrainOnlineAndSupervise(Simulation simulation, VirtualRealityTrain train,
SectionPosition headPosition, boolean right,
VirtualRealityTrain.PreselectionMode preselectionMode) {
train.initManualTrain(headPosition, right);
SimulationDataRepository repository = simulation.getRepository();
//设置列车预选模式驾驶模式运行级别
@ -974,6 +978,9 @@ public class AtsTrainLoadService {
}
}
if (!repository.getConfig().isHandleDepot()) {
if (preselectionMode != null && !preselectionMode.isHigherThan(train.getPreselectionMode())) {
train.initByPreselectionMode(preselectionMode);
}
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
trainInfo.tracking(train);
repository.addOnlineTrain(train);

View File

@ -40,10 +40,11 @@ public class CiLogic {
@Autowired
private AtsStationService atsStationService;
public void runForTrainPosition(Simulation simulation){
public void runForTrainPosition(Simulation simulation) {
// 采集真实设备状态
deviceStatusCollector.collect(simulation);
}
public void run(Simulation simulation) {
// 采集真实设备状态
deviceStatusCollector.collect(simulation);
@ -195,9 +196,9 @@ public class CiLogic {
if (route.isLock()) {
// 进路首区段列车占用进路开始解锁
Section firstLogicSection = route.getFirstLogicSection();
if(route.getStart().isGuideAspect() && firstLogicSection.getAxleCounterSection().isFaultOccupied()) {
if (route.getStart().isGuideAspect() && firstLogicSection.getAxleCounterSection().isFaultOccupied()) {
log.debug(String.format("进路【%s(%s)】引导占用中,列车通过后请人工解锁", route.getName(), route.getCode()));
} else{
} else {
SimulationDataRepository repository = simulation.getRepository();
if (repository.isTrainHeadOccupy(firstLogicSection)) {
trainUnlockStart(simulation, route);
@ -243,7 +244,11 @@ public class CiLogic {
}
}
// 进路延续保护办理判断
if (route.isSettingOverlap()) {
if (config.isOverlapSettingByTrigger()) {
if (route.getOverlap() != null && route.getOverlap().getSignal().isApproachSectionOccupied()) {
ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
}
} else if (route.isSettingOverlap()) {
ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
}
}
@ -298,7 +303,7 @@ public class CiLogic {
simulation.addJob(JobName.SECTION_STOP_COUNTDOWN, () -> sectionStopCountDown(simulation), SimulationConstants.CI_LOOP_RATE);
}
public void addJobsForTrainPosition(Simulation simulation){
public void addJobsForTrainPosition(Simulation simulation) {
simulation.addJob(SimulationModule.CI.name(), () -> runForTrainPosition(simulation), SimulationConstants.CI_LOOP_RATE);
// simulation.addJob(JobName.SECTION_STOP_COUNTDOWN, () -> sectionStopCountDown(simulation), SimulationConstants.CI_LOOP_RATE);
}

View File

@ -222,8 +222,10 @@ public class CiRouteService {
for (SwitchElement switchElement : route.getSwitchList()) {
switchElement.getASwitch().ciUse(switchElement.isNormal());
}
// 延续保护进路办理
this.ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
if (!simulation.getRepository().getConfig().isOverlapSettingByTrigger()) {
// 延续保护进路办理
this.ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
}
simulation.getRepository().addSettingRoute(route);
}
if (Objects.nonNull(failMessage)) {

View File

@ -70,7 +70,7 @@ public class CiService {
* @return
*/
public boolean interlockCheck(Simulation simulation, RouteOverlap overlap) {
if (overlap != null) {
if (!simulation.getRepository().getConfig().isOverlapSettingByTrigger() && overlap != null) {
SectionPath sectionPath = overlap.selectPath();
List<Section> logicList = sectionPath.getLogicList();
if (!CollectionUtils.isEmpty(logicList)) {
@ -325,7 +325,8 @@ public class CiService {
}
}
// 延续保护
if (!this.interlockCheck(simulation, route.getOverlap())) {
if (!simulation.getRepository().getConfig().isOverlapSettingByTrigger()
&& !this.interlockCheck(simulation, route.getOverlap())) {
// log.debug("进路[{}]连锁条件检查: 延续保护未锁闭", route.debugStr());
return level;
}

View File

@ -7,24 +7,27 @@ public enum DriveMode {
/**
* 列车自动驾驶模式司机监控下的列车自动驾驶
*/
AM("列车自动驾驶模式"),
AM("列车自动驾驶模式", false),
/**
* ATP防护下的人工驾驶模式司机在列车自动防护设备监控下驾驶列车
*/
CM("ATP防护下的人工驾驶模式"),
CM("ATP防护下的人工驾驶模式", true),
/**
* 限制人工驾驶模式地面设备故障或未设置地面信息设备的线路列车按规定限速运行超速时实时制动直至停车
*/
RM("限制人工驾驶模式"),
RM("限制人工驾驶模式", true),
/**
* 无限制人工驾驶模式列车在运行中没有车载ATP的保护司机根据行车调度员的指示按地面信号机的显示或手信号口令指示行车
*/
NRM("无限制人工驾驶模式");
NRM("无限制人工驾驶模式", true);
private final String label;
//是否人工驾驶模式
private final boolean manual;
DriveMode(String label) {
DriveMode(String label, boolean manual) {
this.label = label;
this.manual = manual;
}
public boolean isNotLowerThan(DriveMode driveMode) {

View File

@ -250,6 +250,16 @@ public class MapConfig {
private boolean hasTDCS;
/**
* 道岔故障时可以办理进路由远及近锁闭到故障处终止
*/
private boolean routeCanSetWhenSwitchFault;
/**
* 人工驾驶模式CM/RM/NRM下的列车默认是停车等待命令状态
*/
private boolean manualTrainDefaultStop;
private Set<SimulationMember.Type> needConfirmConnectMembers =
Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet());
@ -307,6 +317,8 @@ public class MapConfig {
setRailway(configVO.isRailway());
setSignalBolckOptReflectSignal(configVO.isSignalBolckOptReflectSignal());
setSFUCanOnlyApplyForFaultLockSection(configVO.isSFUCanOnlyApplyForFaultLockSection());
setRouteCanSetWhenSwitchFault(configVO.isRouteCanSetWhenSwitchFault());
setManualTrainDefaultStop(configVO.isManualTrainDefaultStop());
}
}

View File

@ -416,17 +416,18 @@ public class Signal extends DelayUnlockDevice {
}
public void updateApproachLock() {
if (CollectionUtils.isEmpty(approachPathList))
return;
for (SectionPath sectionPath : approachPathList) {
for (Section section : sectionPath.getSectionList()) {
if (section.isOccupied()) {
this.approachLock = true;
return;
}
}
}
this.approachLock = false;
this.approachLock = isApproachSectionOccupied();
// if (CollectionUtils.isEmpty(approachPathList))
// return;
// for (SectionPath sectionPath : approachPathList) {
// for (Section section : sectionPath.getSectionList()) {
// if (section.isOccupied()) {
// this.approachLock = true;
// return;
// }
// }
// }
// this.approachLock = false;
}
public boolean containsApproachAtpSection(List<Section> atpSectionList) {
@ -718,6 +719,20 @@ public class Signal extends DelayUnlockDevice {
return isGuideLevel() || isAtpLevel() || isMainLevel();
}
public boolean isApproachSectionOccupied() {
if (CollectionUtils.isEmpty(this.approachPathList)) {
return false;
}
for (SectionPath sectionPath : this.approachPathList) {
for (Section section : sectionPath.getSectionList()) {
if (section.isOccupied()) {
return true;
}
}
}
return false;
}
/**
* 信号机类型
*/

View File

@ -6,11 +6,7 @@ import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.TrainTBControl;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
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.Stand;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
@ -18,15 +14,16 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.vo.client.operation.DriveParamVO;
import club.joylink.rtss.vo.ws.TrainPosition;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
/**
* 虚拟真实列车
*/
@ -1146,6 +1143,22 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
return isCBTC() && DoorMode.AA.equals(doorMode);
}
public void initAsAM_C() {
this.setCommunication(true);
this.setPreselectionMode(PreselectionMode.AM_C);
this.setTempPreselectionMode(this.preselectionMode);
this.setDriveMode(DriveMode.AM);
this.setRunLevel(RunLevel.CBTC);
}
public void initAsSM_C() {
this.setCommunication(true);
this.setPreselectionMode(PreselectionMode.SM_C);
this.setTempPreselectionMode(this.preselectionMode);
this.setDriveMode(DriveMode.CM);
this.setRunLevel(RunLevel.CBTC);
}
public void initAsAM_I() {
this.setCommunication(false);
this.setPreselectionMode(PreselectionMode.AM_I);
@ -1154,6 +1167,14 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
this.setRunLevel(RunLevel.ITC);
}
public void initAsSM_I() {
this.setCommunication(false);
this.setPreselectionMode(PreselectionMode.SM_I);
this.setTempPreselectionMode(this.preselectionMode);
this.setDriveMode(DriveMode.CM);
this.setRunLevel(RunLevel.ITC);
}
public void initAsRM() {
this.setCommunication(false);
this.setPreselectionMode(PreselectionMode.RM);
@ -1164,6 +1185,26 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
this.setGear(Handwheel.MANUAL);
}
public void initByPreselectionMode(PreselectionMode preselectionMode) {
switch (preselectionMode) {
case AM_C:
initAsAM_C();
break;
case SM_C:
initAsSM_C();
break;
case AM_I:
initAsAM_I();
break;
case SM_I:
initAsSM_I();
break;
case RM:
initAsRM();
break;
}
}
/**
* 获取一个非null的限速值计算限速时更方便
*/

View File

@ -26,13 +26,14 @@ import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import club.joylink.rtss.simulation.cbtc.robot.SimulationRobotService;
import club.joylink.rtss.vo.client.project.thailand.ThailandSectionConfigVO;
import io.netty.buffer.ByteBuf;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
@Slf4j
@Service
public class NgyTrainServiceImpl implements UDPRealDeviceService {
@ -231,7 +232,7 @@ public class NgyTrainServiceImpl implements UDPRealDeviceService {
if (section.isSwitchAxleCounterSection()) {
section = section.getLogicList().get(0).getRelSwitch().getA();
}
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false);
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false, null);
}
}

View File

@ -97,7 +97,7 @@ public class SrTrainServiceImpl implements UDPRealDeviceService {
if (section.isSwitchAxleCounterSection()) {
section = section.getLogicList().get(0).getRelSwitch().getA();
}
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false);
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false, null);
}
}

View File

@ -25,13 +25,14 @@ import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import club.joylink.rtss.simulation.cbtc.robot.SimulationRobotService;
import club.joylink.rtss.vo.client.project.thailand.ThailandSectionConfigVO;
import io.netty.buffer.ByteBuf;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
@Slf4j
@Service
public class ThailandTrainServiceImpl implements UDPRealDeviceService {
@ -200,7 +201,7 @@ public class ThailandTrainServiceImpl implements UDPRealDeviceService {
if (section.isSwitchAxleCounterSection()) {
section = section.getLogicList().get(0).getRelSwitch().getA();
}
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false);
atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false, null);
}
}

View File

@ -191,8 +191,8 @@ public class SimulationRobotService {
robotDrive(simulation, driver, train, train.getRobotTargetPosition());
}
} else if (train.isCMMode()) { //CM
SpeedCurve speedCurve = train.getMa2().getAtoStopCurve();
atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), train.getAtoSpeed());
// SpeedCurve speedCurve = train.getMa2().getAtoStopCurve();
// atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), train.getAtoSpeed());
}
}
}

View File

@ -235,6 +235,16 @@ public class RealLineConfigVO {
@JsonProperty(value = "SFUCanOnlyApplyForFaultLockSection")
private boolean SFUCanOnlyApplyForFaultLockSection;
/**
* 道岔故障时可以办理进路由远及近锁闭到故障处终止
*/
private boolean routeCanSetWhenSwitchFault;
/**
* 人工驾驶模式CM/RM/NRM下的列车默认是停车等待命令状态
*/
private boolean manualTrainDefaultStop;
public static RealLineConfigVO parseJsonStr(String configData) {
if (StringUtils.hasText(configData)) {
return JsonUtils.read(configData, RealLineConfigVO.class);