【半闭塞、自动闭塞接发车灯逻辑跳转】

This commit is contained in:
weizhihong 2022-05-06 16:15:30 +08:00
parent 489a6930da
commit f6439fbd83
4 changed files with 223 additions and 103 deletions

View File

@ -840,6 +840,11 @@ public class Operation {
*/
ASSIST_PRESS_DOWN_TURN_DIRECTION,
/**
* 改方抬起操作
*/
ASSIST_PRESS_UP_TURN_DIRECTION,
/**
* 总辅助按钮操作
*/

View File

@ -4,6 +4,7 @@ import club.joylink.rtss.constants.DirectionLabelEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping;
import club.joylink.rtss.simulation.cbtc.ATS.service.assist.ButtonThenInterface;
import club.joylink.rtss.simulation.cbtc.ATS.service.assist.ButtonValidInterface;
import club.joylink.rtss.simulation.cbtc.ATS.service.assist.StationDirectionService;
import club.joylink.rtss.simulation.cbtc.Simulation;
@ -29,11 +30,12 @@ public class StationDirectionOperateHandler {
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_DOWN_TURN_DIRECTION)
public void pressDownTurnDirection(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum
, Integer pressDown) {
ButtonValidInterface validInterface = null;
boolean isPressDown = pressDown == 1;
if (isPressDown) {
validInterface = stationDirectionService.turnDirectionPressDownValid;
}
boolean isPressDown = (pressDown == 1);
// 操作类型
Operation.Type operationType = isPressDown ? Operation.Type.ASSIST_PRESS_DOWN_TURN_DIRECTION
: Operation.Type.ASSIST_PRESS_UP_TURN_DIRECTION;
// 验证函数
ButtonValidInterface validInterface = stationDirectionService.getValidMethodByType(operationType);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.CHANGE_DIRECTION, isPressDown, validInterface, null);
}
@ -49,8 +51,9 @@ public class StationDirectionOperateHandler {
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_MAIN_ASSIST)
public void pressMainAssist(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum
, Integer pressDown) {
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum, StationDirection.ButtonTypeEnum.MAIN_ASSIST
, (pressDown == 1), null, stationDirectionService.turnAssistThen);
ButtonThenInterface thenInterface = stationDirectionService.getThenMethodByType(Operation.Type.ASSIST_PRESS_MAIN_ASSIST);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.MAIN_ASSIST, (pressDown == 1), null, thenInterface);
}
/**
@ -62,8 +65,10 @@ public class StationDirectionOperateHandler {
*/
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_RECEIVE_ASSIST)
public void pressReceiveAssist(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum) {
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum, StationDirection.ButtonTypeEnum.RECEIVE_ASSIST
, Boolean.TRUE, stationDirectionService.receiveAssistValid, stationDirectionService.receiveAssistThen);
ButtonValidInterface validInterface = stationDirectionService.getValidMethodByType(Operation.Type.ASSIST_PRESS_RECEIVE_ASSIST);
ButtonThenInterface thenInterface = stationDirectionService.getThenMethodByType(Operation.Type.ASSIST_PRESS_RECEIVE_ASSIST);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.RECEIVE_ASSIST, Boolean.TRUE, validInterface, thenInterface);
}
/**
@ -75,8 +80,10 @@ public class StationDirectionOperateHandler {
*/
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_DELIVER_ASSIST)
public void pressDeliverAssist(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum) {
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum, StationDirection.ButtonTypeEnum.DELIVER_ASSIST
, Boolean.TRUE, stationDirectionService.turnAssistValid, stationDirectionService.deliverAssistThen);
ButtonValidInterface validInterface = stationDirectionService.getValidMethodByType(Operation.Type.ASSIST_PRESS_DELIVER_ASSIST);
ButtonThenInterface thenInterface = stationDirectionService.getThenMethodByType(Operation.Type.ASSIST_PRESS_DELIVER_ASSIST);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.DELIVER_ASSIST, Boolean.TRUE, validInterface, thenInterface);
}
/**
@ -88,8 +95,9 @@ public class StationDirectionOperateHandler {
*/
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_BLOCK)
public void pressBlockBtn(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum) {
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum, StationDirection.ButtonTypeEnum.OCCLUSION
, Boolean.TRUE, null, stationDirectionService.turnBlockThen);
ButtonThenInterface thenInterface = stationDirectionService.getThenMethodByType(Operation.Type.ASSIST_PRESS_BLOCK);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.OCCLUSION, Boolean.TRUE, null, thenInterface);
}
/**
@ -101,8 +109,10 @@ public class StationDirectionOperateHandler {
*/
@OperateHandlerMapping(type = Operation.Type.ASSIST_PRESS_RESTORE)
public void pressRestoreBtn(Simulation simulation, String stationCode, DirectionLabelEnum labelEnum) {
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum, StationDirection.ButtonTypeEnum.RESTORE
, Boolean.TRUE, stationDirectionService.turnRestoreValid, stationDirectionService.turnRestoreThen);
ButtonValidInterface validInterface = stationDirectionService.getValidMethodByType(Operation.Type.ASSIST_PRESS_RESTORE);
ButtonThenInterface thenInterface = stationDirectionService.getThenMethodByType(Operation.Type.ASSIST_PRESS_RESTORE);
stationDirectionService.changeButtonAspect(simulation, stationCode, labelEnum
, StationDirection.ButtonTypeEnum.RESTORE, Boolean.TRUE, validInterface, thenInterface);
}
/**

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.assist;
import club.joylink.rtss.constants.DirectionLabelEnum;
import club.joylink.rtss.entity.DraftMapStationDirection;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
@ -13,8 +14,12 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@ -24,54 +29,26 @@ import java.util.stream.Collectors;
@Component
@Slf4j
public class StationDirectionService {
/**
* 修改按钮状态信息
*
* @param simulation 仿真数据
* @param stationCode 车站编码
* @param label 按钮类型
* @param type 类型
* @param pressDown true按下false抬起
* @param validMethod 操作检验
* @param buttonDoMethod 操作后触发动作
*/
public void changeButtonAspect(Simulation simulation, String stationCode, DirectionLabelEnum label, StationDirection.ButtonTypeEnum type,
boolean pressDown, ButtonValidInterface validMethod, ButtonThenInterface buttonDoMethod) {
Station curStation = getStationByCode(simulation, stationCode);
StationDirection stationDirection = curStation.getStationDirectionMap().get(label);
// 检验操作
if (validMethod != null) {
validMethod.valid(simulation, stationDirection);
}
// 修改状态
stationDirection.modifyButtonStatus(type, pressDown);
// 后续动作
if (buttonDoMethod != null) {
buttonDoMethod.doThen(simulation, stationDirection);
}
}
/**
* 刷新区间灯状态
* 指示灯状态操作集合
*/
public void refreshSectionLightStatus(Simulation simulation, DraftMapStationDirection draftMapStationDirection) {
Station station = getStationByCode(simulation, draftMapStationDirection.getStationCode());
StationDirection stationDirection = station.getStationDirectionMap().get(draftMapStationDirection.getLabelEnum());
if (stationDirection == null) {
return;
}
// 刷新接发车点灯状态
stationDirection.refreshAspectStatus();
// 刷新区段占用状态
stationDirection.refreshSectionStatus();
// 辅助灯状态
stationDirection.refreshAssistStatus();
}
private Map<StationDirection.DirectionRunModel, BiConsumer<StationDirection, StationDirection>> aspectStatusHandleMap;
/**
* 操作按钮验证操作集合
*/
private Map<Operation.Type, ButtonValidInterface> operationButtonValidMap;
/**
* 操作按钮后续操作集合
*/
private Map<Operation.Type, ButtonThenInterface> operationButtonThenMap;
/**
* 改方按钮按下校验
*/
public ButtonValidInterface turnDirectionPressDownValid = (simulation, stationDirection) -> {
private ButtonValidInterface turnDirectionPressDownValid = (simulation, stationDirection) -> {
// 如果处于发辅助状态说明存在异常情况正在人为处理直接跳过判断
if (stationDirection.isMainAssistStatus() && stationDirection.isDeliverAssistStatus()) {
return;
@ -111,7 +88,7 @@ public class StationDirectionService {
/**
* 发辅助按钮操作校验
*/
public ButtonValidInterface turnAssistValid = (simulation, stationDirection) -> {
private ButtonValidInterface turnAssistValid = (simulation, stationDirection) -> {
if (!stationDirection.isMainAssistStatus()) {
throw new SimulationException(SimulationExceptionType.Operation_Cannot_handed, "操作异常:总辅助按钮未按下");
}
@ -120,7 +97,7 @@ public class StationDirectionService {
/**
* 接辅助按钮操作校验
*/
public ButtonValidInterface receiveAssistValid = (simulation, stationDirection) -> {
private ButtonValidInterface receiveAssistValid = (simulation, stationDirection) -> {
// 判断总辅助
this.turnAssistValid.valid(simulation, stationDirection);
// 获取邻站实体
@ -151,7 +128,7 @@ public class StationDirectionService {
/**
* 总辅助后续操作
*/
public ButtonThenInterface turnAssistThen = (simulation, stationDirection) -> {
private ButtonThenInterface turnAssistThen = (simulation, stationDirection) -> {
// 总辅助弹起后接发辅助倒计时重置
if (!stationDirection.isMainAssistStatus()) {
stationDirection.setReceiveAssistStatus(false);
@ -163,7 +140,7 @@ public class StationDirectionService {
/**
* 接辅助按钮后续操作
*/
public ButtonThenInterface receiveAssistThen = (simulation, stationDirection) -> {
private ButtonThenInterface receiveAssistThen = (simulation, stationDirection) -> {
// 按下接辅助弹起发辅助
stationDirection.setDeliverAssistStatus(false);
// 重新设置倒计时时间
@ -173,7 +150,7 @@ public class StationDirectionService {
/**
* 接辅助按钮后续操作
*/
public ButtonThenInterface deliverAssistThen = (simulation, stationDirection) -> {
private ButtonThenInterface deliverAssistThen = (simulation, stationDirection) -> {
// 按下发辅助弹起发辅助
stationDirection.setReceiveAssistStatus(false);
// 重新设置倒计时时间
@ -183,27 +160,20 @@ public class StationDirectionService {
/**
* 复原按钮操作验证
*/
public ButtonValidInterface turnRestoreValid = (simulation, stationDirection) -> {
// 接车方向需要判断是否已过信号机内方第一道岔区段
if (StationDirection.DirectionRunModel.S.equals(stationDirection.getRunModel())) {
if (StationDirection.ReceiveAndDeliverModel.R.equals(stationDirection.getRunStatus())) {
throw new SimulationException(SimulationExceptionType.Operation_Cannot_handed, "操作异常:列车未到站");
}
if (StationDirection.ReceiveAndDeliverModel.A.equals(stationDirection.getRunStatus())
&& stationDirection.getOccupiedLabel().intValue() != 1) {
throw new SimulationException(SimulationExceptionType.Operation_Cannot_handed, "操作异常:列车未到站");
}
}
private ButtonValidInterface turnRestoreValid = (simulation, stationDirection) -> {
};
/**
* 恢复按钮后续操作
*/
public ButtonThenInterface turnRestoreThen = (simulation, stationDirection) -> {
private ButtonThenInterface turnRestoreThen = (simulation, stationDirection) -> {
try {
// 只有半自动闭塞接车方向可以操作全点亮后才可做
if (StationDirection.DirectionRunModel.S.equals(stationDirection.getRunModel())
&& StationDirection.ReceiveAndDeliverModel.A.equals(stationDirection.getRunStatus())) {
// 只有半自动闭塞接车方向可以操作全点亮可以操作
boolean isRestoreOperation = StationDirection.DirectionRunModel.S.equals(stationDirection.getRunModel())
&& (StationDirection.ReceiveAndDeliverModel.A.equals(stationDirection.getRunStatus())
|| StationDirection.ReceiveAndDeliverModel.R.equals(stationDirection.getRunStatus()));
if (isRestoreOperation) {
// 将本方向接发车状态恢复
stationDirection.reset();
// 获取邻站实体
@ -229,7 +199,7 @@ public class StationDirectionService {
/**
* 闭塞按钮操作
*/
public ButtonThenInterface turnBlockThen = (simulation, stationDirection) -> {
private ButtonThenInterface turnBlockThen = (simulation, stationDirection) -> {
// 获取邻站实体
Optional<Station> adjacentStationOptional = getAdjacentStationOptional(simulation, stationDirection);
// 存在邻站
@ -253,6 +223,139 @@ public class StationDirectionService {
}
};
/**
* 自动模式
*/
private BiConsumer<StationDirection, StationDirection> automaticHandle = (stationDirection, adjacentDirection) -> {
adjacentDirection.setRunStatus(StationDirection.ReceiveAndDeliverModel.R); // 邻站对应方向修改为接车方
};
/**
* 半自动模式
*/
private BiConsumer<StationDirection, StationDirection> semiAutomaticHandle = (stationDirection, adjacentDirection) -> {
if (StationDirection.IndicatorStatusEnum.O.equals(stationDirection.getDeliverAspect())) { // 发车灯变为占用时接车灯也会占用
adjacentDirection.setReceiveAspect(StationDirection.IndicatorStatusEnum.O); // 接车方接车灯占用
}
};
/**
* 默认
*/
private BiConsumer<StationDirection, StationDirection> defaultHandle = (stationDirection, adjacentDirection) -> {
};
@PostConstruct
private void init() {
// 指示灯状态操作集合
this.aspectStatusHandleMap = new HashMap<>();
// 自动模式
this.aspectStatusHandleMap.put(StationDirection.DirectionRunModel.A, this.automaticHandle);
// 半自动模式
this.aspectStatusHandleMap.put(StationDirection.DirectionRunModel.S, this.semiAutomaticHandle);
// 操作按钮验证函数集合
this.operationButtonValidMap = new HashMap<>();
// 改方按下验证函数
this.operationButtonValidMap.put(Operation.Type.ASSIST_PRESS_DOWN_TURN_DIRECTION, this.turnDirectionPressDownValid);
// 接辅助按下验证函数
this.operationButtonValidMap.put(Operation.Type.ASSIST_PRESS_RECEIVE_ASSIST, this.receiveAssistValid);
// 发辅助按下验证函数
this.operationButtonValidMap.put(Operation.Type.ASSIST_PRESS_DELIVER_ASSIST, this.turnAssistValid);
// 复原按下验证函数
this.operationButtonValidMap.put(Operation.Type.ASSIST_PRESS_RESTORE, this.turnRestoreValid);
// 操作按钮后续操作集合
this.operationButtonThenMap = new HashMap<>();
// 总辅助后续操作
this.operationButtonThenMap.put(Operation.Type.ASSIST_PRESS_MAIN_ASSIST, this.turnAssistThen);
// 接辅助后续操作
this.operationButtonThenMap.put(Operation.Type.ASSIST_PRESS_RECEIVE_ASSIST, this.receiveAssistThen);
// 发辅助后续操作
this.operationButtonThenMap.put(Operation.Type.ASSIST_PRESS_DELIVER_ASSIST, this.deliverAssistThen);
// 闭塞后续操作
this.operationButtonThenMap.put(Operation.Type.ASSIST_PRESS_BLOCK, this.turnBlockThen);
// 复原后续操作
this.operationButtonThenMap.put(Operation.Type.ASSIST_PRESS_RESTORE, this.turnRestoreThen);
}
/**
* 修改按钮状态信息
*
* @param simulation 仿真数据
* @param stationCode 车站编码
* @param label 按钮类型
* @param type 类型
* @param pressDown true按下false抬起
* @param validMethod 操作检验
* @param buttonDoMethod 操作后触发动作
*/
public void changeButtonAspect(Simulation simulation, String stationCode, DirectionLabelEnum label, StationDirection.ButtonTypeEnum type,
boolean pressDown, ButtonValidInterface validMethod, ButtonThenInterface buttonDoMethod) {
Station curStation = getStationByCode(simulation, stationCode);
StationDirection stationDirection = curStation.getStationDirectionMap().get(label);
// 检验操作
if (validMethod != null) {
validMethod.valid(simulation, stationDirection);
}
// 修改状态
stationDirection.modifyButtonStatus(type, pressDown);
// 后续动作
if (buttonDoMethod != null) {
buttonDoMethod.doThen(simulation, stationDirection);
}
}
/**
* 刷新区间灯状态
*/
public void refreshSectionLightStatus(Simulation simulation, DraftMapStationDirection draftMapStationDirection) {
Station station = getStationByCode(simulation, draftMapStationDirection.getStationCode());
StationDirection stationDirection = station.getStationDirectionMap().get(draftMapStationDirection.getLabelEnum());
if (stationDirection == null) {
return;
}
// 刷新接发车点灯状态
stationDirection.refreshAspectStatus();
// 发车方向会影响下游接车方向
if (StationDirection.ReceiveAndDeliverModel.D.equals(stationDirection.getRunStatus())) {
// 获取邻站实体
Optional<Station> adjacentStationOptional = getAdjacentStationOptional(simulation, stationDirection);
if (adjacentStationOptional.isPresent()) { // 邻站存在时
// 接车方向
StationDirection adjacentDirection = adjacentStationOptional.get().getStationDirectionMap()
.get(stationDirection.getRelativeDirectionLabelEnum());
if (adjacentDirection != null) {
this.aspectStatusHandleMap.getOrDefault(stationDirection.getRunModel(), this.defaultHandle)
.accept(stationDirection, adjacentDirection);
}
}
}
// 刷新区段占用状态
stationDirection.refreshSectionStatus();
// 辅助灯状态
stationDirection.refreshAssistStatus();
}
/**
* 根据操作类型获取验证方法
*
* @param type 类型
* @return 验证方法
*/
public ButtonValidInterface getValidMethodByType(Operation.Type type) {
return this.operationButtonValidMap.get(type);
}
/**
* 根据操作类型获取后续操作方法
*
* @param type 类型
* @return 操作方法
*/
public ButtonThenInterface getThenMethodByType(Operation.Type type) {
return this.operationButtonThenMap.get(type);
}
/**
* 获取当前车站实体
*

View File

@ -213,15 +213,19 @@ public class StationDirection extends MapNamedElement {
*/
public void modifyButtonStatus(ButtonTypeEnum type, boolean pressDown) {
switch (type) {
// 改方
case CHANGE_DIRECTION:
this.changeDirectionStatus = pressDown;
break;
// 接辅助
case RECEIVE_ASSIST:
this.receiveAssistStatus = pressDown;
break;
// 发辅助
case DELIVER_ASSIST:
this.deliverAssistStatus = pressDown;
break;
// 总辅助
case MAIN_ASSIST:
this.mainAssistStatus = pressDown;
break;
@ -315,17 +319,18 @@ public class StationDirection extends MapNamedElement {
}
/**
* 如果信号灯所在区段任意一边被锁闭
* 判断信号机发车方向的三个区段是否解锁
*
* @return 锁闭状态
*/
private boolean judgeSignalLock() {
// 发车方向
boolean isRight = this.deliverRouteList.stream().findAny().get().isRight();
Section section = this.getSignal().getSection();
boolean isLock = section.isRouteLock();
// 判断信号机所在下一个区段是否锁闭
if (!isLock) {
section = section.getNextSection(getSignal().isRight());
isLock = section.isRouteLock();
boolean isLock = section.isOccupied();
for (int index = 0; !isLock && index < 3 && section != null; index++) {
isLock = section.isOccupied();
section = section.getNextSection(isRight);
}
return isLock;
}
@ -387,28 +392,25 @@ public class StationDirection extends MapNamedElement {
* 半自动闭塞,不会自动恢复
*/
private void semiAutomaticModelAspectStatus() {
// 点灯
if (ReceiveAndDeliverModel.R.equals(this.runStatus)) { // 接车方向
if (IndicatorStatusEnum.F.equals(this.receiveAspect) && IndicatorStatusEnum.O.equals(this.sectionAspect)) {
this.receiveAspect = IndicatorStatusEnum.O;
}
// 信号灯区段
Section section = this.getSignal().getSection().getNextSection(getSignal().isRight());
// 如果区段已被占用也点亮发车灯
if (section != null && section.isOccupied()) {
this.runStatus = ReceiveAndDeliverModel.A;
this.deliverAspect = IndicatorStatusEnum.O;
// 判断有车经过
this.occupiedLabel.incrementAndGet();
}
} else if (ReceiveAndDeliverModel.D.equals(this.runStatus)) { // 发车方向
// 进入区间后标为占用且不主动恢复
if (IndicatorStatusEnum.F.equals(this.deliverAspect) && IndicatorStatusEnum.O.equals(this.sectionAspect)) {
this.deliverAspect = IndicatorStatusEnum.O;
}
} else if (ReceiveAndDeliverModel.NO.equals(this.runStatus)) {
// 已复原恢复空闲状态
if (ReceiveAndDeliverModel.NO.equals(this.runStatus)) {
this.deliverAspect = IndicatorStatusEnum.F;
this.receiveAspect = IndicatorStatusEnum.F;
} else {
// 信号灯区段
Section section = this.getSignal().getSection().getNextSection(getSignal().isRight());
boolean isSectionLock = (section != null && section.isOccupied());
// 点灯
if (ReceiveAndDeliverModel.R.equals(this.runStatus) && isSectionLock) { // 接车方向如果区段已被占用接车方双红
this.runStatus = ReceiveAndDeliverModel.A;
this.deliverAspect = IndicatorStatusEnum.O;
this.receiveAspect = IndicatorStatusEnum.O;
// 判断有车经过
this.occupiedLabel.incrementAndGet();
} else if (ReceiveAndDeliverModel.D.equals(this.runStatus) && isSectionLock) { // 发车方向
// 进入区间后标为占用且不主动恢复
this.deliverAspect = IndicatorStatusEnum.O;
}
}
}