统一列车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.exception.SimulationException;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -491,19 +489,19 @@ public class AtsTrainLoadService {
}
}
private void updateTrainSpeed(Simulation simulation) {
for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) {
if (train.getMa() == null)
continue;
float targetDistance = ATOService.calculateTargetRemainDistance(train, train.getMa());
float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
SpeedCurve speedCurve = SpeedCurve
.buildTargetSpeedCurve(train.getHeadPosition(), train.calculateTailPosition(), train.isRight(),
targetDistance, train.getSpeed(), speedMax);
float speed = speedCurve.getSpeedOf(speedCurve.getTotalDistance());
train.setSpeed(speed);
}
}
// private void updateTrainSpeed(Simulation simulation) {
// for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) {
// if (train.getMa() == null)
// continue;
// float targetDistance = ATOService.calculateTargetRemainDistance(train, train.getMa());
// float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
// SpeedCurve speedCurve = SpeedCurve
// .buildTargetSpeedCurve(train.getHeadPosition(), train.calculateTailPosition(), train.isRight(),
// targetDistance, train.getSpeed(), speedMax);
// float speed = speedCurve.getSpeedOf(speedCurve.getTotalDistance());
// train.setSpeed(speed);
// }
// }
private List<TrainInfo> trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) {
List<TrainInfo> superviseList = new ArrayList<>();

View File

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

View File

@ -1146,31 +1146,11 @@ public class CalculateService {
/**
* 计算考虑时间的ato最大速度
*/
public static Float calculateAtoSpeedMax4RunTime(SimulationDataRepository repository, VirtualRealityTrain train, long runTime) {
// 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;
// }
public static Float calculateAtoSpeedMax4RunTime(SimulationDataRepository repository, VirtualRealityTrain train, long runTime, Section target) {
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(target);
if (CollectionUtils.isEmpty(routePathList)) {
return null;
}
// List<RoutePath> routePaths = queryRoutePathsOnDirection(train.getHeadPosition().getSection(), target, right, 10);
// if (CollectionUtils.isEmpty(routePaths)) {
// return null;
// }
Optional<Float> distanceOptional = routePathList.stream()
.filter(routePath -> routePath.containsSection(train.getHeadPosition().getSection()))
.map(RoutePath::getLength).min(Float::compareTo);

View File

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

View File

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

View File

@ -24,13 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.ArrayList;
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.*;
import java.util.stream.Collectors;
@Component
@ -150,7 +144,7 @@ public class DepotService {
}
break;
}
train.setTarget(endSection);
// train.setTarget(endSection);
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
if (routePaths == null || routePaths.isEmpty()) {
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.data.CalculateService;
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.support.MovementAuthority;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
@ -151,71 +150,71 @@ public class ATOService {
return CalculateService.calculateDistance(headPosition, endPosition, right);
}
/**
* 计算到目标位置剩余距离
*/
public static float calculateTargetRemainDistance(VirtualRealityTrain train, MovementAuthority ma) {
if (train.getTarget() == null)
return 0;
SectionPosition headPosition = train.getHeadPosition();
boolean right = train.isRight();
Float distance = calculateDistanceOfMa(headPosition, right, ma);
if (Objects.isNull(distance)) {
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;
// /**
// * 计算到目标位置剩余距离
// */
// public static float calculateTargetRemainDistance(VirtualRealityTrain train, MovementAuthority ma) {
// if (train.getTarget() == null)
// return 0;
// SectionPosition headPosition = train.getHeadPosition();
// boolean right = train.isRight();
// Float distance = calculateDistanceOfMa(headPosition, right, ma);
// if (Objects.isNull(distance)) {
// return 0;
// }
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;
}
// // 下一计划到站存在
//// 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)) {
// // 下一计划到站台轨存在
//// 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) {
doControlBySpeedCurve(train, speedCurve, remainDistance, train.getAtoSpeed());

View File

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

View File

@ -1,5 +1,6 @@
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.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
@ -28,11 +29,11 @@ public class TrainTargetUpdateService {
List<VirtualRealityTrain> onlineTrain = repository.getOnlineTrainList();
for (VirtualRealityTrain train : onlineTrain) {
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
if (!trainInfo.isManualTrain()) {
continue;
}
// if (!trainInfo.isManualTrain()) {
// continue;
// }
Section target = train.getTarget();
Section newTarget = this.queryArriveTarget4Manual(train, trainInfo, target);
Section newTarget = this.queryArriveTarget(train, trainInfo);
if (newTarget != null && !Objects.equals(target, newTarget)) {
train.setTarget(newTarget);
}
@ -84,29 +85,41 @@ public class TrainTargetUpdateService {
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();
Section newTarget = target;
boolean right = train.isRight();
Section temp = headPosition.getSection();
int count = 0;
while (count < 25) {
++count;
Section nextSection = temp.getNextRunningSectionBaseRealSwitch(right);
if (nextSection == null) {
Section headSection = headPosition.getSection();
Section section = headSection;
for (int i = 0; i < 100; i++) {
if (section.equals(eoaSection) && newTarget == null) { //已经遍历到移动授权终点区段且中途未找到功能轨
newTarget = section;
break;
}
if (Objects.equals(nextSection, target)) {// 找到
break;
if (section.isFunctionTrack()) {
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()) ||
(target.isJustTurnBackTrack() && nextSection.isJustTurnBackTrack()) ||
(target.isTransferTrack() && nextSection.isTransferTrack()) &&
target.getStation().equals(nextSection.getStation())) {
newTarget = nextSection;
section = section.getNextRunningSectionBaseRealSwitch(right);
if (section == null) {
break;
} else {
temp = nextSection;
continue;
}
}
return newTarget;