统一列车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;
// Section nextStopStandSection = null;
// Section base = headPosition.getSection();
// while (true) {
// if ((base.isNormalStandTrack() || base.isTransferTrack())) {
// nextStopStandSection = base;
// 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)) { //// int count = 0;
// 下一计划到站台轨存在 //// Section nextStopStandSection = null;
// log.debug(String.format("列车[%s-%s|%s|%s]下一计划到站[%s(%s)],实际可达站台轨为[%s(%s)]", //// Section base = headPosition.getSection();
// train.getGroupNumber(), train.getServiceNumber(), //// while (true) {
// train.getTripNumber(), train.getDestinationCode(), //// if ((base.isNormalStandTrack() || base.isTransferTrack())) {
// nextStation.getName(), nextStation.getCode(), //// nextStopStandSection = base;
// nextStopStandSection.getName(), nextStopStandSection.getCode())); //// break;
boolean parking = true; //// }
Signal signal = target.getSignalOf(right); //// Section section = base.getNextRunningSectionOf(right);
if (!train.isHold() && (train.isJump() && (Objects.isNull(signal) || signal.isMainAspect()) || !train.isNextParking())) { //// if (Objects.isNull(section)) {
parking = false; //// // 未找到
} //// break;
if (parking) { //// } else {
// 列车停站,计算距离 //// base = section;
SectionPosition targetStopPoint = new SectionPosition(target, //// }
target.getStopPointByDirection(right)); //// if (count > 20) {
Float targetDistance = CalculateService.calculateDistance(headPosition, targetStopPoint, right); //// break;
if (Objects.nonNull(targetDistance) && targetDistance >= 0 && targetDistance < distance) { //// }
return targetDistance; //// ++count;
} //// }
} else { // Section target = train.getTarget();
// log.debug(String.format("列车[%s]下一计划到站[%s(%s)]不停车", // if (Objects.nonNull(target)) {
// train.getGroupNumber(), // // 下一计划到站台轨存在
// nextStation.getName(), nextStation.getCode())); //// log.debug(String.format("列车[%s-%s|%s|%s]下一计划到站[%s(%s)],实际可达站台轨为[%s(%s)]",
} //// train.getGroupNumber(), train.getServiceNumber(),
} //// train.getTripNumber(), train.getDestinationCode(),
// 若不存在下一计划站台轨列车应该在安全防护距离前一段距离停车 //// nextStation.getName(), nextStation.getCode(),
distance -= 10; //// nextStopStandSection.getName(), nextStopStandSection.getCode()));
// log.debug(String.format("列车[%s]剩余目标距离:[%s]", train.getGroupNumber(), distance)); // boolean parking = true;
return distance; // 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()) {
break; if (section.isNormalStandTrack()) {
if (train.isHold()) {
newTarget = section;
break;
}
if (!section.getCode().equals(trainInfo.getActualArriveStandTrack())) { //列车没有抵达该站台轨的信息
newTarget = section;
break;
}
} else {
newTarget = section;
}
} }
if ((target.isNormalStandTrack() && nextSection.isNormalStandTrack()) || section = section.getNextRunningSectionBaseRealSwitch(right);
(target.isJustTurnBackTrack() && nextSection.isJustTurnBackTrack()) || if (section == null) {
(target.isTransferTrack() && nextSection.isTransferTrack()) &&
target.getStation().equals(nextSection.getStation())) {
newTarget = nextSection;
break; break;
} else { } else {
temp = nextSection; continue;
} }
} }
return newTarget; return newTarget;