Merge remote-tracking branch 'origin/test' into dev

This commit is contained in:
joylink_zhangsai 2021-12-09 13:25:44 +08:00
commit fd40f9de78
25 changed files with 928 additions and 489 deletions

View File

@ -3,7 +3,6 @@ package club.joylink.rtss.simulation.cbtc.ATS;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStationService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStationService;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainMonitorService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainMonitorService;
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
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.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
@ -24,11 +23,8 @@ public class ATSLogicLoop {
private AtsStationService atsStationService; private AtsStationService atsStationService;
@Autowired @Autowired
private AtsTrainMonitorService atsTrainMonitorService; private AtsTrainMonitorService atsTrainMonitorService;
@Autowired
private TrainOutboundLoadTool trainOutboundLoadTool;
public void run(Simulation simulation) { public void run(Simulation simulation) {
this.trainOutboundLoadTool.loadOutboundTrain(simulation);
this.atsStandService.countDown(simulation); this.atsStandService.countDown(simulation);
this.atsTrainMonitorService.monitor(simulation); this.atsTrainMonitorService.monitor(simulation);
this.atsStationService.updateFieldThatChangeOverTime(simulation); this.atsStationService.updateFieldThatChangeOverTime(simulation);

View File

@ -50,7 +50,7 @@ public class TrainOperateHandler {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
List<VirtualRealityTrain> onlineTrainList = repository.getOnlineTrainList(); List<VirtualRealityTrain> onlineTrainList = repository.getOnlineTrainList();
VirtualRealityTrain train = repository VirtualRealityTrain train = repository
.getTrain(serviceNumber, tripNumber); .getTrain(simulation, serviceNumber, tripNumber);
for (VirtualRealityTrain online : onlineTrainList) { for (VirtualRealityTrain online : onlineTrainList) {
if (Objects.equals(train, online)) { if (Objects.equals(train, online)) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,

View File

@ -510,7 +510,10 @@ public class AtsTrainLoadService {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
for (VirtualRealityTrain train : loadedList) { for (VirtualRealityTrain train : loadedList) {
// 构建监控列车信息 // 构建监控列车信息
TrainInfo trainInfo = new TrainInfo(train.getGroupNumber()); TrainInfo trainInfo = simulation.getRepository().getTrainInfoMap().get(train.getGroupNumber());
if (trainInfo == null) {
trainInfo = new TrainInfo(train.getGroupNumber());
}
TripPlan tripPlan = repository.getTripPlan(train.getServiceNumber(), train.getTripNumber()); TripPlan tripPlan = repository.getTripPlan(train.getServiceNumber(), train.getTripNumber());
trainInfo.init(tripPlan, repository.getConfig()); trainInfo.init(tripPlan, repository.getConfig());
List<StationPlan> stationPlanList = tripPlan.getPlanList(); List<StationPlan> stationPlanList = tripPlan.getPlanList();
@ -739,7 +742,7 @@ public class AtsTrainLoadService {
break; break;
} }
TripPlan tripPlan = trainLoadParam2.getTripPlan(); TripPlan tripPlan = trainLoadParam2.getTripPlan();
VirtualRealityTrain train = repository.getTrain(tripPlan.getServiceNumber(), tripPlan.getTripNumber()); VirtualRealityTrain train = repository.getTrain(simulation, tripPlan.getServiceNumber(), tripPlan.getTripNumber());
if (loadedTrainList.contains(train)) { if (loadedTrainList.contains(train)) {
throw new SimulationException(SimulationExceptionType.System_Fault, throw new SimulationException(SimulationExceptionType.System_Fault,
String.format("加载计划[%s|%s|%s]和[%s|%s|%s]使用列车重复", String.format("加载计划[%s|%s|%s]和[%s|%s|%s]使用列车重复",
@ -824,7 +827,7 @@ public class AtsTrainLoadService {
List<TripPlan> allTripPlanList = repository.getAllTripPlanList(); List<TripPlan> allTripPlanList = repository.getAllTripPlanList();
allTripPlanList.forEach(tripPlan -> { allTripPlanList.forEach(tripPlan -> {
if (!systemTime.isBefore(tripPlan.getStartTime())) { if (!systemTime.isBefore(tripPlan.getStartTime())) {
tripPlan.dispatch(); tripPlan.departure();
tripPlan.finishStationPlanOf(systemTime); tripPlan.finishStationPlanOf(systemTime);
} }
}); });

View File

@ -3,9 +3,11 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.stage;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; 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.CalculateService;
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.DestinationCodeDefinition;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.map.StationRunLevel;
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.support.SectionPosition; 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.vo.TrainInfo;
@ -13,9 +15,7 @@ import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
@ -87,7 +87,11 @@ public class AtsHeadTrainStageService implements AtsStageService {
*/ */
private void handleArriveDestination(Simulation simulation, TrainInfo trainInfo) { private void handleArriveDestination(Simulation simulation, TrainInfo trainInfo) {
// 先回库后设置为人工车 // 先回库后设置为人工车
trainInfo.finishPlanPrepareInbound(); 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

@ -4,7 +4,6 @@ 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.Section; import club.joylink.rtss.simulation.cbtc.data.map.Section;
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.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -25,12 +24,12 @@ public class AtsManualTrainStageService implements AtsStageService {
@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();
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(parkSection); // List<RoutePath> routePathList = repository.queryRoutePathsByEnd(parkSection);
boolean in = false; // 回库?出库? boolean in = trainInfo.isInbound(); // 回库?
if (routePathList.get(0).isRight() == trainInfo.getRight().booleanValue()) { // if (routePathList.get(0).isRight() == trainInfo.getRight().booleanValue()) {
in = true; // in = true;
} // }
if (!in) { // 出库查询计划是否此轨道有出库计划 if (!in) { // 出库查询计划是否此轨道有出库计划
if (simulation.isPlanRunning()) { if (simulation.isPlanRunning()) {
this.checkAndApplyTripPlan(simulation, trainInfo, parkSection); this.checkAndApplyTripPlan(simulation, trainInfo, parkSection);
@ -69,7 +68,7 @@ public class AtsManualTrainStageService implements AtsStageService {
} }
if (systemTime.toLocalTime().plusMinutes(10).isAfter(tripPlan.getStartTime())) { if (systemTime.toLocalTime().plusMinutes(10).isAfter(tripPlan.getStartTime())) {
this.planTrainStageService.updateTripPlan(simulation, trainInfo, tripPlan); this.planTrainStageService.updateTripPlan(simulation, trainInfo, tripPlan);
tripPlan.dispatch(); tripPlan.departure();
this.realRunRecordService.recordTrainRealRun(simulation, trainInfo, parkSection.getStation(), this.realRunRecordService.recordTrainRealRun(simulation, trainInfo, parkSection.getStation(),
parkSection, true); parkSection, true);
break; break;

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.stage;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService;
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.*;
@ -34,22 +35,31 @@ public class AtsPlanTrainStageService implements AtsStageService {
private AtsStandService atsStandService; private AtsStandService atsStandService;
@Autowired @Autowired
private OnboardAtpApiService onboardAtpApiService; private OnboardAtpApiService onboardAtpApiService;
@Autowired
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()) { //针对上饶沙盘
trainInfo.finishPlanPrepareInbound(); // trainInfo.finishPlanPrepareInbound();
} // }
} else if (tripPlan.getEndSection().equals(parkSection) || // } else 没看懂为啥有这部分逻辑先注掉
if (tripPlan.getEndSection().equals(parkSection) ||
tripPlan.getEndSection().getStation().equals(parkSection.getStation())) { tripPlan.getEndSection().getStation().equals(parkSection.getStation())) {
// 列车到达计划终点准备回库 // 列车到达计划终点准备回库
if (!parkSection.isTurnBackTrack()) { //针对上饶沙盘 if (simulation.getRepository().getConfig().isHandleDepot()) {
trainInfo.finishPlanPrepareInbound(); trainInfo.finishPlanPrepareEnterDepot();
} else {
if (!parkSection.isTurnBackTrack()) { //针对上饶沙盘
trainInfo.finishPlanPrepareInbound();
}
} }
//转人工车
atsTrainService.setManualTrain(simulation, trainInfo.getGroupNumber());
} else if (tripPlan.getStartSection().equals(parkSection)) { } else if (tripPlan.getStartSection().equals(parkSection)) {
// 出库列车 // 出库列车
if (trainInfo.getPlanStandTrack() != null) { if (trainInfo.getPlanStandTrack() != null) {

View File

@ -39,6 +39,8 @@ public class AtsTrainStageHandler {
public void handleInbound(Simulation simulation, TrainInfo train) { public void handleInbound(Simulation simulation, TrainInfo train) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
int deleteRemain = train.getDeleteRemain(); int deleteRemain = train.getDeleteRemain();
if (deleteRemain < 0) //以该条件作为列车入库是要进入车辆段而不是消失的标记
return;
deleteRemain -= SimulationModule.ATS.getRateMs(); deleteRemain -= SimulationModule.ATS.getRateMs();
if (deleteRemain <= 0) { // 删除列车 if (deleteRemain <= 0) { // 删除列车
repository.deleteOnlineTrain(train.getGroupNumber()); repository.deleteOnlineTrain(train.getGroupNumber());

View File

@ -14,14 +14,18 @@ import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder;
import club.joylink.rtss.simulation.cbtc.command.VoiceCommandBO; import club.joylink.rtss.simulation.cbtc.command.VoiceCommandBO;
import club.joylink.rtss.simulation.cbtc.communication.Joylink3DMessageService; import club.joylink.rtss.simulation.cbtc.communication.Joylink3DMessageService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan; import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.depot.DepotService;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.SimulationRealDeviceConnectManager; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.SimulationRealDeviceConnectManager;
import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop; import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop;
import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService; import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
import club.joylink.rtss.simulation.cbtc.event.*; import club.joylink.rtss.simulation.cbtc.event.SimulationCreateSuccessEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationErrorEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationPauseEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationResetEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationResumeEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationRunPlanReloadEvent;
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.fault.FaultGenerator; import club.joylink.rtss.simulation.cbtc.fault.FaultGenerator;
@ -30,10 +34,6 @@ import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPLogicLoop;
import club.joylink.rtss.simulation.cbtc.onboard.TrainTargetUpdateService; import club.joylink.rtss.simulation.cbtc.onboard.TrainTargetUpdateService;
import club.joylink.rtss.simulation.cbtc.robot.RobotLogicLoop; import club.joylink.rtss.simulation.cbtc.robot.RobotLogicLoop;
import club.joylink.rtss.simulation.rt.iscs.IscsStatusPublisher; import club.joylink.rtss.simulation.rt.iscs.IscsStatusPublisher;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.ibp.IbpData;
import club.joylink.rtss.vo.client.ibp.IbpQueryVO;
import club.joylink.rtss.vo.client.ibp.IbpVO;
import club.joylink.rtss.vo.client.runplan.RunPlanVO; import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO; import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -110,6 +110,9 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
@Autowired @Autowired
private IbpService ibpService; private IbpService ibpService;
@Autowired
private DepotService depotService;
@Override @Override
public Simulation create(SimulationBuildParams params, String group) { public Simulation create(SimulationBuildParams params, String group) {
// 构建仿真 // 构建仿真
@ -122,6 +125,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
simulation.addMessagePublisher(new IscsStatusPublisher(simulation)); simulation.addMessagePublisher(new IscsStatusPublisher(simulation));
// 初始化设备状态 // 初始化设备状态
this.deviceStatusService.init(simulation); this.deviceStatusService.init(simulation);
depotService.loadDepotTrain(simulation);
// 初始化成员 // 初始化成员
this.memberManager.init(simulation); this.memberManager.init(simulation);
// 初始化语音指令 // 初始化语音指令
@ -136,6 +140,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
private void addJobs(Simulation simulation) { private void addJobs(Simulation simulation) {
atsLogicLoop.addJobs(simulation); atsLogicLoop.addJobs(simulation);
atpLogicLoop.addJobs(simulation); atpLogicLoop.addJobs(simulation);
depotService.addJobs(simulation);
trainTargetUpdateService.addJobs(simulation); trainTargetUpdateService.addJobs(simulation);
vrTrainRunningService.addJobs(simulation); vrTrainRunningService.addJobs(simulation);
this.ciLogic.addJobs(simulation); this.ciLogic.addJobs(simulation);
@ -215,6 +220,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
// } // }
// 初始化设备状态 // 初始化设备状态
this.deviceStatusService.init(simulation); this.deviceStatusService.init(simulation);
depotService.loadDepotTrain(simulation);
// Map<String, SimulationMember> oldMemberMap = simulation.getMemberMap(); // Map<String, SimulationMember> oldMemberMap = simulation.getMemberMap();
// Simulation build = SimulationBuilder.build(simulation.getBuildParams()); // Simulation build = SimulationBuilder.build(simulation.getBuildParams());
// simulation.resetFrom(build); // simulation.resetFrom(build);

View File

@ -99,6 +99,7 @@ public class MapDeviceBuilder {
aSwitch.setVirtualSwitch(virtualRealitySwitch); aSwitch.setVirtualSwitch(virtualRealitySwitch);
deviceMap.put(virtualRealitySwitch.getCode(), virtualRealitySwitch); deviceMap.put(virtualRealitySwitch.getCode(), virtualRealitySwitch);
}); });
Map<Station, List<Section>> parkingTracksMap = mapDataBuildResult.getParkingTracksMap();
// 区段关系 // 区段关系
sectionList.forEach(sectionVO -> { sectionList.forEach(sectionVO -> {
Section section = (Section) elementMap.get(sectionVO.getCode()); Section section = (Section) elementMap.get(sectionVO.getCode());
@ -167,6 +168,9 @@ public class MapDeviceBuilder {
}); });
} }
} }
if (section.isParkingTrack()) {
parkingTracksMap.computeIfAbsent(section.getStation(), key -> new ArrayList<>()).add(section);
}
}); });
// 计轴区段下的逻辑区段排序 // 计轴区段下的逻辑区段排序
List<Section> physicalSectionList = elementMap.values().stream() List<Section> physicalSectionList = elementMap.values().stream()
@ -314,13 +318,22 @@ public class MapDeviceBuilder {
}); });
/* ZC和区段相互赋值 */ /* ZC和区段相互赋值 */
// ZC // ZC
if (graphData.getZcList().size() == 1) { if (graphData.getZcList().size() == 1 && CollectionUtils.isEmpty(graphData.getZcList().get(0).getManagedSectionList())) {
//线路的ZC只有一个ZC没有设置关联区段自动关联全线计轴区段
MapZcVO mapZcVO = graphData.getZcList().get(0); MapZcVO mapZcVO = graphData.getZcList().get(0);
ZC zc = (ZC) elementMap.get(mapZcVO.getCode()); ZC zc = (ZC) elementMap.get(mapZcVO.getCode());
physicalSectionList.forEach(section -> { elementMap.values().stream()
zc.addSection(section); .filter(element -> element instanceof Section)
section.addZc(zc); .map(element -> (Section) element)
}); .filter(Section::isAxleCounter)
.forEach(section -> {
zc.addSection(section);
section.addZc(zc);
});
// physicalSectionList.forEach(section -> {
// zc.addSection(section);
// section.addZc(zc);
// });
} else { } else {
graphData.getZcList().forEach(mapZcVO -> { graphData.getZcList().forEach(mapZcVO -> {
if (mapZcVO.isNoService()) if (mapZcVO.isNoService())
@ -334,15 +347,20 @@ public class MapDeviceBuilder {
Section section = (Section) elementMap.get(sectionCode); Section section = (Section) elementMap.get(sectionCode);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(section, BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(section,
String.format("ZC[%s]关联的区段[%s]不存在", zc.getCode(), sectionCode)); String.format("ZC[%s]关联的区段[%s]不存在", zc.getCode(), sectionCode));
if (section.isPhysical()) { Section axleCounterSection = section.findAxleCounterSection();
section.addZc(zc); if (axleCounterSection != null) {
zc.addSection(section); axleCounterSection.addZc(zc);
} else if (section.isSwitchAxleCounterSection() || section.isCross()) { zc.addSection(axleCounterSection);
section.getLogicList().forEach(logic -> {
logic.addZc(zc);
zc.addSection(logic);
});
} }
// if (section.isPhysical()) {
// section.addZc(zc);
// zc.addSection(section);
// } else if (section.isSwitchAxleCounterSection() || section.isCross()) {
// section.getLogicList().forEach(logic -> {
// logic.addZc(zc);
// zc.addSection(logic);
// });
// }
} }
} }
}); });
@ -566,6 +584,9 @@ public class MapDeviceBuilder {
} }
MapTrainModelVO trainModelVO = trainModelMap.get(trainVO.getModelCode()); MapTrainModelVO trainModelVO = trainModelMap.get(trainVO.getModelCode());
virtualRealityTrain.setLen(trainModelVO.getLength()); virtualRealityTrain.setLen(trainModelVO.getLength());
if (!StringUtils.isEmpty(trainVO.getStationCode())) {
virtualRealityTrain.setDepotStation((Station) elementMap.get(trainVO.getStationCode()));
}
deviceMap.put(virtualRealityTrain.getGroupNumber(), virtualRealityTrain); deviceMap.put(virtualRealityTrain.getGroupNumber(), virtualRealityTrain);
}); });
// 方向杆 // 方向杆
@ -1004,6 +1025,7 @@ public class MapDeviceBuilder {
section.setTurnBackTrack(sectionVO.isReentryTrack()); section.setTurnBackTrack(sectionVO.isReentryTrack());
section.setFirstTurnBack(sectionVO.isFirstTurnBack()); section.setFirstTurnBack(sectionVO.isFirstTurnBack());
section.setTransferTrack(sectionVO.isTransferTrack()); section.setTransferTrack(sectionVO.isTransferTrack());
section.setParkingTrack(sectionVO.isParkingTrack());
if (section.isTransferTrack()) { if (section.isTransferTrack()) {
if (section.isStandTrack()) { if (section.isStandTrack()) {
errMsgList.add(String.format("区段[%s(%s)]是转换轨,就不能再设置为站台轨", errMsgList.add(String.format("区段[%s(%s)]是转换轨,就不能再设置为站台轨",
@ -1022,8 +1044,8 @@ public class MapDeviceBuilder {
section.setStopPointLeft(sectionVO.getLeftStopPointOffset()); section.setStopPointLeft(sectionVO.getLeftStopPointOffset());
section.setStopPointRight(sectionVO.getRightStopPointOffset()); section.setStopPointRight(sectionVO.getRightStopPointOffset());
} }
// 转换轨/折返轨构建关联车站,站台轨在后面处理站台逻辑里做了 // 转换轨/折返轨/停车轨构建关联车站,站台轨在后面处理站台逻辑里做了
if (section.isStandTrack() || section.isTransferTrack() || section.isTurnBackTrack()) { if (section.isStandTrack() || section.isTransferTrack() || section.isTurnBackTrack() || section.isParkingTrack()) {
if (!StringUtils.hasText(sectionVO.getBelongStation())) { if (!StringUtils.hasText(sectionVO.getBelongStation())) {
errMsgList.add(String.format("区段[%s(%s)]是站台轨或转换轨或折返轨,却未设置关联车站", errMsgList.add(String.format("区段[%s(%s)]是站台轨或转换轨或折返轨,却未设置关联车站",
sectionVO.getName(), sectionVO.getCode())); sectionVO.getName(), sectionVO.getCode()));

View File

@ -3,6 +3,7 @@ package club.joylink.rtss.simulation.cbtc.build;
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.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan; import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
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.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
@ -72,19 +73,34 @@ public class SchedulingBuilder {
trainList.size(), schedulingPlanList.size())); trainList.size(), schedulingPlanList.size()));
} }
// 分配列车到派班计划 // 分配列车到派班计划
LinkedList<VirtualRealityTrain> trainQueue = new LinkedList<>(trainList); if (simulation.getRepository().getConfig().isHandleDepot()) {
Map<String, VirtualRealityTrain> serverTrainMap = new HashMap<>(); Map<Station, Queue<VirtualRealityTrain>> map = new HashMap<>();
for (int i = 0; i < schedulingPlanList.size(); i++) { for (VirtualRealityTrain train : trainList) {
SchedulingTrainPlan schedulingTrainPlan = schedulingPlanList.get(i); Queue<VirtualRealityTrain> queue = map.computeIfAbsent(train.getDepotStation(), key -> new LinkedList<>());
String serviceNumber = schedulingTrainPlan.getOutDepotTrip().getServiceNumber(); queue.add(train);
VirtualRealityTrain train = serverTrainMap.get(serviceNumber); }
if (Objects.nonNull(train)) { Map<String, VirtualRealityTrain> serverTrainMap = new HashMap<>();
schedulingTrainPlan.setGroupNumber(train.getGroupNumber()); for (SchedulingTrainPlan schedulingTrainPlan : schedulingPlanList) {
} else { String serviceNumber = schedulingTrainPlan.getOutDepotTrip().getServiceNumber();
train = trainQueue.poll(); VirtualRealityTrain train = serverTrainMap.get(serviceNumber);
serverTrainMap.put(serviceNumber, train); if (Objects.isNull(train)) {
train = map.get(schedulingTrainPlan.getOutDepotTrip().getStartSection().getStation()).poll();
serverTrainMap.put(serviceNumber, train);
}
schedulingTrainPlan.setGroupNumber(train.getGroupNumber());
}
} else {
LinkedList<VirtualRealityTrain> trainQueue = new LinkedList<>(trainList);
Map<String, VirtualRealityTrain> serverTrainMap = new HashMap<>();
for (SchedulingTrainPlan schedulingTrainPlan : schedulingPlanList) {
String serviceNumber = schedulingTrainPlan.getOutDepotTrip().getServiceNumber();
VirtualRealityTrain train = serverTrainMap.get(serviceNumber);
if (Objects.isNull(train)) {
train = trainQueue.poll();
serverTrainMap.put(serviceNumber, train);
}
schedulingTrainPlan.setGroupNumber(train.getGroupNumber());
} }
schedulingTrainPlan.setGroupNumber(train.getGroupNumber());
} }
repository.setSchedulingTrainPlanList(schedulingPlanList); repository.setSchedulingTrainPlanList(schedulingPlanList);
return schedulingPlanList; return schedulingPlanList;

View File

@ -1,410 +1,492 @@
package club.joylink.rtss.simulation.cbtc.build; package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.entity.Ibp; import club.joylink.rtss.entity.Ibp;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
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.*;
import club.joylink.rtss.simulation.cbtc.data.plan.TerminalDeparturePlan; import club.joylink.rtss.simulation.cbtc.data.plan.TerminalDeparturePlan;
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.vr.VirtualRealityDevice; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityDevice;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.util.JsonUtils; import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.ibp.IbpData; import club.joylink.rtss.vo.client.ibp.IbpData;
import club.joylink.rtss.vo.client.runplan.RunPlanVO; import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO; import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO; import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
import club.joylink.rtss.vo.map.MapVO; import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.RealLineConfigVO; import club.joylink.rtss.vo.map.RealLineConfigVO;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.*;
import javax.swing.text.Element; import java.util.concurrent.atomic.AtomicInteger;
import java.util.*; import java.util.function.Function;
import java.util.function.Function; import java.util.stream.Collectors;
import java.util.stream.Collectors;
import java.util.stream.Stream; @Slf4j
public class SimulationBuilder {
@Slf4j
public class SimulationBuilder { /**
* 构造仿真对象
/** */
* 构造仿真对象 public static Simulation build(String group, SimulationBuildParams buildParams) {
*/ Simulation simulation = new Simulation(group);
public static Simulation build(String group, SimulationBuildParams buildParams) { simulation.setBuildParams(buildParams);
Simulation simulation = new Simulation(group); if (Objects.nonNull(buildParams.getLoginUserInfo())) {
simulation.setBuildParams(buildParams); simulation.setProject(buildParams.getLoginUserInfo().getProject());
if (Objects.nonNull(buildParams.getLoginUserInfo())) { }
simulation.setProject(buildParams.getLoginUserInfo().getProject()); // 线路配置参数
} simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO()));
// 线路配置参数 simulation.getRepository().getConfig()
simulation.getRepository().setConfig(buildConfig(buildParams.getMap().getConfigVO())); .setRouteLikeHa1(buildParams.getMap().getGraphDataNew().getGenerateConfig().isLikeHa1());
simulation.getRepository().getConfig() simulation.getRepository().getConfig()
.setRouteLikeHa1(buildParams.getMap().getGraphDataNew().getGenerateConfig().isLikeHa1()); .setOverlapSettingByTrigger(buildParams.getMap().getGraphDataNew().getGenerateConfig().isOverlapSettingByTrigger());
simulation.getRepository().getConfig() simulation.getRepository().getConfig()
.setOverlapSettingByTrigger(buildParams.getMap().getGraphDataNew().getGenerateConfig().isOverlapSettingByTrigger()); .setSharingECStations(buildParams.getMap().getGraphDataNew().getGenerateConfig().getSharingECStations());
simulation.getRepository().getConfig() simulation.getRepository().getConfig()
.setSharingECStations(buildParams.getMap().getGraphDataNew().getGenerateConfig().getSharingECStations()); .setHandleDepot(buildParams.getMap().getGraphDataNew().getGenerateConfig().isHandleDepot());
// 地图数据构建 // 地图数据构建
SimulationDeviceBuildResult mapDataBuildResult = checkAndBuildMapData(buildParams.getMap()); SimulationDeviceBuildResult mapDataBuildResult = checkAndBuildMapData(buildParams.getMap());
// ibp数据构建 // ibp数据构建
buildIbpData(mapDataBuildResult, buildParams.getMap().getIbpList()); buildIbpData(mapDataBuildResult, buildParams.getMap().getIbpList());
simulation.getRepository().setDeviceMap(mapDataBuildResult.getDeviceMap()); simulation.getRepository().setDeviceMap(mapDataBuildResult.getDeviceMap());
simulation.getRepository().setSectionArriveNearMap(mapDataBuildResult.sectionArriveNearMap); simulation.getRepository().setSectionArriveNearMap(mapDataBuildResult.sectionArriveNearMap);
simulation.getRepository().setVrDeviceMap(mapDataBuildResult.getVrDeviceMap()); simulation.getRepository().setVrDeviceMap(mapDataBuildResult.getVrDeviceMap());
// simulation.getRepository().setRouteUnitMap(mapDataBuildResult.getRouteUnitMap()); // simulation.getRepository().setRouteUnitMap(mapDataBuildResult.getRouteUnitMap());
simulation.getRepository().setRoutePathMap(mapDataBuildResult.getRoutePathMap()); simulation.getRepository().setRoutePathMap(mapDataBuildResult.getRoutePathMap());
simulation.getRepository().setDestinationMap(mapDataBuildResult.getDestinationMap()); simulation.getRepository().setDestinationMap(mapDataBuildResult.getDestinationMap());
simulation.getRepository().setRoutingList(mapDataBuildResult.getRoutingList()); simulation.getRepository().setRoutingList(mapDataBuildResult.getRoutingList());
// simulation.getRepository().setRunLevelList(mapDataBuildResult.getRunLevelList()); // simulation.getRepository().setRunLevelList(mapDataBuildResult.getRunLevelList());
simulation.getRepository().getCatenaryMap().putAll(mapDataBuildResult.getCatenaryMap()); simulation.getRepository().getCatenaryMap().putAll(mapDataBuildResult.getCatenaryMap());
simulation.getRepository().getSectionRespondersMap().putAll(mapDataBuildResult.getSectionRespondersMap()); simulation.getRepository().getSectionRespondersMap().putAll(mapDataBuildResult.getSectionRespondersMap());
// simulation.getRepository().setParkTimeMap(mapDataBuildResult.getParkTimeMap()); simulation.getRepository().setParkingTracksMap(mapDataBuildResult.getParkingTracksMap());
UserConfigDataBuilder.buildRunLevel(simulation.getRepository(), buildParams.getUserRunLevelList(), // simulation.getRepository().setParkTimeMap(mapDataBuildResult.getParkTimeMap());
buildParams.getMap(), mapDataBuildResult.getErrMsgList()); UserConfigDataBuilder.buildRunLevel(simulation.getRepository(), buildParams.getUserRunLevelList(),
UserConfigDataBuilder.buildParkTime(simulation.getRepository(), buildParams.getUserParkTimeList(), buildParams.getMap(), mapDataBuildResult.getErrMsgList());
buildParams.getMap(), mapDataBuildResult.getErrMsgList()); UserConfigDataBuilder.buildParkTime(simulation.getRepository(), buildParams.getUserParkTimeList(),
if (!CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 存在数据异常 buildParams.getMap(), mapDataBuildResult.getErrMsgList());
mapDataBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("地图数据异常:%s", errMsg))); if (!CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 存在数据异常
simulation.setMapDataError(true); mapDataBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("地图数据异常:%s", errMsg)));
simulation.addDataErrMsgs(mapDataBuildResult.getErrMsgList()); simulation.setMapDataError(true);
} simulation.addDataErrMsgs(mapDataBuildResult.getErrMsgList());
// 加载运行图 }
checkAndLoadRunPlan(simulation, buildParams.getRunPlan()); // 加载运行图
// 加载派班计划 checkAndLoadRunPlan(simulation, buildParams.getRunPlan());
checkAndLoadSchedulingPlan(simulation, buildParams.getSchedulingPlan()); // 加载派班计划
return simulation; checkAndLoadSchedulingPlan(simulation, buildParams.getSchedulingPlan());
} // 加载车辆段route path
loadDepotInOutRoutePath(simulation);
private static void buildIbpData(SimulationDeviceBuildResult mapDataBuildResult, List<Ibp> ibpList) { return simulation;
if (CollectionUtils.isEmpty(ibpList)) }
return;
Map<String, MapElement> deviceMap = mapDataBuildResult.getDeviceMap(); /**
Map<String, VirtualRealityDevice> vrDeviceMap = mapDataBuildResult.getVrDeviceMap(); * 加载进出depot的route path
Map<String, Ibp> ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity())); */
List<Station> collect = deviceMap.values().stream() private static void loadDepotInOutRoutePath(Simulation simulation) {
.filter(element -> MapElement.DeviceType.STATION.equals(element.getDeviceType())) // 仿真车辆段站台停车轨列表
.map(element -> (Station) element).collect(Collectors.toList()); Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
collect.forEach(station -> { if (CollectionUtils.isEmpty(parkingTracksMap)) {
//构建添加IBP return;
Ibp ibp = ibpMap.get(station.getCode()); }
if (ibp == null) final Map<String, List<RoutePath>> srps = simulation.getRepository().getRoutePathMap();
ibp = ibpMap.get(null); parkingTracksMap.forEach((station, secs) -> {
if (ibp != null) { if (station.isDepot()) {// 车站为车辆段
IbpData ibpData = JsonUtils.read(ibp.getData(), IbpData.class); List<Section> transferList = station.getTransferList();// 转换轨列表
VirtualRealityIbp vrIbp = new VirtualRealityIbp(station.getCode() + "_IBP", station.getName() + "_IBP", ibpData, station); if (!CollectionUtils.isEmpty(transferList)) {
station.setVrIbp(vrIbp); transferList.forEach(transSec -> {
deviceMap.put(vrIbp.getCode(), vrIbp); // 停车轨到转换轨
vrDeviceMap.put(vrIbp.getCode(), vrIbp); secs.forEach(parkSec -> {
} final String rpKey = RoutePath.buildKey(parkSec, transSec);
}); List<RoutePath> nrp = tryFindRoutePathForOutByDirection(parkSec, transSec, 20);
} List<RoutePath> srp = srps.get(rpKey);
if (null == srp) {
private static boolean isOverlapSettingByTrigger(Map<String, MapElement> deviceMap) { srp = new ArrayList<RoutePath>();
for (MapElement mapElement : deviceMap.values()) { srps.put(rpKey, srp);
if (mapElement.getDeviceType().equals(MapElement.DeviceType.OVERLAP)) { }
if (!CollectionUtils.isEmpty(((RouteOverlap) mapElement).getTriggerPathList())) { if (!CollectionUtils.isEmpty(nrp)) {
return true; srp.addAll(nrp);
} else { }
return false; });
} // 转换轨到停车轨
} secs.forEach(parkSec -> {
} final String rpKey = RoutePath.buildKey(transSec, parkSec);
return false; List<RoutePath> nrp = tryFindRoutePathByDirection(transSec, parkSec, 20);
} List<RoutePath> srp = srps.get(rpKey);
if (null == srp) {
/** srp = new ArrayList<RoutePath>();
* 检查并加载派班计划 srps.put(rpKey, srp);
* @param simulation }
* @param schedulingPlan if (!CollectionUtils.isEmpty(nrp)) {
*/ srp.addAll(nrp);
public static void checkAndLoadSchedulingPlan(Simulation simulation, SchedulingPlanNewVO schedulingPlan) { }
if (simulation.isMapDataError() || simulation.isPlanDataError()) { });
return; });
} } else {
if (Objects.isNull(schedulingPlan)) { log.info("仿真数据有问题,车辆段[{}]没有转换轨", station.getName());
// 如果没有加载计划生成默认的加载计划 }
if (!simulation.isMapDataError() && simulation.isPlanLoaded() && !simulation.isPlanDataError()) { // 地图数据和运行计划加载成功的情况下 }
log.info(String.format("地图[%s(%s)]没有派班计划,生成默认派班计划使用", });
simulation.getBuildParams().getMap().getName(), }
simulation.getBuildParams().getMap().getId()));
SchedulingBuilder.generateSchedulingPlan(simulation); /**
} * 当方向未知时起点终点不变不同方向搜索route path
} else { */
SchedulingBuilder.loadSchedulingPlan(simulation, schedulingPlan); private static List<RoutePath> tryFindRoutePathForOutByDirection(Section start, Section end, int iterTimes) {
} List<RoutePath> r = tryFindRoutePathByDirection(start, end, iterTimes);
} if (r.size() == 2) {
return r.stream().sorted((RoutePath r1, RoutePath r2) -> {
/** return r1.getSignalList().size() - r2.getSignalList().size();
* 检查并加载运行计划 }).findFirst().stream().collect(Collectors.toList());
* @param simulation
* @param runPlan } else if (r.size() > 2) {
* @return log.warn("获取车辆段从停车轨到转换轨的路径, routeKey = {} , 路径数量大于2异常 ");
*/ }
public static void checkAndLoadRunPlan(Simulation simulation, RunPlanVO runPlan) { return r;
if (simulation.isMapDataError()) { }
// 地图逻辑数据有问题不加载
log.info(String.format("仿真地图[%s(%s)]数据有问题,不执行运行计划加载", /**
simulation.getBuildParams().getMap().getName(), * 当方向未知时起点终点不变不同方向搜索route path
simulation.getBuildParams().getMap().getId())); */
return; private static List<RoutePath> tryFindRoutePathByDirection(Section start, Section end, int iterTimes) {
} List<RoutePath> r = CalculateService.queryRoutePathsOnDirection(start, end, true, iterTimes);
if (Objects.nonNull(runPlan)) { if (!CollectionUtils.isEmpty(r)) {
RunPlanBuilder.RunPlanBuildResult runPlanBuildResult = return r;
RunPlanBuilder.buildRunDiagram(simulation.getRepository().getDeviceMap(), runPlan); } else {
simulation.setPlanLoaded(true); return CalculateService.queryRoutePathsOnDirection(start, end, false, iterTimes);
if (!CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常 }
runPlanBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("运行图数据异常:%s", errMsg))); }
simulation.setPlanDataError(true); private static void buildIbpData(SimulationDeviceBuildResult mapDataBuildResult, List<Ibp> ibpList) {
simulation.addDataErrMsgs(runPlanBuildResult.getErrMsgList()); if (CollectionUtils.isEmpty(ibpList))
} else { return;
simulation.getRepository().setServiceTripsMap(runPlanBuildResult.getServerTripMap()); Map<String, MapElement> deviceMap = mapDataBuildResult.getDeviceMap();
simulation.getRepository().setStandTripMap(runPlanBuildResult.getStandTripMap()); Map<String, VirtualRealityDevice> vrDeviceMap = mapDataBuildResult.getVrDeviceMap();
simulation.getRepository().setEndTripMap(runPlanBuildResult.getEndTripMap()); Map<String, Ibp> ibpMap = ibpList.stream().collect(Collectors.toMap(Ibp::getStationCode, Function.identity()));
// 校验运行计划和路径单元 List<Station> collect = deviceMap.values().stream()
List<String> errMsgList = checkRunPlanAndBuildLostRoutePaths(runPlanBuildResult.getServerTripMap(), .filter(element -> MapElement.DeviceType.STATION.equals(element.getDeviceType()))
simulation.getRepository().getRoutePathMap()); .map(element -> (Station) element).collect(Collectors.toList());
if (!errMsgList.isEmpty()) { collect.forEach(station -> {
simulation.setMapDataError(true); //构建添加IBP
simulation.addDataErrMsgs(errMsgList); Ibp ibp = ibpMap.get(station.getCode());
} if (ibp == null)
// // 构建终端发车计划 ibp = ibpMap.get(null);
// TerminalPlanBuildResult terminalPlanBuildResult = buildTerminalPlan(simulation.getRepository(), runPlanBuildResult.getServerTripMap()); if (ibp != null) {
// if (!CollectionUtils.isEmpty(terminalPlanBuildResult.getErrMsgList())) { IbpData ibpData = JsonUtils.read(ibp.getData(), IbpData.class);
// simulation.setMapDataError(true); VirtualRealityIbp vrIbp = new VirtualRealityIbp(station.getCode() + "_IBP", station.getName() + "_IBP", ibpData, station);
// simulation.addDataErrMsgs(terminalPlanBuildResult.getErrMsgList()); station.setVrIbp(vrIbp);
// } else { deviceMap.put(vrIbp.getCode(), vrIbp);
// simulation.getRepository().setTerminalDeparturePlanMap(terminalPlanBuildResult.getTerminalPlanMap()); vrDeviceMap.put(vrIbp.getCode(), vrIbp);
// } }
} });
} else { }
simulation.addDataErrMsg("运行图为空");
} private static boolean isOverlapSettingByTrigger(Map<String, MapElement> deviceMap) {
} for (MapElement mapElement : deviceMap.values()) {
if (mapElement.getDeviceType().equals(MapElement.DeviceType.OVERLAP)) {
public static List<String> checkRunPlanAndBuildLostRoutePaths(Map<String, List<TripPlan>> serverTripMap, if (!CollectionUtils.isEmpty(((RouteOverlap) mapElement).getTriggerPathList())) {
Map<String, List<RoutePath>> routePathMap) { return true;
Map<String, String> errMsgMap = new HashMap<>(); } else {
for (List<TripPlan> tripPlanList : serverTripMap.values()) { return false;
for (TripPlan tripPlan : tripPlanList) { }
List<Section> allViaSectionList = tripPlan.getAllViaStoppedSectionList(); }
for (int i = 1; i < allViaSectionList.size(); i++) { }
Section start = allViaSectionList.get(i - 1); return false;
Section end = allViaSectionList.get(i); }
String key = RoutePath.buildKey(start, end);
if (!routePathMap.containsKey(key)) { /**
// 路径不存在尝试构建 * 检查并加载派班计划
List<RoutePath> routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight(), 10); * @param simulation
if (CollectionUtils.isEmpty(routePaths)) { * @param schedulingPlan
// 计划方向路径未找到反向尝试 */
routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight(), 10); public static void checkAndLoadSchedulingPlan(Simulation simulation, SchedulingPlanNewVO schedulingPlan) {
} if (simulation.isMapDataError() || simulation.isPlanDataError()) {
if (CollectionUtils.isEmpty(routePaths)) { return;
// 依然未找到 }
errMsgMap.put(key, String.format("从[%s]->[%s]无法到达,请检查运行图和联锁数据是否正确", if (Objects.isNull(schedulingPlan)) {
start.debugStr(), end.debugStr())); // 如果没有加载计划生成默认的加载计划
} else { if (!simulation.isMapDataError() && simulation.isPlanLoaded() && !simulation.isPlanDataError()) { // 地图数据和运行计划加载成功的情况下
// 找到保存 log.info(String.format("地图[%s(%s)]没有派班计划,生成默认派班计划使用",
log.info(String.format("运行图从[%s]->[%s]没有站间运行数据,根据路径查询找到并生成默认的路径单元", simulation.getBuildParams().getMap().getName(),
start.debugStr(), end.debugStr())); simulation.getBuildParams().getMap().getId()));
for (RoutePath routePath : routePaths) { SchedulingBuilder.generateSchedulingPlan(simulation);
routePath.calculateDistance(); }
} } else {
routePathMap.put(key, routePaths); SchedulingBuilder.loadSchedulingPlan(simulation, schedulingPlan);
} }
} }
}
} /**
} * 检查并加载运行计划
return new ArrayList<>(errMsgMap.values()); * @param simulation
} * @param runPlan
* @return
// private static List<String> checkRunPlanAndBuildLostRouteUnit(Map<String, List<TripPlan>> serverTripMap, */
// Map<String, RouteUnit> routeUnitMap) { public static void checkAndLoadRunPlan(Simulation simulation, RunPlanVO runPlan) {
// Map<String, String> errMsgMap = new HashMap<>(); if (simulation.isMapDataError()) {
// for (List<TripPlan> tripPlanList : serverTripMap.values()) { // 地图逻辑数据有问题不加载
// for (TripPlan tripPlan : tripPlanList) { log.info(String.format("仿真地图[%s(%s)]数据有问题,不执行运行计划加载",
// List<Section> allViaSectionList = tripPlan.getAllViaSectionList(); simulation.getBuildParams().getMap().getName(),
// for (int i = 1; i < allViaSectionList.size(); i++) { simulation.getBuildParams().getMap().getId()));
// Section start = allViaSectionList.get(i - 1); return;
// Section end = allViaSectionList.get(i); }
// String key = RouteUnit.buildKey(start, end); if (Objects.nonNull(runPlan)) {
// if (!routeUnitMap.containsKey(key)) { RunPlanBuilder.RunPlanBuildResult runPlanBuildResult =
// // 尝试构建 RunPlanBuilder.buildRunDiagram(simulation.getRepository().getDeviceMap(), runPlan);
// List<String> errList = new ArrayList<>(); simulation.setPlanLoaded(true);
// RouteUnit routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, tripPlan.isRight(), errList); if (!CollectionUtils.isEmpty(runPlanBuildResult.getErrMsgList())) { // 数据异常
// if (Objects.isNull(routeUnit)) { runPlanBuildResult.getErrMsgList().forEach(errMsg -> log.warn(String.format("运行图数据异常:%s", errMsg)));
// // 反向再尝试 simulation.setPlanDataError(true);
// routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, !tripPlan.isRight(), errList); simulation.addDataErrMsgs(runPlanBuildResult.getErrMsgList());
// } } else {
// if (Objects.nonNull(routeUnit)) { simulation.getRepository().setServiceTripsMap(runPlanBuildResult.getServerTripMap());
// log.warn(String.format("运行图从[%s(%s)]到[%s(%s)]没有站间运行数据,根据路径查询找到并生成默认的路径单元", simulation.getRepository().setStandTripMap(runPlanBuildResult.getStandTripMap());
// start.getName(), start.getCode(), end.getName(), end.getCode())); simulation.getRepository().setEndTripMap(runPlanBuildResult.getEndTripMap());
// routeUnitMap.put(key, routeUnit); // 校验运行计划和路径单元
// } else { List<String> errMsgList = checkRunPlanAndBuildLostRoutePaths(runPlanBuildResult.getServerTripMap(),
// errMsgMap.put(key, String.format("从[%s(%s)]到[%s(%s)]无法到达,请检查运行图和联锁数据是否正确", simulation.getRepository().getRoutePathMap());
// start.getName(), start.getCode(), end.getName(), end.getCode())); if (!errMsgList.isEmpty()) {
// } simulation.setMapDataError(true);
// } simulation.addDataErrMsgs(errMsgList);
// } }
// } // // 构建终端发车计划
// } // TerminalPlanBuildResult terminalPlanBuildResult = buildTerminalPlan(simulation.getRepository(), runPlanBuildResult.getServerTripMap());
// return new ArrayList<>(errMsgMap.values()); // if (!CollectionUtils.isEmpty(terminalPlanBuildResult.getErrMsgList())) {
// } // simulation.setMapDataError(true);
// simulation.addDataErrMsgs(terminalPlanBuildResult.getErrMsgList());
private static TerminalPlanBuildResult buildTerminalPlan(SimulationDataRepository repository, Map<String, List<TripPlan>> serverTripMap) { // } else {
TerminalPlanBuildResult result = new TerminalPlanBuildResult(); // simulation.getRepository().setTerminalDeparturePlanMap(terminalPlanBuildResult.getTerminalPlanMap());
List<String> errMsgList = result.getErrMsgList(); // }
Map<String, TerminalDeparturePlan> terminalPlanMap = result.getTerminalPlanMap(); }
serverTripMap.values().forEach(tripPlanList -> } else {
tripPlanList.forEach(tripPlan -> { simulation.addDataErrMsg("运行图为空");
Section startSection = tripPlan.getStartSection(); }
TerminalDeparturePlan terminalPlan = terminalPlanMap.get(startSection.getCode()); }
if (Objects.isNull(terminalPlan)) {
terminalPlan = new TerminalDeparturePlan(startSection.getCode()); public static List<String> checkRunPlanAndBuildLostRoutePaths(Map<String, List<TripPlan>> serverTripMap,
terminalPlanMap.put(startSection.getCode(), terminalPlan); Map<String, List<RoutePath>> routePathMap) {
} Map<String, String> errMsgMap = new HashMap<>();
terminalPlan.addTripPlan(tripPlan); for (List<TripPlan> tripPlanList : serverTripMap.values()) {
})); for (TripPlan tripPlan : tripPlanList) {
terminalPlanMap.values().forEach(terminalDeparturePlan -> List<Section> allViaSectionList = tripPlan.getAllViaStoppedSectionList();
terminalDeparturePlan.getPlanList().sort((plan1, plan2) -> { for (int i = 1; i < allViaSectionList.size(); i++) {
return plan1.getStartTime().compareTo(plan2.getStartTime()); Section start = allViaSectionList.get(i - 1);
})); Section end = allViaSectionList.get(i);
return result; String key = RoutePath.buildKey(start, end);
} if (!routePathMap.containsKey(key)) {
// 路径不存在尝试构建
public static MapConfig buildConfig(RealLineConfigVO configVO) { List<RoutePath> routePaths = CalculateService.queryRoutePathsOnDirection(start, end, tripPlan.isRight(), 10);
MapConfig mapConfig = new MapConfig(); if (CollectionUtils.isEmpty(routePaths)) {
if (Objects.nonNull(configVO)) { // 计划方向路径未找到反向尝试
mapConfig.copyConfigBy(configVO); routePaths = CalculateService.queryRoutePathsOnDirection(start, end, !tripPlan.isRight(), 10);
} }
return mapConfig; if (CollectionUtils.isEmpty(routePaths)) {
} // 依然未找到
errMsgMap.put(key, String.format("从[%s]->[%s]无法到达,请检查运行图和联锁数据是否正确",
/** start.debugStr(), end.debugStr()));
* 地图基础数据检查和构建 } else {
* @param map // 找到保存
* @return log.info(String.format("运行图从[%s]->[%s]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
*/ start.debugStr(), end.debugStr()));
public static SimulationDeviceBuildResult checkAndBuildBasicMapData(MapVO map) { for (RoutePath routePath : routePaths) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult(); routePath.calculateDistance();
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult); }
return mapDataBuildResult; routePathMap.put(key, routePaths);
} }
}
/** }
* 地图数据逻辑检查和构建 }
* }
* @param map return new ArrayList<>(errMsgMap.values());
* @return }
*/
public static SimulationDeviceBuildResult checkAndBuildMapData(MapVO map) { // private static List<String> checkRunPlanAndBuildLostRouteUnit(Map<String, List<TripPlan>> serverTripMap,
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult(); // Map<String, RouteUnit> routeUnitMap) {
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult); // Map<String, String> errMsgMap = new HashMap<>();
if (CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 基础数据没有问题再构建逻辑数据 // for (List<TripPlan> tripPlanList : serverTripMap.values()) {
// InterlockBuilder.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult); // for (TripPlan tripPlan : tripPlanList) {
InterlockBuilder2.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult); // List<Section> allViaSectionList = tripPlan.getAllViaSectionList();
List<MapStationParkingTimeVO> parkingTimeList = map.getLogicDataNew().getParkingTimeList(); // for (int i = 1; i < allViaSectionList.size(); i++) {
if (CollectionUtils.isEmpty(parkingTimeList)) { // Section start = allViaSectionList.get(i - 1);
mapDataBuildResult.errMsgList.add("无停站时间数据"); // Section end = allViaSectionList.get(i);
} // String key = RouteUnit.buildKey(start, end);
} // if (!routeUnitMap.containsKey(key)) {
return mapDataBuildResult; // // 尝试构建
} // List<String> errList = new ArrayList<>();
// RouteUnit routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, tripPlan.isRight(), errList);
public static SimulationDeviceBuildResult checkAndBuildMapDeviceData(MapVO map) { // if (Objects.isNull(routeUnit)) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult(); // // 反向再尝试
MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult); // routeUnit = InterlockBuilder2.findAndBuildRouteUnit(start, end, !tripPlan.isRight(), errList);
return mapDataBuildResult; // }
} // if (Objects.nonNull(routeUnit)) {
// log.warn(String.format("运行图从[%s(%s)]到[%s(%s)]没有站间运行数据,根据路径查询找到并生成默认的路径单元",
@Getter // start.getName(), start.getCode(), end.getName(), end.getCode()));
public static class TerminalPlanBuildResult { // routeUnitMap.put(key, routeUnit);
private Map<String, TerminalDeparturePlan> terminalPlanMap; // } else {
// errMsgMap.put(key, String.format("从[%s(%s)]到[%s(%s)]无法到达,请检查运行图和联锁数据是否正确",
private List<String> errMsgList; // start.getName(), start.getCode(), end.getName(), end.getCode()));
// }
public TerminalPlanBuildResult() { // }
this.terminalPlanMap = new HashMap<>(); // }
this.errMsgList = new ArrayList<>(); // }
} // }
} // return new ArrayList<>(errMsgMap.values());
// }
/**
* 地图数据构建结果 private static TerminalPlanBuildResult buildTerminalPlan(SimulationDataRepository repository, Map<String, List<TripPlan>> serverTripMap) {
*/ TerminalPlanBuildResult result = new TerminalPlanBuildResult();
@Getter List<String> errMsgList = result.getErrMsgList();
public static class SimulationDeviceBuildResult { Map<String, TerminalDeparturePlan> terminalPlanMap = result.getTerminalPlanMap();
/** serverTripMap.values().forEach(tripPlanList ->
* 地图设备map tripPlanList.forEach(tripPlan -> {
* key-设备code Section startSection = tripPlan.getStartSection();
* val-设备对象 TerminalDeparturePlan terminalPlan = terminalPlanMap.get(startSection.getCode());
*/ if (Objects.isNull(terminalPlan)) {
private Map<String, MapElement> deviceMap; terminalPlan = new TerminalDeparturePlan(startSection.getCode());
terminalPlanMap.put(startSection.getCode(), terminalPlan);
/** }
* 虚拟真实设备map terminalPlan.addTripPlan(tripPlan);
* key-设备code }));
* val-虚拟真实设备对象 terminalPlanMap.values().forEach(terminalDeparturePlan ->
*/ terminalDeparturePlan.getPlanList().sort((plan1, plan2) -> {
private Map<String, VirtualRealityDevice> vrDeviceMap; return plan1.getStartTime().compareTo(plan2.getStartTime());
}));
/** return result;
* 目的地码定义map }
* key-目的地码code
*/ public static MapConfig buildConfig(RealLineConfigVO configVO) {
private Map<String, DestinationCodeDefinition> destinationMap = new HashMap<>(); MapConfig mapConfig = new MapConfig();
if (Objects.nonNull(configVO)) {
/** mapConfig.copyConfigBy(configVO);
* 交路列表 }
*/ return mapConfig;
@Setter }
private List<Routing> routingList;
/**
/** * 地图基础数据检查和构建
* 站间运行等级列表 * @param map
*/ * @return
@Setter */
private List<StationRunLevel> runLevelList; public static SimulationDeviceBuildResult checkAndBuildBasicMapData(MapVO map) {
SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
// /** MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
// * 路径单元map return mapDataBuildResult;
// */ }
// private Map<String, RouteUnit> routeUnitMap;
/**
/** * 地图数据逻辑检查和构建
* 路径map *
*/ * @param map
private Map<String, List<RoutePath>> routePathMap; * @return
*/
/** public static SimulationDeviceBuildResult checkAndBuildMapData(MapVO map) {
* 接触网map SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
* key-sectionCode MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
*/ if (CollectionUtils.isEmpty(mapDataBuildResult.getErrMsgList())) { // 基础数据没有问题再构建逻辑数据
private Map<String, Set<Catenary>> catenaryMap = new HashMap<>(); // InterlockBuilder.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
InterlockBuilder2.checkAndBuildMapCILogicData(map.getLogicDataNew(), mapDataBuildResult);
private Map<Section,List<Responder>> sectionRespondersMap; List<MapStationParkingTimeVO> parkingTimeList = map.getLogicDataNew().getParkingTimeList();
if (CollectionUtils.isEmpty(parkingTimeList)) {
/** 默认停站时间map */ mapDataBuildResult.errMsgList.add("无停站时间数据");
private Map<String, StationParkTime> parkTimeMap = new HashMap<>(); }
}
@Setter return mapDataBuildResult;
Map<String, Set<Section>> sectionArriveNearMap; }
/**
* 数据错误信息列表 public static SimulationDeviceBuildResult checkAndBuildMapDeviceData(MapVO map) {
*/ SimulationDeviceBuildResult mapDataBuildResult = new SimulationDeviceBuildResult();
private List<String> errMsgList; MapDeviceBuilder.checkAndBuildMapDeviceData(map.getGraphDataNew(), mapDataBuildResult);
return mapDataBuildResult;
public SimulationDeviceBuildResult() { }
this.deviceMap = new HashMap<>();
this.vrDeviceMap = new HashMap<>(); @Getter
// this.routeUnitMap = new HashMap<>(); public static class TerminalPlanBuildResult {
this.routePathMap = new HashMap<>(); private Map<String, TerminalDeparturePlan> terminalPlanMap;
this.sectionRespondersMap = new HashMap<>();
this.errMsgList = new ArrayList<>(); private List<String> errMsgList;
}
} public TerminalPlanBuildResult() {
} this.terminalPlanMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
/**
* 地图数据构建结果
*/
@Getter
public static class SimulationDeviceBuildResult {
/**
* 地图设备map
* key-设备code
* val-设备对象
*/
private Map<String, MapElement> deviceMap;
/**
* 虚拟真实设备map
* key-设备code
* val-虚拟真实设备对象
*/
private Map<String, VirtualRealityDevice> vrDeviceMap;
/**
* 目的地码定义map
* key-目的地码code
*/
private Map<String, DestinationCodeDefinition> destinationMap = new HashMap<>();
/**
* 交路列表
*/
@Setter
private List<Routing> routingList;
/**
* 站间运行等级列表
*/
@Setter
private List<StationRunLevel> runLevelList;
// /**
// * 路径单元map
// */
// private Map<String, RouteUnit> routeUnitMap;
/**
* 路径map
*/
private Map<String, List<RoutePath>> routePathMap;
/**
* 接触网map
* key-sectionCode
*/
private Map<String, Set<Catenary>> catenaryMap = new HashMap<>();
private Map<Section,List<Responder>> sectionRespondersMap;
/** 默认停站时间map */
private Map<String, StationParkTime> parkTimeMap = new HashMap<>();
@Setter
Map<String, Set<Section>> sectionArriveNearMap;
Map<Station, List<Section>> parkingTracksMap = new HashMap<>();
/**
* 数据错误信息列表
*/
private List<String> errMsgList;
public SimulationDeviceBuildResult() {
this.deviceMap = new HashMap<>();
this.vrDeviceMap = new HashMap<>();
// this.routeUnitMap = new HashMap<>();
this.routePathMap = new HashMap<>();
this.sectionRespondersMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}
}

View File

@ -105,6 +105,9 @@ public interface SimulationConstants {
*/ */
int ROUTE_SETTING_TIMEOUT = 20; int ROUTE_SETTING_TIMEOUT = 20;
/** 停车场/车辆段循环逻辑频率单位ms */
int DEPOT_LOOP_RATE = 1000;
/** /**
* 获取仿真运行计划日期运营日 * 获取仿真运行计划日期运营日
* @return * @return

View File

@ -43,6 +43,8 @@ public enum SimulationModule {
DRIVE_POSITION(SimulationConstants.TRAIN_DRIVE_POSITION_SYNC_RATE), DRIVE_POSITION(SimulationConstants.TRAIN_DRIVE_POSITION_SYNC_RATE),
/** 剧本演出模块 */ /** 剧本演出模块 */
SCRIPT(SimulationConstants.SCRIPT_LOOP_RATE), SCRIPT(SimulationConstants.SCRIPT_LOOP_RATE),
/** 停车场/车辆段模块 */
DEPOT(SimulationConstants.DEPOT_LOOP_RATE),
/** 故障模块 */ /** 故障模块 */
FAULT(SimulationConstants.FAULT_GENERATE_RATE), FAULT(SimulationConstants.FAULT_GENERATE_RATE),

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.data;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm; import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.communication.vo.TrainHmiDisplay; import club.joylink.rtss.simulation.cbtc.communication.vo.TrainHmiDisplay;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.RealRun; import club.joylink.rtss.simulation.cbtc.data.plan.RealRun;
@ -221,6 +222,15 @@ public class SimulationDataRepository {
*/ */
private List<RunPlanTripVO> changeTrips = new CopyOnWriteArrayList<>(); private List<RunPlanTripVO> changeTrips = new CopyOnWriteArrayList<>();
/**
* 车辆段/停车场 停车轨
*/
private Map<Station, List<Section>> parkingTracksMap = new HashMap<>();
private List<SchedulingTrainPlan> outboundPlanList = new ArrayList<>();
private List<SchedulingTrainPlan> inboundPlanList = new ArrayList<>();
/** /**
* 间隔时间/s * 间隔时间/s
*/ */
@ -581,12 +591,13 @@ public class SimulationDataRepository {
return this.serviceTripsMap.get(serviceNumber); return this.serviceTripsMap.get(serviceNumber);
} }
public VirtualRealityTrain getTrain(String serviceNumber, String tripNumber) { public VirtualRealityTrain getTrain(Simulation simulation, String serviceNumber, String tripNumber) {
VirtualRealityTrain train = this.queryTrain(serviceNumber, tripNumber); VirtualRealityTrain train = this.queryTrain(serviceNumber, tripNumber);
if (Objects.isNull(train)) { if (Objects.isNull(train)) {
throw new SimulationException(SimulationExceptionType.System_Fault, throw new SimulationException(SimulationExceptionType.System_Fault,
String.format("服务车次[%s|%s]找不到派班的列车", serviceNumber, tripNumber)); String.format("服务车次[%s|%s]找不到派班的列车", serviceNumber, tripNumber));
} else if (this.usedTrainMap.containsKey(train.getGroupNumber())) { } else if (!simulation.getRepository().getConfig().isHandleDepot()
&& this.usedTrainMap.containsKey(train.getGroupNumber())) {
throw new SimulationException(SimulationExceptionType.System_Fault, throw new SimulationException(SimulationExceptionType.System_Fault,
String.format("列车[%s]已经被使用", train.getGroupNumber())); String.format("列车[%s]已经被使用", train.getGroupNumber()));
} }

View File

@ -216,6 +216,9 @@ public class MapConfig {
/** 进路默认开启冲突检测 */ /** 进路默认开启冲突检测 */
private boolean routeDefaultCheckConflict; private boolean routeDefaultCheckConflict;
/** 处理停车场/车辆段逻辑 */
private boolean handleDepot;
/** 运行图中车次号是否唯一 */ /** 运行图中车次号是否唯一 */
private boolean tripNumberIsUnique; private boolean tripNumberIsUnique;

View File

@ -12,10 +12,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/** /**
* 区段 * 区段
@ -142,6 +139,11 @@ public class Section extends DelayUnlockDevice {
*/ */
private boolean transferTrack; private boolean transferTrack;
/**
* 是否停车轨
*/
private boolean parkingTrack;
/** /**
* 目的地码 * 目的地码
*/ */
@ -160,7 +162,7 @@ public class Section extends DelayUnlockDevice {
/** /**
* 所属zc * 所属zc
*/ */
private List<ZC> zcs = new ArrayList<>(); private Set<ZC> zcs = new HashSet<>();
// ------------------状态属性--------------------- // ------------------状态属性---------------------
@ -1143,10 +1145,15 @@ public class Section extends DelayUnlockDevice {
* 任意一个zc正常工作 * 任意一个zc正常工作
*/ */
public boolean anyZcWorking() { public boolean anyZcWorking() {
if (!CollectionUtils.isEmpty(zcs)) { Section axleCounterSection = this.findAxleCounterSection();
return zcs.stream().anyMatch(zc -> !zc.isFault()); if (axleCounterSection != null && !CollectionUtils.isEmpty(axleCounterSection.getZcs())) {
return axleCounterSection.getZcs().stream().anyMatch(zc -> !zc.isFault());
} }
return false; return false;
// if (!CollectionUtils.isEmpty(zcs)) {
// return zcs.stream().anyMatch(zc -> !zc.isFault());
// }
// return false;
} }
public void setInvalid(boolean invalid) { public void setInvalid(boolean invalid) {

View File

@ -1,11 +1,10 @@
package club.joylink.rtss.simulation.cbtc.data.map; package club.joylink.rtss.simulation.cbtc.data.map;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList; import java.util.HashSet;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
/** /**
* 区域控制器 * 区域控制器
@ -13,7 +12,7 @@ import java.util.Objects;
@Getter @Getter
public class ZC extends MayOutOfOrderDevice { public class ZC extends MayOutOfOrderDevice {
private List<Section> sections = new ArrayList<>(); private Set<Section> sections = new HashSet<>();
public ZC(String code, String name) { public ZC(String code, String name) {
super(code, name, DeviceType.ZC); super(code, name, DeviceType.ZC);

View File

@ -232,11 +232,20 @@ public class TripPlan {
return false; return false;
} }
/**
* 按计划发车
*/
public void departure() {
this.departure = true;
if (this.isOutbound()) {
this.dispatched = true;
}
}
/** /**
* 按计划派发 * 按计划派发
*/ */
public void dispatch() { public void dispatched() {
this.departure = true;
if (this.isOutbound()) { if (this.isOutbound()) {
this.dispatched = true; this.dispatched = true;
} }

View File

@ -532,7 +532,7 @@ public class TrainInfo extends MapElement {
} }
public synchronized void applyNewTripPlan(TripPlan tripPlan) { public synchronized void applyNewTripPlan(TripPlan tripPlan) {
tripPlan.dispatch(); tripPlan.departure();
this.serviceNumber = tripPlan.getServiceNumber(); this.serviceNumber = tripPlan.getServiceNumber();
this.tripNumber = tripPlan.getTripNumber(); this.tripNumber = tripPlan.getTripNumber();
this.destinationCode = tripPlan.getDestinationCode(); this.destinationCode = tripPlan.getDestinationCode();
@ -586,11 +586,22 @@ public class TrainInfo extends MapElement {
this.routing = routing; this.routing = routing;
} }
/**
* 准备回库消失
*/
public void finishPlanPrepareInbound() { public void finishPlanPrepareInbound() {
this.inbound = true; this.inbound = true;
this.deleteRemain = 5 * 1000; this.deleteRemain = 5 * 1000;
} }
/**
* 准备进入车辆段
*/
public void finishPlanPrepareEnterDepot() {
this.inbound = true;
this.deleteRemain = -1;
}
public void updateDeleteRemain(int deleteRemain) { public void updateDeleteRemain(int deleteRemain) {
this.deleteRemain = deleteRemain; this.deleteRemain = deleteRemain;
} }

View File

@ -103,6 +103,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
*/ */
private Float maximumPower = 3583333f; private Float maximumPower = 3583333f;
/**
* 所属停车场/车辆段
*/
private Station depotStation;
// -----------列车运行属性----------- // -----------列车运行属性-----------
/** /**

View File

@ -0,0 +1,235 @@
package club.joylink.rtss.simulation.cbtc.depot;
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
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.Station;
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
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.member.SimulationMember;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
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;
@Component
public class DepotService {
@Autowired
private CiRouteService ciRouteService;
@Autowired
private TrainOutboundLoadTool trainOutboundLoadTool;
@Autowired
private GroupSimulationService groupSimulationService;
@Autowired
private ATPService atpService;
public void loadDepotTrain(Simulation simulation) {
if (!simulation.getRepository().getConfig().isHandleDepot()) {
return;
}
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
simulation.getRepository().getAllVrTrain().stream()
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
.forEach((station, trainList) -> {
List<Section> sections = parkingTracksMap.get(station);
// 先加载内侧的停车轨
sections.sort(Comparator.comparing(section ->
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
VirtualRealityTrain train = trainList.get(i);
Section section = sections.get(i);
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
train.parkingAt(section);
train.initAsRM();
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
trainInfo.tracking(train);
simulation.getRepository().addOnlineTrain(train);
simulation.getRepository().addTrainInfo(trainInfo);
}
});
}
public void addJobs(Simulation simulation) {
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
}
private void run(Simulation simulation) {
if (!simulation.isPlanRunning()) {
return;
}
if (!simulation.getRepository().getConfig().isHandleDepot()) {
trainOutboundLoadTool.loadOutboundTrain(simulation);
} else {
timeToDeparture(simulation);
backToParking(simulation);
settingRouteAndMoving(simulation);
arriveDestination(simulation);
}
}
/**
* 根据时间筛选从停车轨自动发车
* @param simulation
*/
private void timeToDeparture(Simulation simulation) {
LocalDateTime systemTime = simulation.getSystemTime();
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
continue;
}
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
if (!simulation.getRepository().getOutboundPlanList().contains(schedulingTrainPlan)) {
simulation.getRepository().getOutboundPlanList().add(schedulingTrainPlan);
schedulingTrainPlan.getOutDepotTrip().dispatched();
}
}
}
}
/**
* 筛选入库
* @param simulation
*/
private void backToParking(Simulation simulation) {
for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) {
if (!train.isParkingAt()) {
continue;
}
Section section = train.getHeadPosition().getSection();
if (!section.isTransferTrack()) {
continue;
}
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
if (!schedulingTrainPlan.getInDepotTrip().getEndSection().equals(section)) {
continue;
}
if (!train.getGroupNumber().equals(schedulingTrainPlan.getGroupNumber())) {
continue;
}
if (!schedulingTrainPlan.getInDepotTrip().getEndTime().minusMinutes(10)
.isBefore(simulation.getSystemTime().toLocalTime())) {
continue;
}
if (!simulation.getRepository().getInboundPlanList().contains(schedulingTrainPlan)) {
train.initAsRM();
simulation.getRepository().getInboundPlanList().add(schedulingTrainPlan);
break;
}
}
}
}
/**
* 列车排进路并运行
* @param simulation
*/
private void settingRouteAndMoving(Simulation simulation) {
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getOutboundPlanList()) {
moving(simulation, schedulingTrainPlan.getGroupNumber(), schedulingTrainPlan.getOutDepotTrip().getStartSection());
}
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getInboundPlanList()) {
Section endSection = schedulingTrainPlan.getInDepotTrip().getEndSection();
for (Section section : simulation.getRepository().getParkingTracksMap().get(endSection.getStation())) {
if (section.isOccupied()) {
continue;
}
if (section.getLeftSection() == null || section.getRightSection() == null) {
moving(simulation, schedulingTrainPlan.getGroupNumber(), section);
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
moving(simulation, schedulingTrainPlan.getGroupNumber(), section.getLeftSection());
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
moving(simulation, schedulingTrainPlan.getGroupNumber(), section.getRightSection());
} else {
moving(simulation, schedulingTrainPlan.getGroupNumber(), section);
}
break;
}
}
}
private void moving(Simulation simulation, String groupNumber, Section endSection) {
VirtualRealityTrain train = simulation.getRepository().getVRByCode(groupNumber, VirtualRealityTrain.class);
Section startSection = train.getHeadPosition().getSection();
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
if (routePaths == null || routePaths.isEmpty()) {
return;
}
RoutePath routePath = routePaths.get(0);
Section lastSection = routePath.getEnd();
train.setRobotTargetPosition(new SectionPosition(lastSection, lastSection.getStopPointByDirection(routePath.isRight())));
for (Signal signal : routePath.getSignalList()) {
for (Route route : signal.getRouteList()) {
if (routePath.getRouteList().contains(route)) {
if (route.isSetting()) {
return;
}
if (route.isLock()) {
break;
}
ciRouteService.setRoute(simulation, route);
return;
}
}
}
}
/**
* 判断运行列车是否到达转换轨并升级
* @param simulation
*/
private void arriveDestination(Simulation simulation) {
for (Iterator<SchedulingTrainPlan> iterator = simulation.getRepository().getOutboundPlanList().iterator(); iterator.hasNext(); ) {
SchedulingTrainPlan schedulingTrainPlan = iterator.next();
String groupNumber = schedulingTrainPlan.getGroupNumber();
VirtualRealityTrain train = simulation.getRepository().getVRByCode(groupNumber, VirtualRealityTrain.class);
if (train.getSpeed() == 0
&& train.getHeadPosition().getSection().equals(schedulingTrainPlan.getOutDepotTrip().getStartSection())
&& train.getTailPosition().getSection().equals(schedulingTrainPlan.getOutDepotTrip().getStartSection())) {
// 到达
iterator.remove();
// 升级
SimulationMember member = simulation.getSimulationMembersByDevice(train).get(0);
Map<String, Object> param = new HashMap<>();
param.put("preselectionMode", "AM_C");
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
member.getId(), param);
groupSimulationService.command(simulation, commandInitiateVO, member);
}
}
for (Iterator<SchedulingTrainPlan> iterator = simulation.getRepository().getInboundPlanList().iterator(); iterator.hasNext(); ) {
SchedulingTrainPlan schedulingTrainPlan = iterator.next();
String groupNumber = schedulingTrainPlan.getGroupNumber();
VirtualRealityTrain train = simulation.getRepository().getVRByCode(groupNumber, VirtualRealityTrain.class);
if (train.getSpeed() == 0 && train.getHeadPosition().getSection().isParkingTrack()
&& train.getTailPosition().getSection().isParkingTrack()) {
// 到达
iterator.remove();
atpService.turnDirectionImmediately(train);
}
}
}
}

View File

@ -127,6 +127,9 @@ public class MapCiGenerateConfig {
// @ApiModelProperty(value = "是否分开生成ATP联锁和地面信号联锁") // @ApiModelProperty(value = "是否分开生成ATP联锁和地面信号联锁")
// private boolean apartGroundAndAtp; // private boolean apartGroundAndAtp;
/** 是否处理停车场/车辆段逻辑 */
private boolean handleDepot;
//--------------------联锁数据生成配置end------------------- //--------------------联锁数据生成配置end-------------------
} }

View File

@ -15,4 +15,5 @@ public class AmendPoints {
private List<Point> points; private List<Point> points;
private Point position; private Point position;
private Float rotate; private Float rotate;
private Boolean reversal;
} }

View File

@ -207,6 +207,11 @@ public class MapSectionNewVO {
*/ */
private Point transferTrackNamePosition; private Point transferTrackNamePosition;
/**
* 是否停车轨
*/
private boolean parkingTrack;
/** /**
* 是否道岔区段 * 是否道岔区段
*/ */

View File

@ -32,5 +32,10 @@ public class MapTrainVO {
@NotBlank(message = "车组号不能为空") @NotBlank(message = "车组号不能为空")
private String groupNumber; private String groupNumber;
/**
* 所属车辆段/停车场
*/
private String stationCode;
private MapTrainModelVO trainModel; private MapTrainModelVO trainModel;
} }