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.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
/**
* 应答器信号发射
*/
@Slf4j
@Component
public class ResponderService {
/**
* 列车经过应答器触发电磁信号
*/
public Responder activeExchangeData(Simulation simulation, VirtualRealityTrain train) {
public Responder viaResponder(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, SectionPosition headPositionNew) {
Map<Section, List<Responder>> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap();
if (CollectionUtils.isEmpty(sectionRespondersMap)) {
return null;
List<Section> sections = List.of(headPosition.getSection(), headPositionNew.getSection());
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;
}
}
}
}
//电磁触发以列车头位置(车载应答器)模拟
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;
return null;
}
}

View File

@ -60,9 +60,13 @@ public class ZCLogicLoop {
}
}
//更新CBTC ma
if (!deviceStation.getZc().isFault()) { //如果列车头所在区段所属设备集中站zc未故障
if (headPosition.getSection().anyZcWorking()) {
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;
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.support.SectionPosition;
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();
standList.forEach(standVO -> {
@ -764,18 +798,19 @@ public class MapDeviceBuilder {
queryAdjoinSections(section, false, leftDirectionList);
log.debug(String.format("区段[%s][右向]邻接区段为[%s],[左向]邻接区段为[%s]",
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()))));
}
return sectionDirectionSectionsMap;
}
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 right
* @param rightDirectionList
@ -1126,7 +1161,7 @@ public class MapDeviceBuilder {
} else if (!section.isPhysical()) {
errMsgList.add(String.format("应答器[%s(%s)]关联区段[(%s)]不是物理区段", responderVO.getName(), responderVO.getCode(), responderVO.getSectionCode()));
} else {
responder.setPhysicalSection(section);
// responder.setPhysicalSection(section);
List<Responder> responders = sectionRespondersMap.computeIfAbsent(section, k -> new ArrayList<Responder>());
responders.add(responder);
}
@ -1136,7 +1171,8 @@ public class MapDeviceBuilder {
errMsgList.add(String.format("应答器[%s(%s)]的区段偏移量未设置或数据异常[%s]",
responderVO.getName(), responderVO.getCode(), responderVO.getOffset()));
} 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.Setter;
import java.util.Objects;
/**
* 应答器仿真数据
*/
@ -27,15 +25,18 @@ public class Responder extends MapNamedElement {
/** 所属设备集中站*/
private Station deviceStation;
/** 物理区段*/
private Section physicalSection;
/** 在区段上的偏移量*/
private float sectionOffset;
// /** 物理区段*/
// private Section physicalSection;
//
// /** 在区段上的偏移量*/
// private float sectionOffset;
/**VB关联信号机*/
private Signal signal;
/** 位置 */
private SectionPosition position;
// ------------------LEU同步的状态---------------------
@ -65,19 +66,26 @@ public class Responder extends MapNamedElement {
return ResponderType.IB == type;
}
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 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) {
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 {
/** 固定应答器*/
FB,

View File

@ -156,6 +156,11 @@ public class Section extends MayOutOfOrderDevice {
*/
private Float stopPointRight;
/**
* 所属zc
*/
private List<ZC> zcs = new ArrayList<>();
// ------------------状态属性---------------------
/**
@ -1014,6 +1019,20 @@ public class Section extends MayOutOfOrderDevice {
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 {
/**
* 左行线

View File

@ -1,11 +1,20 @@
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;
/**
* 区域控制器
*/
@Getter
public class ZC extends MayOutOfOrderDevice {
private List<Section> sections = new ArrayList<>();
public ZC(String code, String name) {
super(code, name, DeviceType.ZC);
}
@ -15,6 +24,10 @@ public class ZC extends MayOutOfOrderDevice {
super.reset();
}
public void addSection(Section section) {
sections.add(section);
}
public enum Fault implements DeviceFault {
/**ZC故障*/
FAULT{

View File

@ -463,6 +463,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
this.headPosition = null;
this.robotTargetPosition = null;
this.ma = null;
this.cbtcMaMissDuration = 0;
this.itcMaMissDuration = 0;
this.gear = null;
this.speed = 0;
this.targetDistance = 0;
@ -1074,7 +1076,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
return !lastTwoPassedResponders.isEmpty();
}
public void passingResponder(Responder responder) {
public void viaResponder(Responder responder) {
if (lastTwoPassedResponders.isEmpty()) {
lastTwoPassedResponders.offer(responder);
return;
@ -1088,8 +1090,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
}
public boolean isCommunicable() {
Station deviceStation = headPosition.getSection().getDeviceStation();
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault || Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault() || deviceStation.getZc().isFault()) {
Section section = headPosition.getSection();
Station deviceStation = section.getDeviceStation();
if (VirtualRealityTrain.Fault.COMMUNICATION_ABNORMAL == fault
|| Station.Fault.INTERLOCK_MACHINE_FAULT == deviceStation.getFault()
|| !section.anyZcWorking()) {
return false;
}
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.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;
@ -18,6 +19,7 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
@Component
@Slf4j
@ -122,7 +124,7 @@ public class VRTrainRunningService {
if (change)
train.setHeadPosition(headPositionNew);
//列车级别
trainRunLevelUpgrade(simulation, train);
viaResponder(simulation, train, headPosition, headPositionNew);
//计轴器计数
axleCounterCount(simulation, train, headPosition, headPositionNew);
@ -166,36 +168,23 @@ public class VRTrainRunningService {
}
}
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;
}
}
/**
* 穿过应答器
*/
private void viaResponder(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, SectionPosition headPositionNew) {
if (!simulation.getRepository().hasResponder())
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);
train.setMa(null);
}
}
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);
} else {
train.setCbtcMaMissDuration(train.getCbtcMaMissDuration() + SimulationConstants.ATP_LOOP_RATE);
if (!train.isCBTC() && defaultRunLevel.equals(RunLevel.CBTC)) { //如果列车不是CBTC同时线路默认级别是CBTC
train.setCBTCMode();
}
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级别
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) {

View File

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