按计划行车办理进路、解锁进路逻辑调整

进路路径筛选进路逻辑调整
直接办理进路道岔转动bug修改
This commit is contained in:
walker-sheng 2021-10-11 16:59:33 +08:00
parent 55769ee2dc
commit fc8f17cdb4
4 changed files with 169 additions and 43 deletions

View File

@ -39,6 +39,8 @@ import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Component @Component
@ -400,16 +402,16 @@ public class AtsTrainLoadService {
log.debug(String.format("实际加载列车数量:[%s]", loadedList.size())); log.debug(String.format("实际加载列车数量:[%s]", loadedList.size()));
// 处理加载到折返轨的重叠列车 // 处理加载到折返轨的重叠列车
this.handleTurnBackCollisionTrainByTripPlan(simulation, loadedList); this.handleTurnBackCollisionTrainByTripPlan(simulation, loadedList);
// 列车进路排列
this.setTrainRouteByTripPlan(simulation, loadedList);
// 重叠列车处理 // 重叠列车处理
this.handleCollision(simulation, loadedList); this.handleCollision(simulation, loadedList);
// 车次计划发车状态 // 车次计划发车状态
this.updateTripPlanStatus(simulation); this.updateTripPlanStatus(simulation);
// 列车上线并构建ATS监控列车信息 // 列车上线并构建ATS监控列车信息
this.trainOnlineAndBuildSupervise(simulation, loadedList); List<TrainInfo> superviseList = this.trainOnlineAndBuildSupervise(simulation, loadedList);
// 办理ats选择的进路 // 列车进路排列
this.setRoutesThatSelectedByAts(simulation); this.setTrainRouteByTripPlan(simulation, loadedList, superviseList);
// // 办理ats选择的进路
// this.setRoutesThatSelectedByAts(simulation);
// 计算移动授权 // 计算移动授权
// this.maService.calculateMaOfCtcTrains(simulation); // this.maService.calculateMaOfCtcTrains(simulation);
// this.zcLogicLoop.run(simulation); // this.zcLogicLoop.run(simulation);
@ -503,7 +505,8 @@ public class AtsTrainLoadService {
} }
} }
private void trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) { private List<TrainInfo> trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) {
List<TrainInfo> superviseList = new ArrayList<>();
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
for (VirtualRealityTrain train : loadedList) { for (VirtualRealityTrain train : loadedList) {
// 构建监控列车信息 // 构建监控列车信息
@ -555,8 +558,10 @@ public class AtsTrainLoadService {
} }
trainInfo.tracking(train); trainInfo.tracking(train);
repository.addTrainInfo(trainInfo); repository.addTrainInfo(trainInfo);
superviseList.add(trainInfo);
} }
repository.addOnlineTrainList(loadedList); repository.addOnlineTrainList(loadedList);
return superviseList;
} }
private boolean isOnSectionStopPoint(SectionPosition headPosition, Section section, boolean right) { private boolean isOnSectionStopPoint(SectionPosition headPosition, Section section, boolean right) {
@ -646,8 +651,16 @@ public class AtsTrainLoadService {
return collisionList; return collisionList;
} }
private void setTrainRouteByTripPlan(Simulation simulation, List<VirtualRealityTrain> loadedList) { private void setTrainRouteByTripPlan(Simulation simulation, List<VirtualRealityTrain> loadedList, List<TrainInfo> superviseList) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
Map<String, TrainInfo> trainInfoMap = superviseList.stream()
.collect(Collectors.toMap(TrainInfo::getCode, Function.identity()));
// 按运行计划时间排序
loadedList.sort((train1, train2) -> {
TripPlan tripPlan1 = repository.getTripPlan(train1.getServiceNumber(), train1.getTripNumber());
TripPlan tripPlan2 = repository.getTripPlan(train2.getServiceNumber(), train2.getTripNumber());
return TripPlan.compare(tripPlan1, tripPlan2);
});
for (VirtualRealityTrain train : loadedList) { for (VirtualRealityTrain train : loadedList) {
Section headSection = train.getHeadPosition().getSection(); Section headSection = train.getHeadPosition().getSection();
boolean right = train.isRight(); boolean right = train.isRight();
@ -658,19 +671,58 @@ public class AtsTrainLoadService {
for (int i = 1; i < viaSectionList.size(); i++) { for (int i = 1; i < viaSectionList.size(); i++) {
Section start = viaSectionList.get(i - 1); Section start = viaSectionList.get(i - 1);
Section end = viaSectionList.get(i); Section end = viaSectionList.get(i);
// 取相邻两区段的路径单元查询进路 TrainInfo trainInfo = trainInfoMap.get(train.getCode());
RoutePath routePath = this.selectDefaultRoutePath(repository, start, end); if (trainInfo.getPlanStandTrack() == null) {
Route route = routePath.queryRouteContainsSection(train.isCommunicable(), headSection, repository.getConfig());
if (Objects.nonNull(route)) {
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 根据列车位置直接进路正常解锁
this.deviceStatusModifyTool.routeUnlockByEndSection(route, tailPosition);
// 进路设置为正常解锁
this.ciLogic.trainUnlockStart(simulation, route);
route.setUnlockedSection(tailPosition.getSection());
break; break;
} }
if (!end.getCode().equals(trainInfo.getPlanStandTrack())) {
continue;
}
Section tailSection = tailPosition.getSection();
// 取相邻两区段的路径单元查询进路
RoutePath routePath = this.selectDefaultRoutePath(repository, start, end);
if (!routePath.isPathSection(tailSection)) {
if (i - 2 >= 0) {
Section pre = viaSectionList.get(i - 2);
RoutePath preRoutePath = this.selectDefaultRoutePath(repository, pre, start);
Route route = preRoutePath.queryRouteContainsSection(train.isCommunicable(), tailSection, repository.getConfig());
if (route != null) {
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 根据列车位置直接进路正常解锁
this.deviceStatusModifyTool.routeUnlockByEndSection(route, tailSection);
}
}
}
List<Route> routeList = routePath.getRouteList();
Set<String> handledRouteStarts = new HashSet<>();
for (Route route : routeList) {
if (handledRouteStarts.contains(route.getStart().getCode())) {
continue;
}
if (route.isRouteSection(tailSection) || route.isRouteSection(headSection)) {
Route selected = routePath.selectDefaultRouteOfStart(route.getStart(), train.isCommunicable(), repository.getConfig());
if (selected != null) {
handledRouteStarts.add(route.getStart().getCode());
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 根据列车位置直接进路正常解锁
Section unlockTo = tailSection;
if (!route.isRouteSection(tailSection)) {
unlockTo = headSection;
}
this.deviceStatusModifyTool.routeUnlockByEndSection(route, unlockTo);
}
} else if (!train.isStop() && route.getStart().isApproachSection(headSection.getCode())) {
// 排列好进路
Route aheadRoute = routePath.selectDefaultRouteOfStart(route.getStart(), train.isCommunicable(), repository.getConfig());
if (aheadRoute != null) {
this.deviceStatusModifyTool.openRouteDirect(simulation, aheadRoute);
}
break;
}
}
break;
} }
} }
} }

View File

@ -447,4 +447,42 @@ public class TripPlan {
} }
} }
} }
/**
* 按计划时间先后顺序排序对于同向的按到某个都达到的站的时间排序对于不同向的默认向右在前
* @param list
*/
public static void sort(List<TripPlan> list) {
list.sort(TripPlan::compare);
}
/**
* 比较车次计划先后顺序, 对于同向的按到某个都达到的站的时间排序对于不同向的默认向右在前
* @param plan1
* @param plan2
* @return
*/
public static int compare(TripPlan plan1, TripPlan plan2) {
if (plan1.isRight() != plan2.isRight()) {
if (plan2.isRight()) {
return 1;
} else {
return -1;
}
} else {
List<StationPlan> spList1 = plan1.getPlanList();
List<StationPlan> spList2 = plan2.getPlanList();
StationPlan stationPlan1 = spList1.get(spList1.size() - 1);
StationPlan stationPlan2 = plan2.queryStationPlan(stationPlan1.getStation());
if (stationPlan2 != null) {
return stationPlan1.getArriveTime().compareTo(stationPlan2.getArriveTime());
}
stationPlan2 = spList2.get(spList2.size() - 1);
stationPlan1 = plan1.queryStationPlan(stationPlan2.getStation());
if (stationPlan1 != null) {
return stationPlan1.getArriveTime().compareTo(stationPlan2.getArriveTime());
}
}
return plan1.getStartTime().compareTo(plan2.getStartTime());
}
} }

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.support; package club.joylink.rtss.simulation.cbtc.data.support;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.*;
import lombok.Getter; import lombok.Getter;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -431,4 +430,57 @@ public class RoutePath {
} }
return false; return false;
} }
/**
* 根据始端信号机选择此进路路径所需的进路对于哈尔滨的进路根据通信和进路是否ATP判断其他取延续保护默认定位进路
* @param signal
* @param communicable
* @param config
* @return
*/
public Route selectDefaultRouteOfStart(Signal signal, boolean communicable, MapConfig config) {
List<Route> triggerList = new ArrayList<>();
for (Route route : this.routeList) {
if (config.isRouteLikeHa1()) {
if (communicable) { // 通信车找ATP进路
if (!route.isAtp()) {
continue;
}
} else { // 非通信车找地面进路
if (!route.isGround()) {
continue;
}
}
}
if (route.getStart().equals(signal) && !route.isTurnBack() &&
!triggerList.contains(route) && route.isAtsControl()) {
if (config.isRouteLikeHa1()) {
if (communicable && route.isAtp()) {
triggerList.add(route);
} else if (!communicable && route.isGround()) {
triggerList.add(route);
}
} else {
triggerList.add(route);
}
}
}
//选择要触发的进路
Route route = null;
if (triggerList.size() == 1) {
route = triggerList.get(0);
} else if (triggerList.size() > 1) {
// 取第一个延续保护道岔定位的
for (Route temp : triggerList) {
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
if (switchList.get(0).isNormal()) {
route = temp;
break;
} else {
route = temp;
}
}
}
return route;
}
} }

