diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ResponderService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ResponderService.java index 577655435..d9d686855 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ResponderService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ResponderService.java @@ -1,56 +1,43 @@ package club.joylink.rtss.simulation.cbtc.ATP.ground; -import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.Simulation; 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.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Queue; +import java.util.Objects; -/** TODO - * 应答器信号 +/** + * 应答器信号发射 */ @Slf4j @Component public class ResponderService { - @Autowired - private CiApiService ciApiService; - - /**循环逻辑,列车到达触发电磁信号,交换数据*/ - public void exchangeData2Train(Simulation simulation){ - Map> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap(); - if(CollectionUtils.isEmpty(sectionRespondersMap)){ - return; + /** + * 列车经过应答器触发电磁信号 + */ + public Responder activeExchangeData(Simulation simulation, VirtualRealityTrain train) { + Map> sectionRespondersMap = simulation.getRepository().getSectionRespondersMap(); + if (CollectionUtils.isEmpty(sectionRespondersMap)) { + 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)).findAny().orElse(null); + if (Objects.isNull(activeResponder)) return null; log.info("列车触发应答器交换数据"); - List trainList = simulation.getRepository().getOnlineTrainList(); - trainList.forEach(train -> { - //电磁触发以列车头位置(车载应答器)模拟 - SectionPosition headPosition = train.getHeadPosition(); - Section section = headPosition.getSection(); - var responders = sectionRespondersMap.get(section); - if(CollectionUtils.isEmpty(responders)) return; -// if(responders.f) - }); - + activeResponder.exchangeData(train); + return activeResponder; } - - /**接受LEU移动授权*/ - public void receiveMA(){ - - log.info("应答器接收移动授权信息"); - - } - - } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java index 233d12ac7..d271dcd53 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/MapDeviceBuilder.java @@ -942,6 +942,18 @@ public class MapDeviceBuilder { errMsgList.add(String.format("应答器[%s(%s)]类型未设置", responderVO.getName(), responderVO.getCode())); } else { responder.setType(responderVO.getType()); + if (responder.isVB()){ + if(StringUtils.isEmpty(responderVO.getSignalCode())){ + errMsgList.add(String.format("可变应答器[%s(%s)]未设置关联信号机", responderVO.getName(), responderVO.getCode())); + }else{ + Signal signal = (Signal) elementMap.get(responderVO.getSignalCode()); + if(Objects.isNull(signal)){ + errMsgList.add(String.format("可变应答器[%s(%s)]关联信号机[%s]不存在", responderVO.getName(), responderVO.getCode(),responderVO.getSignalCode())); + }else{ + responder.setSignal(signal); + } + } + } } Station deviceStation = (Station) elementMap.get(responderVO.getStationCode()); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Responder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Responder.java index 6eff9831a..795c8d29a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Responder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Responder.java @@ -1,16 +1,21 @@ package club.joylink.rtss.simulation.cbtc.data.map; -import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority; +import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import lombok.Getter; import lombok.Setter; +import java.util.Objects; + /** - * 区段 + * 应答器仿真数据 */ @Getter @Setter public class Responder extends MapNamedElement { + private final static int ACTIVE_DISTANCE = 3; //应答器激活距离, 单位 m + public Responder(String code, String name) { super(code, name, DeviceType.RESPONDER); } @@ -28,40 +33,45 @@ public class Responder extends MapNamedElement { /** 在区段上的偏移量*/ private float sectionOffset; + /**VB关联信号机*/ + private Signal signal; - // ------------------状态属性--------------------- + + // ------------------LEU同步的状态--------------------- /**坡度*/ /**弯度*/ /**限速*/ - /**移动授权位置*/ - private MovementAuthority ma; + /**移动授权*/ /**其它警示信息:升降弓/进出隧道/鸣笛/...*/ // ------------------操作--------------------- - /***LEU状态数据同步给应答器*/ - - - /**推送数据给列车*/ - @Override public void reset() { - } - public boolean isFB(){ + public boolean isFB() { return ResponderType.FB == type; } - public boolean isVB(){ + + public boolean isVB() { return ResponderType.VB == type; } - public boolean isIB(){ + + public boolean isIB() { return ResponderType.IB == type; } + public boolean active(SectionPosition headPosition) { + return Objects.equals(physicalSection, headPosition.getSection()) && Math.abs(sectionOffset - headPosition.getOffset()) <= ACTIVE_DISTANCE; + } + + public void exchangeData(VirtualRealityTrain train) { + train.passingResponder(this); + } public enum ResponderType { /** 固定应答器*/ FB, diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/FixedQueue.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/FixedQueue.java index 42ee53b5f..18b4b1383 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/FixedQueue.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/FixedQueue.java @@ -1,15 +1,12 @@ package club.joylink.rtss.simulation.cbtc.data.support; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Queue; +import java.util.*; public final class FixedQueue implements Queue { private final int limit; - private final Queue queue = new LinkedList<>(); + private final LinkedList queue = new LinkedList<>(); public FixedQueue(int limit){ this.limit = limit; @@ -18,7 +15,6 @@ public final class FixedQueue implements Queue { @Override public boolean offer(E e){ if(queue.size() >= limit){ - //如果超出长度,入队时,先出队 queue.poll(); } return queue.offer(e); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java index 1d4ead075..98cbfbde8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java @@ -55,6 +55,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice { */ public static final float RM_ATP_Speed = 25 / 3.6f; + + public static final int Responders_Record = 2; + // -----------列车基础属性----------- /** * 列车长度 @@ -360,7 +363,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { /**最近经过的两个应答器*/ - private Queue lastTwoPassedResponders = new FixedQueue<>(2); + private Queue lastTwoPassedResponders = new FixedQueue<>(Responders_Record); public void setAtpOn(boolean on) { this.atpOn = on; @@ -425,6 +428,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { this.pantograph1Up = true; this.pantograph2Up = true; this.linkTrain = null; + this.lastTwoPassedResponders.clear(); } public boolean isEB() { @@ -449,6 +453,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice { return Objects.equals(RunLevel.ITC, this.runLevel); } + public boolean isIL() { + return Objects.equals(RunLevel.IL, this.runLevel); + } + /** * 初始化方向和位置 * @@ -663,6 +671,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice { this.runLevel = RunLevel.ITC; } + public void setCBTCMode() { + this.runLevel = RunLevel.CBTC; + } + public void changeEndsStart() { this.changeEndsRemainTime = SimulationConstants.TRAIN_CHANGE_END_TIME * 1000; this.changeEnds = true; @@ -979,11 +991,34 @@ public class VirtualRealityTrain extends VirtualRealityDevice { } } + public boolean passedResponder() { + return !lastTwoPassedResponders.isEmpty(); + } + + public void passingResponder(Responder responder) { + if (lastTwoPassedResponders.isEmpty()) { + lastTwoPassedResponders.offer(responder); + return; + } + lastTwoPassedResponders.remove(responder); + lastTwoPassedResponders.offer(responder); + } + + public void clearResponders() { + lastTwoPassedResponders.clear(); + } public enum Fault { /** * 通信异常 */ - COMMUNICATION_ABNORMAL, + COMMUNICATION_ABNORMAL{ + @Override + public void fix(MapElement device) { + VirtualRealityTrain train = (VirtualRealityTrain) device; + train.setFault(null); + train.getLastTwoPassedResponders().clear(); + } + }, DRIVE_FAULT { @Override public boolean apply(MapElement device) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/virtual/VRTrainRunningService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/virtual/VRTrainRunningService.java index 90ad4d873..8eb17a588 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/virtual/VRTrainRunningService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/virtual/VRTrainRunningService.java @@ -1,31 +1,39 @@ 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.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 lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Objects; @Component @Slf4j public class VRTrainRunningService { + @Autowired + private ResponderService responderService; + public void trainRunning(Simulation simulation) { List trainList = simulation.getRepository().getOnlineTrainList(); - trainList.forEach(train -> this.trainRunning(train)); + trainList.forEach(train -> this.trainRunning(simulation,train)); } /** * 列车根据功率计算速度,根据速度计算位移,并更新列车所在区段位置 - * + *@param simulation * @param train */ - public void trainRunning(VirtualRealityTrain train) { + public void trainRunning(Simulation simulation,VirtualRealityTrain train) { // 原始速度 float originSpeed = train.getSpeed(); float fr = (float) (2.27 + 0.00156f * originSpeed * 3.6); // 基本阻力 @@ -62,5 +70,26 @@ 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"); + return; + } + } + } else if (train.isITC()) { + if (train.getLastTwoPassedResponders().size() == VirtualRealityTrain.Responders_Record) { + train.setCBTCMode(); + log.info("列车越过两个应答器从ITC升级CBTC"); + return; + } + + } } } diff --git a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapResponderVO.java b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapResponderVO.java index 286f879db..26e0b8a2f 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapResponderVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/newmap/MapResponderVO.java @@ -58,4 +58,8 @@ public class MapResponderVO { /**关联区段 编号*/ @NotNull(message="关联区段不能为Null") private String sectionCode; + + /**关联信号机 编号*/ + @NotNull(message="关联信号机不能为Null") + private String signalCode; }