Merge remote-tracking branch 'origin/test' into wechat-micro2-login

This commit is contained in:
walker-sheng 2021-06-23 18:26:06 +08:00
commit 8d275849a1
10 changed files with 171 additions and 87 deletions

View File

@ -5,39 +5,31 @@ 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.Section;
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.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.*;
import java.util.Map;
import java.util.Objects;
/** /**
* 应答器信号发射 * 应答器信号发射
*/ */
@Slf4j
@Component @Component
public class ResponderService { public class ResponderService {
/** public Responder viaResponder(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, SectionPosition headPositionNew) {
* 列车经过应答器触发电磁信号
*/
public Responder activeExchangeData(Simulation simulation, VirtualRealityTrain train) {
Map<Section, List<Responder>> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap(); Map<Section, List<Responder>> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap();
if (CollectionUtils.isEmpty(sectionRespondersMap)) { List<Section> sections = List.of(headPosition.getSection(), headPositionNew.getSection());
return null; for (Section section : sections) {
List<Responder> responders = sectionRespondersMap.get(section);
if (!CollectionUtils.isEmpty(responders)) {
for (Responder responder : responders) {
if (responder.isTrigger(headPosition, headPositionNew)) {
train.viaResponder(responder);
return responder;
}
}
}
} }
//电磁触发以列车头位置(车载应答器)模拟 return null;
SectionPosition headPosition = train.getHeadPosition();
Section section = headPosition.getSection();
var responders = sectionRespondersMap.get(section);
if (CollectionUtils.isEmpty(responders)) return null;
Responder activeResponder = responders.stream().filter(responder ->
responder.active(headPosition, train.isRight())).findAny().orElse(null);
if (Objects.isNull(activeResponder)) return null;
log.info("列车触发应答器交换数据");
activeResponder.exchangeData(train);
return activeResponder;
} }
} }

View File

@ -60,9 +60,13 @@ public class ZCLogicLoop {
} }
} }
//更新CBTC ma //更新CBTC ma
if (!deviceStation.getZc().isFault()) { //如果列车头所在区段所属设备集中站zc未故障 if (headPosition.getSection().anyZcWorking()) {
this.calculateMAOfCBTC(simulation, train, trainList); this.calculateMAOfCBTC(simulation, train, trainList);
} }
// //更新CBTC ma
// if (!deviceStation.getZc().isFault()) { //如果列车头所在区段所属设备集中站zc未故障
// this.calculateMAOfCBTC(simulation, train, trainList);
// }
} }
}); });
} }

View File