View File

@ -7,7 +7,6 @@ import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication; import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
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.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService; import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
@ -17,7 +16,6 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -183,7 +181,7 @@ public class DeviceStatusModifyTool {
virtualSwitch.finish(); virtualSwitch.finish();
aSwitch.setPos(SwitchIndication.N); aSwitch.setPos(SwitchIndication.N);
} else { } else {
virtualSwitch.control(VirtualRealitySwitch.Operation.NP); virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
virtualSwitch.finish(); virtualSwitch.finish();
aSwitch.setPos(SwitchIndication.R); aSwitch.setPos(SwitchIndication.R);
} }
@ -207,34 +205,20 @@ public class DeviceStatusModifyTool {
* 直接根据最后一根区段解锁进路 * 直接根据最后一根区段解锁进路
* @param route * @param route
*/ */
public void routeUnlockByEndSection(Route route, SectionPosition tailPosition) { public void routeUnlockByEndSection(Route route, Section tailSection) {
Section endOccupied = tailPosition.getSection(); if (!route.isRouteSection(tailSection)) {
if (!route.isRouteSection(endOccupied)) {
// 不是进路区段不解锁 // 不是进路区段不解锁
return; return;
} }
route.startNormalUnlock();
// 关闭始端信号机
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
boolean right = route.getStart().isRight(); boolean right = route.getStart().isRight();
// 区段是顺序的(否则会有问题) // 区段是顺序的(否则会有问题)
List<Section> sectionList = route.getSectionList(); List<Section> sectionList = route.getSectionList();
for (Section section : sectionList) { for (Section section : sectionList) {
if (section.isSamePhysical(endOccupied.getCode())) { if (section.isSamePhysical(tailSection.getCode())) {
if (!CollectionUtils.isEmpty(section.getLogicList())) { route.updateUnlockedSection(tailSection);
// 逻辑区段占用根据逻辑区段占用位置解锁
List<Section> logicList = section.getLogicList();
if (!right) { // 向左逻辑区段列表reverse
logicList = new ArrayList<>(section.getLogicList());
Collections.reverse(logicList);
}
Section logicSection = tailPosition.getLogicSection();
for (Section logic : logicList) {
if (logic.equals(logicSection)) {
break;
} else {
logic.routeUnlocking(route);
logic.overlapUnlocking();
}
}
}
break; break;
} }
// 直接解锁区段 // 直接解锁区段