Compare commits

..

3 Commits

5 changed files with 330 additions and 278 deletions

View File

@ -46,7 +46,14 @@ public class SortDiagramStation {
private Station findNotDepotStation(boolean isRight, int index) { private Station findNotDepotStation(boolean isRight, int index) {
Station station = stationList.get(index); Station station = null;
if (index >= stationList.size()) {
station = stationList.get(stationList.size() - 1);
} else if (index <= 0) {
station = stationList.get(0);
} else {
station = stationList.get(index);
}
while (station.isDepot()) { while (station.isDepot()) {
index += isRight ? -1 : 1; index += isRight ? -1 : 1;
station = stationList.get(index); station = stationList.get(index);

View File

@ -32,6 +32,7 @@ public abstract class AtsRouteSelectService {
* 查询需要触发的进路 * 查询需要触发的进路
* *
* @param simulation * @param simulation
* @param targetList 运行计划中的计划区段包含站后折返轨
* @param turnBackSection 站后折返的折返轨 * @param turnBackSection 站后折返的折返轨
* @return * @return
*/ */
@ -63,13 +64,18 @@ public abstract class AtsRouteSelectService {
MapConfig config = repository.getConfig(); MapConfig config = repository.getConfig();
if (!config.isSignalOpenAfterParking() || (headSection.equals(planSection) if (!config.isSignalOpenAfterParking() || (headSection.equals(planSection)
&& trainInfo.isParking())) { //不需要停站就可以开放信号机或者已经在计划区段停站可以继续向前办理进路 && trainInfo.isParking())) { //不需要停站就可以开放信号机或者已经在计划区段停站可以继续向前办理进路
if (nextPlanSection != null) { //计划区段路径未跑完 //根据车站折返策略处理
Station station = planSection.getStation();
if (station.getTbStrategyId() != null && Objects.equals(turnBackSection,
nextPlanSection)) { //有折返策略时按折返策略
return queryTriggerRoutes4TurnBack(simulation, planSection, turnBackSection, trainInfo);
} else if (nextPlanSection != null) { //无折返策略按计划
routePaths = repository.queryRoutePaths(planSection, nextPlanSection); routePaths = repository.queryRoutePaths(planSection, nextPlanSection);
if (!CollectionUtils.isEmpty(routePaths)) { if (!CollectionUtils.isEmpty(routePaths)) {
return this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths, return this.queryTriggerRoutesOfRoutePath(repository, trainInfo, routePaths,
nextPlanSection).getRoute(); nextPlanSection).getRoute();
} }
} else if (turnBackSection != null) { //站后折返 } else if (turnBackSection != null) {
return queryTriggerRoutes4TurnBack(simulation, planSection, turnBackSection, trainInfo); return queryTriggerRoutes4TurnBack(simulation, planSection, turnBackSection, trainInfo);
} }
} }

View File

@ -5,23 +5,26 @@ import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; 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.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; 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.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; 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;
/** /**
* 计划车阶段处理服务 * 计划车阶段处理服务
@ -29,6 +32,7 @@ import java.util.Objects;
@Slf4j @Slf4j
@Component @Component
public class AtsPlanTrainStageService implements AtsStageService { public class AtsPlanTrainStageService implements AtsStageService {
@Autowired @Autowired
private AtsRealRunRecordService realRunRecordService; private AtsRealRunRecordService realRunRecordService;
@Autowired @Autowired
@ -39,9 +43,11 @@ public class AtsPlanTrainStageService implements AtsStageService {
private AtsTrainService atsTrainService; private AtsTrainService atsTrainService;
@Override @Override
public void handleTransferTrackParking(Simulation simulation, TrainInfo trainInfo, Section parkSection) { public void handleTransferTrackParking(Simulation simulation, TrainInfo trainInfo,
Section parkSection) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
trainInfo.getTripNumber());
// List<RoutePath> routePathList = repository.queryRoutePathsByEnd(parkSection); // List<RoutePath> routePathList = repository.queryRoutePathsByEnd(parkSection);
// if (routePathList.get(0).isRight() == trainInfo.getRight()) { //准备回库 // if (routePathList.get(0).isRight() == trainInfo.getRight()) { //准备回库
// if (!parkSection.isTurnBackTrack()) { //针对上饶沙盘 // if (!parkSection.isTurnBackTrack()) { //针对上饶沙盘
@ -82,15 +88,18 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
@Override @Override
public void handleNormalStandParking(Simulation simulation, TrainInfo trainInfo, Section parkSection) { public void handleNormalStandParking(Simulation simulation, TrainInfo trainInfo,
Section parkSection) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
MapConfig config = repository.getConfig(); MapConfig config = repository.getConfig();
List<Stand> standList = parkSection.getStandList(); List<Stand> standList = parkSection.getStandList();
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
trainInfo.getTripNumber());
TripPlan nextTripPlan = null; TripPlan nextTripPlan = null;
StationPlan stationPlan = tripPlan.queryStationPlan(parkSection); StationPlan stationPlan = tripPlan.queryStationPlan(parkSection);
if (config.isStandTbStrategyIsInvalid()) { if (config.isStandTbStrategyIsInvalid()) {
if (stationPlan != null && tripPlan.isLastPlan(stationPlan) && tripPlan.isFrontTurnBack()) { // 到达终点站了判断站前折返还是站后折返 if (stationPlan != null && tripPlan.isLastPlan(stationPlan)
&& tripPlan.isFrontTurnBack()) { // 到达终点站了判断站前折返还是站后折返
// 站前折返查询下一车次计划 // 站前折返查询下一车次计划
nextTripPlan = repository.queryNextTripPlanOf(tripPlan); nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
} else if (stationPlan == null && tripPlan.isLastPlanStation(parkSection.getStation())) { } else if (stationPlan == null && tripPlan.isLastPlanStation(parkSection.getStation())) {
@ -101,9 +110,12 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
if (nextTripPlan != null) { // 站前折返更新计划 if (nextTripPlan != null) { // 站前折返更新计划
this.updateTripPlan(simulation, trainInfo, nextTripPlan); this.updateTripPlan(simulation, trainInfo, nextTripPlan);
BusinessExceptionAssertEnum.DATA_ERROR.assertEquals(nextTripPlan.getFirstStationPlan().getSection(), parkSection, BusinessExceptionAssertEnum.DATA_ERROR.assertEquals(
String.format("下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s]", nextTripPlan.getStNumber(), parkSection.getName())); nextTripPlan.getFirstStationPlan().getSection(), parkSection,
this.updateNextPlan(simulation, trainInfo, nextTripPlan, nextTripPlan.getFirstStationPlan()); String.format("下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s]",
nextTripPlan.getStNumber(), parkSection.getName()));
this.updateNextPlan(simulation, trainInfo, nextTripPlan,
nextTripPlan.getFirstStationPlan());
} }
} else { } else {
if (!CollectionUtils.isEmpty(standList)) { if (!CollectionUtils.isEmpty(standList)) {
@ -114,20 +126,24 @@ public class AtsPlanTrainStageService implements AtsStageService {
case AUTO: case AUTO:
if (stationPlan != null && tripPlan.isLastPlan(stationPlan)) { // 当前计划终点站 if (stationPlan != null && tripPlan.isLastPlan(stationPlan)) { // 当前计划终点站
if (Objects.equals(stand.isRight(), trainInfo.getRight())) { if (Objects.equals(stand.isRight(), trainInfo.getRight())) {
onboardAtpApiService.startTurnBack(simulation, trainInfo.getGroupNumber(), parkSection.getCode()); onboardAtpApiService.startTurnBack(simulation, trainInfo.getGroupNumber(),
parkSection.getCode());
nextTripPlan = repository.queryNextTripPlanOf(tripPlan); nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
if (nextTripPlan != null) { // 站前折返更新计划 if (nextTripPlan != null) { // 站前折返更新计划
this.updateTripPlan(simulation, trainInfo, nextTripPlan); this.updateTripPlan(simulation, trainInfo, nextTripPlan);
this.updateNextPlan(simulation, trainInfo, nextTripPlan, nextTripPlan.getSecondStationPlan()); this.updateNextPlan(simulation, trainInfo, nextTripPlan,
nextTripPlan.getSecondStationPlan());
} }
} }
} }
break; break;
default: default:
if (stationPlan != null && tripPlan.isLastPlan(stationPlan) && tripPlan.isFrontTurnBack()) { // 到达终点站了判断站前折返还是站后折返 if (stationPlan != null && tripPlan.isLastPlan(stationPlan)
&& tripPlan.isFrontTurnBack()) { // 到达终点站了判断站前折返还是站后折返
// 站前折返查询下一车次计划 // 站前折返查询下一车次计划
nextTripPlan = repository.queryNextTripPlanOf(tripPlan); nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
} else if (stationPlan == null && tripPlan.isLastPlanStation(parkSection.getStation())) { } else if (stationPlan == null && tripPlan.isLastPlanStation(
parkSection.getStation())) {
if (config.isAtsAutoHandleManualFrontTurnBack()) { if (config.isAtsAutoHandleManualFrontTurnBack()) {
// 人工站前折返 // 人工站前折返
nextTripPlan = repository.queryNextTripPlanOf(tripPlan); nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
@ -135,9 +151,12 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
if (nextTripPlan != null) { // 站前折返更新计划 if (nextTripPlan != null) { // 站前折返更新计划
this.updateTripPlan(simulation, trainInfo, nextTripPlan); this.updateTripPlan(simulation, trainInfo, nextTripPlan);
BusinessExceptionAssertEnum.DATA_ERROR.assertEquals(nextTripPlan.getFirstStationPlan().getSection(), parkSection, BusinessExceptionAssertEnum.DATA_ERROR.assertEquals(
String.format("下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s]", nextTripPlan.getStNumber(), parkSection.getName())); nextTripPlan.getFirstStationPlan().getSection(), parkSection,
this.updateNextPlan(simulation, trainInfo, nextTripPlan, nextTripPlan.getFirstStationPlan()); String.format("下一车次计划[%s]第一站台轨和停靠站台轨不相同:[%s]",
nextTripPlan.getStNumber(), parkSection.getName()));
this.updateNextPlan(simulation, trainInfo, nextTripPlan,
nextTripPlan.getFirstStationPlan());
} }
break; break;
} }
@ -146,9 +165,11 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
@Override @Override
public void ready2DepartFromNormalStand(Simulation simulation, TrainInfo trainInfo, Section parkSection) { public void ready2DepartFromNormalStand(Simulation simulation, TrainInfo trainInfo,
Section parkSection) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
trainInfo.getTripNumber());
StationPlan stationPlan = tripPlan.queryStationPlan(parkSection); StationPlan stationPlan = tripPlan.queryStationPlan(parkSection);
if (stationPlan == null) { if (stationPlan == null) {
// 非计划中的停靠站台轨暂不处理 // 非计划中的停靠站台轨暂不处理
@ -168,7 +189,8 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
// 到达终点站准备折返 // 到达终点站准备折返
log.debug(String.format("列车[%s]折返初始化", trainInfo.getGroupNumber())); log.debug(String.format("列车[%s]折返初始化", trainInfo.getGroupNumber()));
List<RoutePath> routePaths = repository.getRoutePaths(parkSection, tripPlan.getEndSection()); List<RoutePath> routePaths = repository.getRoutePaths(parkSection,
tripPlan.getEndSection());
Signal signal = parkSection.getSignalOf(routePaths.get(0).isRight()); Signal signal = parkSection.getSignalOf(routePaths.get(0).isRight());
if (signal.isMainAspect() || signal.isGuideAspect()) { if (signal.isMainAspect() || signal.isGuideAspect()) {
Route lockedRoute = signal.getLockedRoute(); Route lockedRoute = signal.getLockedRoute();
@ -190,7 +212,8 @@ public class AtsPlanTrainStageService implements AtsStageService {
this.onboardAtpApiService.updateTripPlan(simulation, trainInfo.getGroupNumber(), nextTripPlan); this.onboardAtpApiService.updateTripPlan(simulation, trainInfo.getGroupNumber(), nextTripPlan);
} }
public void updateNextPlan(Simulation simulation, TrainInfo trainInfo, TripPlan tripPlan, StationPlan nextStationPlan) { public void updateNextPlan(Simulation simulation, TrainInfo trainInfo, TripPlan tripPlan,
StationPlan nextStationPlan) {
if (nextStationPlan == null) { if (nextStationPlan == null) {
log.warn(String.format("列车[%s]下一计划到站为null", trainInfo.debugStr())); log.warn(String.format("列车[%s]下一计划到站为null", trainInfo.debugStr()));
return; return;
@ -239,7 +262,8 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
int planRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime); int planRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime);
int adjustRunTime = planRunTime; int adjustRunTime = planRunTime;
if (!turnBack && !outbound && config.isAdjustOperationAutomatically() && trainInfo.isAtsAutoAdjust()) { if (!turnBack && !outbound && config.isAdjustOperationAutomatically()
&& trainInfo.isAtsAutoAdjust()) {
startTime = systemTime.toLocalTime(); startTime = systemTime.toLocalTime();
adjustRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime); adjustRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime);
} }
@ -253,12 +277,17 @@ public class AtsPlanTrainStageService implements AtsStageService {
} }
@Override @Override
public void handleTurnBackTrackParking(Simulation simulation, TrainInfo trainInfo, Section parkSection) { public void handleTurnBackTrackParking(Simulation simulation, TrainInfo trainInfo,
Section parkSection) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
LocalDateTime systemTime = simulation.getSystemTime(); LocalDateTime systemTime = simulation.getSystemTime();
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
if (tripPlan.getEndSection().equals(parkSection) trainInfo.getTripNumber());
/*|| tripPlan.getEndSection().getStation().equals(parkSection.getStation())*/) {
// 车次计划中的车站计划全部完成并且当前折返轨与计划折返轨属于同一站则认为车次计划完成
boolean completed = tripPlan.getPlanList().stream().allMatch(StationPlan::isFinished)
&& tripPlan.getEndSection().getStation().equals(parkSection.getStation());
if (completed) {
// 计划终端折返轨或和计划终端折返轨同站的折返轨,根据车次类型处理 // 计划终端折返轨或和计划终端折返轨同站的折返轨,根据车次类型处理
TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan); TripPlan nextTripPlan = repository.queryNextTripPlanOf(tripPlan);
if (nextTripPlan == null) { if (nextTripPlan == null) {
@ -268,15 +297,19 @@ public class AtsPlanTrainStageService implements AtsStageService {
// 备用车 // 备用车
if (systemTime.toLocalTime().plusMinutes(5).isAfter(nextTripPlan.getStartTime())) { if (systemTime.toLocalTime().plusMinutes(5).isAfter(nextTripPlan.getStartTime())) {
this.updateTripPlan(simulation, trainInfo, nextTripPlan); this.updateTripPlan(simulation, trainInfo, nextTripPlan);
BusinessExceptionAssertEnum.DATA_ERROR.assertNotEquals(parkSection, nextTripPlan.getFirstStationPlan().getSection()); BusinessExceptionAssertEnum.DATA_ERROR.assertNotEquals(parkSection,
this.updateNextPlan(simulation, trainInfo, nextTripPlan, nextTripPlan.getFirstStationPlan()); nextTripPlan.getFirstStationPlan().getSection());
this.updateNextPlan(simulation, trainInfo, nextTripPlan,
nextTripPlan.getFirstStationPlan());
return; return;
} }
} else if (tripPlan.isTurnBack()) { } else if (tripPlan.isTurnBack()) {
// 折返计划 // 折返计划
this.updateTripPlan(simulation, trainInfo, nextTripPlan); this.updateTripPlan(simulation, trainInfo, nextTripPlan);
BusinessExceptionAssertEnum.DATA_ERROR.assertNotEquals(parkSection, nextTripPlan.getFirstStationPlan().getSection()); BusinessExceptionAssertEnum.DATA_ERROR.assertNotEquals(parkSection,
this.updateNextPlan(simulation, trainInfo, nextTripPlan, nextTripPlan.getFirstStationPlan()); nextTripPlan.getFirstStationPlan().getSection());
this.updateNextPlan(simulation, trainInfo, nextTripPlan,
nextTripPlan.getFirstStationPlan());
return; return;
} }
} else { } else {
@ -317,7 +350,8 @@ public class AtsPlanTrainStageService implements AtsStageService {
return; return;
} }
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(), trainInfo.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(trainInfo.getServiceNumber(),
trainInfo.getTripNumber());
StationPlan stationPlan = tripPlan.queryStationPlan(planStandTrack); StationPlan stationPlan = tripPlan.queryStationPlan(planStandTrack);
Section section = repository.getByCode(planStandTrack, Section.class); Section section = repository.getByCode(planStandTrack, Section.class);
//更新离站信息 //更新离站信息

View File

@ -345,10 +345,15 @@ public class SimulationRobotService {
|| Objects.equals(vrSignal.getAspect(), signal.getGuideAspect())) { //引导信号 || Objects.equals(vrSignal.getAspect(), signal.getGuideAspect())) { //引导信号
if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(), if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(),
throughAspect)) { throughAspect)) {
SectionPosition noPassPosition = CalculateService.calculateNextPositionByStartAndLen( SectionPosition tempPosition;
if (section.isFunctionTrack()) { //解决福州一列车从车辆段开出来时在转换轨停车位置有误导致无法发车的问题
tempPosition = new SectionPosition(section, section.getStopPointByDirection(right));
} else {
tempPosition = CalculateService.calculateNextPositionByStartAndLen(
signalPosition, !right, 2, true); signalPosition, !right, 2, true);
if (targetPosition == null || noPassPosition.isAheadOf(targetPosition, right)) { }
targetPosition = noPassPosition; if (targetPosition == null || tempPosition.isAheadOf(targetPosition, right)) {
targetPosition = tempPosition;
} }
} }
} }

View File

@ -222,7 +222,7 @@ public class MetroSimulationWorkServiceImpl implements SimulationWorkService {
faultGenerator.addJobs(simulation); faultGenerator.addJobs(simulation);
atsMessageCollectAndDispatcher.addJobs(simulation); atsMessageCollectAndDispatcher.addJobs(simulation);
nccAlarmService.addJobs(simulation); nccAlarmService.addJobs(simulation);
trainMessageDiagram.addJobs(simulation); // trainMessageDiagram.addJobs(simulation); 逻辑报错暂时注掉
} }
@Override @Override