应答器逻辑修改

This commit is contained in:
DU 2021-01-20 09:13:33 +08:00
parent ad529992af
commit d0c2ed8544
16 changed files with 153 additions and 58 deletions

View File

@ -34,7 +34,7 @@ public class ResponderService {
var responders = sectionRespondersMap.get(section);
if (CollectionUtils.isEmpty(responders)) return null;
Responder activeResponder = responders.stream().filter(responder ->
responder.active(headPosition)).findAny().orElse(null);
responder.active(headPosition, train.isRight())).findAny().orElse(null);
if (Objects.isNull(activeResponder)) return null;
log.info("列车触发应答器交换数据");
activeResponder.exchangeData(train);

View File

@ -190,9 +190,9 @@ public class ZCLogicLoop {
MovementAuthority.End signalEnd = checkSignal(section, right);
if (Objects.nonNull(signalEnd)) {
deviceEnd = signalEnd;
MovementAuthority.End faultSwitchEnd = this.checkUnlockedOverlap(simulation, section, right);
if (Objects.nonNull(faultSwitchEnd)) {
endList.add(faultSwitchEnd);
MovementAuthority.End unlockedOverlapEnd = this.checkUnlockedOverlap(simulation, section, right);
if (Objects.nonNull(unlockedOverlapEnd)) {
endList.add(unlockedOverlapEnd);
}
break;
}

View File

@ -115,8 +115,7 @@ public class SectionOperateHandler {
/**强解*/
@OperateHandlerMapping(type = Operation.Type.Section_Force_Unlock)
public void forceUnlock(Simulation simulation, String sectionCode) {
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
this.atsSectionService.forceUnlock(simulation, section);
this.ciApiService.sectionForceUnlock(simulation, sectionCode);
}
}

View File

@ -51,11 +51,4 @@ public class AtsSectionService {
section.confirmValid();
}
public void forceUnlock(Simulation simulation, Section section) {
if (Objects.nonNull(section.getParent())) {
section = section.getParent();
}
log.debug("仿真[{}] : 区段/岔心[{}]强解",simulation.getGroup(),String.format("%s(%s)", section.getName(), section.getCode()));
section.forceUnlocking();
}
}

View File

@ -164,6 +164,8 @@ public interface CiApiService {
*/
void sectionFaultUnlock(Simulation simulation, String sectionCode);
void sectionForceUnlock(Simulation simulation, String sectionCode);
/**
* 区故解
* @param simulation

View File

@ -217,6 +217,26 @@ public class CiApiServiceImpl implements CiApiService {
this.sectionService.sectionFaultUnlock(simulation, section, lockedRoute);
}
@Override
public void sectionForceUnlock(Simulation simulation, String sectionCode) {
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
List<Route> lockedRouteList = simulation.getRepository().queryAllLockedRoute();
Route lockedRoute = null;
for (Route route : lockedRouteList) {
if (route.isRouteSection(section)) {
lockedRoute = route;
break;
}
}
if (Objects.nonNull(lockedRoute)) {
TrainInfo firstTrain = simulation.getRepository().querySignalApproachedFirstTrain(lockedRoute.getStart());
if (lockedRoute.isApproachLock() && Objects.nonNull(firstTrain) && !firstTrain.isStop()) { // 接近锁闭总人解
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "有运行列车接近");
}
}
this.sectionService.sectionForceUnlock(simulation, section, lockedRoute);
}
@Override
public void switchSectionFaultUnlock(Simulation simulation, String switchCode) {
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);

View File

@ -1194,6 +1194,7 @@ public class RouteService {
overlap.releaseImmediately();
} else {
boolean allUnlock = true;
List<Section> logicList = sectionPath.getLogicList();
if (!CollectionUtils.isEmpty(logicList)) {
for (Section section : logicList) {

View File

@ -82,6 +82,25 @@ public class SectionService {
}
}
public void sectionForceUnlock(Simulation simulation, Section section, Route route) {
if (Objects.nonNull(route) && route.isApproachLock()) { // 进路接近锁闭
// 区段延时解锁
section.setDelayTime(route.getDelayReleaseTime() * 1000);
} else { // 解锁
if (Objects.nonNull(route)) {
if (route.isOpen()) {
this.signalService.close(simulation, route.getStart());
} else if (route.isLock()){
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
"延时解锁中");
}
}
section.forceUnlocking();
if(section.isShowLogic()){
section.getLogicList().forEach(ls -> ls.forceUnlocking());
}
}
}
/**
* 区段延时区故解
* @param simulation
@ -102,8 +121,13 @@ public class SectionService {
}
if (Objects.nonNull(lockedRoute)) {
lockedRoute.setLock(false);
this.signalService.close(simulation, lockedRoute.getStart());
}
if(section.isFaultLock()){
section.faultUnlock();
}else{
section.forceUnlocking();
}
section.faultUnlock();
section.setDelayTime(0);
} else {
section.setDelayTime(remainTime);

View File

@ -925,11 +925,11 @@ public class MapDeviceBuilder {
// 接触网
buildCatenary(graphData, elementMap, errMsgList, mapDataBuildResult.getCatenaryMap());
//应答器
buildResponderDataRef(graphData, elementMap, errMsgList);
buildResponderDataRef(graphData, elementMap, errMsgList ,mapDataBuildResult.getSectionRespondersMap());
}
/**应答器数据验证及关系构建*/
private static void buildResponderDataRef(MapGraphDataNewVO graphData, Map<String, MapElement> elementMap, List<String> errMsgList) {
private static void buildResponderDataRef(MapGraphDataNewVO graphData, Map<String, MapElement> elementMap, List<String> errMsgList, Map<Section, List<Responder>> sectionRespondersMap) {
List<MapResponderVO> responderList = graphData.getResponderList();
responderList.forEach(responderVO -> {
Responder responder = new Responder(responderVO.getCode(), responderVO.getName());
@ -965,7 +965,7 @@ public class MapDeviceBuilder {
responder.setDeviceStation(deviceStation);
}
// 关联一般计轴区段偏移量
// 关联一般计轴区段或道岔区段偏移量
Section section = (Section) elementMap.get(responderVO.getSectionCode());
if (Objects.isNull(section)) {
errMsgList.add(String.format("应答器[%s(%s)]未关联区段或关联区段[(%s)]不存在", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
@ -973,6 +973,8 @@ public class MapDeviceBuilder {
errMsgList.add(String.format("应答器[%s(%s)]关联区段[(%s)]不是物理区段", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
} else {
responder.setPhysicalSection(section);
List<Responder> responders = sectionRespondersMap.computeIfAbsent(section, k -> new ArrayList<Responder>());
responders.add(responder);
}
if (Objects.isNull(responderVO.getOffset()) ||
(Objects.nonNull(section) && Objects.nonNull(section.getLen()) &&

View File

@ -55,6 +55,7 @@ public class SimulationBuilder {
simulation.getRepository().setRoutingList(mapDataBuildResult.getRoutingList());
simulation.getRepository().setRunLevelList(mapDataBuildResult.getRunLevelList());
simulation.getRepository().getCatenaryMap().putAll(mapDataBuildResult.getCatenaryMap());
simulation.getRepository().getSectionRespondersMap().putAll(mapDataBuildResult.getSectionRespondersMap());
// 加载运行图
checkAndLoadRunPlan(simulation, buildParams.getRunPlan());
// 加载派班计划
@ -341,6 +342,8 @@ public class SimulationBuilder {
*/
private Map<String, Set<Catenary>> catenaryMap = new HashMap<>();
private Map<Section,List<Responder>> sectionRespondersMap;
/**
* 数据错误信息列表
*/
@ -351,6 +354,7 @@ public class SimulationBuilder {
this.vrDeviceMap = new HashMap<>();
// this.routeUnitMap = new HashMap<>();
this.routePathMap = new HashMap<>();
this.sectionRespondersMap = new HashMap<>();
this.errMsgList = new ArrayList<>();
}
}

View File

@ -328,15 +328,7 @@ public class SimulationDataRepository {
}
public boolean hasResponder() {
return !CollectionUtils.isEmpty(getListByType(MapElement.DeviceType.RESPONDER, Responder.class));
}
public Map<Section,List<Responder>> getSectionRespondersMap() {
if(hasResponder() && CollectionUtils.isEmpty(sectionRespondersMap)){
sectionRespondersMap = getListByType(MapElement.DeviceType.RESPONDER, Responder.class).stream().collect(Collectors.groupingBy(Responder::getPhysicalSection));
return sectionRespondersMap;
}
return sectionRespondersMap;
return !CollectionUtils.isEmpty(sectionRespondersMap);
}
public Station findStationByName(String stationName) {

View File

@ -65,8 +65,14 @@ public class Responder extends MapNamedElement {
return ResponderType.IB == type;
}
public boolean active(SectionPosition headPosition) {
return Objects.equals(physicalSection, headPosition.getSection()) && Math.abs(sectionOffset - headPosition.getOffset()) <= ACTIVE_DISTANCE;
public boolean active(SectionPosition headPosition, boolean right) {
if (Objects.equals(physicalSection, headPosition.getSection())) {
float o = right ? headPosition.getOffset() - sectionOffset : sectionOffset - headPosition.getOffset();
if (o >= 0 && o < ACTIVE_DISTANCE) {
return true;
}
}
return false;
}
public void exchangeData(VirtualRealityTrain train) {

View File

@ -5,10 +5,12 @@ import club.joylink.rtss.simulation.cbtc.constant.DriveMode;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.constant.TrainTBControl;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Responder;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.storage.support.StorageMA;
import club.joylink.rtss.simulation.cbtc.data.storage.support.StorageSectionPosition;
import club.joylink.rtss.simulation.cbtc.data.support.FixedQueue;
import club.joylink.rtss.simulation.cbtc.data.vr.StandParkedTrainActivity;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityDevice;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
@ -17,6 +19,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Objects;
import java.util.Queue;
@Getter
@Setter
@ -251,7 +254,7 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
private boolean pantograph2Up = true;
private String linkTrainGroupNumber;
private Queue<Responder> lastTwoPassedResponders;
public StorageVirtualRealityTrain(VirtualRealityTrain train) {
super(train);
this.groupNumber = train.getGroupNumber();
@ -321,6 +324,7 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
if (train.getLinkTrain() != null) {
this.linkTrainGroupNumber = train.getLinkTrain().getGroupNumber();
}
this.lastTwoPassedResponders = train.getLastTwoPassedResponders();
}
public static StorageVirtualRealityTrain convert2Storage(VirtualRealityTrain vrTrain) {
@ -404,5 +408,7 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
if (linkTrainGroupNumber != null) {
train.setLinkTrain(repository.getVRByCode(linkTrainGroupNumber, VirtualRealityTrain.class));
}
train.setLastTwoPassedResponders(lastTwoPassedResponders);
}
}

View File

@ -1007,6 +1007,15 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
public void clearResponders() {
lastTwoPassedResponders.clear();
}
public boolean isCommunicable() {
Station deviceStation = headPosition.getSection().getDeviceStation();
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault() || deviceStation.getZc().isFault()) {
return false;
}
return true;
}
public enum Fault {
/**
* 通信异常

View File

@ -3,12 +3,15 @@ package club.joylink.rtss.simulation.cbtc.device.virtual;
import club.joylink.rtss.simulation.cbtc.ATP.ground.ResponderService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.ControlGear;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.map.Responder;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -70,26 +73,59 @@ public class VRTrainRunningService {
SectionPosition headPositionNew = CalculateService.calculateNextPositionByStartAndLen(headPosition, right, s);
// todo 碰撞检测如果撞车不修改位置
train.setHeadPosition(headPositionNew);
Responder passingResponder = responderService.activeExchangeData(simulation, train);
if (Objects.isNull(passingResponder)) {
return;
}
if (train.isIL()) {
if (passingResponder.isVB()) {
Signal signal = passingResponder.getSignal();
if (Objects.equals(signal.isRight(), train.isRight()) && Objects.nonNull(signal.getLockedRoute())) {
train.setITCMode();
log.info("列车越过VB应答器从IL升级ITC");
//列车级别
trainRunLevelUpgrade(simulation, train);
}
private void trainRunLevelUpgrade(Simulation simulation, VirtualRealityTrain train) {
//有应答器
if (simulation.getRepository().hasResponder()) {
if (train.isCBTC()) {
return;
}
Responder passingResponder = responderService.activeExchangeData(simulation, train);
if (Objects.isNull(passingResponder)) {
return;
}
if (train.isIL()) {
if (passingResponder.isVB()) {
Signal signal = passingResponder.getSignal();
if (Objects.equals(signal.isRight(), train.isRight()) && signal.isNormalOpen() && Objects.nonNull(signal.getLockedRoute())) {
train.setITCMode();
log.info("列车越过VB应答器从IL升级ITC");
}
}
}
if (train.isCommunicable()) {
if (train.getLastTwoPassedResponders().size() == VirtualRealityTrain.Responders_Record) {
train.setCBTCMode();
log.info("列车越过两个应答器从ITC升级CBTC");
train.clearResponders();
return;
}
}
} else if (train.isITC()) {
if (train.getLastTwoPassedResponders().size() == VirtualRealityTrain.Responders_Record) {
train.setCBTCMode();
log.info("列车越过两个应答器从ITC升级CBTC");
return;
}
return;
}
//无应答器
if (!train.isCbtcMaMiss()) {
RunLevel defaultRunLevel = simulation.getRepository().getConfig().getRunMode();
if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
train.setRunLevel(RunLevel.CBTC);
}
train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.TRAIN_RUNNING_RATE);
}
if (!train.isItcMaMiss()) { //itc级别ma未丢失
if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别
train.setRunLevel(RunLevel.ITC);
}
train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.TRAIN_RUNNING_RATE);
}
}
}

View File

@ -75,26 +75,27 @@ public class ATPLogicLoop {
* 检查ma接收情况并改变列车运行级别
*/
private void maCheckAndChangeRunLevel(Simulation simulation, VirtualRealityTrain train) {
RunLevel defaultRunLevel = simulation.getRepository().getConfig().getRunMode();
// RunLevel defaultRunLevel = simulation.getRepository().getConfig().getRunMode();
if (train.isCbtcMaMiss()) { //cbtc级别ma丢失
if (train.isCBTC()) { //并且列车处于CBTC级别
train.setRunLevel(RunLevel.IL);
ATPService.triggerSignalEB(train);
train.setMa(null);
}
} else {
if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
train.setRunLevel(RunLevel.CBTC);
}
train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
}
if (!train.isItcMaMiss()) { //itc级别ma未丢失
if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别
train.setRunLevel(RunLevel.ITC);
}
train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
}
// else {
// if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
// train.setRunLevel(RunLevel.CBTC);
// }
// train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
// }
//
// if (!train.isItcMaMiss()) { //itc级别ma未丢失
// if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别
// train.setRunLevel(RunLevel.ITC);
// }
// train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
// }
}
private void driveLogicRun(Simulation simulation, VirtualRealityTrain train) {