@ -1,6 +1,7 @@
package club.joylink.rtss.simulation.cbtc.build; package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.constants.BusinessConsts; import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
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.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption; import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption;
@ -302,6 +303,39 @@ public class MapDeviceBuilder {
} }
} }
}); });
/* ZC和区段相互赋值 */
// ZC
if (graphData.getZcList().size() == 1) {
MapZcVO mapZcVO = graphData.getZcList().get(0);
ZC zc = (ZC) elementMap.get(mapZcVO.getCode());
physicalSectionList.forEach(section -> {
zc.addSection(section);
section.addZc(zc);
});
} else {
graphData.getZcList().forEach(mapZcVO -> {
ZC zc = (ZC) elementMap.get(mapZcVO.getCode());
List<String> zcSections = mapZcVO.getManagedSectionList();
if (CollectionUtils.isEmpty(zcSections))
errMsgList.add(String.format("ZC[%s]无关联区段", mapZcVO.getCode()));
if (!CollectionUtils.isEmpty(zcSections)) {
for (String sectionCode : zcSections) {
Section section = (Section) elementMap.get(sectionCode);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(section,
String.format("ZC[%s]关联的区段[%s]不存在", zc.getCode(), sectionCode));
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);
});
}
}
}
});
}
// 站台 // 站台
List<MapStationStandNewVO> standList = graphData.getStationStandList(); List<MapStationStandNewVO> standList = graphData.getStationStandList();
standList.forEach(standVO -> { standList.forEach(standVO -> {
@ -764,18 +798,19 @@ public class MapDeviceBuilder {
queryAdjoinSections(section, false, leftDirectionList); queryAdjoinSections(section, false, leftDirectionList);
log.debug(String.format("区段[%s][右向]邻接区段为[%s],[左向]邻接区段为[%s]", log.debug(String.format("区段[%s][右向]邻接区段为[%s],[左向]邻接区段为[%s]",
section.debugStr(), section.debugStr(),
String.join(",",rightDirectionList.stream().map(Section::debugStr).collect(Collectors.toList())), String.join(",", rightDirectionList.stream().map(Section::debugStr).collect(Collectors.toList())),
String.join(",", leftDirectionList.stream().map(Section::debugStr).collect(Collectors.toList())))); String.join(",", leftDirectionList.stream().map(Section::debugStr).collect(Collectors.toList()))));
} }
return sectionDirectionSectionsMap; return sectionDirectionSectionsMap;
} }
private static String buildSectionDirectionKey(Section section, boolean right) { private static String buildSectionDirectionKey(Section section, boolean right) {
return String.format("%s-%s", section.getCode(), right?"R":"L"); return String.format("%s-%s", section.getCode(), right ? "R" : "L");
} }
/** /**
* 查找区段临近的功能区段站台轨转换轨折返轨 * 查找区段临近的功能区段站台轨转换轨折返轨
*
* @param section * @param section
* @param right * @param right
* @param rightDirectionList * @param rightDirectionList
@ -1126,7 +1161,7 @@ public class MapDeviceBuilder {
} else if (!section.isPhysical()) { } else if (!section.isPhysical()) {
errMsgList.add(String.format("应答器[%s(%s)]关联区段[(%s)]不是物理区段", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode())); errMsgList.add(String.format("应答器[%s(%s)]关联区段[(%s)]不是物理区段", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
} else { } else {
responder.setPhysicalSection(section); // responder.setPhysicalSection(section);
List<Responder> responders = sectionRespondersMap.computeIfAbsent(section, k -> new ArrayList<Responder>()); List<Responder> responders = sectionRespondersMap.computeIfAbsent(section, k -> new ArrayList<Responder>());
responders.add(responder); responders.add(responder);
} }
@ -1136,7 +1171,8 @@ public class MapDeviceBuilder {
errMsgList.add(String.format("应答器[%s(%s)]的区段偏移量未设置或数据异常[%s]", errMsgList.add(String.format("应答器[%s(%s)]的区段偏移量未设置或数据异常[%s]",
responderVO.getName(), responderVO.getCode(), responderVO.getOffset())); responderVO.getName(), responderVO.getCode(), responderVO.getOffset()));
} else { } else {
responder.setSectionOffset(responderVO.getOffset()); // responder.setSectionOffset(responderVO.getOffset());
responder.setPosition(new SectionPosition(section, responderVO.getOffset()));
} }
}); });
} }

View File

@ -5,8 +5,6 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Objects;
/** /**
* 应答器仿真数据 * 应答器仿真数据
*/ */
@ -27,15 +25,18 @@ public class Responder extends MapNamedElement {
/** 所属设备集中站*/ /** 所属设备集中站*/
private Station deviceStation; private Station deviceStation;
/** 物理区段*/ // /** 物理区段*/
private Section physicalSection; // private Section physicalSection;
//
/** 在区段上的偏移量*/ // /** 在区段上的偏移量*/
private float sectionOffset; // private float sectionOffset;
/**VB关联信号机*/ /**VB关联信号机*/
private Signal signal; private Signal signal;
/** 位置 */
private SectionPosition position;
// ------------------LEU同步的状态--------------------- // ------------------LEU同步的状态---------------------
@ -65,19 +66,26 @@ public class Responder extends MapNamedElement {
return ResponderType.IB == type; return ResponderType.IB == type;
} }
public boolean active(SectionPosition headPosition, boolean right) { // public boolean active(SectionPosition headPosition, boolean right) {
if (Objects.equals(physicalSection, headPosition.getSection())) { // if (Objects.equals(physicalSection, headPosition.getSection())) {
float o = right ? headPosition.getOffset() - sectionOffset : sectionOffset - headPosition.getOffset(); // float o = right ? headPosition.getOffset() - sectionOffset : sectionOffset - headPosition.getOffset();
if (o >= 0 && o < ACTIVE_DISTANCE) { // if (o >= 0 && o < ACTIVE_DISTANCE) {
return true; // return true;
} // }
} // }
return false; // return false;
} // }
public void exchangeData(VirtualRealityTrain train) { public void exchangeData(VirtualRealityTrain train) {
train.passingResponder(this); train.viaResponder(this);
} }
public boolean isTrigger(SectionPosition headPosition, SectionPosition headPositionNew) {
if (this.isVB() && !signal.isNormalOpen())
return false;
return this.position.isBetween(headPosition, headPositionNew);
}
public enum ResponderType { public enum ResponderType {
/** 固定应答器*/ /** 固定应答器*/
FB, FB,

View File

@ -156,6 +156,11 @@ public class Section extends MayOutOfOrderDevice {
*/ */
private Float stopPointRight; private Float stopPointRight;
/**
* 所属zc
*/
private List<ZC> zcs = new ArrayList<>();
// ------------------状态属性--------------------- // ------------------状态属性---------------------
/** /**
@ -1014,6 +1019,20 @@ public class Section extends MayOutOfOrderDevice {
return false; return false;
} }
public void addZc(ZC zc) {
this.zcs.add(zc);
}
/**
* 任意一个zc正常工作
*/
public boolean anyZcWorking() {
if (!CollectionUtils.isEmpty(zcs)) {
return zcs.stream().anyMatch(zc -> !zc.isFault());
}
return false;
}
public enum SectionRoadType { public enum SectionRoadType {
/** /**
* 左行线 * 左行线

View File

@ -1,11 +1,20 @@
package club.joylink.rtss.simulation.cbtc.data.map; package club.joylink.rtss.simulation.cbtc.data.map;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* 区域控制器 * 区域控制器
*/ */
@Getter
public class ZC extends MayOutOfOrderDevice { public class ZC extends MayOutOfOrderDevice {
private List<Section> sections = new ArrayList<>();
public ZC(String code, String name) { public ZC(String code, String name) {
super(code, name, DeviceType.ZC); super(code, name, DeviceType.ZC);
} }
@ -15,6 +24,10 @@ public class ZC extends MayOutOfOrderDevice {
super.reset(); super.reset();
} }
public void addSection(Section section) {
sections.add(section);
}
public enum Fault implements DeviceFault { public enum Fault implements DeviceFault {
/**ZC故障*/ /**ZC故障*/
FAULT{ FAULT{

View File

@ -463,6 +463,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
this.headPosition = null; this.headPosition = null;
this.robotTargetPosition = null; this.robotTargetPosition = null;
this.ma = null; this.ma = null;
this.cbtcMaMissDuration = 0;
this.itcMaMissDuration = 0;
this.gear = null; this.gear = null;
this.speed = 0; this.speed = 0;
this.targetDistance = 0; this.targetDistance = 0;
@ -1074,7 +1076,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
return !lastTwoPassedResponders.isEmpty(); return !lastTwoPassedResponders.isEmpty();
} }
public void passingResponder(Responder responder) { public void viaResponder(Responder responder) {
if (lastTwoPassedResponders.isEmpty()) { if (lastTwoPassedResponders.isEmpty()) {
lastTwoPassedResponders.offer(responder); lastTwoPassedResponders.offer(responder);
return; return;
@ -1088,8 +1090,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
} }
public boolean isCommunicable() { public boolean isCommunicable() {
Station deviceStation = headPosition.getSection().getDeviceStation(); Section section = headPosition.getSection();
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault() || deviceStation.getZc().isFault()) { Station deviceStation = section.getDeviceStation();
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault
|| Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault()
|| !section.anyZcWorking()) {
return false; return false;
} }
return true; return true;

View File

@ -3,6 +3,7 @@ package club.joylink.rtss.simulation.cbtc.device.virtual;
import club.joylink.rtss.simulation.cbtc.ATP.ground.ResponderService; import club.joylink.rtss.simulation.cbtc.ATP.ground.ResponderService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.ControlGear; 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.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
@ -18,6 +19,7 @@ import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Queue;
@Component @Component
@Slf4j @Slf4j
@ -122,7 +124,7 @@ public class VRTrainRunningService {
if (change) if (change)
train.setHeadPosition(headPositionNew); train.setHeadPosition(headPositionNew);
//列车级别 //列车级别
trainRunLevelUpgrade(simulation, train); viaResponder(simulation, train, headPosition, headPositionNew);
//计轴器计数 //计轴器计数
axleCounterCount(simulation, train, headPosition, headPositionNew); axleCounterCount(simulation, train, headPosition, headPositionNew);
@ -166,36 +168,23 @@ public class VRTrainRunningService {
} }
} }
/**
private void trainRunLevelUpgrade(Simulation simulation, VirtualRealityTrain train) { * 穿过应答器
*/
//有应答器 private void viaResponder(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, SectionPosition headPositionNew) {
if (simulation.getRepository().hasResponder()) { 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;
}
}
return; return;
// 列车升级
if (!train.isIL())
return;
Responder passingResponder = responderService.viaResponder(simulation, train, headPosition, headPositionNew);
if (passingResponder == null || !passingResponder.isVB())
return;
Queue<Responder> responders = train.getLastTwoPassedResponders();
if (responders.size() != 2)
return;
if (responders.stream().allMatch(responder -> responder.isVB() || responder.isFB())) {
train.setITCMode();
} }
} }

View File

@ -78,22 +78,35 @@ public class ATPLogicLoop {
atpService.triggerSignalEB(train); atpService.triggerSignalEB(train);
train.setMa(null); train.setMa(null);
} }
} } else {
if (!simulation.getRepository().hasResponder()) { train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
//无应答器 if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
if (!train.isCbtcMaMiss()) { train.setCBTCMode();
if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
train.setCBTCMode();
}
train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
} }
if (!train.isItcMaMiss()) { //itc级别ma未丢失 }
if (!train.isItcMaMiss()) {
train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
if (!simulation.getRepository().hasResponder()) {
if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别 if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别
train.setITCMode(); train.setITCMode();
} }
train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
} }
} }
// if (!simulation.getRepository().hasResponder()) {
// //无应答器
// if (!train.isCbtcMaMiss()) {
// if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
// train.setCBTCMode();
// }
// train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
// }
// if (!train.isItcMaMiss()) { //itc级别ma未丢失
// if (RunLevel.IL.equals(train.getRunLevel())) { //如果列车是IL级别
// train.setITCMode();
// }
// train.setItcMaMissDuration(train.getItcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
// }
// }
} }
private void driveLogicRun(Simulation simulation, VirtualRealityTrain train) { private void driveLogicRun(Simulation simulation, VirtualRealityTrain train) {

View File

@ -43,4 +43,9 @@ public class MapZcVO {
* 管控集中站列表 * 管控集中站列表
*/ */
private List<String> concentrateStationList; private List<String> concentrateStationList;
/**
* 管理的区段列表
*/
private List<String> managedSectionList;
} }