Merge remote-tracking branch 'origin/test' into wechat-micro2-login
This commit is contained in:
commit
8d275849a1
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
// }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
/**
|
||||
* 左行线
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -43,4 +43,9 @@ public class MapZcVO {
|
||||
* 管控集中站列表
|
||||
*/
|
||||
private List<String> concentrateStationList;
|
||||
|
||||
/**
|
||||
* 管理的区段列表
|
||||
*/
|
||||
private List<String> managedSectionList;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user