统一列车target更新逻辑

This commit is contained in:
joylink_zhangsai 2021-12-13 17:29:14 +08:00
parent be92513d93
commit 61fdd4941d
9 changed files with 125 additions and 141 deletions

View File

@ -26,8 +26,6 @@ import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -491,19 +489,19 @@ public class AtsTrainLoadService {
} }
} }
private void updateTrainSpeed(Simulation simulation) { // private void updateTrainSpeed(Simulation simulation) {
for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) { // for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) {
if (train.getMa() == null) // if (train.getMa() == null)
continue; // continue;
float targetDistance = ATOService.calculateTargetRemainDistance(train, train.getMa()); // float targetDistance = ATOService.calculateTargetRemainDistance(train, train.getMa());
float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f); // float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
SpeedCurve speedCurve = SpeedCurve // SpeedCurve speedCurve = SpeedCurve
.buildTargetSpeedCurve(train.getHeadPosition(), train.calculateTailPosition(), train.isRight(), // .buildTargetSpeedCurve(train.getHeadPosition(), train.calculateTailPosition(), train.isRight(),
targetDistance, train.getSpeed(), speedMax); // targetDistance, train.getSpeed(), speedMax);
float speed = speedCurve.getSpeedOf(speedCurve.getTotalDistance()); // float speed = speedCurve.getSpeedOf(speedCurve.getTotalDistance());
train.setSpeed(speed); // train.setSpeed(speed);
} // }
} // }
private List<TrainInfo> trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) { private List<TrainInfo> trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) {
List<TrainInfo> superviseList = new ArrayList<>(); List<TrainInfo> superviseList = new ArrayList<>();

View File

@ -45,6 +45,12 @@ public class AtsHeadTrainStageService implements AtsStageService {
if (dcd == null) if (dcd == null)
return; return;
if (Objects.equals(dcd.getSection(), parkSection)) { if (Objects.equals(dcd.getSection(), parkSection)) {
// 先回库
if (simulation.getRepository().getConfig().isHandleDepot()) {
trainInfo.finishPlanPrepareEnterDepot();
} else {
trainInfo.finishPlanPrepareInbound();
}
// 列车到达目的地 // 列车到达目的地
handleArriveDestination(simulation, trainInfo); handleArriveDestination(simulation, trainInfo);
} else { } else {
@ -86,12 +92,6 @@ public class AtsHeadTrainStageService implements AtsStageService {
* 处理列车到达目的地 * 处理列车到达目的地
*/ */
private void handleArriveDestination(Simulation simulation, TrainInfo trainInfo) { private void handleArriveDestination(Simulation simulation, TrainInfo trainInfo) {
// 先回库后设置为人工车
if (simulation.getRepository().getConfig().isHandleDepot()) {
trainInfo.finishPlanPrepareEnterDepot();
} else {
trainInfo.finishPlanPrepareInbound();
}
if (simulation.getRepository().getConfig().isSetManualWhenHeadTrainArriveTarget()) { if (simulation.getRepository().getConfig().isSetManualWhenHeadTrainArriveTarget()) {
atsTrainService.setManualTrain(simulation, trainInfo.getGroupNumber()); atsTrainService.setManualTrain(simulation, trainInfo.getGroupNumber());
} }

View File

@ -1146,31 +1146,11 @@ public class CalculateService {
/** /**
* 计算考虑时间的ato最大速度 * 计算考虑时间的ato最大速度
*/ */
public static Float calculateAtoSpeedMax4RunTime(SimulationDataRepository repository, VirtualRealityTrain train, long runTime) { public static Float calculateAtoSpeedMax4RunTime(SimulationDataRepository repository, VirtualRealityTrain train, long runTime, Section target) {
// if (train.getSpeed() != 0 /*|| !train.getHeadPosition().getSection().isStandTrack()*/) {
// return null;
// }
Section target = train.getTarget();
boolean right = train.isRight();
// float stopPoint;
// if (target.isStandTrack()) {
// stopPoint = target.getStopPointByDirection(right);
// } else {
// stopPoint = right ? target.getMaxOffset() - 10 : 10;
// }
// SectionPosition endPosition = new SectionPosition(target, stopPoint);
// Float distance2Target = calculateDistance(train.getHeadPosition(), endPosition, right);
// if (distance == null) {
// return null;
// }
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(target); List<RoutePath> routePathList = repository.queryRoutePathsByEnd(target);
if (CollectionUtils.isEmpty(routePathList)) { if (CollectionUtils.isEmpty(routePathList)) {
return null; return null;
} }
// List<RoutePath> routePaths = queryRoutePathsOnDirection(train.getHeadPosition().getSection(), target, right, 10);
// if (CollectionUtils.isEmpty(routePaths)) {
// return null;
// }
Optional<Float> distanceOptional = routePathList.stream() Optional<Float> distanceOptional = routePathList.stream()
.filter(routePath -> routePath.containsSection(train.getHeadPosition().getSection())) .filter(routePath -> routePath.containsSection(train.getHeadPosition().getSection()))
.map(RoutePath::getLength).min(Float::compareTo); .map(RoutePath::getLength).min(Float::compareTo);

View File

@ -1191,7 +1191,7 @@ public class Section extends DelayUnlockDevice {
} }
public boolean isJustTurnBackTrack() { public boolean isJustTurnBackTrack() {
return !this.isNormalStandTrack() && this.isTurnBackTrack(); return !this.isNormalStandTrack() && !this.isTransferTrack() && this.isTurnBackTrack();
} }
public boolean isLogicOverlapLock() { public boolean isLogicOverlapLock() {

View File

@ -680,7 +680,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
public synchronized void updateNextStationPlan(Station nextStation, Section targetSection, boolean nextParking) { public synchronized void updateNextStationPlan(Station nextStation, Section targetSection, boolean nextParking) {
this.nextStation = nextStation; this.nextStation = nextStation;
this.setTarget(targetSection); // this.setTarget(targetSection);
this.nextParking = nextParking; this.nextParking = nextParking;
// log.info(String.format("列车[%s]更新下一站[%s] 轨道[%s], [%s]", // log.info(String.format("列车[%s]更新下一站[%s] 轨道[%s], [%s]",
@ -690,7 +690,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
} }
public void startTurnBack(Section tbSection) { public void startTurnBack(Section tbSection) {
this.setTarget(tbSection); // this.setTarget(tbSection);
this.dtro = true; this.dtro = true;
this.nextStation = null; this.nextStation = null;
this.terminalStation = null; this.terminalStation = null;

View File

@ -24,13 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
@ -150,7 +144,7 @@ public class DepotService {
} }
break; break;
} }
train.setTarget(endSection); // train.setTarget(endSection);
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection); List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
if (routePaths == null || routePaths.isEmpty()) { if (routePaths == null || routePaths.isEmpty()) {
return; return;

View File

@ -7,7 +7,6 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.map.Stand; import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority; import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
@ -151,71 +150,71 @@ public class ATOService {
return CalculateService.calculateDistance(headPosition, endPosition, right); return CalculateService.calculateDistance(headPosition, endPosition, right);
} }
/** // /**
* 计算到目标位置剩余距离 // * 计算到目标位置剩余距离
*/ // */
public static float calculateTargetRemainDistance(VirtualRealityTrain train, MovementAuthority ma) { // public static float calculateTargetRemainDistance(VirtualRealityTrain train, MovementAuthority ma) {
if (train.getTarget() == null) // if (train.getTarget() == null)
return 0; // return 0;
SectionPosition headPosition = train.getHeadPosition(); // SectionPosition headPosition = train.getHeadPosition();
boolean right = train.isRight(); // boolean right = train.isRight();
Float distance = calculateDistanceOfMa(headPosition, right, ma); // Float distance = calculateDistanceOfMa(headPosition, right, ma);
if (Objects.isNull(distance)) { // if (Objects.isNull(distance)) {
return 0; // return 0;
} // }
// 下一计划到站存在 // // 下一计划到站存在
// int count = 0; //// int count = 0;
// Section nextStopStandSection = null; //// Section nextStopStandSection = null;
// Section base = headPosition.getSection(); //// Section base = headPosition.getSection();
// while (true) { //// while (true) {
// if ((base.isNormalStandTrack() || base.isTransferTrack())) { //// if ((base.isNormalStandTrack() || base.isTransferTrack())) {
// nextStopStandSection = base; //// nextStopStandSection = base;
// break; //// break;
//// }
//// Section section = base.getNextRunningSectionOf(right);
//// if (Objects.isNull(section)) {
//// // 未找到
//// break;
//// } else {
//// base = section;
//// }
//// if (count > 20) {
//// break;
//// }
//// ++count;
//// }
// Section target = train.getTarget();
// if (Objects.nonNull(target)) {
// // 下一计划到站台轨存在
//// log.debug(String.format("列车[%s-%s|%s|%s]下一计划到站[%s(%s)],实际可达站台轨为[%s(%s)]",
//// train.getGroupNumber(), train.getServiceNumber(),
//// train.getTripNumber(), train.getDestinationCode(),
//// nextStation.getName(), nextStation.getCode(),
//// nextStopStandSection.getName(), nextStopStandSection.getCode()));
// boolean parking = true;
// Signal signal = target.getSignalOf(right);
// if (!train.isHold() && (train.isJump() && (Objects.isNull(signal) || signal.isMainAspect()) || !train.isNextParking())) {
// parking = false;
// }
// if (parking) {
// // 列车停站,计算距离
// SectionPosition targetStopPoint = new SectionPosition(target,
// target.getStopPointByDirection(right));
// Float targetDistance = CalculateService.calculateDistance(headPosition, targetStopPoint, right);
// if (Objects.nonNull(targetDistance) && targetDistance >= 0 && targetDistance < distance) {
// return targetDistance;
// } // }
// Section section = base.getNextRunningSectionOf(right);
// if (Objects.isNull(section)) {
// // 未找到
// break;
// } else { // } else {
// base = section; //// log.debug(String.format("列车[%s]下一计划到站[%s(%s)]不停车",
//// train.getGroupNumber(),
//// nextStation.getName(), nextStation.getCode()));
// } // }
// if (count > 20) {
// break;
// } // }
// ++count; // // 若不存在下一计划站台轨列车应该在安全防护距离前一段距离停车
// distance -= 10;
//// log.debug(String.format("列车[%s]剩余目标距离:[%s]", train.getGroupNumber(), distance));
// return distance;
// } // }
Section target = train.getTarget();
if (Objects.nonNull(target)) {
// 下一计划到站台轨存在
// log.debug(String.format("列车[%s-%s|%s|%s]下一计划到站[%s(%s)],实际可达站台轨为[%s(%s)]",
// train.getGroupNumber(), train.getServiceNumber(),
// train.getTripNumber(), train.getDestinationCode(),
// nextStation.getName(), nextStation.getCode(),
// nextStopStandSection.getName(), nextStopStandSection.getCode()));
boolean parking = true;
Signal signal = target.getSignalOf(right);
if (!train.isHold() && (train.isJump() && (Objects.isNull(signal) || signal.isMainAspect()) || !train.isNextParking())) {
parking = false;
}
if (parking) {
// 列车停站,计算距离
SectionPosition targetStopPoint = new SectionPosition(target,
target.getStopPointByDirection(right));
Float targetDistance = CalculateService.calculateDistance(headPosition, targetStopPoint, right);
if (Objects.nonNull(targetDistance) && targetDistance >= 0 && targetDistance < distance) {
return targetDistance;
}
} else {
// log.debug(String.format("列车[%s]下一计划到站[%s(%s)]不停车",
// train.getGroupNumber(),
// nextStation.getName(), nextStation.getCode()));
}
}
// 若不存在下一计划站台轨列车应该在安全防护距离前一段距离停车
distance -= 10;
// log.debug(String.format("列车[%s]剩余目标距离:[%s]", train.getGroupNumber(), distance));
return distance;
}
public void doControlBySpeedCurve(VirtualRealityTrain train, SpeedCurve speedCurve, float remainDistance) { public void doControlBySpeedCurve(VirtualRealityTrain train, SpeedCurve speedCurve, float remainDistance) {
doControlBySpeedCurve(train, speedCurve, remainDistance, train.getAtoSpeed()); doControlBySpeedCurve(train, speedCurve, remainDistance, train.getAtoSpeed());

View File

@ -149,7 +149,7 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
this.checkAndChangeDirection(simulation, train, targetSection); this.checkAndChangeDirection(simulation, train, targetSection);
//根据时间控制速度 //根据时间控制速度
// runningTime -= 10; //减去开关门和延迟启动耗费的时间 // runningTime -= 10; //减去开关门和延迟启动耗费的时间
Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runningTime); Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runningTime, targetSection);
if (atoMaxSpeed != null) { if (atoMaxSpeed != null) {
train.setAtoSpeedMax(atoMaxSpeed); train.setAtoSpeedMax(atoMaxSpeed);
} }
@ -165,7 +165,7 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
this.checkAndChangeDirection(simulation, train, planSection); this.checkAndChangeDirection(simulation, train, planSection);
//根据时间控制速度 //根据时间控制速度
// runningTime -= 10; //减去开关门和延迟启动耗费的时间 // runningTime -= 10; //减去开关门和延迟启动耗费的时间
Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runTime); Float atoMaxSpeed = CalculateService.calculateAtoSpeedMax4RunTime(repository, train, runTime, planSection);
if (atoMaxSpeed != null) { if (atoMaxSpeed != null) {
train.setAtoSpeedMax(atoMaxSpeed); train.setAtoSpeedMax(atoMaxSpeed);
} }
@ -233,7 +233,7 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
return; return;
} }
checkAndChangeDirection(simulation, train, target); checkAndChangeDirection(simulation, train, target);
train.setTarget(target); // train.setTarget(target);
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.onboard; package club.joylink.rtss.simulation.cbtc.onboard;
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
@ -28,11 +29,11 @@ public class TrainTargetUpdateService {
List<VirtualRealityTrain> onlineTrain = repository.getOnlineTrainList(); List<VirtualRealityTrain> onlineTrain = repository.getOnlineTrainList();
for (VirtualRealityTrain train : onlineTrain) { for (VirtualRealityTrain train : onlineTrain) {
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber()); TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
if (!trainInfo.isManualTrain()) { // if (!trainInfo.isManualTrain()) {
continue; // continue;
} // }
Section target = train.getTarget(); Section target = train.getTarget();
Section newTarget = this.queryArriveTarget4Manual(train, trainInfo, target); Section newTarget = this.queryArriveTarget(train, trainInfo);
if (newTarget != null && !Objects.equals(target, newTarget)) { if (newTarget != null && !Objects.equals(target, newTarget)) {
train.setTarget(newTarget); train.setTarget(newTarget);
} }
@ -84,29 +85,41 @@ public class TrainTargetUpdateService {
return newTarget; return newTarget;
} }
private Section queryArriveTarget(VirtualRealityTrain train, Section target) { private Section queryArriveTarget(VirtualRealityTrain train, TrainInfo trainInfo) {
Section newTarget = null;
MaService.Ma ma = train.getMa2();
if (ma == null)
return null;
SectionPosition eoaPosition = ma.getEoaPosition();
Section eoaSection = eoaPosition.getSection();
SectionPosition headPosition = train.getHeadPosition(); SectionPosition headPosition = train.getHeadPosition();
Section newTarget = target;
boolean right = train.isRight(); boolean right = train.isRight();
Section temp = headPosition.getSection(); Section headSection = headPosition.getSection();
int count = 0; Section section = headSection;
while (count < 25) { for (int i = 0; i < 100; i++) {
++count; if (section.equals(eoaSection) && newTarget == null) { //已经遍历到移动授权终点区段且中途未找到功能轨
Section nextSection = temp.getNextRunningSectionBaseRealSwitch(right); newTarget = section;
if (nextSection == null) {
break; break;
} }
if (Objects.equals(nextSection, target)) {// 找到 if (section.isFunctionTrack()) {
if (section.isNormalStandTrack()) {
if (train.isHold()) {
newTarget = section;
break; break;
} }
if ((target.isNormalStandTrack() && nextSection.isNormalStandTrack()) || if (!section.getCode().equals(trainInfo.getActualArriveStandTrack())) { //列车没有抵达该站台轨的信息
(target.isJustTurnBackTrack() && nextSection.isJustTurnBackTrack()) || newTarget = section;
(target.isTransferTrack() && nextSection.isTransferTrack()) && break;
target.getStation().equals(nextSection.getStation())) { }
newTarget = nextSection; } else {
newTarget = section;
}
}
section = section.getNextRunningSectionBaseRealSwitch(right);
if (section == null) {
break; break;
} else { } else {
temp = nextSection; continue;
} }
} }
return newTarget; return newTarget;