diff --git a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java index 79cda6032..3129c1a61 100644 --- a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java +++ b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java @@ -3,6 +3,7 @@ package club.joylink.rtss.controller.simulation; import club.joylink.rtss.controller.advice.AuthenticateInterceptor; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.services.IVirtualRealityIbpService; +import club.joylink.rtss.services.simulation.SimulationSupportService; import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm; import club.joylink.rtss.simulation.cbtc.ATS.data.SimulationLog; import club.joylink.rtss.simulation.cbtc.GroupSimulationService; @@ -10,6 +11,7 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO; import club.joylink.rtss.simulation.cbtc.communication.vo.fault.DeviceFaultInfo; import club.joylink.rtss.simulation.cbtc.data.status.IbpStatus; +import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vo.SimulationVO; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; @@ -55,6 +57,9 @@ public class SimulationV1Controller { @Autowired private IVirtualRealityIbpService iVirtualRealityIBPService; + @Autowired + private SimulationSupportService simulationSupportService; + @ApiOperation(value = "根据产品类型创建仿真") @GetMapping("") public String simulation(Long mapId, String prdType, @@ -300,4 +305,10 @@ public class SimulationV1Controller { public PageVO getLog(@PathVariable String group, SimulationLogPagedQueryVO queryVO) { return groupSimulationService.getLog(group, queryVO); } + + @ApiOperation("查询进路路径") + @GetMapping("/{group}/queryRoutePaths") + public List queryRoutePaths(@PathVariable String group, String groupNumber, String standCode, String signalCode) { + return simulationSupportService.queryRoutePaths(group, groupNumber, standCode, signalCode); + } } diff --git a/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java new file mode 100644 index 000000000..22079e229 --- /dev/null +++ b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java @@ -0,0 +1,45 @@ +package club.joylink.rtss.services.simulation; + +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.GroupSimulationService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.CalculateService; +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.Stand; +import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; +import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +/** + * 仿真运行支持 + */ +@Service +public class SimulationSupportService { + @Autowired + private GroupSimulationService groupSimulationService; + + public List queryRoutePaths(String group, String groupNumber, String standCode, String signalCode) { + Simulation simulation = groupSimulationService.getSimulationByGroup(group); + Section destination; + if (StringUtils.hasText(standCode)) { + Stand stand = simulation.getRepository().getByCode(standCode, Stand.class); + destination = stand.getSection(); + } else if (StringUtils.hasText(signalCode)) { + Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); + destination = signal.getSection(); + } else { + throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception("站台和信号机必须选一个"); + } + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + Section startSection = train.getHeadPosition().getSection(); + + List routePaths = CalculateService.queryRoutePathsOnDirection(startSection, destination, train.isRight()); + return RoutePathVO.convert(routePaths); + } +} diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/GeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/GeneratorNew.java index a841a8b0c..e5cfb29a5 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/GeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/GeneratorNew.java @@ -1,22 +1,22 @@ package club.joylink.rtss.services.training.generatornew; +import club.joylink.rtss.constants.BusinessConsts; import club.joylink.rtss.services.training.constant.TrainingConsts; import club.joylink.rtss.services.training.data.GenerateConfig; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.storage.StorageSimulation; -import club.joylink.rtss.constants.BusinessConsts; import club.joylink.rtss.util.ReflectionUtils; -import club.joylink.rtss.vo.client.map.newmap.MapTurnBackStrategyVO; -import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO; -import club.joylink.rtss.vo.client.training.definition.OperatePlaceholderVO; -import club.joylink.rtss.vo.client.training.definition.OperateStepVO; import club.joylink.rtss.vo.client.map.MapVO; import club.joylink.rtss.vo.client.map.newmap.MapAutomaticRouteButtonVO; import club.joylink.rtss.vo.client.map.newmap.MapCycleButtonVO; +import club.joylink.rtss.vo.client.map.newmap.MapTotalGuideLockButtonVO; +import club.joylink.rtss.vo.client.map.newmap.MapTurnBackStrategyVO; import club.joylink.rtss.vo.client.training.TrainingNewVO; import club.joylink.rtss.vo.client.training.TrainingStepVO; -import org.springframework.util.CollectionUtils; +import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO; +import club.joylink.rtss.vo.client.training.definition.OperatePlaceholderVO; +import club.joylink.rtss.vo.client.training.definition.OperateStepVO; import org.springframework.util.StringUtils; import java.util.ArrayList; @@ -97,6 +97,9 @@ public interface GeneratorNew { } else if (mapButton instanceof MapTurnBackStrategyVO) { s.setDeviceCode(((MapTurnBackStrategyVO) mapButton).getCode()); break; + } else if (mapButton instanceof MapTotalGuideLockButtonVO) { + s.setDeviceCode(((MapTotalGuideLockButtonVO) mapButton).getCode()); + break; } } case NULL: @@ -128,6 +131,8 @@ public interface GeneratorNew { trainingVO.setLocateDeviceCode(((MapAutomaticRouteButtonVO) mapButton).getCode()); } else if (mapButton instanceof MapTurnBackStrategyVO) { trainingVO.setLocateDeviceCode(((MapTurnBackStrategyVO) mapButton).getCode()); + } else if (mapButton instanceof MapTotalGuideLockButtonVO) { + trainingVO.setLocateDeviceCode(((MapTotalGuideLockButtonVO) mapButton).getCode()); } } } diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SignalGeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SignalGeneratorNew.java index 493a1171f..2b4fdd213 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SignalGeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SignalGeneratorNew.java @@ -5,8 +5,10 @@ import club.joylink.rtss.services.training.generatornew.GeneratorNew; import club.joylink.rtss.services.training.generatornew.annotation.GeneratorSelectorNew; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder; import club.joylink.rtss.simulation.cbtc.data.map.Cycle; import club.joylink.rtss.simulation.cbtc.data.map.Route; +import club.joylink.rtss.simulation.cbtc.data.map.SectionPath; import club.joylink.rtss.simulation.cbtc.data.map.Signal; import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO; @@ -179,17 +181,16 @@ public class SignalGeneratorNew implements GeneratorNew { case Signal_Human_Release_Route: { // 查询信号机为始端的进路列表,设置背景为进路排列,且进路接近区段占用 // todo 接近区段设置列车逻辑较复杂,推迟实现 + for (Route route : signal.getRouteList()) { + deviceStatusModifyTool.openRouteDirect(simulation, route); + deviceStatusModifyTool.closeSignalDirectly(route.getStart()); + deviceStatusModifyTool.loadManualTrainOfGroup(simulation, "001", signal.getSection(), signal.isRight()); + // todo 在接近区段设置一辆列车 + trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO)); + // 仿真重置 + simulation.reset(); + } continue; -// List routeList = signal.getRouteList(); -// for (Route route : routeList) { -// deviceStatusModifyTool.openRouteDirect(simulation, route); -// List
approachSectionList = signal.getApproachSectionList(); -// // todo 在接近区段设置一辆列车 -// trainingVOList.add(this.build(config, simulation, signal, operateDefinitionVO)); -// // 仿真重置 -// simulation = SimulationBuilder.build(simulation.getBuildParams()); -// } -// continue; } case Signal_Close_Signal: { // 查询进路,设置背景为进路已排列 @@ -328,26 +329,28 @@ public class SignalGeneratorNew implements GeneratorNew { } case Signal_Set_Guide: { // 若信号机可开引导信号,则生成实训,暂不设置背景(暂时先简单处理,此处业务比较复杂,需明确后再生成各种情况的实训) -// if (!signal.isCallOn()) { // 不是引导信号机,不生成 -// continue; -// } else { -// //非折返进路办理引导 -// List notTurnBackRouteList = routeList.stream() -// .filter(route -> !route.isTurnBack()) -// .collect(Collectors.toList()); -// if (routeLikeHa1) { -// // 对于ATP进路、地面联锁进路、引导进路类的,取引导进路 -// notTurnBackRouteList = notTurnBackRouteList.stream() -// .filter(route -> route.isGuide()) -// .collect(Collectors.toList()); -// } -// for (Route route : notTurnBackRouteList) { -// trainingVOList.add(this.build(config, simulation, route, operateDefinitionVO)); -// // 仿真重置 -// simulation.reset(); -// } -// continue; -// } + if (signal.isCallOn()) { // 不是引导信号机,不生成 + //非折返进路办理引导 + List notTurnBackRouteList = routeList.stream() + .filter(route -> !route.isTurnBack()) + .collect(Collectors.toList()); + if (routeLikeHa1) { + // 对于ATP进路、地面联锁进路、引导进路类的,取引导进路 + notTurnBackRouteList = notTurnBackRouteList.stream() + .filter(route -> route.isGuide()) + .collect(Collectors.toList()); + } + for (Route route : notTurnBackRouteList) { + if(simulation.getRepository().getConfig().isGuideNeedRouteSettingFirst()){ + deviceStatusModifyTool.openRouteDirect(simulation, route); + deviceStatusModifyTool.closeSignalDirectly(route.getStart()); + } + deviceStatusModifyTool.loadManualTrainOfGroup(simulation, "001",signal.getSection(),signal.isRight()); + trainingVOList.add(this.build(config, simulation, route,null, operateDefinitionVO)); + // 仿真重置 + simulation.reset(); + } + } continue; } case Signal_Close_Guide: { diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/base/StandGeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/base/StandGeneratorNew.java index 2cc1b6633..412f0c0ad 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/base/StandGeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/base/StandGeneratorNew.java @@ -6,15 +6,21 @@ import club.joylink.rtss.services.training.generatornew.annotation.GeneratorSele import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.TrainType; +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.Stand; import club.joylink.rtss.constants.MapPrdTypeEnum; +import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityDevice; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; +import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO; import club.joylink.rtss.vo.client.training.TrainingNewVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; import java.util.*; @@ -22,6 +28,8 @@ import java.util.*; public class StandGeneratorNew implements GeneratorNew { protected static final int PARKING_TIME = 20; + @Autowired + private DeviceStatusModifyTool deviceStatusModifyTool; @Override public List generate(GenerateConfig config, Simulation simulation, OperateDefinitionVO operateDefinitionVO) { @@ -43,9 +51,11 @@ public class StandGeneratorNew implements GeneratorNew { stand.setTypeStrategy(Stand.TurnBackType.AUTO); break; case Stand_Set_Hold_Train_Auto: + stand.setTrainLimit(-1); + break; case Stand_Cancel_Hold_Train_Auto: - // 功能暂未实现,不生成 - continue; + stand.setTrainLimit(3); + break; case Stand_Set_Jump_Stop: { // todo 应该设置列车在上一车站,暂时简单处理 // 终点车站正常应不能设置跳停,暂时也不处理 @@ -69,9 +79,15 @@ public class StandGeneratorNew implements GeneratorNew { standList.forEach(stand1 -> stand1.setCenterHoldTrain(true)); break; } - case Stand_Early_Depart:{ - // 提前发车需要列车,暂不生成 - continue; + case Stand_Early_Depart: { + List routeList = simulation.getRepository().getRouteList(); + Route route = routeList.stream().filter(route1 -> + (route1.getStart().getSection() == stand.getSection() || route1.containSection(stand.getSection()) && !route1.routeLastSection(stand.getSection())) && Objects.equals(stand.isRight(), route1.getStart().isRight())).findAny().orElse(null); + if (Objects.nonNull(route)) { + deviceStatusModifyTool.openRouteDirect(simulation, route); + } + deviceStatusModifyTool.loadManualTrainOfGroup(simulation, "001", stand.getSection(), stand.isRight()); + break; } case Stand_Cancel_Jump_Stop:{ // 设置背景为全部跳停 diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/base/StationGeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/base/StationGeneratorNew.java index 2ad4144c5..f1554dd78 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/base/StationGeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/base/StationGeneratorNew.java @@ -5,11 +5,14 @@ import club.joylink.rtss.services.training.generatornew.GeneratorNew; import club.joylink.rtss.services.training.generatornew.annotation.GeneratorSelectorNew; 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.Station; +import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO; import club.joylink.rtss.vo.client.training.TrainingNewVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.CollectionUtils; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -17,7 +20,8 @@ import java.util.stream.Collectors; @GeneratorSelectorNew(operateObject = Operation.Object.Station) public class StationGeneratorNew implements GeneratorNew { - + @Autowired + private DeviceStatusModifyTool deviceStatusModifyTool; @Override public List generate(GenerateConfig config, Simulation simulation, OperateDefinitionVO operateDefinitionVO) { List trainingVOList = new ArrayList<>(); @@ -105,14 +109,66 @@ public class StationGeneratorNew implements GeneratorNew { }); continue; } -// simulation.getRepository().getSignalList().stream() -// .filter(s -> Objects.equals(station.getCode(), s.getDeviceStation().getCode())) -// .forEach(signal -> { -// if (!signal.isBlockade()) { -// signal.setBlockade(false); -// } -// }); break; + case Station_Power_On_Unlock: + if(!station.isCentralized()) { + continue; + } + station.setControlMode(Station.ControlMode.Local); + station.setRestartTime(LocalTime.now()); + List
sections = simulation.getRepository().getSectionList(); + sections.stream().filter(section -> Objects.equals(section.getDeviceStation(), station)).forEach(section -> section.setFaultLock(true)); + break; + case Station_Set_Master_Guide_Lock: + if(!station.isCentralized()) { + continue; + } + station.setControlMode(Station.ControlMode.Local); + List switchList = simulation.getRepository().getSwitchList(); + List collect = switchList.stream().filter( + aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).collect(Collectors.toList()); + collect.forEach(aSwitch -> aSwitch.setFault(Switch.SwitchFault.SPLIT)); + station.setControlMode(Station.ControlMode.Center); + if (operateDefinitionVO.guideTotalLockButton()) { + simulation.getBuildParams().getMap().getGraphDataNew().getTotalGuideLockButtonVOList() + .stream().filter(guideLockButtonVO -> guideLockButtonVO.getStationCode().equals(station.getCode())) + .forEach(button -> { + trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO)); + simulation.reset(); + }); + continue; + } + break; + case Station_Cancel_Master_Guide_Lock: + if(station.isCentralized()) { + station.setTotalGuideLock(true); + station.setControlMode(Station.ControlMode.Local); + List switchList1 = simulation.getRepository().getSwitchList(); + switchList1.stream().filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).forEach(aSwitch -> aSwitch.setSingleLock(true)); + List signalList = simulation.getRepository().getSignalList(); + signalList.stream().filter(signal -> Objects.equals(signal.getDeviceStation(), station)).forEach(signal -> { + if (signal.isCallOn()) { + List routeList = signal.getRouteList(); + if (!CollectionUtils.isEmpty(routeList)) { + for (Route route : routeList) { + if (!route.isTurnBack()) { + this.deviceStatusModifyTool.openGuideRouteDirect(simulation, route); + trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO)); + // 仿真重置 + simulation.reset(); + break; + } + } + } else if (Objects.nonNull(signal.getAutoSignal())) { // 信号机是自动信号 + this.deviceStatusModifyTool.openGuideSignalDirectly(signal); + trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO)); + // 仿真重置 + simulation.reset(); + } + } + }); + } + continue; default: // 其他操作,不生成 continue; 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 fdd0d288c..a080a6468 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 @@ -141,6 +141,13 @@ public class ZCLogicLoop { int count = 0; while (count < 50) { ++count; + // 区段未进路锁闭或延时解锁中(转换轨除外,因为出库列车加载到转换轨没有进路) + if (!section.isTransferTrack()) { + if (!section.isRouteLockOn(right) || section.isDelayUnlock()) { + deviceEnd = new MovementAuthority.End(section, MovementAuthority.EndType.UNLOCK_SECTION); + break; + } + } // 站台屏蔽门 MovementAuthority.End psdEnd = checkPsdOpen(section, tailPosition); if (Objects.nonNull(psdEnd)) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java index 093bac152..be3134eba 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java @@ -179,9 +179,9 @@ public class Operation { Stand_Set_Hold_Train_Batch(), /**批量取消扣车*/ Stand_Cancel_Hold_Train_Batch(), - /** 区间列车数量限制 */ + /** 区间列车数量限制(自动扣车) */ Stand_Set_Hold_Train_Auto(), - /** 取消区间列车数量限制 */ + /** 取消区间列车数量限制(取消自动扣车) */ Stand_Cancel_Hold_Train_Auto(), /** 站台总取消 */ Stand_Total_Cancel, @@ -209,6 +209,8 @@ public class Operation { CM_Surrender_Control(), /** 连锁控 */ CM_Interlock_Control(), + /** 回复中控请求(同意/拒绝) */ + CM_Reply_Interlock_Control(), //--------------------------- 集中车站 --------------------------- /** 设置折返策略 */ @@ -305,6 +307,8 @@ public class Operation { Train_Trust, /** 连挂 */ Train_Link, + /** 排列进路到 */ + Train_Set_Route, //--------------------------- 司机 --------------------------- /** 改变列车的牵引/制动力 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java index 85b2b171b..eaeccd5cb 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/DriverOperateHandler.java @@ -59,7 +59,7 @@ public class DriverOperateHandler { train.updateTBForce(0, 350); } else { throw new SimulationException(SimulationExceptionType.Illegal_Argument, - String.format("列车牵引/制动力可调整比例范围应该在[-1, 1]之间,或为紧急制动-2")); + String.format("数值[%s]超限,列车牵引/制动力可调整比例范围应该在[-1, 1]之间,或为紧急制动-2", percent)); } if (train.isAtoOn()) { this.ATOService.closeATO(train); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java index aade50902..8ef427578 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java @@ -137,8 +137,8 @@ public class StandOperateHandler { * 区间列车数量限制 */ @OperateHandlerMapping(type = Operation.Type.Stand_Set_Hold_Train_Auto) - public void setHoldTrainAuto() { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "功能暂未实现"); + public void setHoldTrainAuto(Simulation simulation, String standCode, int limit) { + atsStandService.setAutoHoldTrainLimit(simulation, standCode, limit); } @@ -146,8 +146,8 @@ public class StandOperateHandler { * 取消区间列车数量限制 */ @OperateHandlerMapping(type = Operation.Type.Stand_Cancel_Hold_Train_Auto) - public void cancelHoldTrainAuto() { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "功能暂未实现"); + public void cancelHoldTrainAuto(Simulation simulation, String standCode) { + atsStandService.setAutoHoldTrainLimit(simulation, standCode, -1); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java index b6c2257c6..1a3f27e6a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StationOperateHandler.java @@ -102,9 +102,9 @@ public class StationOperateHandler { * 上电解锁 */ @OperateHandlerMapping(type = Operation.Type.Station_Power_On_Unlock) - public void powerOnUnlock() { - throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "功能暂未实现"); - + public void powerOnUnlock(Simulation simulation, String stationCode) { + SimulationDataRepository repository = simulation.getRepository(); + ciApiService.powerOnUnlock(simulation, repository.getByCode(stationCode, Station.class)); } /** @@ -143,6 +143,12 @@ public class StationOperateHandler { atsStationService.applyForCenterControl(simulation, fromMember, stationCodes); } + /**连锁控*/ + @OperateHandlerMapping(type = Operation.Type.CM_Interlock_Control) + public void applyForInterlockControl(Simulation simulation, SimulationMember fromMember, List stationCodes){ + atsStationService.applyForInterlockControl(simulation, fromMember, stationCodes); + } + /**强制站控-l*/ @OperateHandlerMapping(type = Operation.Type.CM_Force_Station_Control) public void forceForStationControl(Simulation simulation, SimulationMember fromMember, List stationCodes){ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java index 1ca1d70f8..04bbe75ef 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java @@ -13,6 +13,7 @@ import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.TrainLoadParam2; +import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; @@ -316,4 +317,12 @@ public class TrainOperateHandler { public void link(Simulation simulation, String groupNumber, String groupNumber2) { atsTrainService.link(simulation, groupNumber, groupNumber2); } + + /** + * 排列进路到(站台/信号机)【泰雷兹】 + */ + @OperateHandlerMapping(type = Operation.Type.Train_Link) + public void setRouteTo(Simulation simulation, RoutePathVO routePath) { + atsTrainService.setRouteTo(simulation, routePath); + } } 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 f8d6d17cc..116d92a4f 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 @@ -159,7 +159,7 @@ public class AtsPlanService { // 更新跳停状态 if (jump && Objects.equals(tripPlan.getLastStationPlan().getStation(), target.getStation())) { // 最后一站,不跳停 - jump = false; + jump = true; } if (!Objects.equals(train.isJump(), jump)) { if (jump) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java index 39488a686..6bd386ff6 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsRouteSettingService.java @@ -39,6 +39,7 @@ public class AtsRouteSettingService { // 执行进路排列 for (TrainRoute trainRoute : waitSetList) { Route route = trainRoute.getRoute(); + route.setTrain(trainRoute.getTrain()); this.ciApiService.settingRoute(simulation, route.getCode()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java index f64463595..f7328d2a2 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java @@ -240,9 +240,11 @@ public class AtsStandService { */ public void earlyDepart(Simulation simulation, String standCode) { Stand stand = getStand(simulation, standCode); - if (stand.isHoldTrain()) { - throw new SimulationException(SimulationExceptionType.Operation_Conflict, - "站台处于扣车状态,不能提前发车"); + if (!simulation.getRepository().getConfig().isAllowEarlyDepartureWhenHoldTrain()) { + if (stand.isHoldTrain()) { + throw new SimulationException(SimulationExceptionType.Operation_Conflict, + "站台处于扣车状态,不能提前发车"); + } } if (!stand.isTrainParking()) { throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, @@ -277,6 +279,14 @@ public class AtsStandService { stand.setRunLevelTimeForever(alwaysValid); } + /** + * 设置站间列车数量 + */ + public void setAutoHoldTrainLimit(Simulation simulation, String standCode, int limit) { + Stand stand = getStand(simulation, standCode); + stand.setTrainLimit(limit); + } + /** * 设置人工折返策略 */ @@ -407,7 +417,7 @@ public class AtsStandService { public void manualOpenPsd(Simulation simulation, String standCode) { SimulationDataRepository repository = simulation.getRepository(); Stand stand = repository.getByCode(standCode, Stand.class); - stand.getPsd().getVirtualScreenDoor().updateLockAndClose(false, true); + stand.getPsd().getVirtualScreenDoor().updateOpen2End(true); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java index 6afca0d3e..28bc8070b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStationService.java @@ -61,7 +61,7 @@ public class AtsStationService { station.setTotalGuideLock(true); List switches = simulation.getRepository().getSwitchListByDeviceStationCode(station.getCode()); if (!CollectionUtils.isEmpty(switches)) { - switches.forEach(s -> s.setMasterGuideLock(true)); + switches.forEach(s -> s.setSingleLock(true)); } } @@ -77,7 +77,7 @@ public class AtsStationService { station.setTotalGuideLock(false); List switches = simulation.getRepository().getSwitchListByDeviceStationCode(station.getCode()); if (!CollectionUtils.isEmpty(switches)) { - switches.forEach(s -> s.setMasterGuideLock(false)); + switches.forEach(s -> s.setSingleLock(false)); } } @@ -217,6 +217,20 @@ public class AtsStationService { } + /** + * 请求连锁控处理 + */ + public void applyForInterlockControl(Simulation simulation, SimulationMember fromMember, List stationCodes) { + if (CollectionUtils.isEmpty(stationCodes)) { + throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "连锁控的车站不能为空"); + } + stationCodes.forEach(stationCode -> { + Station station = getStation(simulation, stationCode); + station.setControlMode(Station.ControlMode.Interlock); + }); + atsMessageCollectAndDispatcher.handlerOperateMessage(simulation, new OperationMessage(fromMember.getId(), new HashSet<>(Collections.singleton(fromMember)), Operation.Type.CM_Reply_Interlock_Control, null, true, stationCodes)); + + } /** * 回复站控请求c */ 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 01453da1b..2b12c983f 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 @@ -1,6 +1,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.TrainType; @@ -11,6 +12,7 @@ import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; +import club.joylink.rtss.simulation.cbtc.data.vo.RoutePathVO; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; @@ -36,6 +38,9 @@ public class AtsTrainService { @Autowired private AtsStandService atsStandService; + @Autowired + private CiApiService ciApiService; + @Autowired private OnboardAtpApiService onboardAtpApiService; @@ -884,4 +889,11 @@ public class AtsTrainService { } activeTrain.setLinkTrain(passiveTrain); } + + /** + * 排列进路到(站台/信号机) + */ + public void setRouteTo(Simulation simulation, RoutePathVO routePath) { + routePath.getRouteList().forEach(routeCode -> ciApiService.settingRoute(simulation, routeCode)); + } } 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 2eb1fe61d..ff007355b 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 @@ -305,6 +305,9 @@ public interface CiApiService { */ void restart(Simulation simulation, Station station); + /**上电解锁*/ + void powerOnUnlock(Simulation simulation, Station station); + /** * 站台紧急停车 */ 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 2fd99938b..c76285380 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 @@ -18,6 +18,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.time.LocalTime; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -98,6 +99,9 @@ public class CiApiServiceImpl implements CiApiService { String.format("进路[%s(%s)]联锁关系不满足,不能重开信号机", lockedRoute.getName(), lockedRoute.getCode())); } this.routeService.routeOpen(simulation, lockedRoute); + if (lockedRoute.isDelayUnlocking()) { + lockedRoute.cancelDelayUnlocking(); + } } @Override @@ -397,7 +401,7 @@ public class CiApiServiceImpl implements CiApiService { } BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isClose(), String.format("信号机[%s]需处于关闭状态", signal.getCode())); boolean signalApproachOccupied = signal.getApproachPathList() - .stream().anyMatch(sectionPath -> sectionPath.getLogicList().stream().anyMatch(Section::isOccupied)); + .stream().anyMatch(sectionPath -> sectionPath.getSectionList().stream().anyMatch(Section::isOccupied)); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signalApproachOccupied, String.format("对%s开放引导操作失败,接近区段没有列车占用", signal.getName())); //办理引导进路或开放引导信号 @@ -468,8 +472,21 @@ public class CiApiServiceImpl implements CiApiService { .filter(signal -> signal.getDeviceStation().equals(deviceStation)).collect(Collectors.toList()); signals.forEach(Signal::reset); deviceStation.setInterlockMachineStarting(false); + deviceStation.setRestartTime(LocalTime.now()); } + @Override + public void powerOnUnlock(Simulation simulation, Station station){ + if (!station.isCentralized()) { + station = station.getDeviceStation(); + } + Station deviceStation = station; + if (Objects.nonNull(deviceStation.getRestartTime()) && deviceStation.getRestartTime().plusMinutes(8).isBefore(LocalTime.now())) { + List
sections = simulation.getRepository().getSectionList(); + sections.stream().filter(section -> Objects.equals(section.getDeviceStation(), deviceStation)).forEach(Section::faultUnlock); + } + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("无效操作或连锁机重启过8分钟需手动解锁"); + } @Override public void standEB(Simulation simulation, Stand stand) { if (stand.getEsp() == null) 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 b6f803a34..783060e18 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 @@ -703,7 +703,9 @@ public class RouteService { } else { route.setAtsControl(false); } - this.cancelWithoutCheck(simulation, route); + if (!route.isDelayUnlocking()) { + this.cancelWithoutCheck(simulation, route); + } } else { log.info(String.format("进路[%s(%s)]未锁闭,不需要取消进路。", route.getName(), route.getCode())); @@ -726,6 +728,8 @@ public class RouteService { log.debug(String.format("取消进路,信号机[%s(%s)]关灯", route.getStart().getName(), route.getStart().getCode())); route.getStart().setLevel(Signal.LEVEL_1); + // 始端信号机锁闭进路置为null + route.getStart().setLockedRoute(null); // 进路区段取消锁闭 boolean right = route.getStart().isRight(); List
sectionList = route.getSectionList(); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java index 4eb2d1cfb..aef63f836 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SectionService.java @@ -104,7 +104,7 @@ public class SectionService { Signal start = lockedRoute.getStart(); this.signalService.close(simulation, start); if (start.getLockedRoute() == lockedRoute) { - start.setLockedRoute(lockedRoute); + start.setLockedRoute(null); } } section.faultUnlock(); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java index f1318684a..f507d3bb8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SignalService.java @@ -29,10 +29,10 @@ public class SignalService { public void blockade(Simulation simulation, Signal signal) { if(!signal.isBlockade()) { signal.setBlockade(true); - if (signal.getLockedRoute() != null) { - signal.setReblockade(true); - log.debug(signal.debugStr() + "因信号机封锁且有锁闭的进路而重复封锁"); - } +// if (signal.getLockedRoute() != null) { +// signal.setReblockade(true); +// log.debug(signal.debugStr() + "因信号机封锁且有锁闭的进路而重复封锁"); +// } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java index cfe1e5fc5..e32866acb 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/SwitchService.java @@ -145,7 +145,7 @@ public class SwitchService { Signal start = route.getStart(); route.setLock(false); if (start.getLockedRoute() == route) { - start.setLockedRoute(route); + start.setLockedRoute(null); } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java index 11e38cf60..dd2ae3f2b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/competition/CompetitionAndScriptManager.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.competition; +import club.joylink.rtss.services.IVoiceService; import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService; @@ -18,7 +19,6 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.script.ScriptActionBO; import club.joylink.rtss.simulation.cbtc.script.ScriptBO; -import club.joylink.rtss.services.IVoiceService; import club.joylink.rtss.vo.UserVO; import club.joylink.rtss.vo.client.competition.OperationIndexStatistic; import club.joylink.rtss.vo.client.competition.OperationStatisticVO; @@ -314,10 +314,10 @@ public class CompetitionAndScriptManager { for (String num : split) { switch (num) { case "1": - sb.append("[1一幺妖腰摇要]"); + sb.append("[1一幺妖腰摇要爻]"); break; case "2": - sb.append("[两梁良亮辆]"); + sb.append("[两梁良亮辆量]"); break; case "3": sb.append("[3三]"); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/SimulationVoiceHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/SimulationVoiceHandler.java index 8752dbd43..c88f1dac8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/SimulationVoiceHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/SimulationVoiceHandler.java @@ -3,7 +3,10 @@ package club.joylink.rtss.simulation.cbtc.conversation; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,7 +40,7 @@ public class SimulationVoiceHandler { replacementList.add(new Replacement("(茼蒿)", "通号")); replacementList.add(new Replacement("刺", "次")); replacementList.add(new Replacement("自动折法", "自动折返")); - replacementList.add(new Replacement("(倒插|刀叉|倒茶|倒叉|到插|倒闸)", "道岔")); + replacementList.add(new Replacement("(倒插|刀叉|倒茶|倒叉|到插|倒闸|到察|到厂|道碴)", "道岔")); replacementList.add(new Replacement("(师表|手表|时表)", "失表")); replacementList.add(new Replacement("攻作组", "工作组")); replacementList.add(new Replacement("军事表", "均失表")); @@ -74,14 +77,16 @@ public class SimulationVoiceHandler { replacementList.add(new Replacement("(首领处所)", "受令处所")); replacementList.add(new Replacement("安全保护", "安全防护")); replacementList.add(new Replacement("(手摇质|说杨智|受邀至)", "手摇至")); - replacementList.add(new Replacement("(反胃)", "反位")); + replacementList.add(new Replacement("(反胃|软位)", "反位")); replacementList.add(new Replacement("所逼", "锁闭")); replacementList.add(new Replacement("位直", "位置")); replacementList.add(new Replacement("丞将|成强|成交|沉降", "乘降")); - replacementList.add(new Replacement("售电弓|售电工", "受电弓")); + replacementList.add(new Replacement("售电弓|售电工|收电弓|数电弓", "受电弓")); replacementList.add(new Replacement("故障回复", "故障恢复")); replacementList.add(new Replacement("(出入断线|出路段线)", "出入段线")); - replacementList.add(new Replacement("(控子权|控质权)", "控制权")); + replacementList.add(new Replacement("(控子权|控质权|放置权|矿质权|空置权)", "控制权")); + replacementList.add(new Replacement("(手机号)", "手信号")); + replacementList.add(new Replacement("(鼓掌|部长)", "故障")); //------------- 设备相关 -------------- replacementList.add(new Replacement("(宇花祭|玉花祭|雨化寨|氯化钙|绿化带|优化钙)", "鱼化寨")); replacementList.add(new Replacement("(保税局)", "保税区")); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java index f36a4f48c..651377185 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/CalculateService.java @@ -301,7 +301,7 @@ public class CalculateService { } distance = isRight ? distance - startSection.getStopPointByDirection(isRight) + endSection.getStopPointByDirection(isRight) : - distance - startSection.getLen() + startSection.getStopPointByDirection(isRight) + endSection.getLen()-endSection.getStopPointByDirection(isRight); + distance - startSection.getLen() + startSection.getStopPointByDirection(isRight) + endSection.getLen() - endSection.getStopPointByDirection(isRight); return distance; } @@ -718,7 +718,7 @@ public class CalculateService { list.add(routePath); } else { routePath.addSections(sectionList); - queryRoutePaths(iter+1, route.getLastRouteSection(), routePath, list, warnList); + queryRoutePaths(iter + 1, route.getLastRouteSection(), routePath, list, warnList); } return; } @@ -814,8 +814,9 @@ public class CalculateService { /** * 查找从startSection到destination的途径区段路径 */ - public static Set> querySectionPaths2Destination(Section startSection, Section destination, - Boolean right, boolean stop) { + @NonNull + public static Set> querySectionPaths2Destination(@NonNull Section startSection, @NonNull Section destination, + @NonNull Boolean right, @NonNull Boolean stop) { long start = System.currentTimeMillis(); //从startSection开始寻找第一个同向信号机(如果是折返轨,两边的信号机都算),并记录途径区段 List signals = new ArrayList<>(); @@ -889,7 +890,8 @@ public class CalculateService { /** * 从signal找到destination的进路,并记录途径区段 * (用来找到某目的地码的路径) - * @param destination 目的地码对应的区段 + * + * @param destination 目的地码对应的区段 * @param followSettingRoute 是否要沿着已经/正在排列的进路找路径 */ private static Set> findPath2DestinationAndRecordSections(@NonNull Section destination, @NonNull Signal signal, @@ -1053,22 +1055,31 @@ public class CalculateService { * 计算考虑时间的ato最大速度 */ public static Float calculateAtoSpeedMax4RunTime(VirtualRealityTrain train, long runTime) { - if (train.getSpeed() != 0 || !train.getHeadPosition().getSection().isStandTrack()) { + if (train.getSpeed() != 0 /*|| !train.getHeadPosition().getSection().isStandTrack()*/) { return null; } Section target = train.getTarget(); boolean right = train.isRight(); - float stopPoint; - if (target.isStandTrack()) { - stopPoint = target.getStopPointByDirection(right); - } else { - stopPoint = right ? target.getMaxOffset() - 10 : 10; - } - SectionPosition endPosition = new SectionPosition(target, stopPoint); - Float distance2Target = calculateDistance(train.getHeadPosition(), endPosition, right); - if (distance2Target == null) { +// float stopPoint; +// if (target.isStandTrack()) { +// stopPoint = target.getStopPointByDirection(right); +// } else { +// stopPoint = right ? target.getMaxOffset() - 10 : 10; +// } +// SectionPosition endPosition = new SectionPosition(target, stopPoint); +// Float distance2Target = calculateDistance(train.getHeadPosition(), endPosition, right); +// if (distance == null) { +// return null; +// } + List routePaths = queryRoutePathsOnDirection(train.getHeadPosition().getSection(), target, right); + if (CollectionUtils.isEmpty(routePaths)) { return null; } + Optional distanceOptional = routePaths.stream().map(RoutePath::getLength).min(Float::compareTo); + if (distanceOptional.isEmpty()) { + return null; + } + float distance = distanceOptional.get(); float atpSpeedMax = train.getAtpSpeedMax() * 0.9f; float atoSpeed = atpSpeedMax; float atoSpeedMax = atpSpeedMax; @@ -1081,7 +1092,7 @@ public class CalculateService { float accelerateTime = calculateAccelerateTime(train, atoSpeed); float accelerateDistance = calculateAccelerateDistance(train, atoSpeed); //计算匀速段的距离和时间 - float uniformDistance = (distance2Target - decelerateDistance - accelerateDistance); + float uniformDistance = (distance - decelerateDistance - accelerateDistance); float uniformTime = uniformDistance / atoSpeed; //计算总时间,根据总时间与计划时间的差来调整atoSpeedMax的值 float totalTime = (decelerateTime + accelerateTime + uniformTime); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java index 80bb2eb0b..55bdd8da3 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java @@ -151,6 +151,21 @@ public class MapConfig { */ private boolean signalHumanControlBeforeSetAtsControlOrCIAutoTrigger; + /** + * 扣车时是否允许提前发车 + */ + private boolean allowEarlyDepartureWhenHoldTrain; + + /** + * 取消进路时列车紧急制动 + */ + private boolean EBWhenCancelRoute; + + /** + * ATS自动调整运行 + */ + private boolean adjustOperationAutomatically; + private Set needConfirmConnectMembers = Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet()); @@ -182,6 +197,8 @@ public class MapConfig { setUrmAtpSpeed(configVO.getUrmAtpSpeed() / 3.6f); setCancelAtsControlOfAllRoutesWhenCancelRoute(configVO.isCancelAtsControlOfAllRoutesWhenCancelRoute()); setSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger(configVO.isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()); + setAllowEarlyDepartureWhenHoldTrain(configVO.isAllowEarlyDepartureWhenHoldTrain()); + setEBWhenCancelRoute(configVO.isEBWhenCancelRoute()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java index bed268f0b..f0c3088c0 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.data.map; +import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.util.JsonUtils; @@ -127,6 +128,9 @@ public class Route extends MapNamedElement { /** 正常解锁到的区段 */ private Section unlockedSection; + /** 进路将要或上一次为哪辆列车排列 */ + private TrainInfo train; + @Override public void reset() { this.cbtcMode = true; @@ -141,6 +145,7 @@ public class Route extends MapNamedElement { this.delayUnlocking = false; this.normalUnlock = false; this.unlockedSection = null; + this.train = null; } /** @@ -538,6 +543,17 @@ public class Route extends MapNamedElement { } return sections; } + public boolean routeLastSection(Section section) { + return Objects.equals(this.sectionList.get(sectionList.size()-1),section); + } + /** + * 取消延时解锁 + */ + public void cancelDelayUnlocking() { + this.delayUnlocking = false; + this.start.setDelayTime(0); + getLogicSections().forEach(section -> section.setDelayUnlock(false)); + } /** * 进路检查失败原因 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 ee4801d4e..4a39d92ef 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 @@ -109,6 +109,11 @@ public class Stand extends MayOutOfOrderDevice { */ private boolean runLevelTimeForever; + /** + * 区间列车数量限制(自动扣车)(不限制-1) + */ + private int trainLimit; + /*停站时间相关*/ /** * 停车时间(自动为-1) @@ -155,6 +160,7 @@ public class Stand extends MayOutOfOrderDevice { this.runLevelTimeForever = false; this.parkingTime = -1; this.parkingAlwaysValid = false; + this.typeStrategy = TurnBackType.DEFAULT; this.noStatus = false; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java index b03f5b972..4feee7ea2 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Station.java @@ -12,6 +12,7 @@ import lombok.NonNull; import lombok.Setter; import org.springframework.util.CollectionUtils; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -156,6 +157,11 @@ public class Station extends MayOutOfOrderDevice { */ private boolean interlockMachineStarting; + /** + * 联锁机重启时间 + */ + private LocalTime restartTime; + @Override public void reset() { super.reset(); @@ -473,6 +479,7 @@ public class Station extends MayOutOfOrderDevice { if (!Objects.equals(this, device.getFault())) return; station.setInterlockMachineStarting(true); + station.setRestartTime(null); station.setFault(null); } } 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 333f481f7..6ba8faf93 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 @@ -63,6 +63,9 @@ public class StandStatus extends DeviceStatus { @JsonSerialize(using = Boolean2NumSerializer.class) private boolean runLevelTimeForever; + /**区间列车数量限制(不限制为-1)*/ + private int trainLimit; + /**停车时间(自动为-1)*/ private int parkingTime; @@ -97,6 +100,7 @@ public class StandStatus extends DeviceStatus { } this.runLevelTime = stand.getRunLevelTime(); this.runLevelTimeForever = stand.isRunLevelTimeForever(); + this.trainLimit = stand.getTrainLimit(); this.parkingTime = stand.getParkingTime(); this.parkingAlwaysValid = stand.isParkingAlwaysValid(); this.noStatus = stand.isNoStatus(); @@ -170,6 +174,11 @@ public class StandStatus extends DeviceStatus { status.setRunLevelTimeForever(this.runLevelTimeForever); change = true; } + if (!Objects.equals(this.trainLimit, stand.getTrainLimit())) { + this.trainLimit = stand.getTrainLimit(); + status.setTrainLimit(this.trainLimit); + change = true; + } if (!Objects.equals(this.parkingTime, stand.getParkingTime())) { this.parkingTime = stand.getParkingTime(); status.setParkingTime(this.parkingTime); @@ -203,6 +212,7 @@ public class StandStatus extends DeviceStatus { StandStatusVO statusVO = new StandStatusVO((Stand) device); statusVO.setParkingAlwaysValid(parkingAlwaysValid); statusVO.setParkingTime(parkingTime); + statusVO.setTrainLimit(trainLimit); statusVO.setRunLevelTimeForever(runLevelTimeForever); statusVO.setRunLevelTime(runLevelTime); statusVO.setAssignSkip(assignSkip); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StationStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StationStatus.java index 862c2dd8c..9fccfba2c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StationStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StationStatus.java @@ -10,6 +10,7 @@ import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer; import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer; import lombok.Getter; +import java.time.LocalTime; import java.util.Objects; /** @@ -50,6 +51,9 @@ public class StationStatus extends DeviceStatus { */ private Integer validDuration; + /**连锁机上电重启时间*/ + private LocalTime restartTime; + public StationStatus(Station station) { super(station.getCode(), station.getDeviceType()); this.controlMode = station.getControlMode(); @@ -58,6 +62,7 @@ public class StationStatus extends DeviceStatus { this.applicantId = station.getApplicantId(); this.apply2TheControlMode = station.getApply2TheControlMode(); this.validDuration = station.getValidDurationInSeconds(); + this.restartTime = station.getRestartTime(); } @Override @@ -95,6 +100,12 @@ public class StationStatus extends DeviceStatus { this.validDuration = station.getValidDurationInSeconds(); } status.setValidDuration(validDuration); + + if (!Objects.equals(this.restartTime, station.getRestartTime())) { + change = true; + this.restartTime = station.getRestartTime(); + status.setRestartTime(restartTime); + } return change; } @@ -107,6 +118,7 @@ public class StationStatus extends DeviceStatus { statusVO.setApplicantId(applicantId); statusVO.setApply2TheControlMode(apply2TheControlMode); statusVO.setValidDuration(validDuration); + statusVO.setRestartTime(restartTime); return statusVO; } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/RoutePathVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/RoutePathVO.java new file mode 100644 index 000000000..af48a2f94 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/RoutePathVO.java @@ -0,0 +1,61 @@ +package club.joylink.rtss.simulation.cbtc.data.vo; + +import club.joylink.rtss.simulation.cbtc.data.map.MapElement; +import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 进路路径VO + */ +@Getter +@Setter +@NoArgsConstructor +public class RoutePathVO { + /** 起始区段 */ + private String startSectionCode; + + /** 结束区段 */ + private String endSectionCode; + + /** 路径的标识 */ + private String key; + + /** 信号机列表 */ + private List signalList; + + /** 进路列表 */ + private List routeList; + + /** 区段列表 */ + private List sectionList; + + /** 方向 */ + private boolean right; + + /** 距离 */ + private float length; + + public RoutePathVO(RoutePath routePath) { + this.startSectionCode = routePath.getStart().getCode(); + this.endSectionCode = routePath.getEnd().getCode(); + this.key = routePath.getKey(); + this.signalList = routePath.getSignalList().stream().map(MapElement::getCode).collect(Collectors.toList()); + this.routeList = routePath.getRouteList().stream().map(MapElement::getCode).collect(Collectors.toList()); + this.sectionList = routePath.getSectionList().stream().map(MapElement::getCode).collect(Collectors.toList()); + this.right = routePath.isRight(); + this.length = routePath.getLength(); + } + + public static List convert(List routePaths) { + if (CollectionUtils.isEmpty(routePaths)) + return new ArrayList<>(); + return routePaths.stream().map(RoutePathVO::new).collect(Collectors.toList()); + } +} 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 c2cfda7bf..19b8cd162 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 @@ -60,6 +60,9 @@ public class StandStatusVO extends DeviceStatusVO { @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean runLevelTimeForever; + /**区间列车数量限制(自不限制-1)*/ + private Integer trainLimit; + /**停车时间(自动为-1)*/ private Integer parkingTime; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StationStatusVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StationStatusVO.java index 0c2c3c44e..526f9fa20 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StationStatusVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StationStatusVO.java @@ -10,6 +10,7 @@ import lombok.Getter; import lombok.Setter; import java.time.LocalDateTime; +import java.time.LocalTime; /** * 车站状态 @@ -49,6 +50,8 @@ public class StationStatusVO extends DeviceStatusVO { @JsonInclude() private Integer validDuration; + private LocalTime restartTime; + public StationStatusVO(Station station) { super(station.getCode(), station.getDeviceType()); } 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 adaae2d04..2fc7b9538 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 @@ -365,8 +365,6 @@ public class VirtualRealityTrain extends VirtualRealityDevice { */ private VirtualRealityTrain linkTrain; - - /**最近经过的两个应答器*/ private Queue lastTwoPassedResponders = new FixedQueue<>(Responders_Record); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java index 1cea6d9bb..226e8ae38 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java @@ -158,10 +158,10 @@ public class SpeedCurve { float limitSpeed = recommendedSpeedMax; boolean limit = false; if (Objects.nonNull(tailPosition.getSection().getNeedLimitSpeed())) { - limitSpeed = Math.min(limitSpeed, tailPosition.getSection().getNeedLimitSpeed()); + limitSpeed = Math.min(limitSpeed, tailPosition.getSection().getNeedLimitSpeed() * 0.9f); limit = true; } else if (Objects.nonNull(headPosition.getSection().getNeedLimitSpeed())) { - limitSpeed = Math.min(limitSpeed, headPosition.getSection().getNeedLimitSpeed()); + limitSpeed = Math.min(limitSpeed, headPosition.getSection().getNeedLimitSpeed() * 0.9f); limit = true; } SectionPosition endPosition = null; @@ -190,7 +190,7 @@ public class SpeedCurve { if (Objects.nonNull(limitSpeed1)) { if (ahead) { // 车头前方 - vt = Math.min(limitSpeed, limitSpeed1); + vt = Math.min(limitSpeed, limitSpeed1 * 0.9f); endPosition = new SectionPosition(base, right ? 0 : base.getLen()); break; } else { @@ -208,7 +208,7 @@ public class SpeedCurve { if (Objects.isNull(distance) || distance > totalLen) { return buildTargetSpeedCurve(totalLen, v0, 0, limitSpeed); } else { - return buildTargetSpeedCurve(distance, v0, vt * 0.8f, limitSpeed); + return buildTargetSpeedCurve(distance, v0, vt, limitSpeed); } } return buildTargetSpeedCurve(totalLen, v0, 0, limitSpeed); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java index 79ec60070..49fd116e1 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/service/ATOService.java @@ -7,6 +7,7 @@ import club.joylink.rtss.simulation.cbtc.constant.DriveMode; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.data.CalculateService; 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.Stand; import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; @@ -156,7 +157,8 @@ public class ATOService { // nextStation.getName(), nextStation.getCode(), // nextStopStandSection.getName(), nextStopStandSection.getCode())); boolean parking = true; - if (!train.isHold() && (train.isJump() || !train.isNextParking())) { + Signal signal = target.getSignalOf(right); + if (!train.isHold() && (train.isJump() && signal.isNormalOpen() || !train.isNextParking())) { parking = false; } if (parking) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java index d040972db..eb789ee07 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java @@ -3,7 +3,10 @@ package club.joylink.rtss.simulation.cbtc.onboard.ATP; import club.joylink.rtss.simulation.cbtc.ATP.ground.GroundAtpApiService; import club.joylink.rtss.simulation.cbtc.ATS.AtsApiService; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.constant.*; +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; import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Signal; @@ -220,13 +223,19 @@ public class ATPLogicLoop { } break; case BOARD: // 乘客乘降 - if (parkRemainTime < 10000) { // 小于10秒,关门 - train.nextParkedTrainActivity(); + if (simulation.getRepository().getConfig().isAdjustOperationAutomatically()) { + if (parkRemainTime < 10000) { // 小于10秒,关门 + train.nextParkedTrainActivity(); + } + } else { + if (parkRemainTime <= 0) { + train.nextParkedTrainActivity(); + } } break; case CLOSE_DOOR: // 关门 Signal signal = train.getHeadPosition().getSection().getSignalOf(train.isRight()); - if (!train.isHold()) { // 列车未扣车 + if (!train.isHold() || simulation.getRepository().getConfig().isAllowEarlyDepartureWhenHoldTrain()) { // 列车未扣车或允许在扣车状态下提前发车 // if (Objects.nonNull(signal) && !signal.isNormalOpen()) { // if (!train.isRMMode() && !train.isNRMMode()) { // // 信号机未正常开放 @@ -287,45 +296,51 @@ public class ATPLogicLoop { } private boolean checkConditionToMove2(Simulation simulation, VirtualRealityTrain train) { - boolean safe = true; if (train.isParkingAt() && !train.isStandReadyStart()) { // 站台停靠未完成 - safe = false; - } - boolean right = train.isRight(); - SectionPosition headPosition = train.getHeadPosition(); - Section headSection = headPosition.getSection(); - // 轨道前方信号机是否红灯 - Signal signal = headSection.getSignalOf(right); - if (headSection.isSwitchTrack()) { - signal = headSection.querySwitchSectionRelatedSignalByDirection(right); - } - if (Objects.nonNull(signal) && !signal.isNormalOpen()) { -// log.debug(String.format("列车[%s]前方信号机[%s(%s)]未开放,不能动车", -// train.getGroupNumber(), signal.getName(), signal.getCode())); - safe = false; - } - if (safe) { - // - train.setDelayTime(Math.max(train.getDelayTime() - SimulationConstants.ATP_LOOP_RATE, 0)); - if (train.getDelayTime() > 0) { - return false; - } - } else { - - //RM可启动 - if (!train.getDriveMode().equals(DriveMode.AM)) { - if (train.getDelayTime() > 0) { - train.setDelayTime(Math.max(train.getDelayTime() - SimulationConstants.ATP_LOOP_RATE, 0)); - if (train.getDelayTime() > 0) { - return false; - } - } - } else { - train.setDelayTime(SimulationConstants.ATO_TRAIN_GET_SIGNAL_TO_START_DELAY); - return false; - } + return false; } return true; + + +// boolean safe = true; +// if (train.isParkingAt() && !train.isStandReadyStart()) { // 站台停靠未完成 +// safe = false; +// } +// boolean right = train.isRight(); +// SectionPosition headPosition = train.getHeadPosition(); +// Section headSection = headPosition.getSection(); +// // 轨道前方信号机是否红灯 +// Signal signal = headSection.getSignalOf(right); +// if (headSection.isSwitchTrack()) { +// signal = headSection.querySwitchSectionRelatedSignalByDirection(right); +// } +// if (Objects.nonNull(signal) && !signal.isNormalOpen()) { +//// log.debug(String.format("列车[%s]前方信号机[%s(%s)]未开放,不能动车", +//// train.getGroupNumber(), signal.getName(), signal.getCode())); +// safe = false; +// } +// if (safe) { +// // +// train.setDelayTime(Math.max(train.getDelayTime() - SimulationConstants.ATP_LOOP_RATE, 0)); +// if (train.getDelayTime() > 0) { +// return false; +// } +// } else { +// +// //RM可启动 +// if (!train.getDriveMode().equals(DriveMode.AM)) { +// if (train.getDelayTime() > 0) { +// train.setDelayTime(Math.max(train.getDelayTime() - SimulationConstants.ATP_LOOP_RATE, 0)); +// if (train.getDelayTime() > 0) { +// return false; +// } +// } +// } else { +// train.setDelayTime(SimulationConstants.ATO_TRAIN_GET_SIGNAL_TO_START_DELAY); +// return false; +// } +// } +// return true; } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPService.java index f330a4570..6dab6784f 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPService.java @@ -54,10 +54,10 @@ public class ATPService { // train.getTripNumber(), train.getDestinationCode())); // this.cancelEB(train); // } - log.info(String.format("列车[%s-%s|%s|%s]更新移动授权[%s],安全防护距离[%s]", + log.info(String.format("列车[%s-%s|%s|%s]更新移动授权[%s],位置[%s],安全防护距离[%s]", train.getGroupNumber(), train.getServiceNumber(), train.getTripNumber(), train.getDestinationCode(), - ma.getEnd(), protectDistance)); + ma.getEnd(), ma.getEnd().getEndPosition().toString(), protectDistance)); // 重新生成速度曲线 SpeedCurve speedCurve = SpeedCurve.generateProtectSpeedCurve(protectDistance, train.getAtpSpeedMax()); //未考虑区段限速 // SpeedCurve speedCurve = SpeedCurve.generateProtectSpeedCurve(train); //考虑区段限速 @@ -101,6 +101,7 @@ public class ATPService { switch (driveMode) { case RM: { if (train.getSpeed() > simulation.getRepository().getConfig().getRmAtpSpeed()) { + log.warn(String.format("%s在RM模式下超速,速度:%s", train.debugStr(), train.getSpeed())); this.triggerSignalEB(train); } break; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotLogicLoop.java index e28a0a4b1..43636967e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/RobotLogicLoop.java @@ -68,10 +68,10 @@ public class RobotLogicLoop { if (!simulation.getRepository().isVrTrainOnline(train.getGroupNumber())) { //如果列车不在线 continue; } - if (train.isAtoOn()) { - train.setRobotTargetPosition(null); - continue; - } +// if (train.isAtoOn()) { //为国赛剧本,暂时注掉 +// train.setRobotTargetPosition(null); +// continue; +// } Float distance = CalculateService.calculateDistance(headPosition, targetPosition, right); if (distance == null || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置 this.doBreakMax(simulation, train); @@ -244,7 +244,7 @@ public class RobotLogicLoop { float fk = a * train.getMass(); float fkMax = train.getCurrentFkMax(); fk = Math.min(fk, fkMax); - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), fk / fkMax); + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), Math.min(fk / fkMax, 1)); } private void doBreakMax(Simulation simulation, VirtualRealityTrain train) { @@ -258,7 +258,6 @@ public class RobotLogicLoop { a = -Math.abs(a); float fb = train.getMass() * a; float fbMax = train.getCurrentFbMax(); - fb = Math.min(fb, fbMax); - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), fb / fbMax); + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), Math.max(fb / fbMax, -1)); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java b/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java index 80087693a..bac1de2e0 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/tool/DeviceStatusModifyTool.java @@ -1,11 +1,14 @@ package club.joylink.rtss.simulation.cbtc.tool; +import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService; import club.joylink.rtss.simulation.cbtc.CI.service.RouteService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; +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; @@ -25,6 +28,8 @@ public class DeviceStatusModifyTool { @Autowired private RouteService routeService; + @Autowired + private AtsTrainLoadService atsTrainLoadService; /** * 直接开放进路 @@ -238,4 +243,8 @@ public class DeviceStatusModifyTool { } } } + + public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section , boolean right){ + atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(),right); + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/map/MapLineVO.java b/src/main/java/club/joylink/rtss/vo/client/map/MapLineVO.java index 57a3a0e58..bc5c0bb88 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/MapLineVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/MapLineVO.java @@ -61,4 +61,8 @@ public class MapLineVO { @ApiModelProperty(value = "显示条件") @NotBlank(message="显示条件不能为空") private String showConditions; + + private Integer offsetX; + + private Integer offsetY; } diff --git a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java index f287d0466..92a4662ef 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java @@ -90,6 +90,21 @@ public class RealLineConfigVO { */ private boolean signalHumanControlBeforeSetAtsControlOrCIAutoTrigger; + /** + * 扣车时是否允许提前发车 + */ + private boolean allowEarlyDepartureWhenHoldTrain; + + /** + * 取消进路时列车紧急制动 + */ + private boolean EBWhenCancelRoute; + + /** + * ATS自动调整运行 + */ + private boolean adjustOperationAutomatically = true; + public static RealLineConfigVO parseJsonStr(String configData) { if (StringUtils.hasText(configData)) { return JsonUtils.read(configData, RealLineConfigVO.class); diff --git a/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionConfig.java b/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionConfig.java index 777c7994b..ce17426b9 100644 --- a/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionConfig.java +++ b/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionConfig.java @@ -22,6 +22,8 @@ public class OperateDefinitionConfig { //折返策略按钮 private Boolean tbStrategyBT; + private Boolean guideTotalLockBT; + private List sectionTypes;//区段生成指定类型 public boolean isAtp() { @@ -62,4 +64,10 @@ public class OperateDefinitionConfig { } return false; } + public boolean guideTotalLockButton(){ + if(Objects.nonNull(guideTotalLockBT)){ + return guideTotalLockBT; + } + return false; + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionVO.java b/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionVO.java index 93544aba5..7aa300fcc 100644 --- a/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/training/definition/OperateDefinitionVO.java @@ -189,6 +189,14 @@ public class OperateDefinitionVO { return false; } + public boolean guideTotalLockButton() { + OperateDefinitionConfig routeSettingConfig = this.getRouteSettingConfig(); + if (Objects.nonNull(routeSettingConfig)) { + return routeSettingConfig.guideTotalLockButton(); + } + return false; + } + public List getSectionTypes() { OperateDefinitionConfig routeSettingConfig = this.getRouteSettingConfig(); if (Objects.nonNull(routeSettingConfig)) {