新版ATS进路选择bug修改;头码车计划区段更新逻辑修改;

This commit is contained in:
joylink_zhangsai 2021-08-03 16:58:24 +08:00
parent eb5d355485
commit a3634dda76
5 changed files with 84 additions and 52 deletions

View File

@ -155,19 +155,24 @@ public abstract class AtsRouteSelectService {
RoutePath routePath = this.selectRoutePath(routePathList);
// 查找可以触发的进路列表
boolean ctcLevel = trainInfo.isCtcLevel();
for (Signal signal : routePath.getSignalList()) {
List<Signal> signalList = routePath.getSignalList();
for (Signal signal : signalList) {
Section signalSection = signal.getSection();
if (routePath.containsSection(section) &&
routePath.getSectionSort(signalSection) < routePath.getSectionSort(section)) {
// 列车已越过此信号机
continue;
}
if (signal.hasCiAutoTriggerRoute() || signal.hasFleetModeRoute()) {
break;
}
if (!ctcLevel && signal.isVirtual()) {
continue;
}
if (signal.hasCiAutoTriggerRoute() || signal.hasFleetModeRoute()) {
if (signal.getLockedRoute() != null) {
continue;
} else {
return new RouteSelectResult(null, false);
}
}
if (this.isApproachSignal(repository, trainInfo, signal)) {
// 是信号机接近区段
if (signal.isNormalOpen()) {
@ -217,11 +222,8 @@ public abstract class AtsRouteSelectService {
}
}
}
} else {
// 列车未接近此信号机
return new RouteSelectResult(null, false);
}
break;
return new RouteSelectResult(null, false);
}
}
return new RouteSelectResult(null, true);
@ -242,7 +244,7 @@ public abstract class AtsRouteSelectService {
}
@Getter
class RouteSelectResult{
class RouteSelectResult {
private Route route;
private boolean allSet;

View File

@ -29,7 +29,25 @@ public class AtsTriggerRouteService {
private CiApiService ciApiService;
public void tryTrigger(Simulation simulation, TrainInfo trainInfo) {
if (trainInfo.isManualTrain()) { // 人工车不触发
return;
}
Map<String, Route> atsTriggerRouteMap = trainInfo.getAtsTriggerRouteMap();
boolean triggerRoute = triggerRoute(simulation, trainInfo, atsTriggerRouteMap); //触发了进路办理
if (!triggerRoute) {
AtsRouteSelectService routeSelectService = this.getRouteSelectService(trainInfo);
Route route = routeSelectService.select(simulation, trainInfo);
if (route != null && route.isAtsControl()) {
atsTriggerRouteMap.put(route.getCode(), route);
this.trySetRoute(simulation, trainInfo, route);
}
}
}
/**
* 尝试触发进路办理
*/
public boolean triggerRoute(Simulation simulation, TrainInfo trainInfo, Map<String, Route> atsTriggerRouteMap) {
if (!atsTriggerRouteMap.isEmpty()) {
SimulationDataRepository repository = simulation.getRepository();
for (Route route : atsTriggerRouteMap.values()) {
@ -48,7 +66,7 @@ public class AtsTriggerRouteService {
atsTriggerRouteMap.remove(route.getCode());
}
if (route.isSetting()) {
return;
return true;
}
if (route.getConflictAlarm() != null) {
if (route.isOpen()) {
@ -60,7 +78,7 @@ public class AtsTriggerRouteService {
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber());
AtsPlanTrainRouteSelectServiceImpl.ConflictInfo conflictInfo = this.planTrainRouteSelectService.checkConflict(repository, trainInfo, tripPlan, route);
if (conflictInfo != null) {
return;
return true;
} else {
route.getConflictAlarm().recover(simulation.getCorrectSystemTime());
route.setConflictAlarm(null);
@ -70,25 +88,14 @@ public class AtsTriggerRouteService {
}
}
if (!route.isOpen()) { // 存在未开放的进路直接返回
if(!route.isSetting()){ // 进路未办理继续尝试办理
if (!route.isSetting()) { // 进路未办理继续尝试办理
this.trySetRoute(simulation, trainInfo, route);
}
return;
return true;
}
}
}
if (trainInfo.isManualTrain()) { // 人工车不触发
return;
}
AtsRouteSelectService routeSelectService = this.getRouteSelectService(trainInfo);
Route route = routeSelectService.select(simulation, trainInfo);
if (route == null) { // 没有需要触发的进路返回
return;
}
if (route.isAtsControl()) { // ATS自动排列才处理
atsTriggerRouteMap.put(route.getCode(), route);
this.trySetRoute(simulation, trainInfo, route);
}
return false;
}
private void trySetRoute(Simulation simulation, TrainInfo trainInfo, Route route) {

View File

@ -6,14 +6,18 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
@ -90,52 +94,66 @@ public class AtsHeadTrainStageService implements AtsStageService {
}
private void updatePlanSection(Simulation simulation, TrainInfo trainInfo) {
if (!StringUtils.hasText(trainInfo.getPlanStandTrack()))
return;
boolean planRight = trainInfo.getHctPath().isRight();
SimulationDataRepository repository = simulation.getRepository();
SectionPosition headPosition = repository.buildHeadPositionOfTrainInfo(trainInfo);
Section headSection = headPosition.getSection();
if (StringUtils.hasText(trainInfo.getPlanStandTrack())) {
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
//如果还未到达目标轨
Section headSection = headPosition.getSection();
if (!planSection.equals(headSection) && planSection.isAheadOf(repository, headSection, planRight)) {
return;
}
}
Section nextPlanSection = queryNextPlanSection(repository, headSection, trainInfo);
//寻找目标区段
Section nextPlanSection = queryNextPlanSection(simulation, trainInfo);
if (nextPlanSection == null)
return;
//判断调头
Boolean trainRight = trainInfo.getRight();
if (!nextPlanSection.isAheadOf(repository, headSection, trainRight)) {//下一计划区段不在当前车头方向的前方
atpService.turnDirectionImmediately(repository.getOnlineTrainBy(trainInfo.getGroupNumber())); //调头
onboardAtpApiService.startTurnBack(simulation, trainInfo.getGroupNumber(), headSection.getCode());
}
//更新计划到站
SectionPosition stopPosition = new SectionPosition(nextPlanSection, nextPlanSection.getStopPointByDirection(planRight));
Float distance = CalculateService.calculateDistance(headPosition, stopPosition, planRight);
int runningTime;
if (distance != null) {
runningTime = (int) (distance / (45 / 3.6));
} else {
runningTime = 180;
}
trainInfo.updatePlanInfo(nextPlanSection, null, null);
boolean jump = this.atsStandService.isJump(nextPlanSection, trainInfo.getGroupNumber());
int runningTime = getRunningTime(repository, headSection, nextPlanSection);
onboardAtpApiService.updateNextArriveInfo(simulation, trainInfo.getGroupNumber(), nextPlanSection, true, runningTime, jump);
}
public static Section queryNextPlanSection(Simulation simulation, TrainInfo trainInfo) {
if (trainInfo.getPlanStandTrack() == null) {
return null;
private int getRunningTime(SimulationDataRepository repository, Section headSection, Section nextPlanSection) {
if (!CollectionUtils.isEmpty(headSection.getStandList())) {
Stand stand = headSection.getStandList().get(0);
if (stand.getRunLevelTime() > 0) {
return stand.getRunLevelTime();
}
SimulationDataRepository repository = simulation.getRepository();
}
StationRunLevel runLevel = repository.queryRunLevel(headSection, nextPlanSection);
if (runLevel != null) {
return runLevel.getL3();
}
List<RoutePath> routePaths = repository.queryRoutePaths(headSection, nextPlanSection);
if (!CollectionUtils.isEmpty(routePaths)) {
float distance = routePaths.stream().min(Comparator.comparingDouble(RoutePath::calculateDistance)).get().calculateDistance();
return (int) (distance / (45 / 3.6));
}
return 120;
}
public static Section queryNextPlanSection(SimulationDataRepository repository, Section headSection, TrainInfo trainInfo) {
List<Section> targetList = trainInfo.getHctPath().getSections();
Section planSection = repository.getByCode(trainInfo.getPlanStandTrack(), Section.class);
int index = targetList.indexOf(planSection);
if (index == -1 || index == targetList.size() - 1) {
return null;
} else {
int index = targetList.indexOf(headSection);
if (index == -1) {
for (int i = targetList.size() - 1; i >= 0; i--) {
Section section = targetList.get(i);
List<RoutePath> routePaths = repository.queryRoutePathsByEndAndContainsSection(section, headSection);
if (!CollectionUtils.isEmpty(routePaths)) {
return section;
}
}
} else if (index < targetList.size() - 1) {
return targetList.get(index + 1);
}
return null;
}
}

View File

@ -63,7 +63,7 @@ public class AtsTrainStageHandler {
stageService.handleNormalStandParking(simulation, trainInfo, parkSection);
List<Stand> standList = parkSection.getStandList();
int remainTime = standList.get(0).getRemainTime();
if (remainTime < 2 && !trainInfo.isDoorOpen() &&
if (remainTime < 2000 && !trainInfo.isDoorOpen() &&
(this.atsStandService.isStandDoorCloseOrInterlockRelease(simulation, parkSection)) &&
!this.atsStandService.isHoldTrain(parkSection)) { //即将发车
stageService.ready2DepartFromNormalStand(simulation, trainInfo, parkSection);

View File

@ -1336,4 +1336,9 @@ public class SimulationDataRepository {
public List<AtsAlarm> getAlarmList() {
return new ArrayList<>(this.alarmMap.values());
}
public StationRunLevel queryRunLevel(Section start, Section end) {
String key = start.getCode() + "-" + end.getCode();
return this.runLevelMap.get(key);
}
}