【大铁增加车次、右键发车功能】

This commit is contained in:
weizhihong 2022-05-16 14:51:42 +08:00
parent 193097dc55
commit 83bd55d67f
5 changed files with 154 additions and 25 deletions

View File

@ -737,6 +737,11 @@ public class Operation {
*/
Train_Calculate_Interval,
/**
* 大铁加载指定车次列车
*/
Train_Load_Trip_Number_Train,
//--------------------------- 司机 ---------------------------
/**
* 改变列车的牵引/制动力

View File

@ -104,10 +104,10 @@ public class TrainOperateHandler {
* @param simulation
* @param sectionCode 区段编号
* @param groupNumber 车组号
* @param dn 目的地码可为空
* @param sn 服务号/表号可为空
* @param tn 行程号/序号/车次号可为空
* @param cn 乘务组号可为空
* @param dn 目的地码可为空
* @param sn 服务号/表号可为空
* @param tn 行程号/序号/车次号可为空
* @param cn 乘务组号可为空
* @param autoTrigger 列车自动排列可为空
*/
@OperateHandlerMapping(type = Operation.Type.Train_Add_Train_Trace)
@ -394,4 +394,12 @@ public class TrainOperateHandler {
public IntervalCalculateResult calculateInterval(Simulation simulation, IntervalCalculateParam calculateParam) {
return atsTrainService.calculateInterval(simulation, calculateParam.getTrainNumber(), calculateParam.getInterval());
}
/**
* 大铁加载指定车次列车
*/
@OperateHandlerMapping(type = Operation.Type.Train_Load_Trip_Number_Train)
public void loadServiceNumberTrain(Simulation simulation, String tripNumber, String sectionCode, boolean right) {
atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, sectionCode, right);
}
}

View File

