修复国赛场景编制遇到的问题。修改延续保护中道岔的延续保护及侧防解锁逻辑;修改设计划车时的计划筛选逻辑
This commit is contained in:
parent
0faf852aa6
commit
aec1a01f96
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,6 @@
|
|||
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.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -13,11 +12,12 @@ import org.springframework.stereotype.Component;
|
|||
@Slf4j
|
||||
@Component
|
||||
public class AtsHeadTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
@Override
|
||||
public Route select(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (!trainInfo.isHeadCodeTrain()) {
|
||||
return null;
|
||||
}
|
||||
return queryTriggerRoutes(simulation, trainInfo.getHctPath().getSections(), trainInfo, null);
|
||||
|
||||
@Override
|
||||
public Route select(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (!trainInfo.isHeadCodeTrain()) {
|
||||
return null;
|
||||
}
|
||||
return queryTriggerRoutes(simulation, trainInfo.getHctPath().getSections(), trainInfo, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,6 @@ 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.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
|
@ -23,6 +18,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 计划车进路选择
|
||||
|
@ -31,207 +30,220 @@ import java.util.stream.Collectors;
|
|||
@Component
|
||||
public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
||||
|
||||
@Autowired
|
||||
private AtsAlarmService atsAlarmService;
|
||||
@Autowired
|
||||
private AtsAlarmService atsAlarmService;
|
||||
|
||||
@Override
|
||||
public Route select(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (!trainInfo.isPlanTrain()) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber());
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
// 根据车次计划查找可触发进路列表
|
||||
@Override
|
||||
public Route select(Simulation simulation, TrainInfo trainInfo) {
|
||||
if (!trainInfo.isPlanTrain()) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
|
||||
trainInfo.getTripNumber());
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
// 根据车次计划查找可触发进路列表
|
||||
// Object[] results = this.queryByStationPlan(repository, systemTime, trainInfo, tripPlan);
|
||||
Route route = queryByStationPlan(simulation, systemTime, trainInfo, tripPlan);
|
||||
// 根据计划筛选需触发进路
|
||||
return filterRoutes(simulation, trainInfo, tripPlan, route);
|
||||
}
|
||||
Route route = queryByStationPlan(simulation, systemTime, trainInfo, tripPlan);
|
||||
// 根据计划筛选需触发进路
|
||||
return filterRoutes(simulation, trainInfo, tripPlan, route);
|
||||
}
|
||||
|
||||
private Route queryByStationPlan(Simulation simulation, LocalDateTime systemTime, TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
//判断是否到进路触发时间
|
||||
Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class);
|
||||
if (section.isTransferTrack() || section.isTurnBackTrack()) { //列车在转换轨或折返轨
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
for (StationPlan stationPlan : planList) {
|
||||
if (!stationPlan.getStation().isDepot()) { //第一个非停车场的车站
|
||||
if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())
|
||||
&& !section.equals(stationPlan.getSection())) { //车站是列车的计划
|
||||
if (!systemTime.toLocalTime().plusSeconds(60).isAfter(tripPlan.getStartTime())) { //当前时间不早于计划开始时间60秒
|
||||
log.debug(String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
private Route queryByStationPlan(Simulation simulation, LocalDateTime systemTime,
|
||||
TrainInfo trainInfo, TripPlan tripPlan) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
//判断是否到进路触发时间
|
||||
Section section = repository.getByCode(trainInfo.getPhysicalSection(), Section.class);
|
||||
if (section.isTransferTrack() || section.isTurnBackTrack()) { //列车在转换轨或折返轨
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
for (StationPlan stationPlan : planList) {
|
||||
if (!stationPlan.getStation().isDepot()) { //第一个非停车场的车站
|
||||
if (stationPlan.getSection().getCode().equals(trainInfo.getPlanStandTrack())
|
||||
&& !section.equals(stationPlan.getSection())) { //车站是列车的计划
|
||||
if (!systemTime.toLocalTime().plusSeconds(60)
|
||||
.isAfter(tripPlan.getStartTime())) { //当前时间不早于计划开始时间60秒
|
||||
log.debug(
|
||||
String.format("列车[%s]未到发车时间,不触发进路", trainInfo.getGroupNumber()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
List<Section> targetList = tripPlan.getPlanList().stream().map(StationPlan::getSection).collect(Collectors.toList());
|
||||
if (tripPlan.isBackup()) {
|
||||
targetList.add(tripPlan.getEndSection());
|
||||
}
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
return queryTriggerRoutes(simulation, targetList, trainInfo, tripPlan.getEndSection());
|
||||
} else {
|
||||
return queryTriggerRoutes(simulation, targetList, trainInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 先选取需要征用的进路,再根据计划判断是否存在冲突的未完成计划
|
||||
*/
|
||||
private Route filterRoutes(Simulation simulation,
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Route route) {
|
||||
if (route == null) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
// 先选取需要征用的进路
|
||||
log.debug(String.format("列车[%s]筛选出的进路为:[%s]", trainInfo.getGroupNumber(), route.getName()));
|
||||
if (route.isCheckConflict() && route.getConflictAlarm() == null) {
|
||||
ConflictInfo conflictInfo = this.checkConflict(repository, trainInfo, tripPlan, route);
|
||||
if (conflictInfo != null) {
|
||||
Section startSection = conflictInfo.section;
|
||||
StationPlan stationPlan = conflictInfo.stationPlan;
|
||||
String conflictDesc = String.format("计划车(%s(%s)触发的进路[%s]与计划(%s)从节点(%s_%s)到节点(%s_%s)的计划冲突,无法选排",
|
||||
tripPlan.getStNumber(), trainInfo.getGroupNumber(), route.getName(),
|
||||
stationPlan.getPlan().getStNumber(),
|
||||
startSection.getStation().getName(), startSection.getName(),
|
||||
stationPlan.getStation().getName(), stationPlan.getSection().getName());
|
||||
log.debug(String.format("构建并发送进路冲突告警"));
|
||||
AtsAlarm alarm = this.atsAlarmService.buildAndSendAlarm(
|
||||
simulation,
|
||||
AtsAlarm.Type.Conflict_Route_Set,
|
||||
"0", route.getCode(), conflictDesc);
|
||||
route.setConflictAlarm(alarm);
|
||||
}
|
||||
}
|
||||
return route;
|
||||
List<Section> targetList = tripPlan.getPlanList().stream().map(StationPlan::getSection)
|
||||
.collect(Collectors.toList());
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
targetList.add(tripPlan.getEndSection());
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class ConflictInfo {
|
||||
Section section;
|
||||
StationPlan stationPlan;
|
||||
|
||||
public ConflictInfo(Section section, StationPlan stationPlan) {
|
||||
this.section = section;
|
||||
this.stationPlan = stationPlan;
|
||||
}
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
return queryTriggerRoutes(simulation, targetList, trainInfo, tripPlan.getEndSection());
|
||||
} else {
|
||||
return queryTriggerRoutes(simulation, targetList, trainInfo, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查进路是否和未完成的计划冲突
|
||||
*
|
||||
* @param repository
|
||||
* @param trainInfo
|
||||
* @param tripPlan
|
||||
* @param route
|
||||
* @return
|
||||
*/
|
||||
public ConflictInfo checkConflict(SimulationDataRepository repository, TrainInfo trainInfo,
|
||||
TripPlan tripPlan, Route route) {
|
||||
Section section = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
LocalTime arriveTime = this.queryRouteArriveTime(repository, route, trainInfo, tripPlan, section);
|
||||
if (arriveTime == null) {
|
||||
log.debug(String.format("计划车[%s]未找到进路[%s]下一计划到达时间", trainInfo.getGroupNumber(), route.getName()));
|
||||
return null;
|
||||
/**
|
||||
* 先选取需要征用的进路,再根据计划判断是否存在冲突的未完成计划
|
||||
*/
|
||||
private Route filterRoutes(Simulation simulation,
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Route route) {
|
||||
if (route == null) {
|
||||
return null;
|
||||
}
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
// 先选取需要征用的进路
|
||||
log.debug(
|
||||
String.format("列车[%s]筛选出的进路为:[%s]", trainInfo.getGroupNumber(), route.getName()));
|
||||
if (route.isCheckConflict() && route.getConflictAlarm() == null) {
|
||||
ConflictInfo conflictInfo = this.checkConflict(repository, trainInfo, tripPlan, route);
|
||||
if (conflictInfo != null) {
|
||||
Section startSection = conflictInfo.section;
|
||||
StationPlan stationPlan = conflictInfo.stationPlan;
|
||||
String conflictDesc = String.format(
|
||||
"计划车(%s(%s)触发的进路[%s]与计划(%s)从节点(%s_%s)到节点(%s_%s)的计划冲突,无法选排",
|
||||
tripPlan.getStNumber(), trainInfo.getGroupNumber(), route.getName(),
|
||||
stationPlan.getPlan().getStNumber(),
|
||||
startSection.getStation().getName(), startSection.getName(),
|
||||
stationPlan.getStation().getName(), stationPlan.getSection().getName());
|
||||
log.debug(String.format("构建并发送进路冲突告警"));
|
||||
AtsAlarm alarm = this.atsAlarmService.buildAndSendAlarm(
|
||||
simulation,
|
||||
AtsAlarm.Type.Conflict_Route_Set,
|
||||
"0", route.getCode(), conflictDesc);
|
||||
route.setConflictAlarm(alarm);
|
||||
}
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class ConflictInfo {
|
||||
|
||||
Section section;
|
||||
StationPlan stationPlan;
|
||||
|
||||
public ConflictInfo(Section section, StationPlan stationPlan) {
|
||||
this.section = section;
|
||||
this.stationPlan = stationPlan;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查进路是否和未完成的计划冲突
|
||||
*
|
||||
* @param repository
|
||||
* @param trainInfo
|
||||
* @param tripPlan
|
||||
* @param route
|
||||
* @return
|
||||
*/
|
||||
public ConflictInfo checkConflict(SimulationDataRepository repository, TrainInfo trainInfo,
|
||||
TripPlan tripPlan, Route route) {
|
||||
Section section = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
LocalTime arriveTime = this.queryRouteArriveTime(repository, route, trainInfo, tripPlan,
|
||||
section);
|
||||
if (arriveTime == null) {
|
||||
log.debug(
|
||||
String.format("计划车[%s]未找到进路[%s]下一计划到达时间", trainInfo.getGroupNumber(),
|
||||
route.getName()));
|
||||
return null;
|
||||
}
|
||||
TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
Section start = null;
|
||||
StationPlan conflictStationPlan = null;
|
||||
Map<String, List<TripPlan>> serviceTripsMap = repository.getServiceTripsMap();
|
||||
for (List<TripPlan> planList : serviceTripsMap.values()) {
|
||||
for (TripPlan plan : planList) {
|
||||
if (plan.equals(tripPlan)) {
|
||||
continue;
|
||||
}
|
||||
TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
Section start = null;
|
||||
StationPlan conflictStationPlan = null;
|
||||
Map<String, List<TripPlan>> serviceTripsMap = repository.getServiceTripsMap();
|
||||
for (List<TripPlan> planList : serviceTripsMap.values()) {
|
||||
for (TripPlan plan : planList) {
|
||||
if (plan.equals(tripPlan)) {
|
||||
continue;
|
||||
}
|
||||
if (plan.equals(nextTripPlan)) {
|
||||
continue;
|
||||
}
|
||||
if (plan.getStartTime().isAfter(arriveTime)) {
|
||||
break;
|
||||
}
|
||||
List<StationPlan> stationPlanList = plan.getPlanList();
|
||||
TrainInfo aheadTrain = repository.queryAtsTrainInfoOfTripPlan(plan);
|
||||
start = plan.getStartSection();
|
||||
for (StationPlan temp : stationPlanList) {
|
||||
if (temp.getArriveTime().isAfter(arriveTime)) {
|
||||
break;
|
||||
}
|
||||
if (!temp.isFinished()) {
|
||||
if (!start.equals(temp.getSection())) {
|
||||
if (this.isConflict(repository, route, aheadTrain, start, temp.getSection())) {
|
||||
conflictStationPlan = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
break;
|
||||
}
|
||||
start = temp.getSection();
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
if (plan.equals(nextTripPlan)) {
|
||||
continue;
|
||||
}
|
||||
if (plan.getStartTime().isAfter(arriveTime)) {
|
||||
break;
|
||||
}
|
||||
List<StationPlan> stationPlanList = plan.getPlanList();
|
||||
TrainInfo aheadTrain = repository.queryAtsTrainInfoOfTripPlan(plan);
|
||||
start = plan.getStartSection();
|
||||
for (StationPlan temp : stationPlanList) {
|
||||
if (temp.getArriveTime().isAfter(arriveTime)) {
|
||||
break;
|
||||
}
|
||||
if (!temp.isFinished()) {
|
||||
if (!start.equals(temp.getSection())) {
|
||||
if (this.isConflict(repository, route, aheadTrain, start, temp.getSection())) {
|
||||
conflictStationPlan = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
break;
|
||||
}
|
||||
start = temp.getSection();
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
log.debug(String.format("列车[%s]的进路[%s]和未完成车站计划[%s]冲突",
|
||||
trainInfo.getGroupNumber(), route.getName(),
|
||||
String.format("%s{%s}", conflictStationPlan.getPlan().getStNumber(), conflictStationPlan.debugStr())));
|
||||
return new ConflictInfo(start, conflictStationPlan);
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (conflictStationPlan != null) {
|
||||
log.debug(String.format("列车[%s]的进路[%s]和未完成车站计划[%s]冲突",
|
||||
trainInfo.getGroupNumber(), route.getName(),
|
||||
String.format("%s{%s}", conflictStationPlan.getPlan().getStNumber(),
|
||||
conflictStationPlan.debugStr())));
|
||||
return new ConflictInfo(start, conflictStationPlan);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所需办理进路所需到达的计划时间
|
||||
*/
|
||||
private LocalTime queryRouteArriveTime(SimulationDataRepository repository, Route route,
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Section nextPlanSection) {
|
||||
boolean start = false;
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
for (int i = 0; i < planList.size(); i++) {
|
||||
StationPlan stationPlan = planList.get(i);
|
||||
if (stationPlan.getSection().equals(nextPlanSection)) {
|
||||
start = true;
|
||||
}
|
||||
if (start) {
|
||||
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(stationPlan.getSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
return stationPlan.getArriveTime();
|
||||
}
|
||||
}
|
||||
if (i == planList.size() - 1) { // 最后一站,判断是否站后折返
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
routePathList = repository.queryRoutePathsByStart(stationPlan.getSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
return nextTripPlan.getFirstStationPlan().getArriveTime();
|
||||
}
|
||||
}
|
||||
} else if (!Objects.equals(tripPlan.getEndSection(), stationPlan.getSection())) {
|
||||
routePathList = repository.getRoutePaths(stationPlan.getSection(), tripPlan.getEndSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
return tripPlan.getEndTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 查询所需办理进路所需到达的计划时间
|
||||
*/
|
||||
private LocalTime queryRouteArriveTime(SimulationDataRepository repository, Route route,
|
||||
TrainInfo trainInfo, TripPlan tripPlan, Section nextPlanSection) {
|
||||
boolean start = false;
|
||||
List<StationPlan> planList = tripPlan.getPlanList();
|
||||
for (int i = 0; i < planList.size(); i++) {
|
||||
StationPlan stationPlan = planList.get(i);
|
||||
if (stationPlan.getSection().equals(nextPlanSection)) {
|
||||
start = true;
|
||||
}
|
||||
if (start) {
|
||||
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(stationPlan.getSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
return stationPlan.getArriveTime();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (i == planList.size() - 1) { // 最后一站,判断是否站后折返
|
||||
if (tripPlan.isBehindTurnBack()) {
|
||||
routePathList = repository.queryRoutePathsByStart(stationPlan.getSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
return nextTripPlan.getFirstStationPlan().getArriveTime();
|
||||
}
|
||||
}
|
||||
} else if (!Objects.equals(tripPlan.getEndSection(), stationPlan.getSection())) {
|
||||
routePathList = repository.getRoutePaths(stationPlan.getSection(),
|
||||
tripPlan.getEndSection());
|
||||
for (RoutePath routePath : routePathList) {
|
||||
if (routePath.isPathRoute(route)) {
|
||||
return tripPlan.getEndTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 检查进路是否和未完成的计划冲突
|
||||
|
@ -309,116 +321,125 @@ public class AtsPlanTrainRouteSelectServiceImpl extends AtsRouteSelectService {
|
|||
// return null;
|
||||
// }
|
||||
|
||||
private boolean isConflict(SimulationDataRepository repository, Route route,
|
||||
TrainInfo aheadTrain, Section start, Section end) {
|
||||
if (start.equals(end)) {
|
||||
return false;
|
||||
}
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(start, end);
|
||||
boolean conflict = false;// 是否有冲突的路径,列车不在此路径中时,返回此状态
|
||||
RoutePath routePath = this.selectRoutePath(routePaths);
|
||||
if (routePath.isConflictWith(route)) {
|
||||
conflict = true;
|
||||
if (aheadTrain != null) {
|
||||
if (routePath.containsSection(aheadTrain.getPhysicalSection())) {//前车在此计划路径中
|
||||
Map<String, Route> atsTriggerRouteMap = aheadTrain.getAtsTriggerRouteMap();
|
||||
if (!atsTriggerRouteMap.isEmpty()) {
|
||||
for (Route triggerRoute : atsTriggerRouteMap.values()) {
|
||||
if (triggerRoute.isConflictWith(route) && (triggerRoute.isSetting() || triggerRoute.isOpenMain())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (routePath.isRight() == route.isRight()) {
|
||||
if (routePath.containsSection(route.getFirstRouteSection()) &&
|
||||
routePath.getSectionSort(route.getFirstRouteSection()) <= routePath.getSectionSort(aheadTrain.getPhysicalSection())) {
|
||||
// 前车已经走过区段,非冲突
|
||||
return false;
|
||||
} else if (routePath.containsSection(route.getLastRouteSection()) &&
|
||||
routePath.getSectionSort(route.getLastRouteSection()) <= routePath.getSectionSort(aheadTrain.getPhysicalSection())) {
|
||||
// 前车已经走过区段,非冲突
|
||||
return false;
|
||||
}
|
||||
} else if (routePath.isRight() != route.isRight()) { // 相反方向
|
||||
// 列车是否已经经过敌对进路
|
||||
if (routePath.containsSection(route.getLastRouteSection()) &&
|
||||
routePath.getSectionSort(route.getLastRouteSection()) <= routePath.getSectionSort(aheadTrain.getPhysicalSection())) {
|
||||
return false;
|
||||
} else if (routePath.containsSection(route.getFirstRouteSection()) &&
|
||||
routePath.getSectionSort(route.getFirstRouteSection()) <= routePath.getSectionSort(aheadTrain.getPhysicalSection())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return conflict;
|
||||
private boolean isConflict(SimulationDataRepository repository, Route route,
|
||||
TrainInfo aheadTrain, Section start, Section end) {
|
||||
if (start.equals(end)) {
|
||||
return false;
|
||||
}
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(start, end);
|
||||
boolean conflict = false;// 是否有冲突的路径,列车不在此路径中时,返回此状态
|
||||
RoutePath routePath = this.selectRoutePath(routePaths);
|
||||
if (routePath.isConflictWith(route)) {
|
||||
conflict = true;
|
||||
if (aheadTrain != null) {
|
||||
if (routePath.containsSection(aheadTrain.getPhysicalSection())) {//前车在此计划路径中
|
||||
Map<String, Route> atsTriggerRouteMap = aheadTrain.getAtsTriggerRouteMap();
|
||||
if (!atsTriggerRouteMap.isEmpty()) {
|
||||
for (Route triggerRoute : atsTriggerRouteMap.values()) {
|
||||
if (triggerRoute.isConflictWith(route) && (triggerRoute.isSetting()
|
||||
|| triggerRoute.isOpenMain())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (routePath.isRight() == route.isRight()) {
|
||||
if (routePath.containsSection(route.getFirstRouteSection()) &&
|
||||
routePath.getSectionSort(route.getFirstRouteSection()) <= routePath.getSectionSort(
|
||||
aheadTrain.getPhysicalSection())) {
|
||||
// 前车已经走过区段,非冲突
|
||||
return false;
|
||||
} else if (routePath.containsSection(route.getLastRouteSection()) &&
|
||||
routePath.getSectionSort(route.getLastRouteSection()) <= routePath.getSectionSort(
|
||||
aheadTrain.getPhysicalSection())) {
|
||||
// 前车已经走过区段,非冲突
|
||||
return false;
|
||||
}
|
||||
} else if (routePath.isRight() != route.isRight()) { // 相反方向
|
||||
// 列车是否已经经过敌对进路
|
||||
if (routePath.containsSection(route.getLastRouteSection()) &&
|
||||
routePath.getSectionSort(route.getLastRouteSection()) <= routePath.getSectionSort(
|
||||
aheadTrain.getPhysicalSection())) {
|
||||
return false;
|
||||
} else if (routePath.containsSection(route.getFirstRouteSection()) &&
|
||||
routePath.getSectionSort(route.getFirstRouteSection()) <= routePath.getSectionSort(
|
||||
aheadTrain.getPhysicalSection())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return conflict;
|
||||
}
|
||||
|
||||
private Route filter(SimulationDataRepository repository, TrainInfo trainInfo,
|
||||
TripPlan tripPlan, List<Route> triggerList, boolean turnBack) {
|
||||
Route route = triggerList.get(0);
|
||||
if (turnBack) {
|
||||
for (Route temp : triggerList) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if (triggerList.size() > 1) {
|
||||
Section section = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
List<Route> routeList = new ArrayList<>();
|
||||
for (Route temp : triggerList) {
|
||||
if (!routeList.isEmpty() && routeList.get(0).getReverseSwitchQuantity() > temp.getReverseSwitchQuantity()) {
|
||||
routeList.clear();
|
||||
}
|
||||
routeList.add(temp);
|
||||
}
|
||||
if (routeList.size() == 1) {
|
||||
route = routeList.get(0);
|
||||
} else {
|
||||
// 不同延续保护
|
||||
StationPlan nextStationPlan = tripPlan.queryNextStationPlan(section);
|
||||
if (section.equals(routeList.get(0).getLastRouteSection()) && nextStationPlan != null) {
|
||||
// 进路是计划站台轨,根据后续计划筛选
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(section, nextStationPlan.getSection());
|
||||
for (Route temp : routeList) {
|
||||
if (routePaths.get(0).containsAllSections(temp.getOverlap().getFirstPath().getSectionList())) {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取第一个延续保护道岔定位的
|
||||
for (Route temp : routeList) {
|
||||
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
|
||||
if (switchList.isEmpty()) {
|
||||
log.debug(String.format("列车[%s]过滤进路异常:进路不是延续保护差异进路[%s]",
|
||||
trainInfo.getGroupNumber(),
|
||||
String.join(",", routeList.stream().map(Route::getName).collect(Collectors.toList()))));
|
||||
}
|
||||
if (switchList.get(0).isNormal()) {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private Route filter(SimulationDataRepository repository, TrainInfo trainInfo,
|
||||
TripPlan tripPlan, List<Route> triggerList, boolean turnBack) {
|
||||
Route route = triggerList.get(0);
|
||||
if (turnBack) {
|
||||
for (Route temp : triggerList) {
|
||||
List<Section> sectionList = temp.getSectionList();
|
||||
boolean trainOccupy = false;
|
||||
for (Section rs : sectionList) {
|
||||
if (rs.isOccupied()) {
|
||||
trainOccupy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return route;
|
||||
if (trainOccupy) {
|
||||
continue;
|
||||
} else {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (triggerList.size() > 1) {
|
||||
Section section = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
|
||||
List<Route> routeList = new ArrayList<>();
|
||||
for (Route temp : triggerList) {
|
||||
if (!routeList.isEmpty()
|
||||
&& routeList.get(0).getReverseSwitchQuantity() > temp.getReverseSwitchQuantity()) {
|
||||
routeList.clear();
|
||||
}
|
||||
routeList.add(temp);
|
||||
}
|
||||
if (routeList.size() == 1) {
|
||||
route = routeList.get(0);
|
||||
} else {
|
||||
// 不同延续保护
|
||||
StationPlan nextStationPlan = tripPlan.queryNextStationPlan(section);
|
||||
if (section.equals(routeList.get(0).getLastRouteSection()) && nextStationPlan != null) {
|
||||
// 进路是计划站台轨,根据后续计划筛选
|
||||
List<RoutePath> routePaths = repository.getRoutePaths(section,
|
||||
nextStationPlan.getSection());
|
||||
for (Route temp : routeList) {
|
||||
if (routePaths.get(0)
|
||||
.containsAllSections(temp.getOverlap().getFirstPath().getSectionList())) {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取第一个延续保护道岔定位的
|
||||
for (Route temp : routeList) {
|
||||
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
|
||||
if (switchList.isEmpty()) {
|
||||
log.debug(String.format("列车[%s]过滤进路异常:进路不是延续保护差异进路[%s]",
|
||||
trainInfo.getGroupNumber(),
|
||||
String.join(",",
|
||||
routeList.stream().map(Route::getName).collect(Collectors.toList()))));
|
||||
}
|
||||
if (switchList.get(0).isNormal()) {
|
||||
route = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return (List<Route>)[0]: 可触发的进路;(Boolean)[1]:是否需要折返
|
||||
|
|
|
@ -11,300 +11,408 @@ import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
|||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteFls;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteFls.FlsElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SectionPath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiLogic {
|
||||
interface JobName {
|
||||
String SECTION_STOP_COUNTDOWN = "SECTION_STOP_COUNTDOWN";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CiDeviceStatusCollector deviceStatusCollector;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private CiSignalControlService signalControlService;
|
||||
@Autowired
|
||||
private CiService ciService;
|
||||
@Autowired
|
||||
private StationDirectionService stationDirectionService;
|
||||
interface JobName {
|
||||
|
||||
@Autowired
|
||||
private AtsStationService atsStationService;
|
||||
String SECTION_STOP_COUNTDOWN = "SECTION_STOP_COUNTDOWN";
|
||||
}
|
||||
|
||||
public void runForTrainPosition(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
}
|
||||
@Autowired
|
||||
private CiDeviceStatusCollector deviceStatusCollector;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private CiSignalControlService signalControlService;
|
||||
@Autowired
|
||||
private CiService ciService;
|
||||
@Autowired
|
||||
private StationDirectionService stationDirectionService;
|
||||
|
||||
public void run(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
// 信号机监控控制
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
for (Signal signal : repository.getSignalList()) {
|
||||
signalMonitor(simulation, signal);
|
||||
}
|
||||
// 联锁监控逻辑
|
||||
List<Route> routeList = repository.getRouteList();
|
||||
for (Route route : routeList) {
|
||||
interlockMonitor(simulation, route);
|
||||
}
|
||||
List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList();
|
||||
for (RouteOverlap routeOverlap : routeOverlapList) {
|
||||
overlapMonitor(simulation, routeOverlap);
|
||||
}
|
||||
@Autowired
|
||||
private AtsStationService atsStationService;
|
||||
|
||||
// 区间灯点灯逻辑
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
// 车站站控操作模式转换
|
||||
atsStationService.replyOperationMode(simulation);
|
||||
// 车站
|
||||
simulation.getRepository().getStationList().stream().forEach(station -> {
|
||||
// 允许自律状态刷新
|
||||
station.refreshAllowAutonomyStatus();
|
||||
// 接、发辅助按钮倒计时刷新
|
||||
station.getStationDirectionMap().values().stream()
|
||||
.forEach(stationDirection -> {
|
||||
// 判断进路状态是否发生变化
|
||||
if (stationDirection.monitorRouteChangeStatus()) {
|
||||
stationDirection.modifyRunStatus();
|
||||
}
|
||||
// 如果倒数结束弹起接、发辅助按钮,超过50秒时,不再自动抬起
|
||||
if (!stationDirection.isAssistReadyStatus()
|
||||
&& !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime())
|
||||
&& stationDirection.getCountDown().decrementAndGet() <= 0) {
|
||||
stationDirection.setDeliverAssistStatus(false);
|
||||
stationDirection.setReceiveAssistStatus(false);
|
||||
stationDirection.getCountDown().set(0);
|
||||
}
|
||||
// 联锁数据检查
|
||||
stationDirectionService.refreshSectionLightStatus(simulation, stationDirection);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation),
|
||||
SimulationConstants.CI_LOOP_RATE);
|
||||
simulation.addJob(JobName.SECTION_STOP_COUNTDOWN, () -> sectionStopCountDown(simulation),
|
||||
SimulationConstants.CI_LOOP_RATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 区段停稳倒计时
|
||||
*/
|
||||
public void sectionStopCountDown(Simulation simulation) {
|
||||
for (Section section : simulation.getRepository().getHasStopCountDownSections()) {
|
||||
int stopCountDown = section.getStopCountDown();
|
||||
if (stopCountDown == 0) {
|
||||
//股道占用且股道有占用
|
||||
if (section.isOccupied()) {
|
||||
if (section.getNextRunningSectionOf(false).isOccupied() || section.getNextRunningSectionOf(true).isOccupied()) {
|
||||
section.readyStartStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stopCountDown == -1) {
|
||||
// 股道占用、股道两边没有占用、股道没有进路锁闭或该进路正在正常解锁
|
||||
if (section.isOccupied()) {
|
||||
if ((!section.getNextRunningSectionOf(false).isOccupied()
|
||||
&& !section.getNextRunningSectionOf(true).isOccupied())
|
||||
&& (section.getRoute() == null || section.getRoute().isNormalUnlock())) {
|
||||
section.startStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.setStopCountDown(stopCountDown - SimulationConstants.CI_LOOP_RATE);
|
||||
if (stopCountDown <= 0) {
|
||||
section.setStopCountDown(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void signalMonitor(Simulation simulation, Signal signal) {
|
||||
signalControlService.controlLightOfSignal(simulation, signal);
|
||||
//控制通过信号机的显示:信号机前第一个区段被占用开红灯;第二个区段被占用开黄灯;否则开绿灯
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
railwaySignalMonitor(simulation, signal);
|
||||
}
|
||||
}
|
||||
|
||||
private void railwaySignalMonitor(Simulation simulation, Signal signal) {
|
||||
if (signal.isGuideAspect() && signal.getLockedRoute() == null) { //引导总锁后开放的引导信号
|
||||
if (signal.getRouteList().stream().noneMatch(Route::isAnySwitchMasterLock)) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, signal.getDefaultAspect());
|
||||
}
|
||||
}
|
||||
if (signal.isPassingSignal()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param route
|
||||
*/
|
||||
public void interlockMonitor(Simulation simulation, Route route) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (route.isCiControl()) { // 进路联锁自动触发
|
||||
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
|
||||
routeService.setRoute(simulation, route, route.getAspect());
|
||||
}
|
||||
} else if (route.isFleetMode()) { // 联锁自动进路
|
||||
if (ciService.isCiRouteTrigger(simulation, route)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getSettedAspect());
|
||||
}
|
||||
}
|
||||
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
|
||||
if (route.isDelayUnlocking()) {
|
||||
routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
routeService.routeSettingProcess(simulation, route);
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
ciService.interlockCheck(simulation, route); //南铁院叶老师提出列车越过始端信号机后灯座应该是红色
|
||||
routeService.trainUnlockRoute(simulation, route);
|
||||
}
|
||||
if (route.isLock()) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
Section firstLogicSection = route.getFirstLogicSection();
|
||||
if (route.getStart().isGuideAspect() && firstLogicSection.getAxleCounterSection().isFaultOccupied()) {
|
||||
log.debug(String.format("进路【%s(%s)】引导占用中,列车通过后请人工解锁", route.getName(), route.getCode()));
|
||||
} else {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (repository.isTrainHeadOccupy(firstLogicSection)) {
|
||||
trainUnlockStart(simulation, route);
|
||||
}
|
||||
}
|
||||
}
|
||||
Signal start = route.getStart();
|
||||
int guideRemain = start.getGuideRemain();
|
||||
if (guideRemain != 0) {
|
||||
guideRemain -= SimulationConstants.CI_LOOP_RATE;
|
||||
if (guideRemain <= 0) { //计时结束,关闭信号
|
||||
start.setGuideRemain(0);
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else {
|
||||
start.setGuideRemain(guideRemain);
|
||||
}
|
||||
}
|
||||
if (route.isLock() && !route.isSetting()) {
|
||||
ciService.interlockCheck(simulation, route);
|
||||
if (!config.isRailway()) {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, route.getSettedAspect());
|
||||
}
|
||||
} else {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
start.setForcePhysical(true); //大铁线路暂时限制自动重开信号
|
||||
} else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
SignalAspect aspect = route.getAspectOfRailway();
|
||||
if (!Objects.equals(route.getStart().getAspect(), aspect)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 进路延续保护办理判断
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void trainUnlockStart(Simulation simulation, Route route) {
|
||||
route.startNormalUnlock();
|
||||
CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
route.getStart(), route.getStart().getDefaultAspect());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延续保护进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param overlap
|
||||
*/
|
||||
public void overlapMonitor(Simulation simulation, RouteOverlap overlap) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isSetting()) {
|
||||
routeService.overlapSettingProcess(simulation, overlap);
|
||||
}
|
||||
if (overlap.isForbidden()) {
|
||||
routeService.checkAndAllowOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) {
|
||||
overlap.setLock(false);
|
||||
}
|
||||
if (overlap.isSectionOverlapLocked()) {
|
||||
if (simulation.getRepository().isTrainParking(overlap.getSection())) {
|
||||
CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁",
|
||||
overlap.getName(),
|
||||
overlap.getSection().debugStr());
|
||||
overlap.releaseImmediately();
|
||||
return;
|
||||
}
|
||||
if (overlap.isReleasing()) {
|
||||
overlap.releaseProgress();
|
||||
} else if (!overlap.isReleasing() && simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
overlap.startReleasing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
simulation.addJob(JobName.SECTION_STOP_COUNTDOWN, () -> sectionStopCountDown(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
}
|
||||
|
||||
public void addJobsForTrainPosition(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> runForTrainPosition(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
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);
|
||||
}
|
||||
|
||||
public void runForTrainPosition(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
}
|
||||
|
||||
public void run(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
// 信号机监控控制
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
for (Signal signal : repository.getSignalList()) {
|
||||
signalMonitor(simulation, signal);
|
||||
}
|
||||
// 联锁监控逻辑
|
||||
List<Route> routeList = repository.getRouteList();
|
||||
for (Route route : routeList) {
|
||||
interlockMonitor(simulation, route);
|
||||
}
|
||||
//延续保护监控
|
||||
List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList();
|
||||
Map<Switch, Boolean> unlockSwitchMap = new HashMap<>(); //记录不能解锁和需要(延续保护)解锁的道岔
|
||||
for (RouteOverlap routeOverlap : routeOverlapList) {
|
||||
overlapMonitor(simulation, routeOverlap, unlockSwitchMap);
|
||||
}
|
||||
unlockSwitchMap.forEach((aSwitch, unlock) -> {
|
||||
if (unlock) {
|
||||
aSwitch.overlapUnLock();
|
||||
}
|
||||
});
|
||||
//延续保护侧防解锁
|
||||
for (RouteOverlap routeOverlap : routeOverlapList) {
|
||||
overlapFlsUnlock(routeOverlap);
|
||||
}
|
||||
// 区间灯点灯逻辑
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
// 车站站控操作模式转换
|
||||
atsStationService.replyOperationMode(simulation);
|
||||
// 车站
|
||||
simulation.getRepository().getStationList().stream().forEach(station -> {
|
||||
// 允许自律状态刷新
|
||||
station.refreshAllowAutonomyStatus();
|
||||
// 接、发辅助按钮倒计时刷新
|
||||
station.getStationDirectionMap().values().stream()
|
||||
.forEach(stationDirection -> {
|
||||
// 判断进路状态是否发生变化
|
||||
if (stationDirection.monitorRouteChangeStatus()) {
|
||||
stationDirection.modifyRunStatus();
|
||||
}
|
||||
// 如果倒数结束弹起接、发辅助按钮,超过50秒时,不再自动抬起
|
||||
if (!stationDirection.isAssistReadyStatus()
|
||||
&& !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime())
|
||||
&& stationDirection.getCountDown().decrementAndGet() <= 0) {
|
||||
stationDirection.setDeliverAssistStatus(false);
|
||||
stationDirection.setReceiveAssistStatus(false);
|
||||
stationDirection.getCountDown().set(0);
|
||||
}
|
||||
// 联锁数据检查
|
||||
stationDirectionService.refreshSectionLightStatus(simulation, stationDirection);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 延续保护侧防解锁
|
||||
*/
|
||||
private void overlapFlsUnlock(RouteOverlap overlap) {
|
||||
SectionPath sectionPath = overlap.selectPath();
|
||||
if (CollectionUtils.isEmpty(sectionPath.getFlsList())) {
|
||||
return;
|
||||
}
|
||||
for (RouteFls routeFls : sectionPath.getFlsList()) {
|
||||
SwitchElement base = routeFls.getBase();
|
||||
if (base == null) {
|
||||
continue;
|
||||
}
|
||||
if (base.getASwitch().isRouteLock() || base.getASwitch().isOverlapLock()) {
|
||||
continue;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(routeFls.getLevel1List())) {
|
||||
continue;
|
||||
}
|
||||
for (FlsElement flsElement : routeFls.getLevel1List()) {
|
||||
if (flsElement.getPSwitch() == null) {
|
||||
continue;
|
||||
}
|
||||
flsElement.getPSwitch().getASwitch().fpUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 区段停稳倒计时
|
||||
*/
|
||||
public void sectionStopCountDown(Simulation simulation) {
|
||||
for (Section section : simulation.getRepository().getHasStopCountDownSections()) {
|
||||
int stopCountDown = section.getStopCountDown();
|
||||
if (stopCountDown == 0) {
|
||||
//股道占用且股道有占用
|
||||
if (section.isOccupied()) {
|
||||
if (section.getNextRunningSectionOf(false).isOccupied()
|
||||
|| section.getNextRunningSectionOf(true).isOccupied()) {
|
||||
section.readyStartStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stopCountDown == -1) {
|
||||
// 股道占用、股道两边没有占用、股道没有进路锁闭或该进路正在正常解锁
|
||||
if (section.isOccupied()) {
|
||||
if ((!section.getNextRunningSectionOf(false).isOccupied()
|
||||
&& !section.getNextRunningSectionOf(true).isOccupied())
|
||||
&& (section.getRoute() == null || section.getRoute().isNormalUnlock())) {
|
||||
section.startStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.setStopCountDown(stopCountDown - SimulationConstants.CI_LOOP_RATE);
|
||||
if (stopCountDown <= 0) {
|
||||
section.setStopCountDown(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void signalMonitor(Simulation simulation, Signal signal) {
|
||||
signalControlService.controlLightOfSignal(simulation, signal);
|
||||
//控制通过信号机的显示:信号机前第一个区段被占用开红灯;第二个区段被占用开黄灯;否则开绿灯
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
railwaySignalMonitor(simulation, signal);
|
||||
}
|
||||
}
|
||||
|
||||
private void railwaySignalMonitor(Simulation simulation, Signal signal) {
|
||||
if (signal.isGuideAspect() && signal.getLockedRoute() == null) { //引导总锁后开放的引导信号
|
||||
if (signal.getRouteList().stream().noneMatch(Route::isAnySwitchMasterLock)) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, signal.getDefaultAspect());
|
||||
}
|
||||
}
|
||||
if (signal.isPassingSignal()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param route
|
||||
*/
|
||||
public void interlockMonitor(Simulation simulation, Route route) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (route.isCiControl()) { // 进路联锁自动触发
|
||||
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
|
||||
routeService.setRoute(simulation, route, route.getAspect());
|
||||
}
|
||||
} else if (route.isFleetMode()) { // 联锁自动进路
|
||||
if (ciService.isCiRouteTrigger(simulation, route)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(),
|
||||
route.getSettedAspect());
|
||||
}
|
||||
}
|
||||
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
|
||||
if (route.isDelayUnlocking()) {
|
||||
routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
routeService.routeSettingProcess(simulation, route);
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
ciService.interlockCheck(simulation, route); //南铁院叶老师提出列车越过始端信号机后灯座应该是红色
|
||||
routeService.trainUnlockRoute(simulation, route);
|
||||
}
|
||||
if (route.isLock()) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
Section firstLogicSection = route.getFirstLogicSection();
|
||||
if (route.getStart().isGuideAspect() && firstLogicSection.getAxleCounterSection()
|
||||
.isFaultOccupied()) {
|
||||
log.debug(String.format("进路【%s(%s)】引导占用中,列车通过后请人工解锁", route.getName(),
|
||||
route.getCode()));
|
||||
} else {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (repository.isTrainHeadOccupy(firstLogicSection)) {
|
||||
trainUnlockStart(simulation, route);
|
||||
}
|
||||
}
|
||||
}
|
||||
Signal start = route.getStart();
|
||||
int guideRemain = start.getGuideRemain();
|
||||
if (guideRemain != 0) {
|
||||
guideRemain -= SimulationConstants.CI_LOOP_RATE;
|
||||
if (guideRemain <= 0) { //计时结束,关闭信号
|
||||
start.setGuideRemain(0);
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else {
|
||||
start.setGuideRemain(guideRemain);
|
||||
}
|
||||
}
|
||||
if (route.isLock() && !route.isSetting()) {
|
||||
ciService.interlockCheck(simulation, route);
|
||||
if (!config.isRailway()) {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade()
|
||||
&& start.isSupportMainAspect()) {
|
||||
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, route.getSettedAspect());
|
||||
}
|
||||
} else {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
start.setForcePhysical(true); //大铁线路暂时限制自动重开信号
|
||||
} else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
SignalAspect aspect = route.getAspectOfRailway();
|
||||
if (!Objects.equals(route.getStart().getAspect(), aspect)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 进路延续保护办理判断
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void trainUnlockStart(Simulation simulation, Route route) {
|
||||
route.startNormalUnlock();
|
||||
CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
route.getStart(), route.getStart().getDefaultAspect());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延续保护进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param overlap
|
||||
* @param unlockSwitchMap
|
||||
* @return
|
||||
*/
|
||||
public void overlapMonitor(Simulation simulation, RouteOverlap overlap,
|
||||
Map<Switch, Boolean> unlockSwitchMap) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isSetting()) {
|
||||
routeService.overlapSettingProcess(simulation, overlap);
|
||||
}
|
||||
if (overlap.isForbidden()) {
|
||||
routeService.checkAndAllowOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) {
|
||||
overlap.setLock(false);
|
||||
}
|
||||
|
||||
//区段锁闭完整的延续保护整体解锁逻辑
|
||||
if (overlap.isSectionOverlapLocked()) {
|
||||
if (simulation.getRepository().isTrainParking(overlap.getSection())) {
|
||||
CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁",
|
||||
overlap.getName(),
|
||||
overlap.getSection().debugStr());
|
||||
overlap.releaseImmediately();
|
||||
}
|
||||
//延时解锁
|
||||
if (overlap.isReleasing()) {
|
||||
overlap.releaseProgress();
|
||||
} else if (simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) {
|
||||
// 进路末区段列车占用,进路开始延时解锁(不能用区段占用作为条件,非通信车占用范围太大,导致延续保护太早开始延时解锁)
|
||||
overlap.startReleasing();
|
||||
}
|
||||
}
|
||||
//统计需要/不能解锁的道岔
|
||||
SectionPath sectionPath = overlap.selectPath();
|
||||
List<Section> sections; //办理过程中锁闭的区段
|
||||
if (!CollectionUtils.isEmpty(sectionPath.getLogicList())) {
|
||||
sections = sectionPath.getLogicList();
|
||||
} else {
|
||||
sections = sectionPath.getSectionList();
|
||||
}
|
||||
for (Section section : sections) {
|
||||
if (!section.isSwitchTrack()) {
|
||||
continue;
|
||||
}
|
||||
if (section.isOverlapLock()) {
|
||||
unlockSwitchMap.put(section.getRelSwitch(), false);
|
||||
Switch linkedSwitch = section.getRelSwitch().queryLinkedSwitch();
|
||||
if (sectionPath.containSwitch(linkedSwitch)) {
|
||||
unlockSwitchMap.put(linkedSwitch, false);
|
||||
}
|
||||
} else if (section.getRelSwitch().isOverlapLock()) {
|
||||
unlockSwitchMap.putIfAbsent(section.getRelSwitch(), true);
|
||||
Switch linkedSwitch = section.getRelSwitch().queryLinkedSwitch();
|
||||
if (sectionPath.containSwitch(linkedSwitch)) {
|
||||
unlockSwitchMap.putIfAbsent(linkedSwitch, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加(需要/不能延续保护解锁)的道岔。添加道岔后,找到延续保护中对应的道岔,判断是否要解除侧防,并添加到Map中
|
||||
*/
|
||||
private void addSwitch(Map<Switch, Integer> map, Switch aSwitch, boolean unlock,
|
||||
List<RouteFls> flsList) {
|
||||
map.put(aSwitch, unlock ? 1 : -1);
|
||||
for (RouteFls routeFls : flsList) {
|
||||
if (routeFls.getBase().getASwitch().equals(aSwitch)) {
|
||||
for (FlsElement element : routeFls.getLevel1List()) {
|
||||
if (element.getPSwitch() != null) {
|
||||
map.put(element.getPSwitch().getASwitch(), unlock ? 2 : -2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -613,7 +613,8 @@ public class CiRouteService {
|
|||
}
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
relSwitch.routeUnlock(route);
|
||||
relSwitch.overlapUnLock();
|
||||
// relSwitch.overlapUnLock(); 仅解锁区段,道岔的解锁由延续保护监控逻辑处理
|
||||
section.overlapUnlocking();
|
||||
// 侧防解锁
|
||||
route.unlockRouteFlsOfSwitch(relSwitch);
|
||||
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
|
||||
|
@ -726,7 +727,13 @@ public class CiRouteService {
|
|||
sectionPath.getSwitchList(), false);
|
||||
// 延续保护区段预先锁闭
|
||||
if (onPos || config.isLockFirst()) {
|
||||
this.checkAndLockOverlap(simulation, overlap);
|
||||
this.checkAndLockOverlapSections(simulation, overlap);
|
||||
}
|
||||
// 延续保护道岔锁闭
|
||||
if (onPos) {
|
||||
for (SwitchElement switchElement : sectionPath.getSwitchList()) {
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
// 侧防办理
|
||||
this.flsSetting(simulation, sectionPath.getFlsList());
|
||||
|
@ -737,7 +744,7 @@ public class CiRouteService {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkAndLockOverlap(Simulation simulation, RouteOverlap overlap) {
|
||||
private void checkAndLockOverlapSections(Simulation simulation, RouteOverlap overlap) {
|
||||
SectionPath sectionPath = overlap.selectPath();
|
||||
boolean right = overlap.isRight();
|
||||
//区段锁闭
|
||||
|
@ -757,10 +764,6 @@ public class CiRouteService {
|
|||
}
|
||||
}
|
||||
}
|
||||
//道岔锁闭
|
||||
for (SwitchElement switchElement : sectionPath.getSwitchList()) {
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,282 +3,296 @@ package club.joylink.rtss.simulation.cbtc.data.map;
|
|||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 进路延续保护
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class RouteOverlap extends MapNamedElement {
|
||||
public RouteOverlap(String code, String name) {
|
||||
super(code, name, DeviceType.OVERLAP);
|
||||
}
|
||||
|
||||
// ------------固有属性/关联关系-----------
|
||||
List<SectionPath> pathList;
|
||||
public RouteOverlap(String code, String name) {
|
||||
super(code, name, DeviceType.OVERLAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路的最后子进路
|
||||
*/
|
||||
private Section section;
|
||||
// ------------固有属性/关联关系-----------
|
||||
List<SectionPath> pathList;
|
||||
|
||||
/**
|
||||
* 延续保护方向
|
||||
*/
|
||||
private boolean right;
|
||||
/**
|
||||
* 进路的最后子进路
|
||||
*/
|
||||
private Section section;
|
||||
|
||||
/**
|
||||
* 延续保护起始信号机
|
||||
*/
|
||||
private Signal signal;
|
||||
/**
|
||||
* 延续保护方向
|
||||
*/
|
||||
private boolean right;
|
||||
|
||||
/**
|
||||
* 触发区段路径
|
||||
*/
|
||||
private List<SectionPath> triggerPathList;
|
||||
/**
|
||||
* 延续保护起始信号机
|
||||
*/
|
||||
private Signal signal;
|
||||
|
||||
/**
|
||||
* 延时解锁时间
|
||||
*/
|
||||
private int delayReleaseTime;
|
||||
/**
|
||||
* 触发区段路径
|
||||
*/
|
||||
private List<SectionPath> triggerPathList;
|
||||
|
||||
// --------------状态属性-------------
|
||||
/**
|
||||
* 办理中
|
||||
*/
|
||||
private boolean setting;
|
||||
/**
|
||||
* 办理开始时间
|
||||
*/
|
||||
private LocalDateTime settingStartTime;
|
||||
/**
|
||||
* 是否锁闭
|
||||
*/
|
||||
private boolean lock;
|
||||
/**
|
||||
* 是否正在解锁
|
||||
*/
|
||||
private boolean releasing;
|
||||
/**
|
||||
* 禁止办理
|
||||
*/
|
||||
private boolean forbidden;
|
||||
/**
|
||||
* 剩余时间
|
||||
*/
|
||||
private int remainTime;
|
||||
/**
|
||||
* 延时解锁时间
|
||||
*/
|
||||
private int delayReleaseTime;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.setting = false;
|
||||
this.settingStartTime = null;
|
||||
this.lock = false;
|
||||
this.releasing = false;
|
||||
this.forbidden = false;
|
||||
this.remainTime = 0;
|
||||
}
|
||||
// --------------状态属性-------------
|
||||
/**
|
||||
* 办理中
|
||||
*/
|
||||
private boolean setting;
|
||||
/**
|
||||
* 办理开始时间
|
||||
*/
|
||||
private LocalDateTime settingStartTime;
|
||||
/**
|
||||
* 是否锁闭
|
||||
*/
|
||||
private boolean lock;
|
||||
/**
|
||||
* 是否正在解锁
|
||||
*/
|
||||
private boolean releasing;
|
||||
/**
|
||||
* 禁止办理
|
||||
*/
|
||||
private boolean forbidden;
|
||||
/**
|
||||
* 剩余时间
|
||||
*/
|
||||
private int remainTime;
|
||||
|
||||
public void startSetting(LocalDateTime systemTime) {
|
||||
this.setLock(false);
|
||||
this.releasing = false;
|
||||
this.settingStartTime = systemTime;
|
||||
this.setting = true;
|
||||
}
|
||||
@Override
|
||||
public void reset() {
|
||||
this.setting = false;
|
||||
this.settingStartTime = null;
|
||||
this.lock = false;
|
||||
this.releasing = false;
|
||||
this.forbidden = false;
|
||||
this.remainTime = 0;
|
||||
}
|
||||
|
||||
public void settingOver() {
|
||||
this.setting = false;
|
||||
this.settingStartTime = null;
|
||||
}
|
||||
public void startSetting(LocalDateTime systemTime) {
|
||||
this.setLock(false);
|
||||
this.releasing = false;
|
||||
this.settingStartTime = systemTime;
|
||||
this.setting = true;
|
||||
}
|
||||
|
||||
public boolean isSectionOverlapLocked() {
|
||||
SectionPath sectionPath = this.selectPath();
|
||||
if (!CollectionUtils.isEmpty(sectionPath.getLogicList())) {
|
||||
for (Section logic : sectionPath.getLogicList()) {
|
||||
if (!logic.isOverlapLockOn(this.isRight())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Section section1 : sectionPath.getSectionList()) {
|
||||
if (!section1.isOverlapLockOn(this.isRight())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void settingOver() {
|
||||
this.setting = false;
|
||||
this.settingStartTime = null;
|
||||
}
|
||||
|
||||
public boolean isSectionOverlapLocked() {
|
||||
SectionPath sectionPath = this.selectPath();
|
||||
if (!CollectionUtils.isEmpty(sectionPath.getLogicList())) {
|
||||
for (Section logic : sectionPath.getLogicList()) {
|
||||
if (!logic.isOverlapLockOn(this.isRight())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Section section1 : sectionPath.getSectionList()) {
|
||||
if (!section1.isOverlapLockOn(this.isRight())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁开始
|
||||
*/
|
||||
public void startReleasing() {
|
||||
this.remainTime = delayReleaseTime * 1000;
|
||||
this.releasing = true;
|
||||
}
|
||||
|
||||
public void allow() {
|
||||
this.forbidden = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即解锁
|
||||
*/
|
||||
public void releaseImmediately() {
|
||||
this.setting = false;
|
||||
this.releasing = false;
|
||||
this.forbidden = true;
|
||||
this.remainTime = 0;
|
||||
this.setLock(false);
|
||||
SectionPath sectionPath = this.selectPath();
|
||||
|
||||
// 只解锁区段,道岔及侧防由延续保护监控逻辑解锁
|
||||
for (Section logic : sectionPath.getLogicList()) {
|
||||
logic.overlapUnlocking();
|
||||
}
|
||||
for (Section section1 : sectionPath.getSectionList()) {
|
||||
section1.overlapUnlocking();
|
||||
if (section1.getLogicList() != null) {
|
||||
for (Section logic : section1.getLogicList()) {
|
||||
logic.overlapUnlocking();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // 先解锁区段,后解锁道岔
|
||||
// for (Section logic : sectionPath.getLogicList()) {
|
||||
// logic.overlapUnlocking();
|
||||
// }
|
||||
// for (Section section1 : sectionPath.getSectionList()) {
|
||||
// section1.overlapUnlocking();
|
||||
// if (section1.getLogicList() != null) {
|
||||
// for (Section logic : section1.getLogicList()) {
|
||||
// logic.overlapUnlocking();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// List<RouteFls> flsList = sectionPath.getFlsList();
|
||||
// for (SwitchElement element : sectionPath.getSwitchList()) {
|
||||
// Switch aSwitch = element.getASwitch();
|
||||
// aSwitch.overlapUnLock();
|
||||
// unlockFlsOfSwitch(flsList, aSwitch);
|
||||
// }
|
||||
}
|
||||
|
||||
public void unlockFlsOfSwitch(List<RouteFls> flsList, Switch aSwitch) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
for (RouteFls routeFls : flsList) {
|
||||
if (routeFls.getBase().getASwitch().equals(aSwitch) &&
|
||||
!aSwitch.isRouteLock()) {
|
||||
routeFls.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 延时解锁
|
||||
*/
|
||||
public void releaseProgress() {
|
||||
if (this.releasing) { // 解锁中
|
||||
this.remainTime -= SimulationModule.CI.getRateMs();
|
||||
if (this.remainTime <= 0) {
|
||||
this.releaseImmediately();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 包含直向路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasStraightPath() {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (!sectionPath.containRpSwitch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁开始
|
||||
*/
|
||||
public void startReleasing() {
|
||||
this.remainTime = delayReleaseTime * 1000;
|
||||
this.releasing = true;
|
||||
}
|
||||
|
||||
public void allow() {
|
||||
this.forbidden = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即解锁
|
||||
*/
|
||||
public void releaseImmediately() {
|
||||
this.setting = false;
|
||||
this.releasing = false;
|
||||
this.forbidden = true;
|
||||
this.remainTime = 0;
|
||||
this.setLock(false);
|
||||
SectionPath sectionPath = this.selectPath();
|
||||
// 先解锁区段,后解锁道岔
|
||||
for (Section logic : sectionPath.getLogicList()) {
|
||||
logic.overlapUnlocking();
|
||||
}
|
||||
for (Section section1 : sectionPath.getSectionList()) {
|
||||
section1.overlapUnlocking();
|
||||
if (section1.getLogicList() != null) {
|
||||
for (Section logic : section1.getLogicList()) {
|
||||
logic.overlapUnlocking();
|
||||
}
|
||||
}
|
||||
}
|
||||
List<RouteFls> flsList = sectionPath.getFlsList();
|
||||
for (SwitchElement element : sectionPath.getSwitchList()) {
|
||||
Switch aSwitch = element.getASwitch();
|
||||
aSwitch.overlapUnLock();
|
||||
unlockFlsOfSwitch(flsList, aSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
public void unlockFlsOfSwitch(List<RouteFls> flsList, Switch aSwitch) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
for (RouteFls routeFls : flsList) {
|
||||
if (routeFls.getBase().getASwitch().equals(aSwitch) &&
|
||||
!aSwitch.isRouteLock()) {
|
||||
routeFls.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 延时解锁
|
||||
*/
|
||||
public void releaseProgress() {
|
||||
if (this.releasing) { // 解锁中
|
||||
this.remainTime -= SimulationModule.CI.getRateMs();
|
||||
if (this.remainTime <= 0) {
|
||||
this.releaseImmediately();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 包含直向路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasStraightPath() {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (!sectionPath.containRpSwitch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 包含反位道岔
|
||||
*/
|
||||
public boolean containRpSwitch() {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (sectionPath.containRpSwitch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOnlyOnePath() {
|
||||
return !CollectionUtils.isEmpty(this.pathList) && this.pathList.size() == 1;
|
||||
}
|
||||
|
||||
public SectionPath getFirstPath() {
|
||||
if (!CollectionUtils.isEmpty(this.pathList)) {
|
||||
return this.pathList.get(0);
|
||||
} else {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault);
|
||||
}
|
||||
}
|
||||
|
||||
public SectionPath selectPath() {
|
||||
if (!CollectionUtils.isEmpty(this.pathList) && !this.isOnlyOnePath()) {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (!CollectionUtils.isEmpty(sectionPath.getSwitchList())) {
|
||||
boolean onPosition = true;
|
||||
for (SwitchElement element : sectionPath.getSwitchList()) {
|
||||
if (element.getASwitch().isSectionOccupied()) {
|
||||
onPosition = false;
|
||||
break;
|
||||
}
|
||||
if (!element.isOnPosition()) {
|
||||
onPosition = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (onPosition) {
|
||||
return sectionPath;
|
||||
}
|
||||
} else {
|
||||
return sectionPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getFirstPath();
|
||||
}
|
||||
|
||||
public boolean isTriggerSectionOccupied() {
|
||||
// 触发区段是否占用
|
||||
for (SectionPath path : this.triggerPathList) {
|
||||
for (Section section1 : path.getSectionList()) {
|
||||
if (section1.isOccupied()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLock(boolean lock) {
|
||||
this.signal.setOverlapLock(lock);
|
||||
this.lock = lock;
|
||||
}
|
||||
|
||||
public boolean containSection(Section section) {
|
||||
return this.selectPath().containSection(section);
|
||||
}
|
||||
|
||||
public boolean containSwitch(Switch aSwitch) {
|
||||
return this.selectPath().containSwitch(aSwitch);
|
||||
}
|
||||
|
||||
public boolean isStraight() {
|
||||
if (CollectionUtils.isEmpty(pathList)) {
|
||||
return true;
|
||||
}
|
||||
for (SectionPath path : pathList) {
|
||||
for (SwitchElement se : path.getSwitchList()) {
|
||||
if (!se.isNormal()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 包含反位道岔
|
||||
*/
|
||||
public boolean containRpSwitch() {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (sectionPath.containRpSwitch()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOnlyOnePath() {
|
||||
return !CollectionUtils.isEmpty(this.pathList) && this.pathList.size() == 1;
|
||||
}
|
||||
|
||||
public SectionPath getFirstPath() {
|
||||
if (!CollectionUtils.isEmpty(this.pathList)) {
|
||||
return this.pathList.get(0);
|
||||
} else {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault);
|
||||
}
|
||||
}
|
||||
|
||||
public SectionPath selectPath() {
|
||||
if (!CollectionUtils.isEmpty(this.pathList) && !this.isOnlyOnePath()) {
|
||||
for (SectionPath sectionPath : this.pathList) {
|
||||
if (!CollectionUtils.isEmpty(sectionPath.getSwitchList())) {
|
||||
boolean onPosition = true;
|
||||
for (SwitchElement element : sectionPath.getSwitchList()) {
|
||||
if (element.getASwitch().isSectionOccupied()) {
|
||||
onPosition = false;
|
||||
break;
|
||||
}
|
||||
if (!element.isOnPosition()) {
|
||||
onPosition = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (onPosition) {
|
||||
return sectionPath;
|
||||
}
|
||||
} else {
|
||||
return sectionPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getFirstPath();
|
||||
}
|
||||
|
||||
public boolean isTriggerSectionOccupied() {
|
||||
// 触发区段是否占用
|
||||
for (SectionPath path : this.triggerPathList) {
|
||||
for (Section section1 : path.getSectionList()) {
|
||||
if (section1.isOccupied()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLock(boolean lock) {
|
||||
this.signal.setOverlapLock(lock);
|
||||
this.lock = lock;
|
||||
}
|
||||
|
||||
public boolean containSection(Section section) {
|
||||
return this.selectPath().containSection(section);
|
||||
}
|
||||
|
||||
public boolean containSwitch(Switch aSwitch) {
|
||||
return this.selectPath().containSwitch(aSwitch);
|
||||
}
|
||||
|
||||
public boolean isStraight() {
|
||||
if (CollectionUtils.isEmpty(pathList)) {
|
||||
return true;
|
||||
}
|
||||
for (SectionPath path : pathList) {
|
||||
for (SwitchElement se : path.getSwitchList()) {
|
||||
if (!se.isNormal()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -764,15 +764,6 @@ public class Section extends DelayUnlockDevice {
|
|||
return this.routeLock && this.route.equals(route);
|
||||
}
|
||||
|
||||
public void forceUnlocking() {
|
||||
this.routeLock = false;
|
||||
this.route = null;
|
||||
this.overlapLock = false;
|
||||
if (!isCross() && !CollectionUtils.isEmpty(this.logicList)) {
|
||||
this.logicList.forEach(logic -> logic.forceUnlocking());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路延续保护(连同逻辑区段)
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -546,19 +546,6 @@ public class TrainInfo extends MapElement {
|
|||
}
|
||||
|
||||
public void updatePlanInfo(StationPlan nextStationPlan) {
|
||||
// if (Objects.nonNull(nextStationPlan)) {
|
||||
// this.planStandTrack = nextStationPlan.getSection().getCode();
|
||||
// this.planArriveTime = nextStationPlan.getArriveTime();
|
||||
// this.planLeaveTime = nextStationPlan.getLeaveTime();
|
||||
// List<Stand> standList = nextStationPlan.getSection().getStandList();
|
||||
// if (!CollectionUtils.isEmpty(standList)) {
|
||||
// this.turnBackStrategy = standList.get(0).getTypeStrategy().name();
|
||||
// }
|
||||
// } else {
|
||||
// this.planStandTrack = null;
|
||||
// this.planArriveTime = null;
|
||||
// this.planLeaveTime = null;
|
||||
// }
|
||||
if (Objects.nonNull(nextStationPlan)) {
|
||||
updatePlanInfo(nextStationPlan.getSection(), nextStationPlan.getArriveTime(),
|
||||
nextStationPlan.getLeaveTime());
|
||||
|
|
|
@ -12,103 +12,104 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
|||
*/
|
||||
public interface OnboardAtpApiService {
|
||||
|
||||
void updateCtcMa(Simulation simulation, MaService.Ma ma);
|
||||
void updateCtcMa(Simulation simulation, MaService.Ma ma);
|
||||
|
||||
void updateItcMa(Simulation simulation, VirtualRealityTrain train, MaService.Ma ma);
|
||||
void updateItcMa(Simulation simulation, VirtualRealityTrain train, MaService.Ma ma);
|
||||
|
||||
/**
|
||||
* 更新CBTC移动授权
|
||||
*/
|
||||
void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
/**
|
||||
* 更新CBTC移动授权
|
||||
*/
|
||||
void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
|
||||
void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma);
|
||||
|
||||
/**
|
||||
* 分配新的车次计划
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param tripPlan
|
||||
*/
|
||||
void updateTripPlan(Simulation simulation, String groupNumber, TripPlan tripPlan);
|
||||
/**
|
||||
* 分配新的车次计划
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param tripPlan
|
||||
*/
|
||||
void updateTripPlan(Simulation simulation, String groupNumber, TripPlan tripPlan);
|
||||
|
||||
/**
|
||||
* 发车
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void departure(Simulation simulation, String groupNumber);
|
||||
/**
|
||||
* 发车
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void departure(Simulation simulation, String groupNumber);
|
||||
|
||||
/**
|
||||
* 更新下一站
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param stationCode
|
||||
* @param sectionCode
|
||||
*/
|
||||
void updateNextStation(Simulation simulation, String groupNumber, String stationCode, String sectionCode, long runningTime, boolean parking);
|
||||
/**
|
||||
* 更新下一计划到站信息
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param planSection
|
||||
* @param park
|
||||
* @param runTime
|
||||
* @param jump
|
||||
*/
|
||||
void updateNextArriveInfo(Simulation simulation, String groupNumber, Section planSection,
|
||||
boolean park, int runTime, boolean jump);
|
||||
|
||||
/**
|
||||
* 更新下一计划到站信息
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param planSection
|
||||
* @param park
|
||||
* @param runTime
|
||||
* @param jump
|
||||
*/
|
||||
void updateNextArriveInfo(Simulation simulation, String groupNumber, Section planSection, boolean park, int runTime, boolean jump);
|
||||
/**
|
||||
* 更新列车为头码车时设置服务号
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param serviceNumber
|
||||
*/
|
||||
void update2HeadTrainServiceNumber(Simulation simulation, String groupNumber,
|
||||
String serviceNumber, String tripNumber, String destinationCode, boolean parking);
|
||||
|
||||
/**
|
||||
* 更新列车为头码车时设置服务号
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param serviceNumber
|
||||
*/
|
||||
void update2HeadTrainServiceNumber(Simulation simulation, String groupNumber,
|
||||
String serviceNumber, String tripNumber, String destinationCode, boolean parking);
|
||||
/**
|
||||
* 扣车
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void standHoldTrain(Simulation simulation, String groupNumber);
|
||||
|
||||
/**
|
||||
* 扣车
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void standHoldTrain(Simulation simulation, String groupNumber);
|
||||
/**
|
||||
* 取消扣车
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void standCancelHoldTrain(Simulation simulation, String groupNumber);
|
||||
|
||||
/**
|
||||
* 取消扣车
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void standCancelHoldTrain(Simulation simulation, String groupNumber);
|
||||
/**
|
||||
* 设置跳停
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void setJump(Simulation simulation, String groupNumber);
|
||||
|
||||
/**
|
||||
* 设置跳停
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void setJump(Simulation simulation, String groupNumber);
|
||||
/**
|
||||
* 取消跳停
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void cancelJump(Simulation simulation, String groupNumber);
|
||||
|
||||
/**
|
||||
* 取消跳停
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
*/
|
||||
void cancelJump(Simulation simulation, String groupNumber);
|
||||
/**
|
||||
* 开始折返
|
||||
*
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param tbSectionCode
|
||||
*/
|
||||
void startTurnBack(Simulation simulation, String groupNumber, String tbSectionCode);
|
||||
|
||||
/**
|
||||
* 开始折返
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param tbSectionCode
|
||||
*/
|
||||
void startTurnBack(Simulation simulation, String groupNumber, String tbSectionCode);
|
||||
void updateNextSection(Simulation simulation, String groupNumber, String targetCode);
|
||||
|
||||
void updateNextSection(Simulation simulation, String groupNumber, String targetCode);
|
||||
void checkAndChangeDirection(Simulation simulation, VirtualRealityTrain train,
|
||||
Section targetSection);
|
||||
|
||||
void checkAndChangeDirection(Simulation simulation, VirtualRealityTrain train,
|
||||
Section targetSection);
|
||||
void parkingInPlace(Simulation simulation, VirtualRealityTrain vrTrain, Section headSection);
|
||||
|
||||
void parkingInPlace(Simulation simulation, VirtualRealityTrain vrTrain, Section headSection);
|
||||
|
||||
void resetAtoSpeedMax(Simulation simulation, String groupNumber);
|
||||
void resetAtoSpeedMax(Simulation simulation, String groupNumber);
|
||||
}
|
||||
|
|
|
@ -6,252 +6,235 @@ import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
|||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
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.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
|
||||
|
||||
@Autowired
|
||||
private ATPService ATPService;
|
||||
@Autowired
|
||||
private ATPService ATPService;
|
||||
|
||||
@Autowired
|
||||
private ATOService ATOService;
|
||||
@Autowired
|
||||
private ATOService ATOService;
|
||||
|
||||
@Override
|
||||
public void updateCtcMa(Simulation simulation, MaService.Ma ma) {
|
||||
VirtualRealityTrain train = ma.getTrain();
|
||||
@Override
|
||||
public void updateCtcMa(Simulation simulation, MaService.Ma ma) {
|
||||
VirtualRealityTrain train = ma.getTrain();
|
||||
// log.debug(String.format("列车[%s]更新CTC-MA: %s", train.getGroupNumber(), ma.debugStr()));
|
||||
SpeedCurve.calculateAndUpdate(simulation, train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
SpeedCurve.calculateAndUpdate(simulation, train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItcMa(Simulation simulation, VirtualRealityTrain train, MaService.Ma ma) {
|
||||
if (ma == null) {
|
||||
return;
|
||||
}
|
||||
if (train.isCommunicable()) {
|
||||
log.debug(String.format("列车[%s]是通信车,不更新ITC-MA", train.getGroupNumber()));
|
||||
}
|
||||
if (!train.isCommunicable()) {
|
||||
log.debug(String.format("列车[%s]更新ITC-MA: %s", train.getGroupNumber(), ma.debugStr()));
|
||||
boolean update = SpeedCurve.calculateAndUpdate(simulation, train, ma);
|
||||
if (train.isIL()) {
|
||||
ATPService.updateRunLevel(train, RunLevel.ITC);
|
||||
}
|
||||
if (train.isReleased()) { // 释放状态
|
||||
if (update) { // 成功更新,取消释放状态的限速,按ATO跑
|
||||
log.debug(String.format("列车[%s]在释放状态成功更新ITC-MA,取消释放,以正常ATO继续运行",
|
||||
train.getGroupNumber()));
|
||||
} else { // 未更新,EB
|
||||
log.debug(String.format("列车[%s]以释放状态限速运行经过前方信号机主应答器却未更新ITC-MA,导致EB",
|
||||
train.getGroupNumber()));
|
||||
this.ATPService.triggerSignalEB(train);
|
||||
}
|
||||
train.setReleased(false);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateItcMa(Simulation simulation, VirtualRealityTrain train, MaService.Ma ma) {
|
||||
if (ma == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma) {
|
||||
if (ma == null)
|
||||
return;
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
if (train.isCommunicable()) {
|
||||
log.debug(String.format("列车[%s]是通信车,不更新ITC-MA", train.getGroupNumber()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma) {
|
||||
if (ma == null)
|
||||
return;
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (!train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
if (train.isIL()) {
|
||||
train.setITCMode();
|
||||
}
|
||||
if (!train.isCommunicable()) {
|
||||
log.debug(String.format("列车[%s]更新ITC-MA: %s", train.getGroupNumber(), ma.debugStr()));
|
||||
boolean update = SpeedCurve.calculateAndUpdate(simulation, train, ma);
|
||||
if (train.isIL()) {
|
||||
ATPService.updateRunLevel(train, RunLevel.ITC);
|
||||
}
|
||||
if (train.isReleased()) { // 释放状态
|
||||
if (update) { // 成功更新,取消释放状态的限速,按ATO跑
|
||||
log.debug(String.format("列车[%s]在释放状态成功更新ITC-MA,取消释放,以正常ATO继续运行",
|
||||
train.getGroupNumber()));
|
||||
} else { // 未更新,EB
|
||||
log.debug(
|
||||
String.format("列车[%s]以释放状态限速运行经过前方信号机主应答器却未更新ITC-MA,导致EB",
|
||||
train.getGroupNumber()));
|
||||
this.ATPService.triggerSignalEB(train);
|
||||
}
|
||||
train.setReleased(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTripPlan(Simulation simulation, String groupNumber,
|
||||
TripPlan tripPlan) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
String serviceNumber = tripPlan.getServiceNumber();
|
||||
String tripNumber = tripPlan.getTripNumber();
|
||||
String destinationCode = tripPlan.getDestinationCode();
|
||||
train.setPlan(tripPlan);
|
||||
log.debug(String.format("列车[%s-%s|%s|%s]更新新的车次计划[%s|%s|%s]",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(),
|
||||
serviceNumber, tripNumber, destinationCode));
|
||||
@Override
|
||||
public void updateMA4CBTC(VirtualRealityTrain train, MovementAuthority ma) {
|
||||
if (ma == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void departure(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (train.isParkingAt()) {
|
||||
train.earlyDeparture();
|
||||
}
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
train.setCbtcMaMissDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNextStation(Simulation simulation, String groupNumber,
|
||||
String stationCode, String sectionCode, long runningTime, boolean parking) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
Station nextStation = repository.getByCode(stationCode, Station.class);
|
||||
Section targetSection = repository.getByCode(sectionCode, Section.class);
|
||||
if (Objects.equals(targetSection, train.getTarget())) {
|
||||
// 已经更新,忽略
|
||||
return;
|
||||
}
|
||||
train.updateNextStationPlan(nextStation, targetSection, parking);
|
||||
this.checkAndChangeDirection(simulation, train, targetSection);
|
||||
//根据时间控制速度
|
||||
@Override
|
||||
public void updateMA4ITC(VirtualRealityTrain train, MovementAuthority ma) {
|
||||
if (ma == null) {
|
||||
return;
|
||||
}
|
||||
if (!train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (!train.isCommunication()) {
|
||||
this.ATPService.updateMA(train, ma);
|
||||
if (train.isIL()) {
|
||||
train.setITCMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTripPlan(Simulation simulation, String groupNumber,
|
||||
TripPlan tripPlan) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
String serviceNumber = tripPlan.getServiceNumber();
|
||||
String tripNumber = tripPlan.getTripNumber();
|
||||
String destinationCode = tripPlan.getDestinationCode();
|
||||
train.setPlan(tripPlan);
|
||||
log.debug(String.format("列车[%s-%s|%s|%s]更新新的车次计划[%s|%s|%s]",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(),
|
||||
serviceNumber, tripNumber, destinationCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void departure(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (train.isParkingAt()) {
|
||||
train.earlyDeparture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNextArriveInfo(Simulation simulation, String groupNumber,
|
||||
Section planSection, boolean park, int runTime, boolean jump) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(jump);
|
||||
train.updateNextStationPlan(planSection.getStation(), planSection, park);
|
||||
this.checkAndChangeDirection(simulation, train, planSection);
|
||||
//根据时间控制速度
|
||||
// runningTime -= 10; //减去开关门和延迟启动耗费的时间
|
||||
Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runningTime, targetSection);
|
||||
if (atoMaxSpeed != null) {
|
||||
train.setAtoSpeedMax(atoMaxSpeed);
|
||||
}
|
||||
Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runTime,
|
||||
planSection);
|
||||
if (atoMaxSpeed != null) {
|
||||
train.setAtoSpeedMax(atoMaxSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNextArriveInfo(Simulation simulation, String groupNumber,
|
||||
Section planSection, boolean park, int runTime, boolean jump) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(jump);
|
||||
train.updateNextStationPlan(planSection.getStation(), planSection, park);
|
||||
this.checkAndChangeDirection(simulation, train, planSection);
|
||||
//根据时间控制速度
|
||||
// runningTime -= 10; //减去开关门和延迟启动耗费的时间
|
||||
Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runTime, planSection);
|
||||
if (atoMaxSpeed != null) {
|
||||
train.setAtoSpeedMax(atoMaxSpeed);
|
||||
}
|
||||
@Override
|
||||
public void update2HeadTrainServiceNumber(Simulation simulation, String groupNumber,
|
||||
String serviceNumber, String tripNumber, String destinationCode, boolean parking) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setServiceNumber(serviceNumber);
|
||||
train.setTripNumber(tripNumber);
|
||||
train.setDestinationCode(destinationCode);
|
||||
train.setNextParking(parking);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void standHoldTrain(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!train.isTrainHold()) {
|
||||
train.setHold(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update2HeadTrainServiceNumber(Simulation simulation, String groupNumber,
|
||||
String serviceNumber, String tripNumber, String destinationCode, boolean parking) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setServiceNumber(serviceNumber);
|
||||
train.setTripNumber(tripNumber);
|
||||
train.setDestinationCode(destinationCode);
|
||||
train.setNextParking(parking);
|
||||
@Override
|
||||
public void standCancelHoldTrain(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!train.isTrainHold()) {
|
||||
train.setHold(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void standHoldTrain(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!train.isTrainHold()) {
|
||||
train.setHold(true);
|
||||
}
|
||||
@Override
|
||||
public void setJump(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelJump(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTurnBack(Simulation simulation, String groupNumber, String tbSectionCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
Section tbSection = repository.getByCode(tbSectionCode, Section.class);
|
||||
log.debug(String.format("列车[%s]准备折返", train.getGroupNumber()));
|
||||
train.startTurnBack(tbSection);
|
||||
this.checkAndChangeDirection(simulation, train, tbSection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNextSection(Simulation simulation, String groupNumber, String targetCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
Section target = repository.getByCode(targetCode, Section.class);
|
||||
if (Objects.equals(target, train.getTarget())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void standCancelHoldTrain(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!train.isTrainHold()) {
|
||||
train.setHold(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJump(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelJump(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.setJump(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTurnBack(Simulation simulation, String groupNumber, String tbSectionCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
Section tbSection = repository.getByCode(tbSectionCode, Section.class);
|
||||
log.debug(String.format("列车[%s]准备折返", train.getGroupNumber()));
|
||||
train.startTurnBack(tbSection);
|
||||
this.checkAndChangeDirection(simulation, train, tbSection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNextSection(Simulation simulation, String groupNumber, String targetCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
Section target = repository.getByCode(targetCode, Section.class);
|
||||
if (Objects.equals(target, train.getTarget())) {
|
||||
return;
|
||||
}
|
||||
checkAndChangeDirection(simulation, train, target);
|
||||
checkAndChangeDirection(simulation, train, target);
|
||||
// train.setTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAndChangeDirection(Simulation simulation, VirtualRealityTrain train,
|
||||
Section targetSection) {
|
||||
Objects.requireNonNull(targetSection);
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
boolean right = train.isRight();
|
||||
Section headSection = train.getHeadPosition().getSection();
|
||||
if (CalculateService.isTargetSectionOnDirectionExist(headSection, right, targetSection)) {
|
||||
return;
|
||||
} else if (CalculateService.isTargetSectionOnDirectionExist(headSection, !right, targetSection)) {
|
||||
if (train.isAtoOn()) { //如果开启了ato
|
||||
// 如果反向,调头
|
||||
this.ATPService.turnDirectionStart(train);
|
||||
}
|
||||
} else {
|
||||
log.debug(String.format("列车[%s]无法到达目标轨道,根据路径判断是否调头", train.getGroupNumber()));
|
||||
// 根据路径判断
|
||||
if (headSection.isFunctionTrack() && targetSection.isFunctionTrack()) {
|
||||
List<RoutePath> routePaths = repository.queryRoutePaths(headSection, targetSection);
|
||||
if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
boolean pathRight = routePaths.get(0).isRight();
|
||||
if (!Objects.equals(right, pathRight) && train.isAtoOn()) {
|
||||
// 和计划方向不同并且开启了ATO,调头
|
||||
this.ATPService.turnDirectionStart(train);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void checkAndChangeDirection(Simulation simulation, VirtualRealityTrain train,
|
||||
Section targetSection) {
|
||||
Objects.requireNonNull(targetSection);
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
boolean right = train.isRight();
|
||||
Section headSection = train.getHeadPosition().getSection();
|
||||
if (CalculateService.isTargetSectionOnDirectionExist(headSection, right, targetSection)) {
|
||||
return;
|
||||
} else if (CalculateService.isTargetSectionOnDirectionExist(headSection, !right,
|
||||
targetSection)) {
|
||||
if (train.isAtoOn()) { //如果开启了ato
|
||||
// 如果反向,调头
|
||||
this.ATPService.turnDirectionStart(train);
|
||||
}
|
||||
} else {
|
||||
log.debug(
|
||||
String.format("列车[%s]无法到达目标轨道,根据路径判断是否调头", train.getGroupNumber()));
|
||||
// 根据路径判断
|
||||
if (headSection.isFunctionTrack() && targetSection.isFunctionTrack()) {
|
||||
List<RoutePath> routePaths = repository.queryRoutePaths(headSection, targetSection);
|
||||
if (!CollectionUtils.isEmpty(routePaths)) {
|
||||
boolean pathRight = routePaths.get(0).isRight();
|
||||
if (!Objects.equals(right, pathRight) && train.isAtoOn()) {
|
||||
// 和计划方向不同并且开启了ATO,调头
|
||||
this.ATPService.turnDirectionStart(train);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (train.getRobotTargetPosition() != null) { //如果列车被托管
|
||||
// return;
|
||||
// }
|
||||
// 列车目标区段无法到达,根据路径单元判定
|
||||
// 列车目标区段无法到达,根据路径单元判定
|
||||
// if (headSection.isSwitchTrack() && headSection.getParent().isTurnBackTrack()) {
|
||||
// headSection = headSection.getParent();
|
||||
// }
|
||||
|
@ -278,17 +261,18 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
|
|||
// this.newATPService.turnDirectionStart(train);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parkingInPlace(Simulation simulation, VirtualRealityTrain vrTrain, Section headSection) {
|
||||
vrTrain.parkingAt(headSection);
|
||||
}
|
||||
@Override
|
||||
public void parkingInPlace(Simulation simulation, VirtualRealityTrain vrTrain,
|
||||
Section headSection) {
|
||||
vrTrain.parkingAt(headSection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAtoSpeedMax(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
train.resetAtoSpeedMax();
|
||||
}
|
||||
@Override
|
||||
public void resetAtoSpeedMax(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
train.resetAtoSpeedMax();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,15 @@ import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
|||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
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.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteFls;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SectionPath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
|
||||
|
@ -17,291 +25,306 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
|
|||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
|
||||
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 设备状态修改工具(有动作设备不需要动作过程可直接设置为想要的状态)
|
||||
* warn:此工具类只在加载列车或实训生成场景使用,正常仿真过程请勿使用
|
||||
* 设备状态修改工具(有动作设备不需要动作过程可直接设置为想要的状态) warn:此工具类只在加载列车或实训生成场景使用,正常仿真过程请勿使用
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DeviceStatusModifyTool {
|
||||
@Autowired
|
||||
private VirtualRealityDeviceService virtualRealityDeviceService;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private AtsTrainLoadService atsTrainLoadService;
|
||||
@Autowired
|
||||
private VRTrainRunningService vrTrainRunningService;
|
||||
|
||||
/**
|
||||
* 直接开放进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void openRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
if (route.isSettingOverlap()) {
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
|
||||
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
route.getOverlap().setLock(true);
|
||||
}
|
||||
}
|
||||
route.setNormalUnlock(false);
|
||||
route.setLock(true);
|
||||
route.setSettedAspect(route.getAspect());
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
this.openSignalDirectly(route.getStart(), route.getSettedAspect());
|
||||
route.getStart().setLockedRoute(route);
|
||||
@Autowired
|
||||
private VirtualRealityDeviceService virtualRealityDeviceService;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private AtsTrainLoadService atsTrainLoadService;
|
||||
@Autowired
|
||||
private VRTrainRunningService vrTrainRunningService;
|
||||
|
||||
/**
|
||||
* 直接开放进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void openRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true,
|
||||
route.getOverlap());
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList()
|
||||
.forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
if (route.isSettingOverlap()) {
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false,
|
||||
route.getOverlap());
|
||||
overlapPath.getSectionList()
|
||||
.forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
route.getOverlap().setLock(true);
|
||||
}
|
||||
}
|
||||
route.setNormalUnlock(false);
|
||||
route.setLock(true);
|
||||
route.setSettedAspect(route.getAspect());
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
this.openSignalDirectly(route.getStart(), route.getSettedAspect());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
List<SwitchElement> switchElementList = new ArrayList<>();
|
||||
for (RouteFls routeFls : flsList) {
|
||||
for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) {
|
||||
SwitchElement pSwitch = flsElement.getPSwitch();
|
||||
if (pSwitch != null) {
|
||||
switchElementList.add(pSwitch);
|
||||
} else if (flsElement.getFpae() != null) {
|
||||
switchElementList.add(flsElement.getFpae());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SwitchElement switchElement : switchElementList) {
|
||||
private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
List<SwitchElement> switchElementList = new ArrayList<>();
|
||||
for (RouteFls routeFls : flsList) {
|
||||
for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) {
|
||||
SwitchElement pSwitch = flsElement.getPSwitch();
|
||||
if (pSwitch != null) {
|
||||
switchElementList.add(pSwitch);
|
||||
} else if (flsElement.getFpae() != null) {
|
||||
switchElementList.add(flsElement.getFpae());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SwitchElement switchElement : switchElementList) {
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
switchElement.getASwitch().fpLock();
|
||||
}
|
||||
}
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
switchElement.getASwitch().fpLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openGuideRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
}
|
||||
route.setLock(true);
|
||||
this.openGuideSignalDirectly(route.getStart());
|
||||
route.getStart().setLockedRoute(route);
|
||||
public void openGuideRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true,
|
||||
route.getOverlap());
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList()
|
||||
.forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false,
|
||||
route.getOverlap());
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
overlapPath.getSectionList()
|
||||
.forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
}
|
||||
route.setLock(true);
|
||||
this.openGuideSignalDirectly(route.getStart());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
public void openGuideSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect();
|
||||
virtualSignal.control(guideAspect);
|
||||
virtualSignal.finish();
|
||||
signal.changeLightType(false);
|
||||
signal.setAspect(guideAspect);
|
||||
public void openGuideSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect();
|
||||
virtualSignal.control(guideAspect);
|
||||
virtualSignal.finish();
|
||||
signal.changeLightType(false);
|
||||
signal.setAspect(guideAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接开灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
* @param aspect
|
||||
*/
|
||||
private void openSignalDirectly(Signal signal, SignalAspect aspect) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
if (virtualSignal != null) {
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(aspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
}
|
||||
signal.setAspect(aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接开灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
* @param aspect
|
||||
*/
|
||||
private void openSignalDirectly(Signal signal, SignalAspect aspect) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
if (virtualSignal != null) {
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(aspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
}
|
||||
signal.setAspect(aspect);
|
||||
/**
|
||||
* 直接关灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
*/
|
||||
public void closeSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect();
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(defaultAspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
signal.setAspect(defaultAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接关灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
*/
|
||||
public void closeSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect();
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(defaultAspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
signal.setAspect(defaultAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置进路道岔位置并锁闭
|
||||
*
|
||||
* @param route
|
||||
* @param switchList
|
||||
* @param routeLock
|
||||
*/
|
||||
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) {
|
||||
if (!CollectionUtils.isEmpty(switchList)) {
|
||||
for (SwitchElement switchElement : switchList) {
|
||||
/**
|
||||
* 批量设置进路道岔位置并锁闭
|
||||
*
|
||||
* @param route
|
||||
* @param switchList
|
||||
* @param routeLock
|
||||
* @param overlap
|
||||
*/
|
||||
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList,
|
||||
boolean routeLock,
|
||||
RouteOverlap overlap) {
|
||||
if (!CollectionUtils.isEmpty(switchList)) {
|
||||
for (SwitchElement switchElement : switchList) {
|
||||
// if (switchElement.getASwitch().isOverlapLock() &&
|
||||
// switchElement.isOnPosition()) {
|
||||
// continue;
|
||||
// }
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
if (routeLock) {
|
||||
switchElement.getASwitch().routeLock(route);
|
||||
} else { // 延续保护锁闭
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
if (routeLock) {
|
||||
switchElement.getASwitch().routeLock(route);
|
||||
} else { // 延续保护锁闭
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把单个道岔转到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) {
|
||||
VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch();
|
||||
if (normal) {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.N);
|
||||
} else {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.R);
|
||||
}
|
||||
/**
|
||||
* 直接把单个道岔转到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) {
|
||||
VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch();
|
||||
if (normal) {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.N);
|
||||
} else {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.R);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把道岔及其联动道岔转动到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch, boolean normal) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
this.setSingleSwitchPositionDirectly(aSwitch, normal);
|
||||
Switch linkedSwitch = aSwitch.queryLinkedSwitch();
|
||||
if (Objects.nonNull(linkedSwitch)) {
|
||||
this.setSingleSwitchPositionDirectly(linkedSwitch, normal);
|
||||
}
|
||||
/**
|
||||
* 直接把道岔及其联动道岔转动到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch,
|
||||
boolean normal) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
this.setSingleSwitchPositionDirectly(aSwitch, normal);
|
||||
Switch linkedSwitch = aSwitch.queryLinkedSwitch();
|
||||
if (Objects.nonNull(linkedSwitch)) {
|
||||
this.setSingleSwitchPositionDirectly(linkedSwitch, normal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接根据最后一根区段解锁进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void routeUnlockByEndSection(Route route, Section tailSection) {
|
||||
if (!route.isRouteSection(tailSection)) {
|
||||
// 不是进路区段,不解锁
|
||||
return;
|
||||
}
|
||||
route.startNormalUnlock();
|
||||
// 关闭始端信号机
|
||||
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
|
||||
boolean right = route.getStart().isRight();
|
||||
// 区段是顺序的(否则会有问题)
|
||||
List<Section> sectionList = route.getSectionList();
|
||||
for (Section section : sectionList) {
|
||||
if (section.isSamePhysical(tailSection.getCode())) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
// 直接解锁区段
|
||||
if (section.isSwitchTrack()) { // 如果是道岔区段,解锁道岔
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
if (section.getParent() != null && section.getParent().isCross()) {
|
||||
section.getParent().routeUnlocking(route);
|
||||
}
|
||||
relSwitch.routeUnlock(route);
|
||||
relSwitch.overlapUnLock();
|
||||
// 侧防解锁
|
||||
route.unlockRouteFlsOfSwitch(relSwitch);
|
||||
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
|
||||
for (SwitchElement switchElement : route.getSwitchList()) {
|
||||
if (switchElement.getASwitch().equals(relSwitch)) {
|
||||
continue;
|
||||
}
|
||||
Switch aSwitch = switchElement.getASwitch();
|
||||
if (route.isRouteSection(aSwitch.getA())) {
|
||||
continue;
|
||||
}
|
||||
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
|
||||
if (!aSwitch.getA().isRouteLock()) {
|
||||
aSwitch.routeUnlock(route);
|
||||
aSwitch.overlapUnLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.routeUnlocking(route);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 直接根据最后一根区段解锁进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void routeUnlockByEndSection(Route route, Section tailSection) {
|
||||
if (!route.isRouteSection(tailSection)) {
|
||||
// 不是进路区段,不解锁
|
||||
return;
|
||||
}
|
||||
route.startNormalUnlock();
|
||||
// 关闭始端信号机
|
||||
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
|
||||
boolean right = route.getStart().isRight();
|
||||
// 区段是顺序的(否则会有问题)
|
||||
List<Section> sectionList = route.getSectionList();
|
||||
for (Section section : sectionList) {
|
||||
if (section.isSamePhysical(tailSection.getCode())) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
// 直接解锁区段
|
||||
if (section.isSwitchTrack()) { // 如果是道岔区段,解锁道岔
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
if (section.getParent() != null && section.getParent().isCross()) {
|
||||
section.getParent().routeUnlocking(route);
|
||||
}
|
||||
relSwitch.routeUnlock(route);
|
||||
relSwitch.overlapUnLock();
|
||||
// 侧防解锁
|
||||
route.unlockRouteFlsOfSwitch(relSwitch);
|
||||
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
|
||||
for (SwitchElement switchElement : route.getSwitchList()) {
|
||||
if (switchElement.getASwitch().equals(relSwitch)) {
|
||||
continue;
|
||||
}
|
||||
Switch aSwitch = switchElement.getASwitch();
|
||||
if (route.isRouteSection(aSwitch.getA())) {
|
||||
continue;
|
||||
}
|
||||
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
|
||||
if (!aSwitch.getA().isRouteLock()) {
|
||||
aSwitch.routeUnlock(route);
|
||||
aSwitch.overlapUnLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.routeUnlocking(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section, boolean right) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!section.isPhysical()) {
|
||||
section = section.getParent();
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
|
||||
//重叠检测
|
||||
SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
|
||||
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||
// 列车上线并构建ATS监控列车信息
|
||||
train.initManualTrain(headPosition, right);
|
||||
//设置列车预选模式、驾驶模式、运行级别
|
||||
if (!headPosition.getSection().anyZcWorking()) {
|
||||
train.initAsRM();
|
||||
} else {
|
||||
MapConfig config = repository.getConfig();
|
||||
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||
train.initAsAM_I();
|
||||
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||
train.initAsRM();
|
||||
}
|
||||
}
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
repository.addOnlineTrain(train);
|
||||
repository.addTrainInfo(trainInfo);
|
||||
public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section,
|
||||
boolean right) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!section.isPhysical()) {
|
||||
section = section.getParent();
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(),
|
||||
"列车需加载到物理区段上");
|
||||
//重叠检测
|
||||
SectionPosition headPosition = new SectionPosition(section,
|
||||
section.getStopPointByDirection(right));
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition,
|
||||
!right, train.getLen(), false);
|
||||
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||
// 列车上线并构建ATS监控列车信息
|
||||
train.initManualTrain(headPosition, right);
|
||||
//设置列车预选模式、驾驶模式、运行级别
|
||||
if (!headPosition.getSection().anyZcWorking()) {
|
||||
train.initAsRM();
|
||||
} else {
|
||||
MapConfig config = repository.getConfig();
|
||||
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||
train.initAsAM_I();
|
||||
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||
train.initAsRM();
|
||||
}
|
||||
}
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
repository.addOnlineTrain(train);
|
||||
repository.addTrainInfo(trainInfo);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue