修改设置备用车时列车级别不正确的bug;修改机器人驾驶及ATS界面的修改预选模式操作逻辑;挤岔恢复操作增加等待
This commit is contained in:
parent
376590f5d1
commit
67175c5919
@ -12,11 +12,10 @@ import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import club.joylink.rtss.simulation.cbtc.robot.SimulationRobotService;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 司机操作处理
|
||||
*/
|
||||
@ -37,8 +36,9 @@ public class DriverOperateHandler {
|
||||
public void changeTrainForce(Simulation simulation, String groupNumber, Float percent) {
|
||||
Objects.requireNonNull(percent);
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.changeTrainForce(train, percent);
|
||||
}
|
||||
|
||||
@ -48,8 +48,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_EB)
|
||||
public void trainEB(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
if (train.isCircuitEB()) {
|
||||
this.ATPService.cancelCircuitEB(train);
|
||||
} else {
|
||||
@ -65,11 +66,13 @@ public class DriverOperateHandler {
|
||||
* @param gear
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Gear_Change)
|
||||
public void changeTrainGear(Simulation simulation, String groupNumber, VirtualRealityTrain.Handwheel gear) {
|
||||
public void changeTrainGear(Simulation simulation, String groupNumber,
|
||||
VirtualRealityTrain.Handwheel gear) {
|
||||
Objects.requireNonNull(gear);
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.changeGear(train, gear);
|
||||
}
|
||||
|
||||
@ -92,16 +95,18 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_ATO_Open)
|
||||
public void openAto(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.openATO(train);
|
||||
}
|
||||
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_ATP_Change)
|
||||
public void changeAtpStatus(Simulation simulation, String groupNumber, boolean cutOff) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
if (cutOff) {
|
||||
this.ATPService.cutOffAtp(train);
|
||||
} else {
|
||||
@ -112,8 +117,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Change_Head)
|
||||
public void changeHead(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
if (train.isStop()) {
|
||||
this.ATPService.turnDirectionImmediately(train);
|
||||
}
|
||||
@ -129,8 +135,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Door_On_Off)
|
||||
public void onOrOffDoor(Simulation simulation, String groupNumber, Boolean right, Boolean open) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.openOrCloseDoor(simulation, train, right, open);
|
||||
}
|
||||
|
||||
@ -146,8 +153,9 @@ public class DriverOperateHandler {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument, "门模式不能为空");
|
||||
}
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
train.setDoorMode(doorMode);
|
||||
}
|
||||
|
||||
@ -163,8 +171,9 @@ public class DriverOperateHandler {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument, "门选择不能为空");
|
||||
}
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
train.setDoorSelection(doorSelection);
|
||||
}
|
||||
|
||||
@ -174,8 +183,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Preselection_Mode_Up)
|
||||
public void beforehandModeUp(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.preselectionModeUp(train);
|
||||
}
|
||||
|
||||
@ -185,8 +195,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Preselection_Mode_Down)
|
||||
public void beforehandModeDown(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.preselectionModeDown(train);
|
||||
}
|
||||
|
||||
@ -196,8 +207,9 @@ public class DriverOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Confirm)
|
||||
public void confirmMessage(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (!validate(train))
|
||||
if (!validate(train)) {
|
||||
return;
|
||||
}
|
||||
ATPService.confirmMessage(train);
|
||||
}
|
||||
|
||||
@ -214,7 +226,8 @@ public class DriverOperateHandler {
|
||||
* ATS停车
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Driver_Stop)
|
||||
public void stopTrain(Simulation simulation, SimulationMember simulationMember, String groupNumber, Boolean eb) {
|
||||
public void stopTrain(Simulation simulation, SimulationMember simulationMember,
|
||||
String groupNumber, Boolean eb) {
|
||||
simulationRobotService.stopTrain(simulation, simulationMember, groupNumber, eb);
|
||||
}
|
||||
|
||||
@ -256,7 +269,9 @@ public class DriverOperateHandler {
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Try_Open_Ato)
|
||||
public void tryOpenAto(Simulation simulation, String groupNumber) {
|
||||
ATPService.openAto(simulation, groupNumber);
|
||||
VirtualRealityTrain train = simulation.getRepository()
|
||||
.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
ATPService.openATO(train);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,15 +15,14 @@ import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@OperateHandler
|
||||
@Slf4j
|
||||
@ -213,7 +212,8 @@ public class SwitchOperateHandler {
|
||||
try {
|
||||
limitSpeed = Integer.parseInt(speedLimitValue);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "速度值必须为数字!");
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
"速度值必须为数字!");
|
||||
}
|
||||
this.groundAtpApiService.setSwitchLimitSpeed(simulation, switchCode, limitSpeed);
|
||||
}
|
||||
@ -287,13 +287,17 @@ public class SwitchOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Switch_Squeeze_Recovery)
|
||||
public void switchSqueezeRecovery(Simulation simulation, String switchCode) {
|
||||
ciApiService.switchSqueezeRecovery(simulation, switchCode);
|
||||
|
||||
waitResult(simulation, simulation.getRepository().getByCode(switchCode, Switch.class),
|
||||
SwitchIndication.N, SwitchIndication.R);
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令【泰雷兹】
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Switch_Command)
|
||||
public void switchCommand(Simulation simulation, String switchCode, Boolean auto, Boolean reserve, Boolean normal) {
|
||||
public void switchCommand(Simulation simulation, String switchCode, Boolean auto, Boolean reserve,
|
||||
Boolean normal) {
|
||||
ciApiService.switchCommand(simulation, switchCode, auto, reserve, normal);
|
||||
}
|
||||
|
||||
@ -307,8 +311,10 @@ public class SwitchOperateHandler {
|
||||
@OperateHandlerMapping(type = Operation.Type.Switch_Defective_Shunting)
|
||||
public void defectiveShunting(Simulation simulation, String switchCode) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
List<Section.ShuntingType> shuntingTypeList = Arrays.asList(Section.ShuntingType.SWITCH_FRONT_SHUNTING,
|
||||
Section.ShuntingType.FIXED_POSITION_SHUNTING, Section.ShuntingType.REVERSE_POSITION_SHUNTING);
|
||||
List<Section.ShuntingType> shuntingTypeList = Arrays.asList(
|
||||
Section.ShuntingType.SWITCH_FRONT_SHUNTING,
|
||||
Section.ShuntingType.FIXED_POSITION_SHUNTING,
|
||||
Section.ShuntingType.REVERSE_POSITION_SHUNTING);
|
||||
atsSectionService.defectiveShunting(simulation, aSwitch.getA().getCode(), shuntingTypeList);
|
||||
}
|
||||
|
||||
@ -324,17 +330,23 @@ public class SwitchOperateHandler {
|
||||
atsSectionService.defectiveShunting(simulation, aSwitch.getA().getCode(), new ArrayList<>());
|
||||
}
|
||||
|
||||
private static void waitResult(Simulation simulation, Switch aSwitch, SwitchIndication pos) {
|
||||
/**
|
||||
* 道岔只要处于{posArr}中任意一个位置就认为操作完成
|
||||
*/
|
||||
private static void waitResult(Simulation simulation, Switch aSwitch,
|
||||
SwitchIndication... posArr) {
|
||||
//等待转动完成
|
||||
LocalDateTime timeoutTime = simulation.getSystemTime().plusSeconds(13);
|
||||
CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
|
||||
while (true) {
|
||||
for (SwitchIndication pos : posArr) {
|
||||
if (Objects.equals(aSwitch.getPos(), pos)) {
|
||||
return true;
|
||||
}
|
||||
if (simulation.getSystemTime().isAfter(timeoutTime)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (Exception e) {
|
||||
|
@ -192,14 +192,6 @@ public interface CiApiService {
|
||||
*/
|
||||
void switchSectionFaultUnlock(Simulation simulation, String switchCode);
|
||||
|
||||
/**
|
||||
* 设置自动通过进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param routeCode
|
||||
*/
|
||||
void setFleetRoute(Simulation simulation, String routeCode);
|
||||
|
||||
/**
|
||||
* 取消自动通过进路
|
||||
*
|
||||
@ -208,22 +200,6 @@ public interface CiApiService {
|
||||
*/
|
||||
void cancelFleetRoute(Simulation simulation, String routeCode);
|
||||
|
||||
/**
|
||||
* 设置进路CI自动触发
|
||||
*
|
||||
* @param simulation
|
||||
* @param routeCode
|
||||
*/
|
||||
void setCIAutoTriggerRoute(Simulation simulation, String routeCode);
|
||||
|
||||
/**
|
||||
* 取消进路CI自动触发
|
||||
*
|
||||
* @param simulation
|
||||
* @param routeCode
|
||||
*/
|
||||
void cancelCIAutoTriggerRoute(Simulation simulation, String routeCode);
|
||||
|
||||
/**
|
||||
* 根据始端信号机查询锁闭进路
|
||||
*
|
||||
@ -233,24 +209,6 @@ public interface CiApiService {
|
||||
*/
|
||||
Route findLockedRouteByStartSignal(Simulation simulation, String signalCode);
|
||||
|
||||
/**
|
||||
* 根据始端、终端信号机查询进路(根据延续保护自动筛选出一条进路)
|
||||
*
|
||||
* @param simulation
|
||||
* @param startSignalCode
|
||||
* @param endSignalCode
|
||||
* @return
|
||||
*/
|
||||
Route findRouteByStartAndEndSignal(Simulation simulation, String startSignalCode, String endSignalCode);
|
||||
|
||||
/**
|
||||
* 办理引导进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param routeCode
|
||||
*/
|
||||
void settingGuideRoute(Simulation simulation, String routeCode);
|
||||
|
||||
/**
|
||||
* 开站台屏蔽门
|
||||
*
|
||||
|
@ -1,33 +1,52 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CI;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.*;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiSectionService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiSignalControlService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiStandService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.ESP;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Server;
|
||||
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.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
|
||||
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* CI子系统
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiApiServiceImpl2 implements CiApiService {
|
||||
|
||||
@Autowired
|
||||
private CiSwitchControlService switchService;
|
||||
@Autowired
|
||||
@ -84,14 +103,16 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
Optional<Route> routeOptional = simulation.getRepository().getSettingRoutes().stream()
|
||||
.filter(route -> route.getStart().equals(signal)).findAny();
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(routeOptional.isPresent(), "信号机不是已排进路的始端信号机");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(routeOptional.isPresent(),
|
||||
"信号机不是已排进路的始端信号机");
|
||||
// settingRoute(simulation, routeOptional.get().getCode());
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (Objects.isNull(lockedRoute)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
"进路未锁闭,不能重开信号机");
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!lockedRoute.isDelayUnlocking(), "进路延时解锁中,不能重开");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!lockedRoute.isDelayUnlocking(),
|
||||
"进路延时解锁中,不能重开");
|
||||
signal.setForbidden(false);
|
||||
}
|
||||
|
||||
@ -101,7 +122,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
SwitchIndication pos = this.switchService.turn(simulation, aSwitch);
|
||||
if (pos == null) {
|
||||
log.info(String.format("道岔[%s(%s)]锁闭,不能转动", aSwitch.getName(), aSwitch.getCode()));
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行转动");
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
"道岔锁闭,不能进行转动");
|
||||
}
|
||||
if (Switch.SwitchFault.SPLIT_1.equals(aSwitch.getFault())) {
|
||||
Switch.SwitchFault.SPLIT_1.fix(aSwitch);
|
||||
@ -113,8 +135,10 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
public void turn2NormalPosition(Simulation simulation, String switchCode) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
if (!this.switchService.turn2NormalPosition(simulation, aSwitch)) {
|
||||
log.info(String.format("道岔[%s(%s)]锁闭,不能进行定操", aSwitch.getName(), aSwitch.getCode()));
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行定操");
|
||||
log.info(
|
||||
String.format("道岔[%s(%s)]锁闭,不能进行定操", aSwitch.getName(), aSwitch.getCode()));
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
"道岔锁闭,不能进行定操");
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,8 +146,10 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
public void turn2ReversePosition(Simulation simulation, String switchCode) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
if (!this.switchService.turn2ReversePosition(simulation, aSwitch)) {
|
||||
log.info(String.format("道岔[%s(%s)]锁闭,不能进行反操", aSwitch.getName(), aSwitch.getCode()));
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "道岔锁闭,不能进行反操");
|
||||
log.info(
|
||||
String.format("道岔[%s(%s)]锁闭,不能进行反操", aSwitch.getName(), aSwitch.getCode()));
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
"道岔锁闭,不能进行反操");
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,8 +220,10 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
@Override
|
||||
public void unlockRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
if (route.isTransferRoute() && simulation.getRepository().getConfig().isTransferRouteCanOnlyFaultUnlock()) {
|
||||
throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("转换轨进路只能通过区故解取消");
|
||||
if (route.isTransferRoute() && simulation.getRepository().getConfig()
|
||||
.isTransferRouteCanOnlyFaultUnlock()) {
|
||||
throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception(
|
||||
"转换轨进路只能通过区故解取消");
|
||||
}
|
||||
if (simulation.getRepository().getConfig().isDelayWhenCancelRouteWithAbnormalInterlock()) {
|
||||
if (this.ciService.isRouteSwitchLost(simulation, route)) {
|
||||
@ -228,11 +256,13 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
public void sectionFaultUnlock(Simulation simulation, String sectionCode) {
|
||||
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
|
||||
if (simulation.getRepository().getConfig().isSFUCanOnlyApplyForFaultLockSection()) {
|
||||
if (!section.isFaultLock())
|
||||
if (!section.isFaultLock()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (section.isCross()) {
|
||||
Optional<Section> crossLockedSectionOptional = section.getLogicList().stream().filter(Section::isLocked).findAny();
|
||||
Optional<Section> crossLockedSectionOptional = section.getLogicList().stream()
|
||||
.filter(Section::isLocked).findAny();
|
||||
if (crossLockedSectionOptional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@ -258,7 +288,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
}
|
||||
if (lockedRoute != null && lockedRoute.isDelayUnlocking()) {
|
||||
throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("进路延时解锁中,不能区故解");
|
||||
throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception(
|
||||
"进路延时解锁中,不能区故解");
|
||||
}
|
||||
this.routeService.sectionFaultUnlock(simulation, section, lockedRoute);
|
||||
}
|
||||
@ -266,8 +297,9 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
@Override
|
||||
public void switchSectionFaultUnlock(Simulation simulation, String switchCode) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
if (!aSwitch.isLocked() && aSwitch.getAllSections().stream().noneMatch(Section::isLocked))
|
||||
if (!aSwitch.isLocked() && aSwitch.getAllSections().stream().noneMatch(Section::isLocked)) {
|
||||
return;
|
||||
}
|
||||
List<Route> lockedRouteList = simulation.getRepository().queryAllLockedRoute();
|
||||
Set<Route> lockSwitchRoutes = new HashSet<>();
|
||||
if (aSwitch.isRouteLock()) {
|
||||
@ -290,30 +322,12 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFleetRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
this.routeService.setFleet(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelFleetRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
this.routeService.cancelFleet(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCIAutoTriggerRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
this.routeService.setCIAutoTrigger(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelCIAutoTriggerRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
this.routeService.cancelCIAutoTrigger(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Route findLockedRouteByStartSignal(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
@ -321,27 +335,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Route findRouteByStartAndEndSignal(Simulation simulation, String startSignalCode, String endSignalCode) {
|
||||
Signal start = simulation.getRepository().getByCode(startSignalCode, Signal.class);
|
||||
List<Route> routeList = start.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
for (Route route : routeList) {
|
||||
if (Objects.equals(route.getDestination().getCode(), endSignalCode)) {
|
||||
return route;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settingGuideRoute(Simulation simulation, String routeCode) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
this.routeService.setGuide(simulation, route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openScreenDoor(Simulation simulation, String standCode, CiStandService.PsdCommandSource source) {
|
||||
public void openScreenDoor(Simulation simulation, String standCode,
|
||||
CiStandService.PsdCommandSource source) {
|
||||
Stand stand = simulation.getRepository().getByCode(standCode, Stand.class);
|
||||
if (Objects.nonNull(stand.getPsd())) {
|
||||
standService.openScreenDoor(simulation, stand, source);
|
||||
@ -349,7 +344,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeScreenDoor(Simulation simulation, String standCode, CiStandService.PsdCommandSource source) {
|
||||
public void closeScreenDoor(Simulation simulation, String standCode,
|
||||
CiStandService.PsdCommandSource source) {
|
||||
Stand stand = simulation.getRepository().getByCode(standCode, Stand.class);
|
||||
if (Objects.nonNull(stand.getPsd())) {
|
||||
standService.closeScreenDoor(simulation, stand, source);
|
||||
@ -413,7 +409,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
route = repository.getByCode(routeCode, Route.class);
|
||||
signal = route.getStart();
|
||||
} else {
|
||||
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception("signalCode和routeCode不能都为空");
|
||||
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception(
|
||||
"signalCode和routeCode不能都为空");
|
||||
}
|
||||
|
||||
if (route == null && signal.getRouteList().stream().anyMatch(Route::isAnySwitchMasterLock)) {
|
||||
@ -427,11 +424,14 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
//条件检查
|
||||
if (firstCheck) {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, String.format("信号机[%s]非进路始端信号机", signal.getCode()));
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList,
|
||||
String.format("信号机[%s]非进路始端信号机", signal.getCode()));
|
||||
if (route != null) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(route.isLock(), String.format("进路[%s]未办理", route.getCode()));
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(route.isLock(),
|
||||
String.format("进路[%s]未办理", route.getCode()));
|
||||
} else {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(signal.getLockedRoute(), String.format("信号机[%s]无已办理进路", signal.getCode()));
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(signal.getLockedRoute(),
|
||||
String.format("信号机[%s]无已办理进路", signal.getCode()));
|
||||
}
|
||||
}
|
||||
// if (config.isSomeCommandNeedInit()) {
|
||||
@ -443,23 +443,27 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
// }
|
||||
if (config.isNeedApproachLockBeforeSetGuide()) {
|
||||
boolean signalApproachOccupied = signal.getApproachPathList()
|
||||
.stream().anyMatch(sectionPath -> sectionPath.getSectionList().stream().anyMatch(Section::isOccupied));
|
||||
.stream().anyMatch(
|
||||
sectionPath -> sectionPath.getSectionList().stream().anyMatch(Section::isOccupied));
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signalApproachOccupied,
|
||||
String.format("对%s开放引导操作失败,接近区段没有列车占用", signal.getName()));
|
||||
}
|
||||
//办理引导进路或开放引导信号
|
||||
if (firstCheck) {
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal, signal.getSignalModel().getGuideAspect());
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal,
|
||||
signal.getSignalModel().getGuideAspect());
|
||||
} else {
|
||||
if (route != null) {
|
||||
if (route.isLock()) {
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal, signal.getSignalModel().getGuideAspect());
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal,
|
||||
signal.getSignalModel().getGuideAspect());
|
||||
} else {
|
||||
this.routeService.setGuide(simulation, route);
|
||||
}
|
||||
} else {
|
||||
if (signal.getLockedRoute() != null) { //如果有已锁闭进路
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal, signal.getSignalModel().getGuideAspect());
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal,
|
||||
signal.getSignalModel().getGuideAspect());
|
||||
} else if (!CollectionUtils.isEmpty(signal.getRouteList())) {
|
||||
List<Route> collect;
|
||||
if (config.isRailway()) { // 大铁配置引导进路
|
||||
@ -475,7 +479,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = signal.getRouteList().stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
|
||||
collect = signal.getRouteList().stream().filter(r -> !r.isTurnBack())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = signal.getRouteList();
|
||||
@ -483,7 +488,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
route = collect.get(0);
|
||||
this.routeService.setGuide(simulation, route);
|
||||
} else { //如果信号机没有关联进路
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal, signal.getSignalModel().getGuideAspect());
|
||||
this.signalService.tryControlSignalAspectAccordingLevel(simulation, signal,
|
||||
signal.getSignalModel().getGuideAspect());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -499,8 +505,7 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在引导总锁的状态下开放引导信号。
|
||||
* 引导总锁之后
|
||||
* 在引导总锁的状态下开放引导信号。 引导总锁之后
|
||||
*/
|
||||
private void openGuideAspect4GuideMasterLock(Simulation simulation, Signal signal) {
|
||||
signalService.controlSignalAspect(simulation, signal, signal.getGuideAspect());
|
||||
@ -549,21 +554,28 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
station = station.getDeviceStation();
|
||||
}
|
||||
Station deviceStation = station;
|
||||
boolean restartFlag = Objects.nonNull(deviceStation.getRestartTime()) && deviceStation.getRestartTime().isBefore(simulation.getCorrectSystemTime().toLocalTime());
|
||||
boolean restartFlag =
|
||||
Objects.nonNull(deviceStation.getRestartTime()) && deviceStation.getRestartTime()
|
||||
.isBefore(simulation.getCorrectSystemTime().toLocalTime());
|
||||
// 是否大铁设备
|
||||
boolean hasCTCFlag = simulation.getRepository().getConfig().isRailway();
|
||||
// 大铁异常提示语
|
||||
String exceptionMsg = hasCTCFlag ? "无效操作:车站未下电" : "无效操作或连锁机重启过8分钟需手动解锁";
|
||||
String exceptionMsg =
|
||||
hasCTCFlag ? "无效操作:车站未下电" : "无效操作或连锁机重启过8分钟需手动解锁";
|
||||
// 是否需要重启
|
||||
if (restartFlag) {
|
||||
// 考试、课程上电标识
|
||||
boolean powerOnFlag = ((Simulation.FunctionalType.LESSON.equals(simulation.getBuildParams().getFunctionalType())
|
||||
|| Simulation.FunctionalType.EXAM.equals(simulation.getBuildParams().getFunctionalType()))
|
||||
boolean powerOnFlag = (
|
||||
(Simulation.FunctionalType.LESSON.equals(simulation.getBuildParams().getFunctionalType())
|
||||
|| Simulation.FunctionalType.EXAM.equals(
|
||||
simulation.getBuildParams().getFunctionalType()))
|
||||
? true : deviceStation.getRestartTime().plusMinutes(8).isAfter(LocalTime.now()));
|
||||
if (hasCTCFlag || powerOnFlag) {
|
||||
deviceStation.setPowerUnlockButtonShow(false);
|
||||
List<Section> sections = simulation.getRepository().getSectionList();
|
||||
sections.stream().filter(section -> Objects.equals(section.getDeviceStation(), deviceStation)).forEach(Section::faultUnlock);
|
||||
sections.stream()
|
||||
.filter(section -> Objects.equals(section.getDeviceStation(), deviceStation))
|
||||
.forEach(Section::faultUnlock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -572,24 +584,28 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
|
||||
@Override
|
||||
public void standEC(Simulation simulation, Stand stand) {
|
||||
if (stand.getEsp() == null)
|
||||
if (stand.getEsp() == null) {
|
||||
return;
|
||||
}
|
||||
stand.getEsp().update(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelStandEC(Simulation simulation, Stand stand) {
|
||||
if (stand.getEsp() == null)
|
||||
if (stand.getEsp() == null) {
|
||||
return;
|
||||
}
|
||||
stand.getEsp().update(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwitchIndication switchForceTurn(Simulation simulation, String switchCode) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.assertTrue(!aSwitch.isLocked() && aSwitch.isSectionOccupied(),
|
||||
BusinessExceptionAssertEnum.SIMULATION_EXCEPTION_FOR_SHOW.assertTrue(
|
||||
!aSwitch.isLocked() && aSwitch.isSectionOccupied(),
|
||||
String.format("对%s强行转岔操作被联锁逻辑取消", aSwitch.getName()));
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!aSwitch.isLocked(), String.format("道岔[%s]锁闭,无法转动", aSwitch.getCode()));
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!aSwitch.isLocked(),
|
||||
String.format("道岔[%s]锁闭,无法转动", aSwitch.getCode()));
|
||||
return this.switchService.forceTurn(simulation, aSwitch);
|
||||
}
|
||||
|
||||
@ -598,7 +614,8 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
|
||||
Section axleSection = section.findAxleCounterSection();
|
||||
//条件检查
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(axleSection != null && axleSection.isAxleCounter(),
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(
|
||||
axleSection != null && axleSection.isAxleCounter(),
|
||||
section.debugStr() + "不是计轴区段也不归属于任何计轴区段");
|
||||
VirtualRealitySectionAxleCounter virtualAxleCounter = axleSection.getVirtualAxleCounter();
|
||||
if (!virtualAxleCounter.isOccupy()) {
|
||||
@ -621,13 +638,15 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchCommand(Simulation simulation, String switchCode, Boolean auto, Boolean reserve, Boolean normal) {
|
||||
public void switchCommand(Simulation simulation, String switchCode, Boolean auto, Boolean reserve,
|
||||
Boolean normal) {
|
||||
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
|
||||
if (auto != null) {
|
||||
aSwitch.setAuto(auto);
|
||||
} else {
|
||||
if (normal != null) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!aSwitch.isAuto(), "道岔未处于人工模式");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(!aSwitch.isAuto(),
|
||||
"道岔未处于人工模式");
|
||||
if (normal) {
|
||||
switchService.turn2NormalPosition(simulation, aSwitch);
|
||||
} else {
|
||||
@ -661,8 +680,9 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
@Override
|
||||
public void axleReset(Simulation simulation, String sectionCode) {
|
||||
VirtualRealitySectionAxleCounter axle = getAxleCounterAndCheck4Reset(simulation, sectionCode);
|
||||
if (!axle.isOccupy())
|
||||
if (!axle.isOccupy()) {
|
||||
return;
|
||||
}
|
||||
axle.axleReset();
|
||||
}
|
||||
|
||||
@ -727,37 +747,47 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
public void signalTurnOn(Simulation simulation, String signalCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNull(signal.getLockedRoute(), "信号机有锁闭进路,禁止点灯");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNull(signal.getLockedRoute(),
|
||||
"信号机有锁闭进路,禁止点灯");
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(vrSignal, signal.debugStr() + "无实体信号机");
|
||||
virtualRealityDeviceService.control(simulation, vrSignal, vrSignal.getModel().getDefaultAspect());
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(vrSignal,
|
||||
signal.debugStr() + "无实体信号机");
|
||||
virtualRealityDeviceService.control(simulation, vrSignal,
|
||||
vrSignal.getModel().getDefaultAspect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void signalTurnOff(Simulation simulation, String signalCode) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(signal.isShunting(), "调车信号机无法灭灯");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNull(signal.getLockedRoute(), "信号机有锁闭进路,禁止灭灯");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(signal.isShunting(),
|
||||
"调车信号机无法灭灯");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNull(signal.getLockedRoute(),
|
||||
"信号机有锁闭进路,禁止灭灯");
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(vrSignal, signal.debugStr() + "无实体信号机");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(vrSignal,
|
||||
signal.debugStr() + "无实体信号机");
|
||||
virtualRealityDeviceService.control(simulation, vrSignal, SignalAspect.No);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取计轴器并为预复位/复位操作检查设备状态
|
||||
*/
|
||||
private VirtualRealitySectionAxleCounter getAxleCounterAndCheck4Reset(Simulation simulation, String sectionCode) {
|
||||
private VirtualRealitySectionAxleCounter getAxleCounterAndCheck4Reset(Simulation simulation,
|
||||
String sectionCode) {
|
||||
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
|
||||
Section axleSection = section.findAxleCounterSection();
|
||||
//条件检查
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(axleSection != null && axleSection.isAxleCounter(),
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(
|
||||
axleSection != null && axleSection.isAxleCounter(),
|
||||
section.debugStr() + "不是计轴区段也不归属于任何计轴区段");
|
||||
VirtualRealitySectionAxleCounter virtualAxleCounter = axleSection.getVirtualAxleCounter();
|
||||
if (simulation.getRepository().getConfig().isStationPreResetBeforeAxlePreReset()) {
|
||||
Station deviceStation = axleSection.getDeviceStation();
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(deviceStation, section.debugStr() + "没有所属集中站");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(deviceStation.isPreReset(), deviceStation.debugStr() + "需处于预复位状态");
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(deviceStation,
|
||||
section.debugStr() + "没有所属集中站");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(deviceStation.isPreReset(),
|
||||
deviceStation.debugStr() + "需处于预复位状态");
|
||||
}
|
||||
return virtualAxleCounter;
|
||||
}
|
||||
@ -771,13 +801,15 @@ public class CiApiServiceImpl2 implements CiApiService {
|
||||
private List<Route> getCtcGuideRouteList(SimulationDataRepository repository, Signal signal) {
|
||||
// 获取以信号机开头的进路集合
|
||||
List<Route> routeList = repository.getRouteList().stream()
|
||||
.filter(routePojo -> routePojo.isTrainRoute() && routePojo.getStart().getCode().equals(signal.getCode()))
|
||||
.filter(routePojo -> routePojo.isTrainRoute() && routePojo.getStart().getCode()
|
||||
.equals(signal.getCode()))
|
||||
.collect(Collectors.toList());
|
||||
// 进路走向
|
||||
boolean isRight = routeList.stream().anyMatch(Route::isRight);
|
||||
// 终端信号机类型,信号机类型匹配时停止循环
|
||||
List<Signal.SignalType> endTypeList = Signal.SignalType.SHUNTING2.equals(signal.getType()) ?
|
||||
Arrays.asList(Signal.SignalType.RECEIVING, Signal.SignalType.DEPARTURE) : Arrays.asList(Signal.SignalType.SHUNTING2);
|
||||
Arrays.asList(Signal.SignalType.RECEIVING, Signal.SignalType.DEPARTURE)
|
||||
: Arrays.asList(Signal.SignalType.SHUNTING2);
|
||||
// 终止索引,最多循环20次,防止死循环
|
||||
int endIndex = 0;
|
||||
Section nextSection = signal.getSection();
|
||||
|
@ -1,27 +1,35 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CI.device;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteFls;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteOverlap;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SectionPath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiRouteService {
|
||||
|
||||
@Autowired
|
||||
private CiSwitchControlService switchControlService;
|
||||
@Autowired
|
||||
@ -31,13 +39,16 @@ public class CiRouteService {
|
||||
|
||||
/**
|
||||
* 进路排列检查
|
||||
*
|
||||
* @param guide 是引导进路?
|
||||
* @return
|
||||
*/
|
||||
public static Route.CheckFailMessage routeSetCheck(Simulation simulation, Route route, boolean guide) {
|
||||
public static Route.CheckFailMessage routeSetCheck(Simulation simulation, Route route,
|
||||
boolean guide) {
|
||||
if (!CollectionUtils.isEmpty(route.getMultiRouteAspects())) {
|
||||
for (Route.MultiRouteAspect multiRouteAspect : route.getMultiRouteAspects()) {
|
||||
Route.CheckFailMessage checkFailMessage = routeSetCheck(simulation, multiRouteAspect.getRoute(), false);
|
||||
Route.CheckFailMessage checkFailMessage = routeSetCheck(simulation,
|
||||
multiRouteAspect.getRoute(), false);
|
||||
if (checkFailMessage != null) {
|
||||
return checkFailMessage;
|
||||
}
|
||||
@ -70,7 +81,8 @@ public class CiRouteService {
|
||||
} else if (!CollectionUtils.isEmpty(section.getLogicList())) {
|
||||
for (Section logicSection : section.getLogicList()) {
|
||||
if (logicSection.isBlockade()) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionBlockade, logicSection);
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionBlockade,
|
||||
logicSection);
|
||||
}
|
||||
}
|
||||
} else if (section.getParent() != null) {
|
||||
@ -81,7 +93,8 @@ public class CiRouteService {
|
||||
// 进路内区段锁闭方向不是此进路方向
|
||||
if ((section.isRouteLock() || section.isOverlapLock()) &&
|
||||
!Objects.equals(section.isLockRight(), start.isRight())) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionLockOppositeDirection, section);
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SectionLockOppositeDirection,
|
||||
section);
|
||||
}
|
||||
//单列车进路区段占用
|
||||
if (section.isOccupied() && route.isSingleTrain()) {
|
||||
@ -89,8 +102,9 @@ public class CiRouteService {
|
||||
}
|
||||
// 故障占用
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (section.getParent() == null || section.isAxleCounter())
|
||||
if (section.getParent() == null || section.isAxleCounter()) {
|
||||
break;
|
||||
}
|
||||
section = section.getParent();
|
||||
}
|
||||
// if (Section.AxleFault.FAULT.equals(section.getFault())) {
|
||||
@ -101,7 +115,8 @@ public class CiRouteService {
|
||||
List<Route> conflictingRouteList = route.getConflictingRouteList();
|
||||
for (Route conflict : conflictingRouteList) {
|
||||
if (conflict.isSetting() || conflict.isLock()) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.ConflictingRouteSetting, conflict);
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.ConflictingRouteSetting,
|
||||
conflict);
|
||||
}
|
||||
}
|
||||
if (start.isCbtcMode()) {
|
||||
@ -130,11 +145,13 @@ public class CiRouteService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Route.CheckFailMessage monitorRouteOverlapConflictCheck(Simulation simulation, Route route) {
|
||||
private static Route.CheckFailMessage monitorRouteOverlapConflictCheck(Simulation simulation,
|
||||
Route route) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Route> settingRoutes = repository.getSettingRoutes();
|
||||
for (Route sr : settingRoutes) {
|
||||
if (sr.isSettingOverlap() && (sr.getOverlap().isSetting() || sr.getOverlap().isLock())/*&& !repository.isTrainParking(sr.getOverlap().getSection())*/) {
|
||||
if (sr.isSettingOverlap() && (sr.getOverlap().isSetting() || sr.getOverlap()
|
||||
.isLock())/*&& !repository.isTrainParking(sr.getOverlap().getSection())*/) {
|
||||
SectionPath sectionPath = sr.getOverlap().selectPath();
|
||||
for (SwitchElement switchElement : sectionPath.getSwitchList()) {
|
||||
if (route.isConflictSwitch(switchElement)) {
|
||||
@ -147,7 +164,8 @@ public class CiRouteService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Route.CheckFailMessage setSwitchCheck(Simulation simulation, List<SwitchElement> switchList, boolean guide) {
|
||||
private static Route.CheckFailMessage setSwitchCheck(Simulation simulation,
|
||||
List<SwitchElement> switchList, boolean guide) {
|
||||
if (switchList != null) {
|
||||
for (SwitchElement switchElement : switchList) {
|
||||
Switch aSwitch = switchElement.getASwitch();
|
||||
@ -162,7 +180,8 @@ public class CiRouteService {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SwitchLockPositionError, aSwitch);
|
||||
}
|
||||
if (aSwitch.isCiUseOnOppositePosition(switchElement.isNormal())) { // 道岔征用在相反位置
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SwitchCiUseOnOppositePosition, aSwitch);
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SwitchCiUseOnOppositePosition,
|
||||
aSwitch);
|
||||
}
|
||||
//道岔失表时,进路中的区段和道岔由远及近锁闭,直到失表的道岔处 -南铁院叶老师
|
||||
if (simulation.getRepository().getConfig().isRouteCanSetWhenSwitchFault()) {
|
||||
@ -170,8 +189,10 @@ public class CiRouteService {
|
||||
}
|
||||
// 非预先锁闭,道岔相应位置失表则不排进路
|
||||
if (!simulation.getRepository().getConfig().isLockFirst() && aSwitch.isLoss()) {
|
||||
if ((Switch.SwitchFault.NORMAL_SPLIT.equals(aSwitch.getFault()) && switchElement.isNormal())
|
||||
|| (Switch.SwitchFault.REVERSE_SPLIT.equals(aSwitch.getFault()) && !switchElement.isNormal())) {
|
||||
if ((Switch.SwitchFault.NORMAL_SPLIT.equals(aSwitch.getFault())
|
||||
&& switchElement.isNormal())
|
||||
|| (Switch.SwitchFault.REVERSE_SPLIT.equals(aSwitch.getFault())
|
||||
&& !switchElement.isNormal())) {
|
||||
return new Route.CheckFailMessage(Route.CheckFailReason.SwitchFault, aSwitch);
|
||||
}
|
||||
}
|
||||
@ -203,7 +224,8 @@ public class CiRouteService {
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
}
|
||||
if (Objects.nonNull(failMessage)) {
|
||||
log.info(String.format("进路[%s]排列检查失败,无法排列:%s", route.debugStr(), failMessage.debugStr()));
|
||||
log.info(String.format("进路[%s]排列检查失败,无法排列:%s", route.debugStr(),
|
||||
failMessage.debugStr()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +236,8 @@ public class CiRouteService {
|
||||
* @param route
|
||||
* @return
|
||||
*/
|
||||
public Route.CheckFailMessage setRoute(Simulation simulation, Route route,SignalAspect settedAspect) {
|
||||
public Route.CheckFailMessage setRoute(Simulation simulation, Route route,
|
||||
SignalAspect settedAspect) {
|
||||
Route.CheckFailMessage failMessage = routeSetCheck(simulation, route, false);
|
||||
if (failMessage == null) {
|
||||
if (route.isLock() && !route.isFleetMode()) {
|
||||
@ -237,7 +260,8 @@ public class CiRouteService {
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
}
|
||||
if (Objects.nonNull(failMessage)) {
|
||||
log.info(String.format("进路[%s]排列检查失败,无法排列:%s", route.debugStr(), failMessage.debugStr()));
|
||||
log.info(String.format("进路[%s]排列检查失败,无法排列:%s", route.debugStr(),
|
||||
failMessage.debugStr()));
|
||||
}
|
||||
return failMessage;
|
||||
}
|
||||
@ -252,7 +276,8 @@ public class CiRouteService {
|
||||
if (route.isSetting()) { // 进路排列中
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (!config.isRouteSettingNoFail()) {
|
||||
if (simulation.getSystemTime().isAfter(route.getSettingStartTime().plusSeconds(SimulationConstants.ROUTE_SETTING_TIMEOUT))) {
|
||||
if (simulation.getSystemTime().isAfter(
|
||||
route.getSettingStartTime().plusSeconds(SimulationConstants.ROUTE_SETTING_TIMEOUT))) {
|
||||
log.info("进路[{}]办理超时,取消办理2", route.debugStr());
|
||||
route.settingOver(false);
|
||||
return;
|
||||
@ -261,7 +286,8 @@ public class CiRouteService {
|
||||
List<Route.MultiRouteAspect> multiRouteAspects = route.getMultiRouteAspects();
|
||||
if (CollectionUtils.isEmpty(multiRouteAspects)) {
|
||||
// 道岔位置转换
|
||||
boolean mainRouteSwitchOnPos = this.switchControlService.ensureSwitchPosCurrent(simulation, route.getSwitchList(), route.isGuideSetting());
|
||||
boolean mainRouteSwitchOnPos = this.switchControlService.ensureSwitchPosCurrent(simulation,
|
||||
route.getSwitchList(), route.isGuideSetting());
|
||||
// 预先锁闭
|
||||
if (mainRouteSwitchOnPos || config.isLockFirst() || config.isRouteCanSetWhenSwitchFault()) {
|
||||
// 进路排列区段预先锁闭
|
||||
@ -282,7 +308,8 @@ public class CiRouteService {
|
||||
aspect = route.getAspectOfRailway();
|
||||
}
|
||||
}
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), aspect);
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(),
|
||||
aspect);
|
||||
if (config.isRailway()) {
|
||||
if (route.isGuideSetting() && route.getStart().isGuideAspect()
|
||||
|| !route.getStart().isDefaultAspect()) {
|
||||
@ -353,13 +380,13 @@ public class CiRouteService {
|
||||
}
|
||||
for (int i = switchList.size() - 1; i >= 0; i--) {
|
||||
SwitchElement switchElement = switchList.get(i);
|
||||
if (switchElement.isOnPosition() || (route.isGuideSetting() && switchElement.getASwitch().isGuideMasterLock())) {
|
||||
if (switchElement.isOnPosition() || (route.isGuideSetting() && switchElement.getASwitch()
|
||||
.isGuideMasterLock())) {
|
||||
switchElement.getASwitch().routeLock(route);
|
||||
}
|
||||
}
|
||||
route.setLock(true);
|
||||
|
||||
|
||||
// for (SwitchElement switchElement : switchList) {
|
||||
// if (switchElement.isOnPosition() || (route.isGuideSetting() && switchElement.getASwitch().isGuideMasterLock())) {
|
||||
// switchElement.getASwitch().routeLock(route);
|
||||
@ -447,7 +474,8 @@ public class CiRouteService {
|
||||
device.delayUnlockStart(route, simulation.getRepository().getConfig());
|
||||
route.setDelayUnlockDevice(device);
|
||||
route.setAtsControl(false); //南铁院叶老师:延时解锁开始的同时信号机应该红名(南京二号线)
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getStart().getDefaultAspect());
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(),
|
||||
route.getStart().getDefaultAspect());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -520,7 +548,8 @@ public class CiRouteService {
|
||||
return;
|
||||
} else {
|
||||
if (route.isOpenMain() || route.isOpenGuide()) {
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(),
|
||||
this.signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
route.getStart(),
|
||||
route.getStart().getDefaultAspect());
|
||||
}
|
||||
route.setLock(false);
|
||||
@ -632,7 +661,8 @@ public class CiRouteService {
|
||||
if (allUnlock) { // 进路所有区段都已经解锁,解锁完成
|
||||
route.normalUnlockOver();
|
||||
simulation.getRepository().removeSettingRoute(route);
|
||||
log.debug(String.format("进路[%s(%s)-%s]解锁完毕,移除", route.getName(), route.getCode(), route.isTurnBack() ? "Z" : "B"));
|
||||
log.debug(String.format("进路[%s(%s)-%s]解锁完毕,移除", route.getName(), route.getCode(),
|
||||
route.isTurnBack() ? "Z" : "B"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -678,7 +708,8 @@ public class CiRouteService {
|
||||
}
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (!config.isRouteSettingNoFail()) {
|
||||
if (simulation.getSystemTime().isAfter(overlap.getSettingStartTime().plusSeconds(SimulationConstants.ROUTE_SETTING_TIMEOUT))) {
|
||||
if (simulation.getSystemTime().isAfter(
|
||||
overlap.getSettingStartTime().plusSeconds(SimulationConstants.ROUTE_SETTING_TIMEOUT))) {
|
||||
log.info(String.format("进路延续保护[%s]办理失败", overlap.debugStr()));
|
||||
overlap.settingOver();
|
||||
return;
|
||||
@ -692,7 +723,8 @@ public class CiRouteService {
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
// 延续保护位置转动
|
||||
boolean onPos = this.switchControlService.ensureSwitchPosCurrent(simulation, sectionPath.getSwitchList(), false);
|
||||
boolean onPos = this.switchControlService.ensureSwitchPosCurrent(simulation,
|
||||
sectionPath.getSwitchList(), false);
|
||||
// 延续保护区段预先锁闭
|
||||
if (onPos || config.isLockFirst()) {
|
||||
this.checkAndLockOverlap(simulation, overlap);
|
||||
@ -727,21 +759,6 @@ public class CiRouteService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动进路模式
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void setFleet(Route route) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFlt(),
|
||||
"不是自动进路,不能设置自动进路");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isCiControl(),
|
||||
"进路联锁自动触发,不能设置自动进路");
|
||||
if (!route.isFleetMode()) {
|
||||
route.setFleetMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消自动进路
|
||||
*
|
||||
@ -753,29 +770,4 @@ public class CiRouteService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动触发
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void setCIAutoTrigger(Route route) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
|
||||
"进路处于自动进路模式中,不能设置联锁自动触发");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isArs(),
|
||||
"进路不具有该功能,无法设置为联锁自动触发");
|
||||
if (!route.isCiControl()) {
|
||||
route.setCiControl(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动触发
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void cancelCIAutoTrigger(Route route) {
|
||||
if (route.isCiControl()) {
|
||||
route.setCiControl(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,14 +19,19 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.Preselectio
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 指令执行
|
||||
*/
|
||||
@ -34,6 +39,7 @@ import java.util.stream.Collectors;
|
||||
@Getter
|
||||
@Setter
|
||||
public class CommandBO {
|
||||
|
||||
private CommandType commandType;
|
||||
|
||||
private SimulationMember fromMember;
|
||||
@ -44,7 +50,8 @@ public class CommandBO {
|
||||
|
||||
private List<Step> stepList;
|
||||
|
||||
public CommandBO(CommandType commandType, SimulationMember fromMember, SimulationMember targetMember,
|
||||
public CommandBO(CommandType commandType, SimulationMember fromMember,
|
||||
SimulationMember targetMember,
|
||||
Map<String, Object> params, List<Step> stepList) {
|
||||
this.commandType = commandType;
|
||||
this.fromMember = fromMember;
|
||||
@ -63,7 +70,8 @@ public class CommandBO {
|
||||
}
|
||||
|
||||
public List<Step> getStepByType(Step.StepType stepType) {
|
||||
return this.stepList.stream().filter(step -> step.getType().equals(stepType)).collect(Collectors.toList());
|
||||
return this.stepList.stream().filter(step -> step.getType().equals(stepType))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,6 +80,7 @@ public class CommandBO {
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Step {
|
||||
|
||||
private StepType type;
|
||||
|
||||
private Operation.Type operationType;
|
||||
@ -145,7 +154,8 @@ public class CommandBO {
|
||||
*/
|
||||
Drive_Ahead(Collections.emptyList(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
Section section = headPosition.getSection();
|
||||
@ -154,22 +164,26 @@ public class CommandBO {
|
||||
List<Step> stepList = new ArrayList<>();
|
||||
stepList.add(buildDriverForceChangeOperationStep(train.getGroupNumber(), 0));
|
||||
if (section.isStandTrack()) { //如果列车的车头所在区段是站台轨
|
||||
SectionPosition standStopPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
SectionPosition standStopPosition = new SectionPosition(section,
|
||||
section.getStopPointByDirection(right));
|
||||
if (train.isStopAtThePosition(standStopPosition)) { //列车已经停在站台停车点
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "列车已在站台轨停车点停车");
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
"列车已在站台轨停车点停车");
|
||||
} else if (standStopPosition.isAheadOf(headPosition, right)) { //站台停车点在列车车头前方
|
||||
stepList.add(buildDriveStep(standStopPosition));
|
||||
} else {
|
||||
SectionPosition nextStopPosition = train.calculateNextStandStopPosition();
|
||||
if (nextStopPosition == null) {
|
||||
nextStopPosition = new SectionPosition(train.getTarget(), train.getTarget().getStopPointByDirection(right));
|
||||
nextStopPosition = new SectionPosition(train.getTarget(),
|
||||
train.getTarget().getStopPointByDirection(right));
|
||||
}
|
||||
stepList.add(buildDriveStep(nextStopPosition));
|
||||
}
|
||||
} else {
|
||||
SectionPosition nextStopPosition = train.calculateNextStandStopPosition();
|
||||
if (nextStopPosition == null && train.getTarget() != null) {
|
||||
nextStopPosition = new SectionPosition(train.getTarget(), train.getTarget().getStopPointByDirection(right));
|
||||
nextStopPosition = new SectionPosition(train.getTarget(),
|
||||
train.getTarget().getStopPointByDirection(right));
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(nextStopPosition,
|
||||
train.debugStr() + "找不到下一个停车点");
|
||||
@ -189,12 +203,15 @@ public class CommandBO {
|
||||
if (!train.isInTheGear(Handwheel.MANUAL)) {
|
||||
return buildGearChangeStep(train.getGroupNumber(), Handwheel.MANUAL);
|
||||
}
|
||||
if (!train.isStop())
|
||||
if (!train.isStop()) {
|
||||
return buildDriverForceChangeOperationStep(train.getGroupNumber(), -1);
|
||||
if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode())
|
||||
}
|
||||
if (!DriveMode.RM.equals(train.getDriveMode()) && !train.isNRMMode()) {
|
||||
return getStep4ChangePreselectionMode(train, PreselectionMode.RM);
|
||||
if (train.isEB())
|
||||
}
|
||||
if (train.isEB()) {
|
||||
return getStep4ReleaseEB(train);
|
||||
}
|
||||
return driveStep;
|
||||
} else { //如果列车已经停到目标位置
|
||||
// if (!DriveMode.AM.equals(train.getDriveMode()))
|
||||
@ -210,7 +227,8 @@ public class CommandBO {
|
||||
*/
|
||||
Route_Block_Drive(Collections.emptyList(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -230,9 +248,11 @@ public class CommandBO {
|
||||
/**
|
||||
* 道岔钩锁
|
||||
*/
|
||||
Switch_Hook_Lock(Arrays.asList(ParamName.switchCode, ParamName.normal), SimulationMember.Type.STATION_SUPERVISOR) {
|
||||
Switch_Hook_Lock(Arrays.asList(ParamName.switchCode, ParamName.normal),
|
||||
SimulationMember.Type.STATION_SUPERVISOR) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
if (!SimulationMember.Type.STATION_SUPERVISOR.equals(targetMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Station_Supervisor);
|
||||
}
|
||||
@ -265,7 +285,8 @@ public class CommandBO {
|
||||
*/
|
||||
Drive_Through_The_Red_Light(Collections.emptyList(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(targetMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
@ -273,7 +294,8 @@ public class CommandBO {
|
||||
List<Step> stepList = new ArrayList<>();
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
stepList.add(buildDriveStep(train.calculateStopPosition4CrossTheRedLight()));
|
||||
stepList.add(buildCrossSignalStep(train.getHeadPosition().getSection().getSignalOf(train.isRight())));
|
||||
stepList.add(buildCrossSignalStep(
|
||||
train.getHeadPosition().getSection().getSignalOf(train.isRight())));
|
||||
stepList.add(buildRmToBmStep());
|
||||
|
||||
return stepList;
|
||||
@ -306,7 +328,8 @@ public class CommandBO {
|
||||
*/
|
||||
Drive_Through_The_Guide_Signal(Collections.emptyList(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(targetMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
@ -314,7 +337,8 @@ public class CommandBO {
|
||||
List<Step> stepList = new ArrayList<>();
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
stepList.add(buildDriveStep(calculateStepPosition4CrossTheGuideSignal(train)));
|
||||
stepList.add(buildCrossSignalStep(train.getHeadPosition().getSection().getSignalOf(train.isRight())));
|
||||
stepList.add(buildCrossSignalStep(
|
||||
train.getHeadPosition().getSection().getSignalOf(train.isRight())));
|
||||
|
||||
return stepList;
|
||||
}
|
||||
@ -344,7 +368,8 @@ public class CommandBO {
|
||||
*/
|
||||
Open_Or_Close_Door(Collections.emptyList(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(targetMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
@ -352,7 +377,8 @@ public class CommandBO {
|
||||
List<Step> stepList = new ArrayList<>();
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
List<Stand> standList = train.getHeadPosition().getSection().getStandList();
|
||||
if (!CollectionUtils.isEmpty(standList) && standList.size() == 1 && standList.get(0).isSmall()) {
|
||||
if (!CollectionUtils.isEmpty(standList) && standList.size() == 1 && standList.get(0)
|
||||
.isSmall()) {
|
||||
// 小站台停车,无需开关门
|
||||
return null;
|
||||
}
|
||||
@ -384,7 +410,8 @@ public class CommandBO {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) command.getTargetMember().getDevice();
|
||||
List<Step> steps = command.getStepByType(Step.StepType.OPERATION);
|
||||
Step step = steps.get(0);
|
||||
VirtualRealityTrain.Door door = train.getDoorByDirection((boolean) step.getOperationParams().get("right"));
|
||||
VirtualRealityTrain.Door door = train.getDoorByDirection(
|
||||
(boolean) step.getOperationParams().get("right"));
|
||||
if (!Objects.equals(door.isOpen(), step.getOperationParams().get("open"))) {
|
||||
return step;
|
||||
} else {
|
||||
@ -400,14 +427,16 @@ public class CommandBO {
|
||||
*/
|
||||
Set_Speed_Limit(List.of(ParamName.speedLimit), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step execute(Simulation simulation, CommandBO command) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) command.getTargetMember().getDevice();
|
||||
float speedLimit = Float.parseFloat((String) command.getParams().get(ParamName.speedLimit.name()));
|
||||
float speedLimit = Float.parseFloat(
|
||||
(String) command.getParams().get(ParamName.speedLimit.name()));
|
||||
if (speedLimit < 0) {
|
||||
train.setSpeedLimit(Float.MAX_VALUE);
|
||||
} else {
|
||||
@ -423,8 +452,10 @@ public class CommandBO {
|
||||
*/
|
||||
Turn_Direction(List.of(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(SimulationMember.Type.DRIVER, targetMember.getType());
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(SimulationMember.Type.DRIVER,
|
||||
targetMember.getType());
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
params.put(ParamName.trainRight.name(), !train.isRight());
|
||||
return new ArrayList<>();
|
||||
@ -448,7 +479,8 @@ public class CommandBO {
|
||||
*/
|
||||
Drive_To(List.of(ParamName.sectionCode), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@ -458,7 +490,8 @@ public class CommandBO {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
String sectionCode = (String) command.getParams().get(ParamName.sectionCode.name());
|
||||
Section section = simulation.getRepository().getByCode(sectionCode, Section.class);
|
||||
SectionPosition targetPosition = new SectionPosition(section, section.getStopPointByDirection(train.isRight()));
|
||||
SectionPosition targetPosition = new SectionPosition(section,
|
||||
section.getStopPointByDirection(train.isRight()));
|
||||
if (train.isStopAtThePosition(targetPosition)) {
|
||||
targetMember.setCommand(null);
|
||||
return null;
|
||||
@ -473,7 +506,8 @@ public class CommandBO {
|
||||
*/
|
||||
Inbound(List.of(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@ -500,7 +534,8 @@ public class CommandBO {
|
||||
*/
|
||||
Change_Preselection_Mode(List.of(ParamName.preselectionMode), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -515,11 +550,12 @@ public class CommandBO {
|
||||
return getStep4ReleaseEB(train);
|
||||
}
|
||||
PreselectionMode preselectionMode =
|
||||
PreselectionMode.valueOf((String) command.getParams().get(ParamName.preselectionMode.name()));
|
||||
PreselectionMode.valueOf(
|
||||
(String) command.getParams().get(ParamName.preselectionMode.name()));
|
||||
PreselectionMode trainMode = train.getPreselectionMode();
|
||||
if (trainMode != preselectionMode) { //预选级别不对
|
||||
return getStep4ChangePreselectionMode(train, preselectionMode);
|
||||
} else if (trainMode.isMatchTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
|
||||
} else if (trainMode.isNotLowerThanTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
|
||||
return getStep4OpenATO(train);
|
||||
} else {
|
||||
driver.setCommand(null);
|
||||
@ -533,7 +569,8 @@ public class CommandBO {
|
||||
*/
|
||||
Apply_NRM(List.of(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -554,14 +591,16 @@ public class CommandBO {
|
||||
**/
|
||||
Depart_Train(List.of(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
boolean isRight = train.isRight(); // 列车运行方向
|
||||
Section section = train.getHeadPosition().getSection(); // 列车车头所在区段
|
||||
Section targetSection = getTargetSection(isRight, section);
|
||||
List<Step> stepList = new ArrayList<>();
|
||||
if (targetSection != null) {
|
||||
SectionPosition targetPosition = new SectionPosition(targetSection, targetSection.getStopPointByDirection(isRight));
|
||||
SectionPosition targetPosition = new SectionPosition(targetSection,
|
||||
targetSection.getStopPointByDirection(isRight));
|
||||
// 设置目标位置
|
||||
stepList.add(buildDriveStep(targetPosition));
|
||||
}
|
||||
@ -571,7 +610,8 @@ public class CommandBO {
|
||||
@Override
|
||||
public Step execute(Simulation simulation, CommandBO command) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) command.getTargetMember().getDevice();
|
||||
boolean isOnline = simulation.getRepository().getUsedTrainMap().containsKey(train.getGroupNumber());
|
||||
boolean isOnline = simulation.getRepository().getUsedTrainMap()
|
||||
.containsKey(train.getGroupNumber());
|
||||
if (!isOnline) {
|
||||
command.getTargetMember().setCommand(null);
|
||||
return null;
|
||||
@ -585,7 +625,8 @@ public class CommandBO {
|
||||
if (Objects.equals(section, targetSection)) {
|
||||
command.getTargetMember().setCommand(null);
|
||||
} else {
|
||||
SectionPosition targetPosition = new SectionPosition(targetSection, targetSection.getStopPointByDirection(isRight));
|
||||
SectionPosition targetPosition = new SectionPosition(targetSection,
|
||||
targetSection.getStopPointByDirection(isRight));
|
||||
driveStep.setTargetPosition(targetPosition);
|
||||
return driveStep;
|
||||
}
|
||||
@ -610,7 +651,8 @@ public class CommandBO {
|
||||
*/
|
||||
Parking_Train(List.of(), SimulationMember.Type.DRIVER) {
|
||||
@Override
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params) {
|
||||
public List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -618,7 +660,8 @@ public class CommandBO {
|
||||
public Step execute(Simulation simulation, CommandBO command) {
|
||||
SimulationMember targetMember = command.getTargetMember();
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) targetMember.getDevice();
|
||||
boolean isOnline = simulation.getRepository().getUsedTrainMap().containsKey(train.getGroupNumber());
|
||||
boolean isOnline = simulation.getRepository().getUsedTrainMap()
|
||||
.containsKey(train.getGroupNumber());
|
||||
if (!isOnline) {
|
||||
command.getTargetMember().setCommand(null);
|
||||
return null;
|
||||
@ -671,7 +714,8 @@ public class CommandBO {
|
||||
/**
|
||||
* 构架指令步骤列表
|
||||
*/
|
||||
public abstract List<Step> buildStepList(Simulation simulation, SimulationMember targetMember, Map<String, Object> params);
|
||||
public abstract List<Step> buildStepList(Simulation simulation, SimulationMember targetMember,
|
||||
Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 执行指令,返回无法直接完成的指令
|
||||
@ -679,7 +723,6 @@ public class CommandBO {
|
||||
public abstract Step execute(Simulation simulation, CommandBO command);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 构建“开启ATO操作”步骤
|
||||
*/
|
||||
@ -798,13 +841,15 @@ public class CommandBO {
|
||||
Section section = headPosition.getSection();
|
||||
Signal trainHeadSignal = section.getSignalOf(right);
|
||||
if (trainHeadSignal == null || !trainHeadSignal.isGuideAspect()) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "指令要求:列车车头所在区段有同向信号机并且开放引导信号");
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
"指令要求:列车车头所在区段有同向信号机并且开放引导信号");
|
||||
}
|
||||
|
||||
SectionPosition sectionPosition = null;
|
||||
for (int i = 0; i < 30; i++) {
|
||||
section = section.findNextRunningSectionBaseRealSwitch(right);
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(section, "引导信号前方未找到停车位置");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotNull(section,
|
||||
"引导信号前方未找到停车位置");
|
||||
Signal signal = section.getSignalOf(right);
|
||||
if (section.isStandTrack() || section.isTurnBackTrack()) {
|
||||
sectionPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
@ -815,7 +860,8 @@ public class CommandBO {
|
||||
}
|
||||
}
|
||||
if (sectionPosition == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "引导信号前方未找到停车位置");
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
"引导信号前方未找到停车位置");
|
||||
}
|
||||
return sectionPosition;
|
||||
}
|
||||
@ -946,7 +992,8 @@ public class CommandBO {
|
||||
return step;
|
||||
}
|
||||
|
||||
public static Step getStep4ChangePreselectionMode(VirtualRealityTrain train, PreselectionMode preselectionMode) {
|
||||
public static Step getStep4ChangePreselectionMode(VirtualRealityTrain train,
|
||||
PreselectionMode preselectionMode) {
|
||||
PreselectionMode trainMode = train.getPreselectionMode();
|
||||
PreselectionMode tempMode = train.getTempPreselectionMode();
|
||||
String groupNumber = train.getGroupNumber();
|
||||
|
@ -6,7 +6,11 @@ import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.TrainTBControl;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
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.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
@ -14,15 +18,14 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.vo.client.operation.DriveParamVO;
|
||||
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* 虚拟真实列车
|
||||
@ -351,9 +354,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
private DoorSelection doorSelection;
|
||||
|
||||
/**
|
||||
* 牵引力,单位kN
|
||||
* 公式 fk = 350 (0 <= v <= 36km/h)
|
||||
* fk = 12900 / v (36 < v < 80km/h)
|
||||
* 牵引力,单位kN 公式 fk = 350 (0 <= v <= 36km/h) fk = 12900 / v (36 < v < 80km/h)
|
||||
*/
|
||||
private float fk;
|
||||
|
||||
@ -446,7 +447,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
private final LinkedHashSet<ConfirmationMessage> confirmationMessages = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* ato可以开启
|
||||
* ato可以开启。此状态仅用以前端显示,因为此状态更新不及时,使用起来比较麻烦
|
||||
*/
|
||||
private boolean atoCanOpen;
|
||||
|
||||
@ -465,7 +466,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* @param railway 是大铁线路?如果是,将最高速度改为320km/h
|
||||
* @param manualTrainDefaultStop
|
||||
*/
|
||||
public VirtualRealityTrain(String code, String groupNumber, boolean railway, boolean manualTrainDefaultStop) {
|
||||
public VirtualRealityTrain(String code, String groupNumber, boolean railway,
|
||||
boolean manualTrainDefaultStop) {
|
||||
super(code, groupNumber, DeviceType.TRAIN);
|
||||
this.groupNumber = groupNumber;
|
||||
this.gear = Handwheel.ATO;
|
||||
@ -489,8 +491,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
public void setCommunication(boolean communication) {
|
||||
if ((Fault.COMMUNICATION_ABNORMAL.equals(this.fault) || !atpOn || this.noCommunicateDevice) && communication)
|
||||
if ((Fault.COMMUNICATION_ABNORMAL.equals(this.fault) || !atpOn || this.noCommunicateDevice)
|
||||
&& communication) {
|
||||
return;
|
||||
}
|
||||
this.communication = communication;
|
||||
}
|
||||
|
||||
@ -674,6 +678,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
this.initPosition(right, headPosition);
|
||||
init();
|
||||
}
|
||||
|
||||
public void initManualTrain(SectionPosition headPosition, boolean right, TrainPosition tp) {
|
||||
this.initPosition(right, headPosition);
|
||||
init();
|
||||
@ -681,6 +686,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
this.locationKM = tp.getLocation();
|
||||
this.right = tp.isRight();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.communication = true;
|
||||
this.jump = false;
|
||||
@ -709,7 +715,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
// }
|
||||
}
|
||||
|
||||
public synchronized void updateNextStationPlan(Station nextStation, Section targetSection, boolean nextParking) {
|
||||
public synchronized void updateNextStationPlan(Station nextStation, Section targetSection,
|
||||
boolean nextParking) {
|
||||
this.nextStation = nextStation;
|
||||
// this.setTarget(targetSection);
|
||||
this.nextParking = nextParking;
|
||||
@ -745,8 +752,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
public void updateTBForce(float fk, float fb) {
|
||||
if (isEB())
|
||||
if (isEB()) {
|
||||
return;
|
||||
}
|
||||
if (Fault.DRIVE_FAULT.equals(fault) && fk > 0) {
|
||||
return;
|
||||
}
|
||||
@ -804,7 +812,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
public SectionPosition calculateTailPosition() {
|
||||
this.tailPosition = CalculateService.calculateNextPositionByStartAndLen(this.headPosition, !right, this.getLen(), true);
|
||||
this.tailPosition = CalculateService.calculateNextPositionByStartAndLen(this.headPosition,
|
||||
!right, this.getLen(), true);
|
||||
return this.tailPosition;
|
||||
}
|
||||
|
||||
@ -862,6 +871,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
/**
|
||||
* 获取列车后方的车站停车位置
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SectionPosition calculateBackStandStopPosition() {
|
||||
@ -880,6 +890,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算列车前方下一个站台的停车位置
|
||||
*/
|
||||
@ -908,7 +919,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
Section section = this.headPosition.getSection();
|
||||
Signal signal = section.getSignalOf(right);
|
||||
if (signal == null || !signal.isDefaultAspect()) { //没有同向信号机或信号机不处于信号关闭状态
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "指令要求:列车车头所在区段有同向信号机并且信号关闭");
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation,
|
||||
"指令要求:列车车头所在区段有同向信号机并且信号关闭");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
@ -1014,11 +1026,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
public boolean isStandReadyStart() {
|
||||
return Objects.nonNull(this.standParkedTrainActivity) && StandParkedTrainActivity.START.equals(this.standParkedTrainActivity);
|
||||
return Objects.nonNull(this.standParkedTrainActivity) && StandParkedTrainActivity.START.equals(
|
||||
this.standParkedTrainActivity);
|
||||
}
|
||||
|
||||
public boolean isStandBoarding() {
|
||||
return Objects.nonNull(this.standParkedTrainActivity) && StandParkedTrainActivity.BOARD.equals(this.standParkedTrainActivity);
|
||||
return Objects.nonNull(this.standParkedTrainActivity) && StandParkedTrainActivity.BOARD.equals(
|
||||
this.standParkedTrainActivity);
|
||||
}
|
||||
|
||||
public synchronized void nextParkedTrainActivity() {
|
||||
@ -1050,8 +1064,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
public boolean isInTheStandArea() {
|
||||
if (this.getHeadPosition() == null)
|
||||
if (this.getHeadPosition() == null) {
|
||||
return false;
|
||||
}
|
||||
return this.getHeadPosition().getSection().isNormalStandTrack()
|
||||
|| this.calculateTailPosition().getSection().isNormalStandTrack();
|
||||
}
|
||||
@ -1081,7 +1096,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* 在AM级预选模式下
|
||||
*/
|
||||
public boolean isInAMPreselectionMode() {
|
||||
return preselectionMode.isMatchTheDriveMode(DriveMode.AM);
|
||||
return preselectionMode.isNotLowerThanTheDriveMode(DriveMode.AM);
|
||||
}
|
||||
|
||||
public void addMessage(ConfirmationMessage message) {
|
||||
@ -1128,12 +1143,16 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return getAtoSpeed() * 3.6 < 20;
|
||||
}
|
||||
|
||||
/** 操纵杆是否在惰行位 */
|
||||
/**
|
||||
* 操纵杆是否在惰行位
|
||||
*/
|
||||
public boolean isLeverInCoastingGear() {
|
||||
return leverPosition == 0;
|
||||
}
|
||||
|
||||
/** 是否不在牵引位 */
|
||||
/**
|
||||
* 是否不在牵引位
|
||||
*/
|
||||
public boolean isLeverNotInTractionGear() {
|
||||
return leverPosition <= 0;
|
||||
}
|
||||
@ -1260,9 +1279,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* 道岔支持的操作
|
||||
*/
|
||||
public enum Operation {
|
||||
/** 开门 */
|
||||
/**
|
||||
* 开门
|
||||
*/
|
||||
K,
|
||||
/** 关门 */
|
||||
/**
|
||||
* 关门
|
||||
*/
|
||||
G,
|
||||
}
|
||||
|
||||
@ -1352,7 +1375,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
},
|
||||
|
||||
/** 驾驶异常 */
|
||||
/**
|
||||
* 驾驶异常
|
||||
*/
|
||||
DRIVE_FAULT {
|
||||
@Override
|
||||
public boolean apply(MapElement device) {
|
||||
@ -1364,10 +1389,15 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/** 列车脱线 */
|
||||
/**
|
||||
* 列车脱线
|
||||
*/
|
||||
OFF_LINE {},
|
||||
/** 突然EB */
|
||||
SUDDEN_EB{},;
|
||||
/**
|
||||
* 突然EB
|
||||
*/
|
||||
SUDDEN_EB {},
|
||||
;
|
||||
|
||||
public boolean apply(MapElement device) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
@ -1377,6 +1407,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
train.setFault(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消故障
|
||||
*/
|
||||
@ -1495,9 +1526,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
},
|
||||
;
|
||||
/** 所允许的最高驾驶模式 */
|
||||
/**
|
||||
* 所允许的最高驾驶模式
|
||||
*/
|
||||
private DriveMode driveMode;
|
||||
/** 所允许的最高运行级别 */
|
||||
/**
|
||||
* 所允许的最高运行级别
|
||||
*/
|
||||
private RunLevel runLevel;
|
||||
|
||||
PreselectionMode(DriveMode driveMode, RunLevel runLevel) {
|
||||
@ -1508,19 +1543,23 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
public abstract PreselectionMode findNext(boolean up);
|
||||
|
||||
/**
|
||||
* 该预选模式与该驾驶模式匹配(即允许升到该模式)
|
||||
* 该预选模式的驾驶模式不低于指定的驾驶模式
|
||||
*/
|
||||
public boolean isMatchTheDriveMode(DriveMode driveMode) {
|
||||
public boolean isNotLowerThanTheDriveMode(DriveMode driveMode) {
|
||||
return this.driveMode.isNotLowerThan(driveMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该预选模式与该运行级别匹配
|
||||
* 该预选模式的运行级别不低于指定级别
|
||||
*/
|
||||
public boolean isMatchTheRunLevel(RunLevel runLevel) {
|
||||
public boolean isNotLowerThanTheRunLevel(RunLevel runLevel) {
|
||||
return this.runLevel.isNotLowerThan(runLevel);
|
||||
}
|
||||
|
||||
public boolean isMatchTheRunLevel(RunLevel runLevel) {
|
||||
return this.runLevel == runLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否比该模式级别更高
|
||||
*/
|
||||
|
@ -26,15 +26,14 @@ import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
|
||||
import club.joylink.rtss.simulation.cbtc.robot.SimulationRobotService;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 自动保护系统服务
|
||||
*/
|
||||
@ -82,7 +81,8 @@ public class ATPService {
|
||||
train.getServiceNumber(), train.getTripNumber(), train.getDestinationCode(),
|
||||
ma.getEnd(), ma.getEnd().getEndPosition().toString(), protectDistance));
|
||||
// 重新生成速度曲线
|
||||
SpeedCurve speedCurve = SpeedCurve.generateProtectSpeedCurve(protectDistance, train.getAtpSpeedMax()); //未考虑区段限速
|
||||
SpeedCurve speedCurve = SpeedCurve.generateProtectSpeedCurve(protectDistance,
|
||||
train.getAtpSpeedMax()); //未考虑区段限速
|
||||
// SpeedCurve speedCurve = SpeedCurve.generateProtectSpeedCurve(train); //考虑区段限速
|
||||
log.debug(String.format("列车[%s-%s|%s|%s]重新生成防护速度曲线[%s]",
|
||||
train.getGroupNumber(),
|
||||
@ -132,7 +132,8 @@ public class ATPService {
|
||||
case AM:
|
||||
case CM:
|
||||
if (train.getSpeed() > train.getAtpSpeed()) {
|
||||
log.warn(String.format("系统时间:[%s],列车[%s]超速EB。驾驶模式:[%s], 移动授权:[%s], 速度:[%s],防护速度:[%s]",
|
||||
log.warn(String.format(
|
||||
"系统时间:[%s],列车[%s]超速EB。驾驶模式:[%s], 移动授权:[%s], 速度:[%s],防护速度:[%s]",
|
||||
simulation.getCorrectSystemTime(),
|
||||
train.getGroupNumber(), train.getDriveMode(),
|
||||
train.getMa2() != null ? train.getMa2().debugStr() : '无',
|
||||
@ -304,10 +305,14 @@ public class ATPService {
|
||||
}
|
||||
}
|
||||
|
||||
public void openOrCloseDoor(Simulation simulation, VirtualRealityTrain train, boolean right, boolean open) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getSpeed() == 0, String.format("列车[%s]未停止,不能操作车门", train.getGroupNumber()));
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getDoorMode().isManual(open), String.format("列车[%s]门模式自动,不能操作车门", train.getGroupNumber()));
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getDoorSelection().match(right),String.format("列车[%s]门选择与操作不匹配", train.getGroupNumber()));
|
||||
public void openOrCloseDoor(Simulation simulation, VirtualRealityTrain train, boolean right,
|
||||
boolean open) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getSpeed() == 0,
|
||||
String.format("列车[%s]未停止,不能操作车门", train.getGroupNumber()));
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getDoorMode().isManual(open),
|
||||
String.format("列车[%s]门模式自动,不能操作车门", train.getGroupNumber()));
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(train.getDoorSelection().match(right),
|
||||
String.format("列车[%s]门选择与操作不匹配", train.getGroupNumber()));
|
||||
List<Stand> standList = train.getHeadPosition().getSection().getStandList();
|
||||
VirtualRealityTrain.Door door = train.getDoorByDirection(right);
|
||||
if (open) {
|
||||
@ -317,7 +322,8 @@ public class ATPService {
|
||||
}
|
||||
if (train.isCommunicable()) {
|
||||
for (Stand stand : standList) {
|
||||
this.ciApiService.openScreenDoor(simulation, stand.getCode(), CiStandService.PsdCommandSource.SIG);
|
||||
this.ciApiService.openScreenDoor(simulation, stand.getCode(),
|
||||
CiStandService.PsdCommandSource.SIG);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -327,7 +333,8 @@ public class ATPService {
|
||||
}
|
||||
if (train.isCommunicable()) {
|
||||
for (Stand stand : standList) {
|
||||
this.ciApiService.closeScreenDoor(simulation, stand.getCode(), CiStandService.PsdCommandSource.SIG);
|
||||
this.ciApiService.closeScreenDoor(simulation, stand.getCode(),
|
||||
CiStandService.PsdCommandSource.SIG);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -350,7 +357,7 @@ public class ATPService {
|
||||
* 开启ATO
|
||||
*/
|
||||
public void openATO(VirtualRealityTrain train) {
|
||||
if (train.isAtoCanOpen()) {
|
||||
if (canOpenATO(train)) {
|
||||
train.setAtoOn(true);
|
||||
train.setDriveMode(DriveMode.AM);
|
||||
}
|
||||
@ -374,19 +381,29 @@ public class ATPService {
|
||||
*/
|
||||
public boolean canOpenATO(VirtualRealityTrain train) {
|
||||
if (train.isAtoOn()) //ATO已经开启
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!train.isInAMPreselectionMode()) //不在AM-预选模式
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!VirtualRealityTrain.Handwheel.ATO.equals(train.getGear())) //工况手轮不在ATO位
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// if (!train.isLeverInCoastingGear()) //操纵杆不在惰行位
|
||||
// return false;
|
||||
// if (train.getAtoSpeed() <= 0) //列车无推荐速度
|
||||
// return false;
|
||||
if (!train.isITC() && !train.isCBTC()) //非ITC、CTC运行级别
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!train.isAtpOn()) //列车ATP未启用
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// if (train.isEB())
|
||||
// return false;
|
||||
// if (train.isITC() && !train.isReleased()
|
||||
@ -418,13 +435,15 @@ public class ATPService {
|
||||
}
|
||||
}
|
||||
|
||||
public void confirmMessage(VirtualRealityTrain train, VirtualRealityTrain.ConfirmationMessage message) {
|
||||
public void confirmMessage(VirtualRealityTrain train,
|
||||
VirtualRealityTrain.ConfirmationMessage message) {
|
||||
if (train.containsMessage(message)) {
|
||||
handleConfirmMessage(train, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleConfirmMessage(VirtualRealityTrain train, VirtualRealityTrain.ConfirmationMessage message) {
|
||||
private void handleConfirmMessage(VirtualRealityTrain train,
|
||||
VirtualRealityTrain.ConfirmationMessage message) {
|
||||
switch (message) {
|
||||
case Exit_TGMT:
|
||||
break;
|
||||
@ -438,7 +457,8 @@ public class ATPService {
|
||||
case Switch_To_RM:
|
||||
break;
|
||||
default:
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("未知的消息类型:%s", message));
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(
|
||||
String.format("未知的消息类型:%s", message));
|
||||
}
|
||||
train.removeMessage(message);
|
||||
}
|
||||
@ -449,15 +469,16 @@ public class ATPService {
|
||||
|
||||
public void updateRunLevel(VirtualRealityTrain train, @NonNull RunLevel runLevel,
|
||||
PreselectionMode preselectionMode) {
|
||||
if (!preselectionMode.isMatchTheRunLevel(runLevel)) {
|
||||
if (!preselectionMode.isNotLowerThanTheRunLevel(runLevel)) {
|
||||
return;
|
||||
}
|
||||
switch (runLevel) {
|
||||
case CBTC:
|
||||
case ITC:
|
||||
MaService.Ma ma = train.getMa2();
|
||||
if (ma == null)
|
||||
if (ma == null) {
|
||||
return;
|
||||
}
|
||||
SpeedCurve ebTriggerCurve = ma.getEbTriggerCurve();
|
||||
float ebTriggerRemain = ma.calculateDistanceOfEbTriggerEnd();
|
||||
ma.setEbTriggerCurve(ebTriggerCurve);
|
||||
@ -484,15 +505,18 @@ public class ATPService {
|
||||
updateDriveMode(train, driveMode, train.getPreselectionMode());
|
||||
}
|
||||
|
||||
private void updateDriveMode(VirtualRealityTrain train, DriveMode driveMode, PreselectionMode preselectionMode) {
|
||||
if (driveMode.equals(train.getDriveMode()))
|
||||
private void updateDriveMode(VirtualRealityTrain train, DriveMode driveMode,
|
||||
PreselectionMode preselectionMode) {
|
||||
if (driveMode.equals(train.getDriveMode())) {
|
||||
return;
|
||||
if (preselectionMode.isMatchTheDriveMode(driveMode)) {
|
||||
}
|
||||
if (preselectionMode.isNotLowerThanTheDriveMode(driveMode)) {
|
||||
train.setDriveMode(driveMode);
|
||||
if (!train.isAMMode())
|
||||
if (!train.isAMMode()) {
|
||||
closeATO(train);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开关门
|
||||
@ -500,7 +524,8 @@ public class ATPService {
|
||||
public void openOrCloseDoor(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
List<Stand> standList = train.getHeadPosition().getSection().getStandList();
|
||||
if (!CollectionUtils.isEmpty(standList) && standList.size() == 1 && standList.get(0).isSmall()) {
|
||||
if (!CollectionUtils.isEmpty(standList) && standList.size() == 1 && standList.get(0)
|
||||
.isSmall()) {
|
||||
// 小站台停车,无需开关门
|
||||
return;
|
||||
}
|
||||
@ -556,7 +581,8 @@ public class ATPService {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
|
||||
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(headSection);
|
||||
if (routePathList.stream().anyMatch(routePath -> routePath.isRight() == trainInfo.getRight())) { //准备回库
|
||||
if (routePathList.stream()
|
||||
.anyMatch(routePath -> routePath.isRight() == trainInfo.getRight())) { //准备回库
|
||||
trainInfo.finishPlanPrepareInbound();
|
||||
}
|
||||
}
|
||||
@ -565,7 +591,8 @@ public class ATPService {
|
||||
/**
|
||||
* 修改预选模式
|
||||
*/
|
||||
public void changePreselectionMode(Simulation simulation, String groupNumber, VirtualRealityTrain.PreselectionMode preselectionMode) {
|
||||
public void changePreselectionMode(Simulation simulation, String groupNumber,
|
||||
VirtualRealityTrain.PreselectionMode preselectionMode) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (preselectionMode == train.getPreselectionMode()) {
|
||||
return;
|
||||
@ -573,31 +600,34 @@ public class ATPService {
|
||||
if (!train.isAtpOn()) {
|
||||
this.openAtp(train);
|
||||
}
|
||||
if ((train.isSignalEB() || preselectionMode.isMatchTheDriveMode(DriveMode.RM) )
|
||||
&& !train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位
|
||||
changeGear(train, VirtualRealityTrain.Handwheel.MANUAL);
|
||||
}
|
||||
if (train.isSignalEB()) {
|
||||
if (!train.isStop() || !train.isLeverNotInTractionGear()) {
|
||||
changeTrainForce(train, -2F); // 改变列车的牵引/
|
||||
}
|
||||
if (!train.isRMMode()) {
|
||||
train.setTempPreselectionMode(PreselectionMode.RM);
|
||||
train.setPreselectionMode(PreselectionMode.RM);
|
||||
}
|
||||
}
|
||||
// 对预选模式条件卡控
|
||||
if (preselectionMode.isMatchTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
|
||||
if (!train.isInTheGear(VirtualRealityTrain.Handwheel.ATO)) {
|
||||
changeGear(train, VirtualRealityTrain.Handwheel.ATO);
|
||||
}
|
||||
if (!train.isLeverInCoastingGear()) {
|
||||
changeTrainForce(train, 0f); // 改变列车的牵引/
|
||||
}
|
||||
}
|
||||
train.setTempPreselectionMode(preselectionMode);
|
||||
train.setPreselectionMode(preselectionMode);
|
||||
handlePreselectionMode(simulation, train);
|
||||
train.setTempPreselectionMode(preselectionMode);
|
||||
// 不需要下面的逻辑,转了预选模式,剩下的事机器人会做
|
||||
// if ((train.isSignalEB() || preselectionMode.isNotLowerThanTheDriveMode(DriveMode.RM) )
|
||||
// && !train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位
|
||||
// changeGear(train, VirtualRealityTrain.Handwheel.MANUAL);
|
||||
// }
|
||||
// if (train.isSignalEB()) {
|
||||
// if (!train.isStop() || !train.isLeverNotInTractionGear()) {
|
||||
// changeTrainForce(train, -2F); // 改变列车的牵引/
|
||||
// }
|
||||
// if (!train.isRMMode()) {
|
||||
// train.setTempPreselectionMode(PreselectionMode.RM);
|
||||
// train.setPreselectionMode(PreselectionMode.RM);
|
||||
// }
|
||||
// }
|
||||
// // 对预选模式条件卡控
|
||||
// if (preselectionMode.isNotLowerThanTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
|
||||
// if (!train.isInTheGear(VirtualRealityTrain.Handwheel.ATO)) {
|
||||
// changeGear(train, VirtualRealityTrain.Handwheel.ATO);
|
||||
// }
|
||||
// if (!train.isLeverInCoastingGear()) {
|
||||
// changeTrainForce(train, 0f); // 改变列车的牵引/
|
||||
// }
|
||||
// }
|
||||
// train.setTempPreselectionMode(preselectionMode);
|
||||
// train.setPreselectionMode(preselectionMode);
|
||||
// handlePreselectionMode(simulation, train);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -640,30 +670,9 @@ public class ATPService {
|
||||
train.leaverUpdateTBForce(0, 350);
|
||||
} else {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument,
|
||||
String.format("数值[%s]超限,列车牵引/制动力可调整比例范围应该在[-1, 1]之间,或为快速制动-2", percent));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开ato
|
||||
*/
|
||||
public void openAto(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
if (train.isAtoOn()) { //ATO已经开启
|
||||
return;
|
||||
}
|
||||
if (!train.isAtpOn()) { // 列车ATP未启用
|
||||
this.openAtp(train);
|
||||
}
|
||||
if (!VirtualRealityTrain.Handwheel.ATO.equals(train.getGear())) { //工况手轮不在ATO位
|
||||
changeGear(train, VirtualRealityTrain.Handwheel.ATO);
|
||||
}
|
||||
if (!train.isInAMPreselectionMode()) { //不在AM-预选模式
|
||||
changePreselectionMode(simulation, groupNumber, PreselectionMode.AM_C);
|
||||
}
|
||||
if (!train.isAtoOn()) {
|
||||
train.setAtoOn(true);
|
||||
train.setDriveMode(DriveMode.AM);
|
||||
String.format(
|
||||
"数值[%s]超限,列车牵引/制动力可调整比例范围应该在[-1, 1]之间,或为快速制动-2",
|
||||
percent));
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,11 +681,13 @@ public class ATPService {
|
||||
.filter(simulationMember -> simulationMember.isDriver()
|
||||
&& train.getCode().equals(simulationMember.getDevice().getCode()))
|
||||
.anyMatch(SimulationMember::isRobot);
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(!driverRobot,"成员由用户扮演,操作不执行");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(!driverRobot,
|
||||
"成员由用户扮演,操作不执行");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理预处理模式
|
||||
*
|
||||
* @param simulation 仿真
|
||||
* @param train 列车
|
||||
*/
|
||||
@ -685,12 +696,14 @@ public class ATPService {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
switch (preselectionMode) {
|
||||
case AM_C:
|
||||
if (!train.isCBTC() && config.getRunMode().isNotLowerThan(RunLevel.CBTC))
|
||||
if (!train.isCBTC() && config.getRunMode().isNotLowerThan(RunLevel.CBTC)) {
|
||||
train.setCommunication(true);
|
||||
}
|
||||
break;
|
||||
case SM_C:
|
||||
if (!train.isCBTC() && config.getRunMode().isNotLowerThan(RunLevel.CBTC))
|
||||
if (!train.isCBTC() && config.getRunMode().isNotLowerThan(RunLevel.CBTC)) {
|
||||
train.setCommunication(true);
|
||||
}
|
||||
closeATO(train);
|
||||
break;
|
||||
case AM_I:
|
||||
@ -708,9 +721,10 @@ public class ATPService {
|
||||
/**
|
||||
* 更新列车运行级别
|
||||
*/
|
||||
private void updateRunLevel(Simulation simulation, VirtualRealityTrain train, VirtualRealityTrain.PreselectionMode preselectionMode) {
|
||||
private void updateRunLevel(Simulation simulation, VirtualRealityTrain train,
|
||||
VirtualRealityTrain.PreselectionMode preselectionMode) {
|
||||
//如果当前级别高于预选,降至IL
|
||||
if (!preselectionMode.isMatchTheRunLevel(train.getRunLevel())) {
|
||||
if (!preselectionMode.isNotLowerThanTheRunLevel(train.getRunLevel())) {
|
||||
updateRunLevel(train, RunLevel.IL, preselectionMode);
|
||||
}
|
||||
|
||||
@ -727,7 +741,8 @@ public class ATPService {
|
||||
if (train.isCBTC() && train.isCbtcMaMiss()) { //CBTC列车的移动授权丢失
|
||||
updateRunLevel(train, RunLevel.IL, preselectionMode);
|
||||
triggerSignalEB(train);
|
||||
} else if (!train.isCBTC() && !train.isCbtcMaMiss() && defaultRunLevel.equals(RunLevel.CBTC)) {
|
||||
} else if (!train.isCBTC() && !train.isCbtcMaMiss() && defaultRunLevel.equals(
|
||||
RunLevel.CBTC)) {
|
||||
updateRunLevel(train, RunLevel.CBTC, preselectionMode);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package club.joylink.rtss.simulation.cbtc.robot;
|
||||
|
||||
import static club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage.Confirm_Release_Speed;
|
||||
|
||||
import club.joylink.rtss.services.psl.IVirtualRealityPslService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher;
|
||||
@ -10,32 +12,46 @@ import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.DriveMode;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
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.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.PSD;
|
||||
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.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.ControlTransferReplyVO;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.StandParkedTrainActivity;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.Training2;
|
||||
import club.joylink.rtss.vo.client.operation.DriveParamVO;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage.Confirm_Release_Speed;
|
||||
|
||||
/**
|
||||
* 仿真机器人逻辑循环
|
||||
*/
|
||||
@ -94,9 +110,7 @@ public class SimulationRobotService {
|
||||
}
|
||||
break;
|
||||
case START:
|
||||
if (train.isAtoCanOpen()) {
|
||||
atpService.openATO(train);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -158,30 +172,32 @@ public class SimulationRobotService {
|
||||
List<SimulationMember> drivers = simulation.querySimulationMembersOfRole(
|
||||
SimulationMember.Type.DRIVER);
|
||||
for (SimulationMember driver : drivers) {
|
||||
// if (!driver.isRobot())
|
||||
// continue;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) driver.getDevice();
|
||||
if (train.isTakeOver() || !repository.isVrTrainOnline(train.getGroupNumber())) { //如果列车被接管或不在线
|
||||
continue;
|
||||
}
|
||||
//判断是否需要转换手轮档位到ATO
|
||||
robotOpenATOAfterCheck(train);
|
||||
//准备发车
|
||||
robotReadyForDeparture(simulation, train);
|
||||
//机器人驾驶
|
||||
//机器人人工驾驶
|
||||
robotManualDrive(simulation, driver, train);
|
||||
}
|
||||
}
|
||||
|
||||
private void robotManualDrive(Simulation simulation, SimulationMember driver,
|
||||
VirtualRealityTrain train) {
|
||||
if (train.isRobotNeedStop()) {
|
||||
if (train.isStop()) {
|
||||
train.getRobotDriveParam().setStop(false);
|
||||
} else {
|
||||
if (!train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位
|
||||
CommandBO.Step step = CommandBO.buildGearChangeStep(train.getGroupNumber(),
|
||||
VirtualRealityTrain.Handwheel.MANUAL);
|
||||
atsOperationDispatcher.execute(simulation, driver, step.getOperationType().name(),
|
||||
step.getOperationParams());
|
||||
}
|
||||
ensureTrainInTheGear(train, VirtualRealityTrain.Handwheel.MANUAL);
|
||||
doBreakMax(simulation, train);
|
||||
}
|
||||
} else if (train.isRobotNeedRun()) {
|
||||
if ((train.isRMMode() || train.isNRMMode())) { //RM或NRM
|
||||
ensureTrainInTheGear(train, VirtualRealityTrain.Handwheel.MANUAL);
|
||||
VirtualRealityTrain linkTrain = train.getLinkTrain();
|
||||
if (linkTrain == null) {
|
||||
Optional<SectionPosition> targetPositionOptional = calculateTargetPosition(simulation,
|
||||
@ -191,11 +207,40 @@ public class SimulationRobotService {
|
||||
robotDrive(simulation, driver, train, train.getRobotTargetPosition());
|
||||
}
|
||||
} else if (train.isCMMode()) { //CM
|
||||
ensureTrainInTheGear(train, VirtualRealityTrain.Handwheel.MANUAL);
|
||||
SpeedCurve speedCurve = train.getMa2().getAtoStopCurve();
|
||||
atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), train.getAtoSpeed());
|
||||
atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(),
|
||||
train.getAtoSpeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在检查通过后开启ATO
|
||||
*/
|
||||
private void robotOpenATOAfterCheck(VirtualRealityTrain train) {
|
||||
//停站时的情况可能比较特殊,保险起见停站时不做处理
|
||||
if (train.isParkingAt()) {
|
||||
return;
|
||||
}
|
||||
//列车的预选模式支持到达AM驾驶模式,并且列车的ATO推荐速度大于0
|
||||
if (train.getPreselectionMode().isNotLowerThanTheDriveMode(DriveMode.AM)
|
||||
&& train.getAtoSpeed() > 0) {
|
||||
ensureTrainInTheGear(train, VirtualRealityTrain.Handwheel.ATO);
|
||||
atpService.openATO(train);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保列车在指定挡
|
||||
*/
|
||||
private void ensureTrainInTheGear(VirtualRealityTrain train, VirtualRealityTrain.Handwheel gear) {
|
||||
if (!train.isInTheGear(gear)) {
|
||||
train.setGear(gear);
|
||||
// CommandBO.Step step = CommandBO.buildGearChangeStep(train.getGroupNumber(), gear);
|
||||
// atsOperationDispatcher.execute(simulation, driver, step.getOperationType().name(),
|
||||
// step.getOperationParams()); 机器人驾驶逻辑中有很多操作都不是通过仿真操作执行的,所以这里也不需要了吧
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -245,7 +290,8 @@ public class SimulationRobotService {
|
||||
SignalAspect throughAspect = robotDriveParam.getThroughSignalAspect();
|
||||
Section section = headPosition.getSection();
|
||||
|
||||
if (throughSignal != null && !Objects.equals(section, throughSignal.getSection())) { //当车头与要越过的信号机不在同一区段
|
||||
if (throughSignal != null && !Objects.equals(section,
|
||||
throughSignal.getSection())) { //当车头与要越过的信号机不在同一区段
|
||||
throughSignal = null;
|
||||
throughAspect = null;
|
||||
robotDriveParam.setThrough(DriveParamVO.DRIVER_ROUTE_BLOCK);
|
||||
@ -257,9 +303,11 @@ public class SimulationRobotService {
|
||||
// 车头在正常的站台上
|
||||
if (section.isNormalStandTrack() && !section.equals(train.getParkSection())) { //正常站台轨且未在此处停过车
|
||||
// 如果计划停车区段为空或者计划停车区段中有包含当前区段
|
||||
if (CollectionUtils.isEmpty(plannedParkingSections) || plannedParkingSections.contains(section)) {
|
||||
if (CollectionUtils.isEmpty(plannedParkingSections) || plannedParkingSections.contains(
|
||||
section)) {
|
||||
SectionPosition stopPosition = section.buildStopPointPosition(right);
|
||||
SectionPosition maxStopPosition = CalculateService.calculateNextPositionByStartAndLen(stopPosition,
|
||||
SectionPosition maxStopPosition = CalculateService.calculateNextPositionByStartAndLen(
|
||||
stopPosition,
|
||||
right, SimulationConstants.PARK_POINT_MAX_OFFSET, true);
|
||||
if (maxStopPosition.isAheadOf(headPosition, right)) { //未越过最大停车点
|
||||
targetPosition = stopPosition;
|
||||
@ -280,11 +328,14 @@ public class SimulationRobotService {
|
||||
if (signal != null && !signal.isShunting()) { // 信号机不为调车信号机
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
SectionPosition signalPosition = signal.getPosition();
|
||||
if (vrSignal != null && (i != 0 || signalPosition.isAheadOf(headPosition, right))) { //有实体信号机且列车未越过信号机
|
||||
if (vrSignal != null && (i != 0 || signalPosition.isAheadOf(headPosition,
|
||||
right))) { //有实体信号机且列车未越过信号机
|
||||
if (Objects.equals(vrSignal.getAspect(), signal.getDefaultAspect()) //禁止信号
|
||||
|| Objects.equals(vrSignal.getAspect(), signal.getGuideAspect())) { //引导信号
|
||||
if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(), throughAspect)) {
|
||||
SectionPosition noPassPosition = CalculateService.calculateNextPositionByStartAndLen(signalPosition, !right, 2, true);
|
||||
if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(),
|
||||
throughAspect)) {
|
||||
SectionPosition noPassPosition = CalculateService.calculateNextPositionByStartAndLen(
|
||||
signalPosition, !right, 2, true);
|
||||
if (targetPosition == null || noPassPosition.isAheadOf(targetPosition, right)) {
|
||||
targetPosition = noPassPosition;
|
||||
}
|
||||
@ -294,7 +345,8 @@ public class SimulationRobotService {
|
||||
}
|
||||
|
||||
if (targetPosition == null) {
|
||||
if (selectedPosition != null && section.equals(selectedPosition.getSection())) { //不会有比选定位置更靠前的停车点了
|
||||
if (selectedPosition != null && section.equals(
|
||||
selectedPosition.getSection())) { //不会有比选定位置更靠前的停车点了
|
||||
targetPosition = selectedPosition;
|
||||
} else {
|
||||
Section tempSection = section.findNextRunningSectionBaseRealSwitch(right);
|
||||
|
Loading…
Reference in New Issue
Block a user