新版ATS进路选择修改
This commit is contained in:
commit
0a989ab9e2
@ -86,9 +86,9 @@ public class AtpSectionService {
|
||||
for (VirtualRealityTrain train : onlineTrainList) {
|
||||
List<Section> atpSectionList = trainAtpSectionMap.get(train.getGroupNumber());
|
||||
List<Section> physicalList = this.convert2PhysicalSectionList(atpSectionList);
|
||||
if (train.isCBTC() && signal.containsApproachAtpSection(atpSectionList)) { //通信车在atp接近区段上
|
||||
if (train.isCommunicable() && signal.containsApproachAtpSection(atpSectionList)) { //通信车在atp接近区段上
|
||||
approachMsg = SignalApproachMessage.ApproachMessage.CBTC;
|
||||
} else if (!train.isCBTC() && signal.containsApproachPhysicalSection(physicalList)) { //非通信车在物理接近区段上
|
||||
} else if (!train.isCommunicable() && signal.containsApproachPhysicalSection(physicalList)) { //非通信车在物理接近区段上
|
||||
approachMsg = SignalApproachMessage.ApproachMessage.NCT;
|
||||
nctApproachSignalMap.put(train, signal);
|
||||
}
|
||||
@ -142,7 +142,7 @@ public class AtpSectionService {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
atpSectionList = CalculateService.getAtpSections(trainHeadPosition, trainTailPosition,
|
||||
right, repository.getConfig().isSwitchSingleHandle());
|
||||
if (train.isCBTC()) { // cbtc通信车占用
|
||||
if (train.isCommunicable()) { // 通信车占用
|
||||
atpSectionList.forEach(atpSection -> atpSection.communicateTrainOccupy(right));
|
||||
} else { // 非通信车
|
||||
Set<Section> collect = atpSectionList.stream().map(section -> { //找到列车占压区段所属的物理区段
|
||||
|
@ -74,35 +74,13 @@ public class ZCLogicLoop {
|
||||
}));
|
||||
}
|
||||
//更新CBTC ma
|
||||
if (headPosition.getSection().anyZcWorking()) {
|
||||
if (train.isCommunicable()) {
|
||||
this.calculateMAOfCBTC(simulation, train, trainList);
|
||||
}
|
||||
// //更新CBTC ma
|
||||
// if (!deviceStation.getZc().isFault()) { //如果列车头所在区段所属设备集中站zc未故障
|
||||
// this.calculateMAOfCBTC(simulation, train, trainList);
|
||||
// }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 为升级CM而强制更新ma(简单处理)
|
||||
* @return 是否更新成功
|
||||
*/
|
||||
public boolean updateCbtcMa4CM(Simulation simulation, VirtualRealityTrain train) {
|
||||
RunLevel defaultRunLevel = simulation.getRepository().getConfig().getRunMode();
|
||||
if (RunLevel.CBTC.equals(defaultRunLevel)) {
|
||||
List<VirtualRealityTrain> trainList = simulation.getRepository().getOnlineTrainList();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
if (headPosition.getSection().anyZcWorking()) {
|
||||
List<MovementAuthority.End> endList = this.findMaEnd(simulation, train, trainList);
|
||||
MovementAuthority ma = this.compareAndBuildMa(train, endList);
|
||||
return onboardAtpApiService.ignoreDriveModeUpdateMA4CBTC(train, ma);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void calculateMAOfCBTC(Simulation simulation, VirtualRealityTrain train,
|
||||
List<VirtualRealityTrain> trainList) {
|
||||
// 查找移动授权终端列表
|
||||
@ -154,13 +132,8 @@ public class ZCLogicLoop {
|
||||
// }
|
||||
//非通信车占用区段
|
||||
if (section.isNonCbtcOccupy() && !section.isInvalid()) {
|
||||
VirtualRealitySectionAxleCounter axle = section.getVirtualAxleCounter();
|
||||
if (axle == null && section.getParent() != null)
|
||||
axle = section.getParent().getVirtualAxleCounter();
|
||||
if (axle == null || axle.getLeftCount() > 1 || axle.getRightCount() > 1) { //以计轴器计数为1作为是当前列车导致区段非通信车占用的判断依据
|
||||
endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_SECTION));
|
||||
return endList;
|
||||
}
|
||||
endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_SECTION));
|
||||
return endList;
|
||||
}
|
||||
//通信车占用区段
|
||||
List<Section> occupiedLogicSectionList = simulation.getRepository().queryTrainOccupyAtpSectionList(train.getGroupNumber());
|
||||
@ -236,7 +209,7 @@ public class ZCLogicLoop {
|
||||
if (trainEnd != null)
|
||||
endList.add(trainEnd);
|
||||
//非通信车占用区段
|
||||
if (temp.isNonCbtcOccupy() && !temp.isInvalid()) {
|
||||
if (temp.isNctOccupied() && !temp.isInvalid()) {
|
||||
endList.add(new MovementAuthority.End(temp, MovementAuthority.EndType.NCT_OCCUPIED_SECTION));
|
||||
}
|
||||
//检查关闭的区段
|
||||
@ -696,7 +669,7 @@ public class ZCLogicLoop {
|
||||
if (section.isStandTrack()) {
|
||||
List<Stand> standList = section.getStandList();
|
||||
for (Stand stand : standList) {
|
||||
if (!stand.isInterlockRelease() && stand.isPsdOpen()) {
|
||||
if (!stand.isPsdSafe()) {
|
||||
return new MovementAuthority.End(stand, MovementAuthority.EndType.OPENED_PSD, section);
|
||||
}
|
||||
if (stand.isClosed()) {
|
||||
|
@ -1,9 +1,11 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.operation.handler;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.ZCLogicLoop;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CILogicLoop;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.ControlGear;
|
||||
@ -39,6 +41,9 @@ public class DriverOperateHandler {
|
||||
@Autowired
|
||||
private ZCLogicLoop zcLogicLoop;
|
||||
|
||||
@Autowired
|
||||
private GroundAtpApiService groundAtpApiService;
|
||||
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Force_Change)
|
||||
public void changeTrainForce(Simulation simulation, String groupNumber, Float percent) {
|
||||
Objects.requireNonNull(percent);
|
||||
@ -114,28 +119,12 @@ public class DriverOperateHandler {
|
||||
public void changeTrainDriveMode(Simulation simulation, String groupNumber, DriveMode driveMode) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
switch (driveMode) {
|
||||
case CM: {
|
||||
if (!train.isAtpOn()) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
String.format("列车[%s]ATP未开启,无法升级CM驾驶模式", train.getGroupNumber()));
|
||||
}
|
||||
if (zcLogicLoop.updateCbtcMa4CM(simulation, train)) {
|
||||
train.useCMMode();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AM:
|
||||
case CM:
|
||||
case RM: {
|
||||
if (!train.isAtpOn()) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
String.format("列车[%s]ATP未开启,无法升级RM驾驶模式", train.getGroupNumber()));
|
||||
}
|
||||
train.useRMMode();
|
||||
train.setPreDriveMode(driveMode);
|
||||
break;
|
||||
}
|
||||
case NRM:
|
||||
ATPService.cutOffAtp(train);
|
||||
// train.useNRMMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,8 +752,8 @@ public class AtsRouteSettingService {
|
||||
++count;
|
||||
Signal signal = base.getSignalOf(right);
|
||||
if (Objects.isNull(signal) || !signal.isClose() ||
|
||||
(!train.isCtcLevel() && signal.isVirtual())) {
|
||||
// 指定方向信号机不存在,或已经开放,或非CTC列车碰到虚拟信号机,继续往下找
|
||||
(!train.isCommunication() && signal.isVirtual())) {
|
||||
// 指定方向信号机不存在,或已经开放,或非通信车碰到虚拟信号机,继续往下找
|
||||
base = base.getNextRunningSectionOf(right);
|
||||
continue;
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ public class AtsTrainLoadService {
|
||||
Section end = viaSectionList.get(i);
|
||||
// 取相邻两区段的路径单元,查询进路
|
||||
RoutePath routePath = this.selectDefaultRoutePath(repository, start, end);
|
||||
Route route = routePath.queryRouteContainsSection(train.getRunLevel(), headSection, repository.getConfig());
|
||||
Route route = routePath.queryRouteContainsSection(train.isCommunicable(), headSection, repository.getConfig());
|
||||
if (Objects.nonNull(route)) {
|
||||
// 排列好进路
|
||||
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
|
||||
|
@ -308,8 +308,7 @@ public class AtsTrainService {
|
||||
if (!sections.get(0).equals(headSection)) {
|
||||
sections.add(0, headSection);
|
||||
}
|
||||
SectionPath headPath = new SectionPath(selectRouting.isRight(), null, sections, null);
|
||||
supervisedTrain.setHeadPath(headPath);
|
||||
supervisedTrain.setHctPath(new SectionRunPath(sections, selectRouting.isRight()));
|
||||
break;
|
||||
default:
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("无法识别的目的地码类型[%s]", destinationCodeDefinition.getType()));
|
||||
@ -675,7 +674,7 @@ public class AtsTrainService {
|
||||
}
|
||||
break;
|
||||
case OTHER:
|
||||
List<Section> path = train.getHeadPath().getSectionList();
|
||||
List<Section> path = train.getHctPath().getSections();
|
||||
if (path != null) {
|
||||
int index = path.indexOf(headSection);
|
||||
if (index == -1) {
|
||||
|
@ -2,19 +2,10 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.ars;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DestinationCodeDefinition;
|
||||
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.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.vo.TrainInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 头码车进路选择
|
||||
@ -28,45 +19,6 @@ public class AtsHeadTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
// 基础检查
|
||||
Boolean right = trainInfo.getRight();
|
||||
if (right == null)
|
||||
return null;
|
||||
DestinationCodeDefinition dcd = repository.getDestinationCodeDefinition(trainInfo.getDestinationCode());
|
||||
Object[] results = queryTriggerRoutes(repository, trainInfo.getHeadPath().getSectionList(), trainInfo, null, trainInfo.getHeadPath().isRight());
|
||||
return filterRoutes(repository, trainInfo, results, dcd);
|
||||
}
|
||||
|
||||
private Route filterRoutes(SimulationDataRepository repository, TrainInfo trainInfo, Object[] results, DestinationCodeDefinition dcd) {
|
||||
if (results == null)
|
||||
return null;
|
||||
List<Route> triggers = (List<Route>) results[0];
|
||||
if (CollectionUtils.isEmpty(triggers))
|
||||
return null;
|
||||
Route route;
|
||||
if (triggers.size() == 1) {
|
||||
route = triggers.get(0);
|
||||
} else {
|
||||
route = triggers.stream().min(Comparator.comparingInt(Route::getReverseSwitchQuantity)).get();
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
private boolean isConflicting(SimulationDataRepository repository, TrainInfo trainInfo, Route route) {
|
||||
if (!trainInfo.isPlanTrain())
|
||||
return false;
|
||||
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber());
|
||||
Section start = repository.getByCode(trainInfo.getPhysicalSection(), Section.class);
|
||||
for (StationPlan stationPlan : tripPlan.getPlanList()) {
|
||||
if (!stationPlan.isFinished()) {
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(start, stationPlan.getSection());
|
||||
RoutePath routePath = selectRoutePath(routePaths);
|
||||
if (routePath.isConflictWith(route)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
start = stationPlan.getSection();
|
||||
}
|
||||
return false;
|
||||
return queryTriggerRoutes(repository, trainInfo.getHctPath().getSections(), trainInfo, null);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
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.StationTurnBackStrategyOption;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -44,13 +43,12 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
// 根据车次计划查找可触发进路列表
|
||||
// Object[] results = this.queryByStationPlan(repository, systemTime, trainInfo, tripPlan);
|
||||
Object[] results = queryByStationPlan2(repository, systemTime, trainInfo, tripPlan);
|
||||
Route route = queryByStationPlan(repository, systemTime, trainInfo, tripPlan);
|
||||
// 根据计划筛选需触发进路
|
||||
Route route = filterRoutes(simulation, trainInfo, tripPlan, results);
|
||||
return route;
|
||||
return filterRoutes(simulation, trainInfo, tripPlan, route);
|
||||
}
|
||||
|
||||
private Object[] queryByStationPlan2(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
private Route queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
// 计划时间
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
LocalTime startTime = tripPlan.getStartTime();
|
||||
@ -66,9 +64,9 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
}
|
||||
List<Section> targetList = tripPlan.getPlanList().stream().map(StationPlan::getSection).collect(Collectors.toList());
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
return queryTriggerRoutes(repository, targetList, trainInfo, tripPlan.getEndSection(), tripPlan.isRight());
|
||||
return queryTriggerRoutes(repository, targetList, trainInfo, tripPlan.getEndSection());
|
||||
} else {
|
||||
return queryTriggerRoutes(repository, targetList, trainInfo, null, tripPlan.isRight());
|
||||
return queryTriggerRoutes(repository, targetList, trainInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,25 +75,16 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
* @param simulation
|
||||
* @param trainInfo
|
||||
* @param tripPlan
|
||||
* @param results
|
||||
* @param route
|
||||
* @return
|
||||
*/
|
||||
private Route filterRoutes(Simulation simulation,
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Object[] results) {
|
||||
if (results == null) {
|
||||
return null;
|
||||
}
|
||||
List<Route> triggerList = (List<Route>) results[0];
|
||||
if (CollectionUtils.isEmpty(triggerList)) {
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Route route) {
|
||||
if (route == null) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
// 先选取需要征用的进路
|
||||
boolean turnBack = (boolean) results[1];
|
||||
Route route = this.filter(repository, trainInfo, tripPlan, triggerList, turnBack);
|
||||
if (route == null) {
|
||||
return null;
|
||||
}
|
||||
log.debug(String.format("列车[%s]筛选出的进路为:[%s]", trainInfo.getGroupNumber(), route.getName()));
|
||||
if (route.isCheckConflict() && route.getConflictAlarm() == null) {
|
||||
ConflictInfo conflictInfo = this.checkConflict(repository, trainInfo, tripPlan, route);
|
||||
@ -432,147 +421,147 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
return route;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return (List<Route>)[0]: 可触发的进路;(Boolean)[1]:是否需要折返
|
||||
*/
|
||||
private Object[] queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
Route route = null;
|
||||
Object[] result = new Object[3];
|
||||
result[1] = false;
|
||||
result[2] = false;
|
||||
List<Route> triggerList = null;
|
||||
// 获取列车上一停靠站台轨和下一计划达到轨道,结合列车位置,查询需要办理的进路
|
||||
if (trainInfo.getPlanStandTrack() == null) { // 列车下一计划存在
|
||||
return null;
|
||||
}
|
||||
// 计划时间
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
LocalTime startTime = tripPlan.getStartTime();
|
||||
for (StationPlan stationPlan : planList) {
|
||||
if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())) {
|
||||
break;
|
||||
}
|
||||
startTime = stationPlan.getLeaveTime();
|
||||
}
|
||||
if (!systemTime.toLocalTime().plusSeconds(50).isAfter(startTime)) {
|
||||
log.debug(String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber()));
|
||||
return null;
|
||||
}
|
||||
Section planTrack = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);//下一计划
|
||||
Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段
|
||||
if (!planTrack.isSamePhysical(section.getCode())) {
|
||||
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(planTrack);
|
||||
routePathList = routePathList.stream()
|
||||
.filter(routePath -> routePath.containsSection(section))
|
||||
.collect(Collectors.toList());
|
||||
result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
}
|
||||
if (!((boolean) result[1]) && !((boolean) result[2])) { // 不存在未开放进路,且不存在未接近的信号机
|
||||
// 判断配置是否列车停站才触发接下来的进路
|
||||
MapConfig config = repository.getConfig();
|
||||
if (config.isSignalOpenAfterParking() && !trainInfo.isParking()) {
|
||||
return null;
|
||||
} else {
|
||||
if (tripPlan.isLastPlanStationSection(planTrack)) {
|
||||
//是计划的终点站
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
// 是站后折返
|
||||
triggerList = this.queryAccordingTbStrategy(repository, trainInfo, tripPlan);
|
||||
Object[] rs = {triggerList, true};
|
||||
return rs;
|
||||
} else if (!tripPlan.getEndSection().equals(tripPlan.getLastStationPlan().getSection())) {
|
||||
// 备用车
|
||||
List<RoutePath> routePathList = repository.getRoutePaths(tripPlan.getLastStationPlan().getSection(),
|
||||
tripPlan.getEndSection());
|
||||
result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
}
|
||||
} else {
|
||||
StationPlan nextStationPlan = tripPlan.queryNextStationPlan(planTrack);
|
||||
if (nextStationPlan != null) {
|
||||
// 下一计划车站存在
|
||||
List<RoutePath> routePathList = repository.getRoutePaths(planTrack, nextStationPlan.getSection());
|
||||
result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
triggerList = (List<Route>) result[0];
|
||||
Object[] rs = {triggerList, false};
|
||||
return rs;
|
||||
}
|
||||
// /**
|
||||
// * @return (List<Route>)[0]: 可触发的进路;(Boolean)[1]:是否需要折返
|
||||
// */
|
||||
// private Object[] queryByStationPlan(SimulationDataRepository repository, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
// Route route = null;
|
||||
// Object[] result = new Object[3];
|
||||
// result[1] = false;
|
||||
// result[2] = false;
|
||||
// List<Route> triggerList = null;
|
||||
// // 获取列车上一停靠站台轨和下一计划达到轨道,结合列车位置,查询需要办理的进路
|
||||
// if (trainInfo.getPlanStandTrack() == null) { // 列车下一计划存在
|
||||
// return null;
|
||||
// }
|
||||
// // 计划时间
|
||||
// List<StationPlan> planList = tripPlan.getPlanList();
|
||||
// LocalTime startTime = tripPlan.getStartTime();
|
||||
// for (StationPlan stationPlan : planList) {
|
||||
// if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())) {
|
||||
// break;
|
||||
// }
|
||||
// startTime = stationPlan.getLeaveTime();
|
||||
// }
|
||||
// if (!systemTime.toLocalTime().plusSeconds(50).isAfter(startTime)) {
|
||||
// log.debug(String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber()));
|
||||
// return null;
|
||||
// }
|
||||
// Section planTrack = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);//下一计划
|
||||
// Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段
|
||||
// if (!planTrack.isSamePhysical(section.getCode())) {
|
||||
// List<RoutePath> routePathList = repository.queryRoutePathsByEnd(planTrack);
|
||||
// routePathList = routePathList.stream()
|
||||
// .filter(routePath -> routePath.containsSection(section))
|
||||
// .collect(Collectors.toList());
|
||||
// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
// }
|
||||
// if (!((boolean) result[1]) && !((boolean) result[2])) { // 不存在未开放进路,且不存在未接近的信号机
|
||||
// // 判断配置是否列车停站才触发接下来的进路
|
||||
// MapConfig config = repository.getConfig();
|
||||
// if (config.isSignalOpenAfterParking() && !trainInfo.isParking()) {
|
||||
// return null;
|
||||
// } else {
|
||||
// if (tripPlan.isLastPlanStationSection(planTrack)) {
|
||||
// //是计划的终点站
|
||||
// if (tripPlan.isBehindTurnBack()) {
|
||||
// // 是站后折返
|
||||
// triggerList = this.queryAccordingTbStrategy(repository, trainInfo, tripPlan);
|
||||
// Object[] rs = {triggerList, true};
|
||||
// return rs;
|
||||
// } else if (!tripPlan.getEndSection().equals(tripPlan.getLastStationPlan().getSection())) {
|
||||
// // 备用车
|
||||
// List<RoutePath> routePathList = repository.getRoutePaths(tripPlan.getLastStationPlan().getSection(),
|
||||
// tripPlan.getEndSection());
|
||||
// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
// }
|
||||
// } else {
|
||||
// StationPlan nextStationPlan = tripPlan.queryNextStationPlan(planTrack);
|
||||
// if (nextStationPlan != null) {
|
||||
// // 下一计划车站存在
|
||||
// List<RoutePath> routePathList = repository.getRoutePaths(planTrack, nextStationPlan.getSection());
|
||||
// result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePathList);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// triggerList = (List<Route>) result[0];
|
||||
// Object[] rs = {triggerList, false};
|
||||
// return rs;
|
||||
// }
|
||||
|
||||
private boolean isTriggerTurnBackRoute(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
Section eaStandSection = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class);
|
||||
Section arriveStandSection = repository.getByCode(trainInfo.getActualArriveStandTrack(), Section.class);
|
||||
if (tripPlan.isBehindTurnBack()) {// 是站后折返计划
|
||||
Section lastStationSection = tripPlan.getLastStationPlan().getSection();
|
||||
if (lastStationSection.isSamePhysical(arriveStandSection.getCode())) {
|
||||
// 列车达到计划终点站
|
||||
return true;
|
||||
} else if (lastStationSection.isSamePhysical(eaStandSection.getCode())) {
|
||||
// 预计到达为终点站,再判断是否到达折返始端信号机触发范围
|
||||
List<RoutePath> list = repository.getRoutePaths(lastStationSection, tripPlan.getEndSection());
|
||||
boolean right = list.get(0).isRight();
|
||||
Signal signal = lastStationSection.getSignalOf(right);
|
||||
// private boolean isTriggerTurnBackRoute(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
// Section eaStandSection = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class);
|
||||
// Section arriveStandSection = repository.getByCode(trainInfo.getActualArriveStandTrack(), Section.class);
|
||||
// if (tripPlan.isBehindTurnBack()) {// 是站后折返计划
|
||||
// Section lastStationSection = tripPlan.getLastStationPlan().getSection();
|
||||
// if (lastStationSection.isSamePhysical(arriveStandSection.getCode())) {
|
||||
// // 列车达到计划终点站
|
||||
// return true;
|
||||
// } else if (lastStationSection.isSamePhysical(eaStandSection.getCode())) {
|
||||
// // 预计到达为终点站,再判断是否到达折返始端信号机触发范围
|
||||
// List<RoutePath> list = repository.getRoutePaths(lastStationSection, tripPlan.getEndSection());
|
||||
// boolean right = list.get(0).isRight();
|
||||
// Signal signal = lastStationSection.getSignalOf(right);
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<Route> queryAccordingTbStrategy(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
Section standSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
if (!standSection.isRouteLock()) {
|
||||
|
||||
}
|
||||
Station station = standSection.getStation();
|
||||
StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy();
|
||||
Section tbSection = tripPlan.getEndSection();
|
||||
Route tbRoute = null;
|
||||
List<Section> tbSectionList = new ArrayList<>();
|
||||
if (Objects.isNull(strategy)) {
|
||||
tbSectionList.add(tbSection);
|
||||
} else {
|
||||
switch (strategy.getType()) {
|
||||
// 按计划
|
||||
case NONE: {
|
||||
tbSectionList.add(tbSection);
|
||||
break;
|
||||
}
|
||||
// 仅某个折返轨
|
||||
case ONLY: {
|
||||
tbSectionList.add(strategy.getSectionList().get(0));
|
||||
break;
|
||||
}
|
||||
// 折返轨等价
|
||||
case FIRST:
|
||||
case EQUAL: {
|
||||
tbSectionList.addAll(strategy.getSectionList());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<RoutePath> list = repository.getRoutePaths(standSection, tbSection);
|
||||
boolean right = list.get(0).isRight();
|
||||
Signal signal = standSection.getSignalOf(right);
|
||||
if (!this.isApproachSignal(repository, trainInfo, signal)) {
|
||||
return null;
|
||||
}
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
List<Route> tbRouteList = new ArrayList<>();
|
||||
for (Route route : routeList) {
|
||||
if (route.isTurnBack()) {
|
||||
tbRouteList.add(route);
|
||||
}
|
||||
}
|
||||
if (!tbRouteList.isEmpty()) {
|
||||
routeList = tbRouteList;
|
||||
}
|
||||
routeList = routeList.stream()
|
||||
.filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route))
|
||||
.filter(route -> route.containSameSection(tbSectionList))
|
||||
.collect(Collectors.toList());
|
||||
return routeList;
|
||||
}
|
||||
// private List<Route> queryAccordingTbStrategy(SimulationDataRepository repository, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
// Section standSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
// if (!standSection.isRouteLock()) {
|
||||
//
|
||||
// }
|
||||
// Station station = standSection.getStation();
|
||||
// StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy();
|
||||
// Section tbSection = tripPlan.getEndSection();
|
||||
// Route tbRoute = null;
|
||||
// List<Section> tbSectionList = new ArrayList<>();
|
||||
// if (Objects.isNull(strategy)) {
|
||||
// tbSectionList.add(tbSection);
|
||||
// } else {
|
||||
// switch (strategy.getType()) {
|
||||
// // 按计划
|
||||
// case NONE: {
|
||||
// tbSectionList.add(tbSection);
|
||||
// break;
|
||||
// }
|
||||
// // 仅某个折返轨
|
||||
// case ONLY: {
|
||||
// tbSectionList.add(strategy.getSectionList().get(0));
|
||||
// break;
|
||||
// }
|
||||
// // 折返轨等价
|
||||
// case FIRST:
|
||||
// case EQUAL: {
|
||||
// tbSectionList.addAll(strategy.getSectionList());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// List<RoutePath> list = repository.getRoutePaths(standSection, tbSection);
|
||||
// boolean right = list.get(0).isRight();
|
||||
// Signal signal = standSection.getSignalOf(right);
|
||||
// if (!this.isApproachSignal(repository, trainInfo, signal)) {
|
||||
// return null;
|
||||
// }
|
||||
// List<Route> routeList = signal.getRouteList();
|
||||
// List<Route> tbRouteList = new ArrayList<>();
|
||||
// for (Route route : routeList) {
|
||||
// if (route.isTurnBack()) {
|
||||
// tbRouteList.add(route);
|
||||
// }
|
||||
// }
|
||||
// if (!tbRouteList.isEmpty()) {
|
||||
// routeList = tbRouteList;
|
||||
// }
|
||||
// routeList = routeList.stream()
|
||||
// .filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route))
|
||||
// .filter(route -> route.containSameSection(tbSectionList))
|
||||
// .collect(Collectors.toList());
|
||||
// return routeList;
|
||||
// }
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service.ars;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
@ -23,53 +25,45 @@ public abstract class AtsRouteSelectService {
|
||||
* 查询需要触发的进路
|
||||
*
|
||||
* @param turnBackSection 站后折返的折返轨
|
||||
* @param right 计划运行方向
|
||||
* @return
|
||||
*/
|
||||
public Object[] queryTriggerRoutes(SimulationDataRepository repository, List<Section> targetList,
|
||||
TrainInfo trainInfo, Section turnBackSection, boolean right) {
|
||||
public Route queryTriggerRoutes(SimulationDataRepository repository, List<Section> targetList,
|
||||
TrainInfo trainInfo, Section turnBackSection) {
|
||||
if (trainInfo.getPlanStandTrack() == null) {
|
||||
return null;
|
||||
}
|
||||
//寻找通向计划区段的进路
|
||||
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
Section headSection = repository.getByCode(trainInfo.getPhysicalSection(), Section.class);
|
||||
Object[] result = {null, false, false};
|
||||
List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(planSection, headSection);
|
||||
int index = targetList.indexOf(planSection);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
Section nextPlanSection = null; //下一个计划区段
|
||||
if (index < targetList.size() - 1) {
|
||||
nextPlanSection = targetList.get(index + 1);
|
||||
}
|
||||
Route route = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths, nextPlanSection);
|
||||
if (route != null) { //有进路未触发
|
||||
return route;
|
||||
}
|
||||
//通向计划区段的进路已全部办理,根据条件尝试向下一个计划区段或站后折返轨办理进路
|
||||
MapConfig config = repository.getConfig();
|
||||
Section targetSection = null;
|
||||
Section nextTarget = null;
|
||||
//选择目标区段
|
||||
for (int i = targetList.size() - 1; i >= 0; i--) {
|
||||
Section target = targetList.get(i);
|
||||
List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(target, headSection);
|
||||
routePaths.removeIf(routePath -> routePath.isRight() != right);
|
||||
if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
result = queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths);
|
||||
targetSection = target;
|
||||
if (i < targetList.size() - 1) {
|
||||
nextTarget = targetList.get(i + 1);
|
||||
if (!config.isSignalOpenAfterParking() || (headSection.equals(planSection) && trainInfo.isParking())) { //不需要停站就可以开放信号机或者已经在计划区段停站(可以继续向前办理进路)
|
||||
if (nextPlanSection != null) { //计划区段路径未跑完
|
||||
routePaths = repository.queryRoutePaths(planSection, nextPlanSection);
|
||||
if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
return this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths, nextPlanSection);
|
||||
}
|
||||
} else if (turnBackSection != null) { //站后折返
|
||||
return queryTriggerRoutes4TurnBack(repository, planSection, turnBackSection, trainInfo);
|
||||
}
|
||||
}
|
||||
//选择进路
|
||||
boolean noRoute2Trigger = result != null && !(boolean) result[1] && !(boolean) result[2];
|
||||
if (targetSection != null) {
|
||||
if (!config.isSignalOpenAfterParking()) {
|
||||
if (noRoute2Trigger) {
|
||||
if (nextTarget != null) {
|
||||
List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(nextTarget, headSection);
|
||||
routePaths.removeIf(routePath -> routePath.isRight() != right);
|
||||
result = this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths);
|
||||
} else if (turnBackSection != null) {
|
||||
List<Route> triggerRoutes = queryTriggerRoutes4TurnBack(repository, targetSection, turnBackSection, trainInfo);
|
||||
return new Object[]{triggerRoutes, true};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (nextTarget == null && targetSection.equals(headSection) && trainInfo.isParking()) {
|
||||
List<Route> triggerRoutes = queryTriggerRoutes4TurnBack(repository, targetSection, turnBackSection, trainInfo);
|
||||
return new Object[]{triggerRoutes, true};
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Route> queryTriggerRoutes4TurnBack(SimulationDataRepository repository, Section standSection, Section tbSection, TrainInfo trainInfo) {
|
||||
public Route queryTriggerRoutes4TurnBack(SimulationDataRepository repository, Section standSection, Section tbSection, TrainInfo trainInfo) {
|
||||
Station station = standSection.getStation();
|
||||
StationTurnBackStrategyOption strategy = station.getCurrentTurnBackStrategy();
|
||||
List<Section> tbSectionList = new ArrayList<>();
|
||||
@ -115,7 +109,24 @@ public abstract class AtsRouteSelectService {
|
||||
.filter(route -> !repository.hasSameStartTriggerRoute(trainInfo, route))
|
||||
.filter(route -> route.containSameSection(tbSectionList))
|
||||
.collect(Collectors.toList());
|
||||
return routeList;
|
||||
Route route = null;
|
||||
for (Route temp : routeList) {
|
||||
List<Section> sectionList = temp.getSectionList();
|
||||
boolean trainOccupy = false;
|
||||
for (Section rs : sectionList) {
|
||||
if (rs.isOccupied()) {
|
||||
trainOccupy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (trainOccupy) {
|
||||
continue;
|
||||
} else {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,24 +145,11 @@ public abstract class AtsRouteSelectService {
|
||||
return pathList.get(0);
|
||||
}
|
||||
|
||||
public Object[] queryTriggerRoutesOfRoutePath(SimulationDataRepository repository,
|
||||
TrainInfo trainInfo, List<RoutePath> routePathList) {
|
||||
Boolean right = trainInfo.getRight();
|
||||
public Route queryTriggerRoutesOfRoutePath(SimulationDataRepository repository,
|
||||
TrainInfo trainInfo, List<RoutePath> routePathList, Section nextPlanSection) {
|
||||
Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class); // 列车所在区段
|
||||
Section logicSection = repository.getByCode(trainInfo.getSection(), Section.class);
|
||||
return queryTriggers(repository, trainInfo, routePathList, right, section, logicSection);
|
||||
}
|
||||
|
||||
public Object[] queryTriggers(SimulationDataRepository repository, TrainInfo trainInfo, List<RoutePath> routePathList,
|
||||
Boolean right, Section section, Section logicSection) {
|
||||
Object[] result = new Object[3]; // 结果,0为可触发的进路列表,1为是否存在未触发的进路,2为是否存在未接近的信号机
|
||||
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class); //列车计划区段
|
||||
List<Route> triggerList = new ArrayList<>();
|
||||
result[0] = triggerList;
|
||||
result[1] = false;
|
||||
result[2] = false;
|
||||
if (logicSection.isSwitchAxleCounterSection() || logicSection.isCross()) {
|
||||
logicSection = section;
|
||||
}
|
||||
if (!routePathList.isEmpty()) {
|
||||
RoutePath routePath = this.selectRoutePath(routePathList);
|
||||
// 查找可以触发的进路列表
|
||||
@ -164,7 +162,6 @@ public abstract class AtsRouteSelectService {
|
||||
continue;
|
||||
}
|
||||
if (signal.hasCiAutoTriggerRoute() || signal.hasFleetModeRoute()) {
|
||||
result[2] = true; // 存在联锁自动触发进路或联锁自动进路
|
||||
break;
|
||||
}
|
||||
if (!ctcLevel && signal.isVirtual()) {
|
||||
@ -172,15 +169,15 @@ public abstract class AtsRouteSelectService {
|
||||
}
|
||||
if (this.isApproachSignal(repository, trainInfo, signal)) {
|
||||
// 是信号机接近区段
|
||||
if (signal.isNormalOpen()) { //如果信号机已经正常开放,继续查询下一个
|
||||
if (signal.isNormalOpen()) {
|
||||
if (routePath.isPathRoute(signal.getLockedRoute())) {
|
||||
continue;
|
||||
} else {
|
||||
result[2] = true; // 非路径进路办理
|
||||
// 非路径进路办理
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result[1] = true;
|
||||
//筛选可触发的进路
|
||||
for (Route route : routePath.getRouteList()) {
|
||||
TrainInfo other = repository.querySameStartTriggerRouteTrain(trainInfo, route);
|
||||
if (other != null) { // 已经有在排列中的进路,结束
|
||||
@ -192,15 +189,40 @@ public abstract class AtsRouteSelectService {
|
||||
triggerList.add(route);
|
||||
}
|
||||
}
|
||||
//选择要触发的进路
|
||||
if (triggerList.size() == 1) {
|
||||
return triggerList.get(0);
|
||||
} else if (triggerList.size() > 1) {
|
||||
if (planSection.equals(triggerList.get(0).getLastRouteSection()) && nextPlanSection != null) {
|
||||
// 进路是计划站台轨,根据后续计划筛选
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(planSection, nextPlanSection);
|
||||
for (Route temp : triggerList) {
|
||||
if (routePaths.get(0).containsAllSections(temp.getOverlap().getFirstPath().getSectionList())) {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取第一个延续保护道岔定位的
|
||||
for (Route temp : triggerList) {
|
||||
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(switchList,
|
||||
String.format("列车[%s]过滤进路异常:进路不是延续保护差异进路[%s]",
|
||||
trainInfo.getGroupNumber(),
|
||||
triggerList.stream().map(Route::getName).collect(Collectors.joining(","))));
|
||||
if (switchList.get(0).isNormal()) {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 列车未接近此信号机
|
||||
result[2] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean isApproachSignal(SimulationDataRepository repository, TrainInfo trainInfo, Signal signal) {
|
||||
|
@ -6,14 +6,12 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
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.onboard.ATP.ATPService;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
@ -45,7 +43,6 @@ public class AtsHeadTrainStageService implements AtsStageService {
|
||||
DestinationCodeDefinition dcd = repository.findDestinationCodeDefinition(trainInfo.getDestinationCode());
|
||||
if (dcd == null)
|
||||
return;
|
||||
SectionPosition headPosition = repository.buildHeadPositionOfTrainInfo(trainInfo);
|
||||
if (Objects.equals(dcd.getSection(), parkSection)) {
|
||||
// 列车到达目的地
|
||||
trainInfo.finishPlanPrepareInbound();
|
||||
@ -64,7 +61,7 @@ public class AtsHeadTrainStageService implements AtsStageService {
|
||||
if (Objects.equals(dcd.getSection(), parkSection)) {
|
||||
handleArriveDestination(simulation, trainInfo);
|
||||
} else {
|
||||
this.updateNextTarget(simulation, trainInfo);
|
||||
this.updatePlanSection(simulation, trainInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,13 +71,13 @@ public class AtsHeadTrainStageService implements AtsStageService {
|
||||
if (Objects.equals(dcd.getSection(), parkSection)) {
|
||||
handleArriveDestination(simulation, trainInfo);
|
||||
} else {
|
||||
this.updateNextTarget(simulation, trainInfo);
|
||||
this.updatePlanSection(simulation, trainInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePassStand(Simulation simulation, TrainInfo trainInfo) {
|
||||
this.updateNextTarget(simulation, trainInfo);
|
||||
this.updatePlanSection(simulation, trainInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,92 +89,53 @@ public class AtsHeadTrainStageService implements AtsStageService {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNextTarget(Simulation simulation, TrainInfo trainInfo) {
|
||||
boolean right = trainInfo.getRight();
|
||||
private void updatePlanSection(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (!StringUtils.hasText(trainInfo.getPlanStandTrack()))
|
||||
return;
|
||||
boolean planRight = trainInfo.getHctPath().isRight();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
SectionPosition headPosition = repository.buildHeadPositionOfTrainInfo(trainInfo);
|
||||
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
//如果还未到达目标轨
|
||||
Section headSection = headPosition.getSection();
|
||||
if (StringUtils.hasText(trainInfo.getEstimatedArriveStandTrack())) {
|
||||
Section target = repository.getByCode(trainInfo.getEstimatedArriveStandTrack(), Section.class);
|
||||
if (!target.equals(headSection) && target.isAheadOf(repository, headSection, right)) {
|
||||
return;
|
||||
}
|
||||
if (!planSection.equals(headSection) && planSection.isAheadOf(repository, headSection, planRight)) {
|
||||
return;
|
||||
}
|
||||
//寻找目标区段
|
||||
Section nextTarget = queryNextTarget(simulation, headPosition.getSection(), trainInfo, right);
|
||||
if (nextTarget == null)
|
||||
Section nextPlanSection = queryNextPlanSection(simulation, trainInfo);
|
||||
if (nextPlanSection == null)
|
||||
return;
|
||||
//判断调头
|
||||
if (!nextTarget.isAheadOf(repository, headSection, right)) {//下一目标区段不在当前车头方向的前方
|
||||
Boolean trainRight = trainInfo.getRight();
|
||||
if (!nextPlanSection.isAheadOf(repository, headSection, trainRight)) {//下一计划区段不在当前车头方向的前方
|
||||
atpService.turnDirectionImmediately(repository.getOnlineTrainBy(trainInfo.getGroupNumber())); //调头
|
||||
}
|
||||
//更新预计到站
|
||||
SectionPosition stopPosition = new SectionPosition(nextTarget, nextTarget.getStopPointByDirection(right));
|
||||
Float distance = CalculateService.calculateDistance(headPosition, stopPosition, right);
|
||||
//更新计划到站
|
||||
SectionPosition stopPosition = new SectionPosition(nextPlanSection, nextPlanSection.getStopPointByDirection(planRight));
|
||||
Float distance = CalculateService.calculateDistance(headPosition, stopPosition, planRight);
|
||||
int runningTime;
|
||||
if (distance != null) {
|
||||
runningTime = (int) (distance / (45 / 3.6));
|
||||
} else {
|
||||
runningTime = 180;
|
||||
}
|
||||
trainInfo.updatePlanInfo(nextTarget, null, null);
|
||||
// trainInfo.updateEstimatedArriveInfo(nextTarget, simulation.getSystemTime().toLocalTime().plusSeconds(runningTime));
|
||||
boolean jump = this.atsStandService.isJump(nextTarget, trainInfo.getGroupNumber());
|
||||
onboardAtpApiService.updateNextArriveInfo(simulation, trainInfo.getGroupNumber(), nextTarget, true, runningTime, jump);
|
||||
trainInfo.updatePlanInfo(nextPlanSection, null, null);
|
||||
boolean jump = this.atsStandService.isJump(nextPlanSection, trainInfo.getGroupNumber());
|
||||
onboardAtpApiService.updateNextArriveInfo(simulation, trainInfo.getGroupNumber(), nextPlanSection, true, runningTime, jump);
|
||||
}
|
||||
|
||||
public static Section queryNextTarget(Simulation simulation, Section headSection, TrainInfo trainInfo, Boolean right) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Section> targetList = trainInfo.getHeadPath().getSectionList();
|
||||
for (int i = targetList.size() - 1; i >= 0; i--) {
|
||||
Section target = targetList.get(i);
|
||||
List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(target, headSection);
|
||||
if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
return target;
|
||||
}
|
||||
public static Section queryNextPlanSection(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (trainInfo.getPlanStandTrack() == null) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Section> targetList = trainInfo.getHctPath().getSections();
|
||||
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
int index = targetList.indexOf(planSection);
|
||||
if (index == -1 || index == targetList.size() - 1) {
|
||||
return null;
|
||||
} else {
|
||||
return targetList.get(index + 1);
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
// SimulationDataRepository repository = simulation.getRepository();
|
||||
// String dc = trainInfo.getDestinationCode();
|
||||
// List<Routing> routings = repository.queryRoutingByDestCode(dc);
|
||||
// Section nextSection = null;
|
||||
// if (!CollectionUtils.isEmpty(routings)) { //目的地码在区段上
|
||||
// for (Routing routing : routings) {
|
||||
// if (headSection.isTurnBackTrack()) { //是折返轨,不限制方向
|
||||
// nextSection = routing.queryNextSection(headSection);
|
||||
// if (nextSection != null)
|
||||
// break;
|
||||
// for (Section s : routing.getAllSections()) {
|
||||
// List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(s, headSection);
|
||||
// if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
// if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == routing.isRight())) {
|
||||
// return s;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else { //不是折返轨,必须和列车同向
|
||||
// if (routing.isRight() == right) {
|
||||
// nextSection = routing.queryNextSection(headSection);
|
||||
// if (nextSection != null)
|
||||
// break;
|
||||
// for (Section s : routing.getAllSections()) {
|
||||
// List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(s, headSection);
|
||||
// if (routePaths.stream().anyMatch(routePath -> routePath.isRight() == right)) {
|
||||
// return s;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// DestinationCodeDefinition dcd = repository.findDestinationCodeDefinition(dc);
|
||||
// if (dcd == null)
|
||||
// return null;
|
||||
// nextSection = AtsTrainService.findNextTarget4HeadTrain(simulation, trainInfo, repository, headSection, headSection.getStation(), dcd);
|
||||
// }
|
||||
// return nextSection;
|
||||
}
|
||||
}
|
||||
|
@ -280,15 +280,18 @@ public class RouteService {
|
||||
// 进路内区段占用检查
|
||||
List<Section> sectionList = route.getSectionList();
|
||||
for (Section section : sectionList) {
|
||||
if (section.isOccupied() && !section.isPreReset()) {
|
||||
if (section.isSwitchTrack()) {
|
||||
if (!section.getRelSwitch().isPreReset()) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section);
|
||||
}
|
||||
} else {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section);
|
||||
}
|
||||
if (section.isOccupied()) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section);
|
||||
}
|
||||
// if (section.isOccupied() && !section.isPreReset()) {
|
||||
// if (section.isSwitchTrack()) {
|
||||
// if (!section.getRelSwitch().isPreReset()) {
|
||||
// return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section);
|
||||
// }
|
||||
// } else {
|
||||
// return new Route.CheckFailMessage(Route.CheckFailReason.SectionNotFree, section);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// 延续保护检查
|
||||
RouteOverlap overlap = route.getOverlap();
|
||||
|
@ -186,7 +186,7 @@ public class CommandBO {
|
||||
if (!train.isStopAtThePosition(driveStep.getTargetPosition())) { //如果列车没停到目标位置
|
||||
if (!train.isStop())
|
||||
return buildDriverForceChangeOperationStep(train.getGroupNumber(), -1);
|
||||
if (!DriveMode.RM.equals(train.getDriveMode()))
|
||||
if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode())
|
||||
return buildDriverDriveModeChangeOperationStep(train.getGroupNumber(), DriveMode.RM);
|
||||
if (train.isEB())
|
||||
return buildReleaseEBStep(train);
|
||||
@ -305,7 +305,7 @@ public class CommandBO {
|
||||
// command.getTargetMember().setCommand(null);
|
||||
// }
|
||||
} else {
|
||||
if (!DriveMode.RM.equals(train.getDriveMode())) {
|
||||
if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode()) {
|
||||
return buildDriverDriveModeChangeOperationStep(train.getGroupNumber(), DriveMode.RM);
|
||||
}
|
||||
if (train.isSignalEB()) {
|
||||
|
@ -0,0 +1,17 @@
|
||||
package club.joylink.rtss.simulation.cbtc.data.map;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class SectionRunPath {
|
||||
private List<Section> sections;
|
||||
|
||||
private boolean right;
|
||||
|
||||
public SectionRunPath(List<Section> sections, boolean right) {
|
||||
this.sections = sections;
|
||||
this.right = right;
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ public class PSDStatus extends DeviceStatus {
|
||||
|
||||
public PSDStatus(PSD psd) {
|
||||
super(psd.getCode(), psd.getDeviceType());
|
||||
this.close = psd.isClose();
|
||||
this.close = psd.isCloseAndLock();
|
||||
// this.lock = psd.isLock();
|
||||
this.interlockRelease = psd.isInterlockRelease();
|
||||
this.noStatus = psd.isNoStatus();
|
||||
@ -49,8 +49,8 @@ public class PSDStatus extends DeviceStatus {
|
||||
PSD psd = (PSD) device;
|
||||
PSDStatusVO status = (PSDStatusVO)statusVO;
|
||||
boolean change = false;
|
||||
if (!Objects.equals(this.close, psd.isClose())) {
|
||||
this.close = psd.isClose();
|
||||
if (!Objects.equals(this.close, psd.isCloseAndLock())) {
|
||||
this.close = psd.isCloseAndLock();
|
||||
status.setClose(this.close);
|
||||
change = true;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ public class RoutePath {
|
||||
return new SectionPosition(section, offset);
|
||||
}
|
||||
|
||||
public Route queryRouteContainsSection(RunLevel runLevel, Section section, MapConfig config) {
|
||||
public Route queryRouteContainsSection(boolean communication, Section section, MapConfig config) {
|
||||
for (Signal signal : this.signalList) {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (CollectionUtils.isEmpty(routeList)) {
|
||||
@ -261,11 +261,11 @@ public class RoutePath {
|
||||
}
|
||||
for (Route route : routeList) {
|
||||
if (config.isRouteLikeHa1()) {
|
||||
if (Objects.equals(runLevel, RunLevel.CBTC)) { // ctc级别列车找ATP进路
|
||||
if (communication) { // 通信车找ATP进路
|
||||
if (!route.isAtp()) {
|
||||
continue;
|
||||
}
|
||||
} else { // 非CTC列车找地面进路
|
||||
} else { // 非通信车找地面进路
|
||||
if (!route.isGround()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ public class TrainInfo extends MapElement {
|
||||
* 头码车的区段路径
|
||||
*/
|
||||
@Setter
|
||||
private SectionPath headPath;
|
||||
private SectionRunPath hctPath;
|
||||
|
||||
/**
|
||||
* 下令停车
|
||||
@ -244,29 +244,21 @@ public class TrainInfo extends MapElement {
|
||||
*/
|
||||
@Setter
|
||||
private String turnBackStatus = NON;
|
||||
/**
|
||||
* 无折返
|
||||
*/
|
||||
/** 无折返 */
|
||||
public static String NON = "NON";
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
/** 初始化 */
|
||||
public static String INIT = "INIT";
|
||||
/**
|
||||
* 开往折返轨
|
||||
*/
|
||||
/** 开往折返轨 */
|
||||
public static String TO = "TO";
|
||||
/**
|
||||
* 到达折返轨停稳
|
||||
*/
|
||||
/** 到达折返轨停稳 */
|
||||
public static String STOP = "STOP";
|
||||
/**
|
||||
* 开出折返轨
|
||||
*/
|
||||
/** 开出折返轨 */
|
||||
public static String EXIT = "EXIT";
|
||||
/** ATS为此列车触发的进路 */
|
||||
private Map<String, Route> atsTriggerRouteMap = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean communication;
|
||||
|
||||
public TrainInfo(String groupNumber) {
|
||||
super(groupNumber, DeviceType.TRAIN);
|
||||
this.groupNumber = groupNumber;
|
||||
@ -383,7 +375,7 @@ public class TrainInfo extends MapElement {
|
||||
this.offsetp = headPosition.getPercent();
|
||||
if (headPosition.getSection().isSwitchTrack()) {
|
||||
this.section = headPosition.getSection().getParent().getCode();
|
||||
} else if (this.isCtcLevel()) {
|
||||
} else if (this.isCommunication()) {
|
||||
this.section = headPosition.getLogicSection().getCode();
|
||||
} else {
|
||||
this.section = headPosition.getSection().getCode();
|
||||
@ -408,6 +400,7 @@ public class TrainInfo extends MapElement {
|
||||
} else if (speed != 0 && this.turnBackStatus.equals(STOP)) {
|
||||
this.turnBackStatus = EXIT;
|
||||
}
|
||||
this.communication = train.isCommunication();
|
||||
}
|
||||
|
||||
public boolean isCtcLevel() {
|
||||
|
@ -99,7 +99,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 车载服务通讯是否正常在线
|
||||
*/
|
||||
private boolean online;
|
||||
private boolean communication;
|
||||
|
||||
/**
|
||||
* 列车运行级别
|
||||
@ -111,6 +111,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
*/
|
||||
private DriveMode driveMode;
|
||||
|
||||
/**
|
||||
* 预选驾驶模式
|
||||
*/
|
||||
private DriveMode preDriveMode;
|
||||
|
||||
/**
|
||||
* 服务号
|
||||
*/
|
||||
@ -400,6 +405,12 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
*/
|
||||
private int runningTime;
|
||||
|
||||
public void setCommunication(boolean communication) {
|
||||
if (Fault.COMMUNICATION_ABNORMAL.equals(this.fault) && communication)
|
||||
return;
|
||||
this.communication = communication;
|
||||
}
|
||||
|
||||
public void setRunType(RunType runType) {
|
||||
this.runType = runType;
|
||||
switch (runType) {
|
||||
@ -446,8 +457,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.communication = true;
|
||||
this.runLevel = null;
|
||||
this.driveMode = null;
|
||||
this.preDriveMode = null;
|
||||
this.serviceNumber = null;
|
||||
this.tripNumber = null;
|
||||
this.destinationCode = null;
|
||||
@ -569,11 +582,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.communication = true;
|
||||
this.jump = false;
|
||||
this.hold = false;
|
||||
this.standParkedTrainActivity = null;
|
||||
this.runLevel = RunLevel.CBTC;
|
||||
this.driveMode = DriveMode.AM;
|
||||
this.preDriveMode = DriveMode.AM;
|
||||
this.speed = 0;
|
||||
this.atoSpeed = 0;
|
||||
this.atpSpeed = 0;
|
||||
@ -713,8 +728,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
// this.setSignalEB(false);
|
||||
this.setAtoOn(false);
|
||||
this.setDriveMode(DriveMode.RM);
|
||||
setCommunication(false); //断开通信
|
||||
// this.lossPosition();
|
||||
this.setCbtcMaMiss(); //通信断开
|
||||
// this.setCbtcMaMiss(); //通信断开
|
||||
// this.lastTwoPassedResponders.clear();
|
||||
// if (RunLevel.CBTC.equals(this.runLevel)) {
|
||||
// this.setCbtcMaMiss();
|
||||
@ -728,7 +744,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
public void useCMMode() {
|
||||
if (!this.isAtpOn()) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATP", this.getCode()));
|
||||
return;
|
||||
}
|
||||
this.atoOn = false;
|
||||
this.driveMode = DriveMode.CM;
|
||||
@ -736,12 +752,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
public void useAMMode() {
|
||||
if (!atoOn) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATO", this.getCode()));
|
||||
return;
|
||||
}
|
||||
if (!this.isAtpOn()) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATP", this.getCode()));
|
||||
return;
|
||||
}
|
||||
this.driveMode = DriveMode.AM;
|
||||
setCommunication(true);
|
||||
}
|
||||
|
||||
public void useNRMMode() {
|
||||
@ -755,9 +772,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return;
|
||||
}
|
||||
this.driveMode = DriveMode.NRM;
|
||||
if (RunLevel.CBTC.equals(this.runLevel)) {
|
||||
this.setCbtcMaMiss();
|
||||
}
|
||||
setCommunication(false);
|
||||
}
|
||||
|
||||
public void setITCMode() {
|
||||
@ -1113,13 +1128,15 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
public boolean isCommunicable() {
|
||||
Section section = headPosition.getSection();
|
||||
Station deviceStation = section.getDeviceStation();
|
||||
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault
|
||||
|| Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault()
|
||||
|| !section.anyZcWorking()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return communication && section.anyZcWorking();
|
||||
|
||||
// Station deviceStation = section.getDeviceStation();
|
||||
// if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault
|
||||
// || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault()
|
||||
// || !section.anyZcWorking()) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
}
|
||||
|
||||
public boolean isCMMode() {
|
||||
@ -1135,26 +1152,27 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* 通信异常
|
||||
*/
|
||||
COMMUNICATION_ABNORMAL {
|
||||
// @Override
|
||||
// public boolean apply(MapElement device) {
|
||||
// VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
// if (Objects.equals(this, train.getFault())) {
|
||||
// return false;
|
||||
// }
|
||||
// train.setFault(this);
|
||||
// train.lossPosition();
|
||||
// return true;
|
||||
// }
|
||||
@Override
|
||||
public boolean apply(MapElement device) {
|
||||
if (super.apply(device)) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
train.setCommunication(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/** 驾驶异常 */
|
||||
DRIVE_FAULT {
|
||||
@Override
|
||||
public boolean apply(MapElement device) {
|
||||
super.apply(device);
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
train.emergencyBreak(); //暂时就在这里直接处理,可能正常应该是ATP的责任
|
||||
return true;
|
||||
if (super.apply(device)) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
train.emergencyBreak(); //暂时就在这里直接处理,可能正常应该是ATP的责任
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -49,9 +49,10 @@ public class ATOService {
|
||||
}
|
||||
if (Objects.nonNull(train.getMa())) {
|
||||
train.setAtoOn(true);
|
||||
if (DriveMode.CM.equals(train.getDriveMode())) {
|
||||
train.useAMMode();
|
||||
}
|
||||
train.setPreDriveMode(DriveMode.AM);
|
||||
// if (DriveMode.CM.equals(train.getDriveMode())) {
|
||||
// train.useAMMode();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,7 @@ package club.joylink.rtss.simulation.cbtc.onboard.ATP;
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.AtsApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.ControlGear;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
|
||||
@ -109,6 +106,7 @@ public class ATPLogicLoop {
|
||||
|
||||
private void onboardLogicRun2(Simulation simulation, VirtualRealityTrain train) {
|
||||
this.runLevelControl(simulation, train);
|
||||
this.driveModeControl(simulation, train);
|
||||
|
||||
boolean right = train.isRight();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
@ -183,6 +181,33 @@ public class ATPLogicLoop {
|
||||
this.atoService.ATO(train);
|
||||
}
|
||||
|
||||
private void driveModeControl(Simulation simulation, VirtualRealityTrain train) {
|
||||
DriveMode preDriveMode = train.getPreDriveMode();
|
||||
DriveMode driveMode = train.getDriveMode();
|
||||
if (preDriveMode.equals(driveMode))
|
||||
return;
|
||||
switch (preDriveMode) {
|
||||
case AM:
|
||||
train.setCommunication(true); //恢复列车通信
|
||||
if (train.isCMMode() && train.isAtoOn()) {
|
||||
train.useAMMode();
|
||||
}
|
||||
break;
|
||||
case CM:
|
||||
train.setCommunication(true); //恢复列车通信
|
||||
if (!train.isCbtcMaMiss() || !train.isItcMaMiss()) { //CBTC或ITC的移动授权未丢失
|
||||
Float distance = ATOService.calculateDistanceOfMa(train.getHeadPosition(), train.isRight(), train.getMa());
|
||||
if (distance != null && distance > 0) { //移动授权的距离为正
|
||||
train.useCMMode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RM:
|
||||
train.useRMMode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRunningTime(VirtualRealityTrain train) {
|
||||
if (train.isParkingAt()) {
|
||||
train.setRunningTime(0);
|
||||
|
@ -16,11 +16,6 @@ public interface OnboardAtpApiService {
|
||||
*/
|
||||
void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
|
||||
/**
|
||||
* 忽略驾驶模式更新CBTC移动授权
|
||||
*/
|
||||
boolean ignoreDriveModeUpdateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
|
||||
void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
|
||||
/**
|
||||
|
@ -37,30 +37,10 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (train.getFault() == VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL) { //列车通信故障
|
||||
return;
|
||||
}
|
||||
if (train.isRMMode() || train.isNRMMode())
|
||||
return;
|
||||
if (train.isCBTC()) {
|
||||
if (train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreDriveModeUpdateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma) {
|
||||
if (ma == null)
|
||||
return false;
|
||||
if (!train.isAtpOn()) {
|
||||
return false;
|
||||
}
|
||||
if (train.getFault() == VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL) { //列车通信故障
|
||||
return false;
|
||||
}
|
||||
this.ATPService.updateMA(train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,7 +50,7 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (!train.isCBTC()) {
|
||||
if (!train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
train.setItcMaMissDuration(0);
|
||||
}
|
||||
|
@ -13,4 +13,7 @@ public class DisplayVO {
|
||||
private List<String> stationCodeList;
|
||||
|
||||
private List<String> elementList;
|
||||
|
||||
/** 可切换显示的车站 */
|
||||
private List<String> switchStationCodeList;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user