diff --git a/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java b/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java index 5160064e9..8848f23e3 100644 --- a/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java +++ b/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java @@ -72,16 +72,16 @@ public class VirtualRealityIbpService implements IVirtualRealityIbpService { List upStands = station.getNormalStand(config.isRight(true)); switch (button) { case XXKC: - downStands.forEach(stand -> ciApiService.standHoldTrain(simulation, stand.getCode(), false)); + downStands.forEach(stand -> ciApiService.ibpHoldTrain(simulation, stand.getCode())); break; case XXZZKC: - downStands.forEach(stand -> ciApiService.standHoldTrainCancel(simulation, stand.getCode(), false)); + downStands.forEach(stand -> ciApiService.ibpHoldTrainCancel(simulation, stand.getCode())); break; case SXKC: - upStands.forEach(stand -> ciApiService.standHoldTrain(simulation, stand.getCode(), false)); + upStands.forEach(stand -> ciApiService.ibpHoldTrain(simulation, stand.getCode())); break; case SXZZKC: - upStands.forEach(stand -> ciApiService.standHoldTrainCancel(simulation, stand.getCode(), false)); + upStands.forEach(stand -> ciApiService.ibpHoldTrainCancel(simulation, stand.getCode())); break; case JJTC: upStands.forEach(stand -> ciApiService.standEC(simulation, stand)); @@ -175,9 +175,9 @@ public class VirtualRealityIbpService implements IVirtualRealityIbpService { List downStands = station.getNormalStand(config.isRight(false)); List upStands = station.getNormalStand(config.isRight(true)); //下行扣车 - vrIbp.setXxkcLight(downStands.stream().anyMatch(Stand::isStationHoldTrain)); + vrIbp.setXxkcLight(downStands.stream().anyMatch(Stand::isIbpHoldTrain)); //上行扣车 - vrIbp.setSxkcLight(upStands.stream().anyMatch(Stand::isStationHoldTrain)); + vrIbp.setSxkcLight(upStands.stream().anyMatch(Stand::isIbpHoldTrain)); //紧急停车灯 vrIbp.setJjtcLight(downStands.stream().allMatch(Stand::isEmergencyClosed) && upStands.stream().allMatch(Stand::isEmergencyClosed)); //下行关门 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java index 4709c529a..68f6baee7 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java @@ -130,6 +130,11 @@ public class ZCLogicLoop { if (headPosition.getSection().isFault()) { endList.add(new MovementAuthority.End(headPosition.getSection(), MovementAuthority.EndType.FAULT_SECTION)); } + //非通信车占用区段 + if (section.isNonCbtcOccupy()) { + endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_IN_FRONT_OF_SECTION)); + return endList; + } int count = 0; while (count < 50) { ++count; @@ -161,10 +166,6 @@ public class ZCLogicLoop { endList.add(unlockedOverlapEnd); } } - //非通信车占用区段 - if (section.isNonCbtcOccupy()) { - endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_IN_FRONT_OF_SECTION)); - } // 轨道尽头/问题道岔 Section temp = section.getNextRunningSectionOf(right); if (Objects.isNull(temp)) { // 到尽头 @@ -178,12 +179,12 @@ public class ZCLogicLoop { break; } //非通信车占用区段 -// if (temp.isNonCbtcOccupy()) { -// SectionPosition headPosition1 = train.getHeadPosition(); -// if (!temp.isSamePhysical(headPosition1.getSection().getCode())) { -// endList.add(new MovementAuthority.End(section, MovementAuthority.EndType.NCT_OCCUPIED_IN_FRONT_OF_SECTION)); -// } -// } + if (temp.isNonCbtcOccupy()) { + SectionPosition headPosition1 = train.getHeadPosition(); + if (!temp.isSamePhysical(headPosition1.getSection().getCode())) { + endList.add(new MovementAuthority.End(temp, MovementAuthority.EndType.NCT_OCCUPIED_IN_FRONT_OF_SECTION)); + } + } //检查关闭的区段 MovementAuthority.End cs = checkClosedSection(section); if (cs != null) diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java index 09008298e..8443fde1a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsPlanService.java @@ -6,10 +6,7 @@ import club.joylink.rtss.simulation.cbtc.constant.RunLevel; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; -import club.joylink.rtss.simulation.cbtc.data.map.Route; -import club.joylink.rtss.simulation.cbtc.data.map.Section; -import club.joylink.rtss.simulation.cbtc.data.map.Signal; -import club.joylink.rtss.simulation.cbtc.data.map.Station; +import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.plan.RealRun; import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; @@ -696,6 +693,15 @@ public class AtsPlanService { this.atsStandService.updateStandParkTime(section, parkTime); // 更新停站时间 this.onboardAtpApiService.updateStationParkTime(simulation, train.getGroupNumber(), parkTime); + // 更新扣车状态 + List standList = section.getStandList(); + if (!CollectionUtils.isEmpty(standList)) { + if (standList.stream().anyMatch(Stand::isHoldTrain)) { + onboardAtpApiService.standHoldTrain(simulation, train.getGroupNumber()); + } else { + onboardAtpApiService.standCancelHoldTrain(simulation, train.getGroupNumber()); + } + } } public void handleTrainOnTransfer(Simulation simulation, TrainInfo train, Section section) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java index 206e0cd5a..398f646b5 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java @@ -144,6 +144,9 @@ public class AtsTrainService { throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, String.format("不存在追踪的列车[%s]", groupNumber)); } + TrainInfo trainInfo = repository.findSupervisedTrainByTrip(serviceNumber, tripNumber); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(trainInfo, + String.format("服务号[%s]车次号[%s]的列车已经上线", serviceNumber, tripNumber)); TripPlan tripPlan = repository.getTripPlan(serviceNumber, tripNumber); setPlanTrain(simulation, repository, supervisedTrain, tripPlan); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java index 7a560a2eb..024918ded 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java @@ -262,6 +262,10 @@ public interface CiApiService { void sysHoldTrainCancel(Simulation simulation, String standCode); + void ibpHoldTrain(Simulation simulation, String standCode); + + void ibpHoldTrainCancel(Simulation simulation, String standCode); + void standHoldTrainCancelAll(Simulation simulation, String standCode); /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java index 4289f9a07..f9259c6dc 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java @@ -367,6 +367,18 @@ public class CiApiServiceImpl implements CiApiService { this.standService.cancelSysHoldTrain(simulation, stand); } + @Override + public void ibpHoldTrain(Simulation simulation, String standCode) { + Stand stand = simulation.getRepository().getByCode(standCode, Stand.class); + this.standService.ibpHoldTrain(simulation, stand); + } + + @Override + public void ibpHoldTrainCancel(Simulation simulation, String standCode) { + Stand stand = simulation.getRepository().getByCode(standCode, Stand.class); + this.standService.cancelIbpHoldTrain(simulation, stand); + } + @Override public void standHoldTrainCancelAll(Simulation simulation, String standCode) { Stand stand = simulation.getRepository().getByCode(standCode, Stand.class); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java index 4148aad7e..acd9575b8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java @@ -1458,7 +1458,7 @@ public class RouteService { .getListByType(MapElement.DeviceType.OVERLAP, RouteOverlap.class); for (RouteOverlap routeOverlap : overlapList) { Section section = stopMessage.getSection(); - if (routeOverlap.isLock() && routeOverlap.isRouteLastSection(section)) { + if (/*routeOverlap.isLock() && */routeOverlap.isRouteLastSection(section)) { // 是此延续保护的解锁区段,立即解锁 routeOverlap.releaseImmediately(); log.debug(String.format("收到列车停稳消息,[%s]延续保护[%s],触发区段[%s(%s)]立即解锁", diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/StandService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/StandService.java index ef8cc7a97..96bb844cb 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/StandService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/StandService.java @@ -109,6 +109,27 @@ public class StandService { this.reopenSignal(simulation, stand); } } + + public void ibpHoldTrain(Simulation simulation, Stand stand) { + stand.setIbpHoldTrain(true); + // 关闭出站信号机 + Signal signal = stand.getSection().getSignalOf(stand.isRight()); + if (Objects.nonNull(signal)) { + MapConfig config = simulation.getRepository().getConfig(); + if (config.isStandHoldCloseLogicLight() || !signal.isLogicLight()) { + this.signalService.close(simulation, signal); + } + } + } + + public void cancelIbpHoldTrain(Simulation simulation, Stand stand) { + stand.setIbpHoldTrain(false); + // 如果所有扣车都取消,开放出站信号机 + if (!stand.isHoldTrain()) { + this.reopenSignal(simulation, stand); + } + } + /** * 取消扣车 * diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java index 615d72c87..24f0b607e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/command/CommandBO.java @@ -192,8 +192,8 @@ public class CommandBO { return buildReleaseEBStep(train); return driveStep; } else { //如果列车已经停到目标位置 - if (!DriveMode.AM.equals(train.getDriveMode())) - return getStepOfRm2BmAndOpenAto(command); +// if (!DriveMode.AM.equals(train.getDriveMode())) +// return getStepOfRm2BmAndOpenAto(command); command.getTargetMember().setCommand(null); return null; } @@ -292,17 +292,18 @@ public class CommandBO { boolean stopCorrectly = train.isStopAtThePosition(driveStep.getTargetPosition()); if (stopCorrectly) { //如果列车已经停到目标位置 driveStep.finish(); - if (RunLevel.ITC.equals(train.getRunLevel()) || RunLevel.CBTC.equals(train.getRunLevel())) { - Step upgradeStep = getStepOfRm2BmAndOpenAtoWhileStopAtStopPosition(command); - if (upgradeStep != null) { - return upgradeStep; - } else if (train.isAtoOn()) { - command.getTargetMember().setCommand(null); - return buildAtoTurnDirectionStep(); - } - } else { - command.getTargetMember().setCommand(null); - } + command.getTargetMember().setCommand(null); +// if (RunLevel.ITC.equals(train.getRunLevel()) || RunLevel.CBTC.equals(train.getRunLevel())) { +// Step upgradeStep = getStepOfRm2BmAndOpenAtoWhileStopAtStopPosition(command); +// if (upgradeStep != null) { +// return upgradeStep; +// } else if (train.isAtoOn()) { +// command.getTargetMember().setCommand(null); +// return buildAtoTurnDirectionStep(); +// } +// } else { +// command.getTargetMember().setCommand(null); +// } } else { if (!DriveMode.RM.equals(train.getDriveMode())) { return buildDriverDriveModeChangeOperationStep(train.getGroupNumber(), DriveMode.RM); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java index c195f4c69..6557ada0a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java @@ -1120,4 +1120,17 @@ public class SimulationDataRepository { List routePaths = queryRoutePathsByEnd(end); return routePaths.stream().filter(routePath -> routePath.containsSection(section)).collect(Collectors.toList()); } + + /** + * 根据服务、车次号查找列车 + */ + public TrainInfo findSupervisedTrainByTrip(String serviceNumber, String tripNumber) { + for (TrainInfo trainInfo : this.getSuperviseTrainList()) { + if (Objects.equals(trainInfo.getServiceNumber(), serviceNumber) + && Objects.equals(trainInfo.getTripNumber(), tripNumber)) { + return trainInfo; + } + } + return null; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java index 4cf9283a6..0d45b504d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java @@ -88,6 +88,9 @@ public class Stand extends MayOutOfOrderDevice { /**系统扣车*/ private volatile boolean sysHoldTrain; + /** IBP盘扣车 */ + private boolean ibpHoldTrain; + /** * 区间自动扣车 */ @@ -169,6 +172,7 @@ public class Stand extends MayOutOfOrderDevice { this.stationHoldTrain = false; this.centerHoldTrain = false; this.sysHoldTrain = false; + this.ibpHoldTrain = false; this.autoHoldTrain = false; this.allSkip = false; this.skipSet = Collections.synchronizedSet(new HashSet<>()); @@ -193,7 +197,7 @@ public class Stand extends MayOutOfOrderDevice { */ //TODO 反向扣车是否计算在内 public boolean isHoldTrain() { - return stationHoldTrain || centerHoldTrain || sysHoldTrain; + return stationHoldTrain || centerHoldTrain || sysHoldTrain || ibpHoldTrain; } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java index 1dbd16e51..7d88d6cd8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java @@ -45,6 +45,9 @@ public class StandStatus extends DeviceStatus { @JsonSerialize(using = Boolean2NumSerializer.class) private boolean sysHoldTrain; + @JsonSerialize(using = Boolean2NumSerializer.class) + private boolean ibpHoldTrain; + /**区间自动扣车*/ @JsonSerialize(using = Boolean2NumSerializer.class) private boolean autoHoldTrain; @@ -98,6 +101,7 @@ public class StandStatus extends DeviceStatus { this.stationHoldTrain = stand.isStationHoldTrain(); this.centerHoldTrain = stand.isCenterHoldTrain(); this.sysHoldTrain = stand.isSysHoldTrain(); + this.ibpHoldTrain = stand.isIbpHoldTrain(); this.autoHoldTrain = stand.isAutoHoldTrain(); this.allSkip = stand.isAllSkip(); this.skipSet = new HashSet<>(stand.getSkipSet()); @@ -157,6 +161,11 @@ public class StandStatus extends DeviceStatus { status.setSysHoldTrain(this.sysHoldTrain); change = true; } + if (!Objects.equals(this.ibpHoldTrain, stand.isIbpHoldTrain())) { + this.ibpHoldTrain = stand.isIbpHoldTrain(); + status.setIbpHoldTrain(this.isIbpHoldTrain()); + change = true; + } if (!Objects.equals(this.autoHoldTrain, stand.isAutoHoldTrain())) { this.autoHoldTrain = stand.isAutoHoldTrain(); status.setAutoHoldTrain(this.autoHoldTrain); @@ -240,6 +249,7 @@ public class StandStatus extends DeviceStatus { statusVO.setAutoHoldTrain(autoHoldTrain); statusVO.setCenterHoldTrain(centerHoldTrain); statusVO.setSysHoldTrain(sysHoldTrain); + statusVO.setIbpHoldTrain(ibpHoldTrain); statusVO.setStationHoldTrain(stationHoldTrain); statusVO.setEmergencyClosed(emergencyClosed); statusVO.setTrainParking(trainParking); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java index d01b4ca30..7de033b8c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java @@ -41,6 +41,9 @@ public class StandStatusVO extends DeviceStatusVO { @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean sysHoldTrain; + @JsonSerialize(using = Boolean2NumSerializer.class) + private Boolean ibpHoldTrain; + /**区间自动扣车*/ @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean autoHoldTrain;