@ -98,7 +98,7 @@ public class AtsTrainLoadService {
int tripSize = tripPlanList.size();
TripPlan lastPlan = tripPlanList.get(tripSize - 1);
if (current.isAfter(lastPlan.getEndTime())) {
if(!lastPlan.isBackup()){
if (!lastPlan.isBackup()) {
log.info(String.format("服务号[%s]的所有非备用计划早于仿真系统时间[%s],无需加载列车", serviceNumber, current));
return;
}
@ -245,7 +245,7 @@ public class AtsTrainLoadService {
break;
} else if ((tripPlan.isTurnBack() || tripPlan.isBackup())) {
if(i + 1 < tripSize){
if (i + 1 < tripSize) {
// 车次是折返计划且存在下一车次
TripPlan nextPlan = tripPlanList.get(i + 1);
if (current.isAfter(tripPlan.getEndTime()) &&
@ -272,9 +272,9 @@ public class AtsTrainLoadService {
trainLoadList.add(trainLoadParam2);
break;
}
}else{
} else {
//最后一个车次或者仅有的一个车次
if(tripPlan.isBackup()){
if (tripPlan.isBackup()) {
//且是备用车
boolean right;
Section endSection = tripPlan.getEndSection();
@ -580,6 +580,7 @@ public class AtsTrainLoadService {
/**
* 处理碰撞逻辑
*
* @param simulation
* @param loadedList
*/
@ -599,6 +600,7 @@ public class AtsTrainLoadService {
/**
* 碰撞列车位置重置
*
* @param simulation
* @param collisionList
*/
@ -627,6 +629,7 @@ public class AtsTrainLoadService {
/**
* 查询碰撞列车
*
* @param loadedList
* @return
*/
@ -640,7 +643,7 @@ public class AtsTrainLoadService {
List<VirtualRealityTrain> collisionList = new ArrayList<>();
for (int i = 0; i < loadedList.size(); i++) {
VirtualRealityTrain train1 = loadedList.get(i);
for (int j = i+1; j < loadedList.size(); j++) {
for (int j = i + 1; j < loadedList.size(); j++) {
VirtualRealityTrain train2 = loadedList.get(j);
if (CalculateService.isTrainPositionCollision(trainPositionMap.get(train1.getGroupNumber()),
trainPositionMap.get(train2.getGroupNumber()))) {
@ -756,7 +759,7 @@ public class AtsTrainLoadService {
if (tripPlan.isTurnBack() && train.getHeadPosition().getSection().equals(tripPlan.getEndSection())) {
train.startTurnBack(train.getHeadPosition().getSection());
}
if(Objects.equals(RunLevel.ITC,repository.getConfig().getRunMode())){
if (Objects.equals(RunLevel.ITC, repository.getConfig().getRunMode())) {
train.setITCMode();
}
loadedTrainList.add(train);
@ -846,13 +849,54 @@ public class AtsTrainLoadService {
} else {
// 判断列车是否在派班计划中且后面要上线运行
}
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
VirtualRealityTrain virtualRealityTrain = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain);
}
/**
* 大铁加载指定车次列车
*
* @param simulation 仿真实体
* @param tripNumber 车次号
* @param sectionCode 区段编号
* @param right 上下行
*/
public void loadTripNumberTrain(Simulation simulation, String tripNumber, String sectionCode, boolean right) {
SimulationDataRepository repository = simulation.getRepository();
boolean isExist = repository.getTrainInfoMap().values().stream()
.anyMatch(trainInfo -> tripNumber.equals(trainInfo.getTripNumber()));
if (isExist) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
String.format("车次[%s]的列车已经在运行中", tripNumber));
}
Optional<VirtualRealityTrain> virtualRealityTrainOptional = repository.getAllVrTrain().stream()
.filter(trainInfo -> !repository.isVrTrainOnline(trainInfo.getGroupNumber()))
.findFirst();
if (virtualRealityTrainOptional.isEmpty()) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "无备用车");
}
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
// 设置列车车次
virtualRealityTrain.setTripNumber(tripNumber);
trainOnline(simulation, sectionCode, right, repository, virtualRealityTrain);
}
/**
* 列车上线并构建ATS监控列车信息
*
* @param simulation 仿真实体
* @param sectionCode 区段编码
* @param right 运行方向
* @param repository 数据实体
* @param train 列车
*/
private void trainOnline(Simulation simulation, String sectionCode, boolean right, SimulationDataRepository repository
, VirtualRealityTrain train) {
Section section = repository.getByCode(sectionCode, Section.class);
if (!section.isPhysical()) {
section = section.getParent();
}
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(),
"列车需加载到物理区段上");
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
//重叠检测
SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);

View File

@ -4,6 +4,7 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.DriveMode;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
@ -13,7 +14,6 @@ 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.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.Handwheel;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.PreselectionMode;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
@ -555,6 +555,59 @@ public class CommandBO {
}
return buildDriverATPChangeOperationStep(train.getGroupNumber(), true);
}
},
/**
* 大铁发车
**/
Depart_Train(List.of(), SimulationMember.Type.DRIVER) {
@Override
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
return Collections.emptyList();
}
@Override
public Step execute(Simulation simulation, CommandBO command) {
SimulationMember targetMember = command.getTargetMember();
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
if (train == null) {
targetMember.setCommand(null);
return null;
}
boolean isRight = train.isRight(); // 列车运行方向
Section section = train.getHeadPosition().getSection(); // 列车车头所在区段
boolean loop = true;
Signal signal;
Section nextSection = section, targetSection = null;
while (loop) {
signal = isRight ? nextSection.getSignalToRight() : nextSection.getSignalToLeft(); // 方向信号机
// 信号机未开放直接中断
if (signal != null && SignalAspect.R.equals(signal.getAspect())) {
targetSection = nextSection;
break;
}
// 存在锁闭进路获取进路末端
if (signal != null && signal.getLockedRoute() != null) {
nextSection = signal.getLockedRoute().getDestination().getSection();
} else {
nextSection = nextSection.getNextSection(isRight);
}
// 存在邻近区段,赋值
if (nextSection != null) {
targetSection = nextSection;
}
// 进路存在且不占用不出故障
loop = nextSection != null && !nextSection.isOccupied() && !nextSection.isFaultLock();
}
targetMember.setCommand(null);
if (targetSection != null) {
SectionPosition targetPosition = new SectionPosition(targetSection, targetSection.getStopPointByDirection(isRight));
// 设置目标位置
return buildDriveStep(targetPosition);
} else {
return null;
}
}
};
public enum ParamName {

View File

@ -15,6 +15,7 @@ import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -246,26 +247,44 @@ public class TrainInfo extends MapElement {
*/
@Setter
private String turnBackStatus = NON;
/** 无折返 */
/**
* 无折返
*/
public static String NON = "NON";
/** 初始化 */
/**
* 初始化
*/
public static String INIT = "INIT";
/** 开往折返轨 */
/**
* 开往折返轨
*/
public static String TO = "TO";
/** 到达折返轨停稳 */
/**
* 到达折返轨停稳
*/
public static String STOP = "STOP";
/** 开出折返轨 */
/**
* 开出折返轨
*/
public static String EXIT = "EXIT";
/** ATS为此列车触发的进路 */
/**
* ATS为此列车触发的进路
*/
private final Map<String, Route> atsTriggerRouteMap = new ConcurrentHashMap<>();
/** 通信是否正常 */
/**
* 通信是否正常
*/
private boolean communicable;
/** 调度策略 */
/**
* 调度策略
*/
private BusinessConsts.Regulation regulation;
/** 调度参数 */
/**
* 调度参数
*/
private RegulationParam regulationParam;
private VirtualRealityTrain.PreselectionMode preselectionMode;
@ -289,8 +308,8 @@ public class TrainInfo extends MapElement {
public static TrainInfo constructManualTrain(VirtualRealityTrain train) {
TrainInfo info = new TrainInfo(train);
info.type = TrainType.MANUAL;
info.serviceNumber = "";
info.tripNumber = "";
info.serviceNumber = StringUtils.isEmpty(train.getServiceNumber()) ? "" : train.getServiceNumber();
info.tripNumber = StringUtils.isEmpty(train.getTripNumber()) ? "" : train.getTripNumber();
return info;
}