Merge branch 'test' into test-training2

This commit is contained in:
weizhihong 2022-08-16 10:28:46 +08:00
commit 8bf5a4b807
16 changed files with 4067 additions and 3978 deletions

View File

@ -732,6 +732,10 @@ public class Operation {
/** /**
* 托管 * 托管
*/ */
Train_Drive(Operation.CLIENT),
/**
* TODO 托管,由于之前剧本中已包含Train_Trust暂时留下后续删除
*/
Train_Trust(Operation.CLIENT), Train_Trust(Operation.CLIENT),
/** /**
* 连挂 * 连挂

View File

@ -277,6 +277,15 @@ public class TrainOperateHandler {
/** /**
* 列车托管使用司机的驾驶指令 * 列车托管使用司机的驾驶指令
*/ */
@OperateHandlerMapping(type = Operation.Type.Train_Drive)
public void drive(Simulation simulation, String groupNumber, DriveParamVO param) {
atsTrainService.trust(simulation, groupNumber, param);
}
/**
* 列车托管使用司机的驾驶指令
* TODO 后续同Train_Trust一起删除
*/
@OperateHandlerMapping(type = Operation.Type.Train_Trust) @OperateHandlerMapping(type = Operation.Type.Train_Trust)
public void trust(Simulation simulation, String groupNumber, DriveParamVO param) { public void trust(Simulation simulation, String groupNumber, DriveParamVO param) {
atsTrainService.trust(simulation, groupNumber, param); atsTrainService.trust(simulation, groupNumber, param);

View File

@ -1,318 +1,320 @@
package club.joylink.rtss.simulation.cbtc.ATS.service; package club.joylink.rtss.simulation.cbtc.ATS.service;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm; import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService; import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Cycle; import club.joylink.rtss.simulation.cbtc.data.map.Cycle;
import club.joylink.rtss.simulation.cbtc.data.map.Route; import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Signal; import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.status.RouteStatus; import club.joylink.rtss.simulation.cbtc.data.status.RouteStatus;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@Component @Component
public class AtsRouteService { public class AtsRouteService {
@Autowired @Autowired
private CiRouteService routeService; private CiRouteService routeService;
@Autowired @Autowired
private CiApiService ciApiService; private CiApiService ciApiService;
/** /**
* 进路收人工控 * 进路收人工控
* *
* @param simulation * @param simulation
* @param signalCode * @param signalCode
* @param routeCodeList * @param routeCodeList
*/ */
public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) { public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) {
if (!CollectionUtils.isEmpty(routeCodeList)) { if (!CollectionUtils.isEmpty(routeCodeList)) {
routeCodeList.forEach(routeCode -> { routeCodeList.forEach(routeCode -> {
Route route = simulation.getRepository().getByCode(routeCode, Route.class); Route route = simulation.getRepository().getByCode(routeCode, Route.class);
route.setAtsControl(false); route.setAtsControl(false);
}); });
} else if (StringUtils.hasText(signalCode)) { } else if (StringUtils.hasText(signalCode)) {
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
List<Route> routeList = signal.getRouteList(); List<Route> routeList = signal.getRouteList();
if (!CollectionUtils.isEmpty(routeList)) { if (!CollectionUtils.isEmpty(routeList)) {
routeList.forEach(route -> route.setAtsControl(false)); routeList.forEach(route -> route.setAtsControl(false));
} }
} }
} }
/** /**
* 进路交自动控 * 进路交自动控
*/ */
public void setRouteAtsControl(Simulation simulation, String signalCode, public void setRouteAtsControl(Simulation simulation, String signalCode,
List<String> routeCodeList, List<Boolean> checkConflictList) { List<String> routeCodeList, List<Boolean> checkConflictList) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
if (!CollectionUtils.isEmpty(routeCodeList)) { if (!CollectionUtils.isEmpty(routeCodeList)) {
if (!CollectionUtils.isEmpty(checkConflictList)) { if (!CollectionUtils.isEmpty(checkConflictList)) {
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(), BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(),
String.format("进路数和是否检查冲突数量不一致:[%s], [%s]", String.format("进路数和是否检查冲突数量不一致:[%s], [%s]",
String.join(",", routeCodeList), String.join(",", routeCodeList),
String.join(",", checkConflictList.stream().map(String::valueOf).collect(Collectors.toList())))); String.join(",", checkConflictList.stream().map(String::valueOf).collect(Collectors.toList()))));
} }
List<Route> routes = routeCodeList.stream().map(routeCode -> repository.getByCode(routeCode, Route.class)).collect(Collectors.toList()); List<Route> routes = routeCodeList.stream().map(routeCode -> repository.getByCode(routeCode, Route.class)).collect(Collectors.toList());
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
routes.stream() routes.stream()
.map(Route::getStart) .map(Route::getStart)
.distinct() .distinct()
.forEach(signal -> .forEach(signal ->
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
.assertNotTrue(signal.isCiControl(), .assertNotTrue(signal.isCiControl(),
String.format("信号机[%s]需处于人工控状态", signal.getCode()))); String.format("信号机[%s]需处于人工控状态", signal.getCode())));
} }
if (CollectionUtils.isEmpty(checkConflictList)) { if (CollectionUtils.isEmpty(checkConflictList)) {
routes.forEach(route -> route.setAtsControl(true)); routes.forEach(route -> route.setAtsControl(true));
} else { } else {
for (int i = 0; i < routeCodeList.size(); i++) { for (int i = 0; i < routeCodeList.size(); i++) {
Route route = repository.getByCode(routeCodeList.get(i), Route.class); Route route = repository.getByCode(routeCodeList.get(i), Route.class);
boolean checkConflict = checkConflictList.get(i); boolean checkConflict = checkConflictList.get(i);
route.setAtsControl(true); route.setAtsControl(true);
route.setCheckConflict(checkConflict); route.setCheckConflict(checkConflict);
} }
} }
} else if (StringUtils.hasText(signalCode)) { } else if (StringUtils.hasText(signalCode)) {
Signal signal = repository.getByCode(signalCode, Signal.class); Signal signal = repository.getByCode(signalCode, Signal.class);
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode())); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode()));
} }
List<Route> routeList = signal.getRouteList(); List<Route> routeList = signal.getRouteList();
if (!CollectionUtils.isEmpty(routeList)) { if (!CollectionUtils.isEmpty(routeList)) {
routeList.forEach(route -> route.setAtsControl(true)); routeList.forEach(route -> route.setAtsControl(true));
} }
} }
} }
/** /**
* 查询进路状态/模式 * 查询进路状态/模式
*/ */
public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) { public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) {
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
List<Route> routeList = signal.getRouteList(); List<Route> routeList = signal.getRouteList();
return routeList.stream().map(RouteStatus::new).collect(Collectors.toList()); return routeList.stream().map(RouteStatus::new).collect(Collectors.toList());
} }
/** /**
* 设置联锁自动进路 * 设置联锁自动进路
*/ */
public void setCiAuto(Simulation simulation, String signalCode) { public void setCiAuto(Simulation simulation, String signalCode) {
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) { if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
Route lockedRoute = signal.getLockedRoute(); Route lockedRoute = signal.getLockedRoute();
if (lockedRoute == null) { if (lockedRoute == null) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode())); String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode()));
} }
if (!lockedRoute.isFlt()) { if (!lockedRoute.isFlt()) {
throw new SimulationException(SimulationExceptionType.Unsupported_Operation, throw new SimulationException(SimulationExceptionType.Unsupported_Operation,
String.format("进路[%s]不能设置车队进路", lockedRoute.getCode())); String.format("进路[%s]不能设置车队进路", lockedRoute.getCode()));
} }
if (lockedRoute.isCiControl()) { if (lockedRoute.isCiControl()) {
throw new SimulationException(SimulationExceptionType.Operation_Conflict, throw new SimulationException(SimulationExceptionType.Operation_Conflict,
String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode())); String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode()));
} }
lockedRoute.setFleetMode(true); lockedRoute.setFleetMode(true);
} else { } else {
List<Route> routeList = signal.getRouteList(); List<Route> routeList = signal.getRouteList();
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机"); BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机");
// 筛选最适合的进路筛选逻辑与办理引导时筛选逻辑类似 // 筛选最适合的进路筛选逻辑与办理引导时筛选逻辑类似
List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList()); List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList());
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路"); BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路");
List<Route> collect = fltRoutes.stream() List<Route> collect = fltRoutes.stream()
.filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList())) .filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollectionUtils.isEmpty(collect)) { if (CollectionUtils.isEmpty(collect)) {
collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList()); collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
} }
if (CollectionUtils.isEmpty(collect)) { if (CollectionUtils.isEmpty(collect)) {
collect = fltRoutes; collect = fltRoutes;
} }
Route route = collect.get(0); Route route = collect.get(0);
Route.CheckFailMessage message = routeService.setRoute(simulation, route); Route.CheckFailMessage message = routeService.setRoute(simulation, route,route.getAspect());
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理"); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理");
route.setFleetMode(true); route.setFleetMode(true);
} }
} }
/** /**
* 取消联锁自动进路 * 取消联锁自动进路
*/ */
public void cancelCiAuto(Simulation simulation, String signalCode) { public void cancelCiAuto(Simulation simulation, String signalCode) {
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
Route lockedRoute = signal.getLockedRoute(); Route lockedRoute = signal.getLockedRoute();
if (Objects.isNull(lockedRoute)) { if (Objects.isNull(lockedRoute)) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode())); String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode()));
} }
if (!lockedRoute.isFleetMode()) { if (!lockedRoute.isFleetMode()) {
throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode())); throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode()));
} }
lockedRoute.setFleetMode(false); lockedRoute.setFleetMode(false);
if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) { if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) {
routeService.unlockRoute(simulation, lockedRoute); routeService.unlockRoute(simulation, lockedRoute);
} }
} }
/** /**
* 设置联锁自动触发 * 设置联锁自动触发
*/ */
public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) { public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
List<Route> routeList; List<Route> routeList;
if (StringUtils.hasText(signalCode)) { if (StringUtils.hasText(signalCode)) {
Signal signal = repository.getByCode(signalCode, Signal.class); Signal signal = repository.getByCode(signalCode, Signal.class);
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode())); BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode()));
} }
routeList = signal.getRouteList(); routeList = signal.getRouteList();
} else { } else {
routeList = routeCodeList.stream() routeList = routeCodeList.stream()
.map(code -> repository.getByCode(code, Route.class)) .map(code -> repository.getByCode(code, Route.class))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) { if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
routeList.stream() routeList.stream()
.map(Route::getStart) .map(Route::getStart)
.distinct() .distinct()
.forEach(signal -> .forEach(signal ->
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
.assertNotTrue(signal.isAtsControl(), .assertNotTrue(signal.isAtsControl(),
String.format("信号机[%s]需处于人工控", signal.getCode()))); String.format("信号机[%s]需处于人工控", signal.getCode())));
} }
} }
if (!CollectionUtils.isEmpty(routeList)) { if (!CollectionUtils.isEmpty(routeList)) {
routeList.stream().filter(Route::isArs).forEach(route -> { routeList.stream().filter(Route::isArs).forEach(route -> {
if (route.isFleetMode()) { if (route.isFleetMode()) {
throw new SimulationException(SimulationExceptionType.Operation_Conflict, throw new SimulationException(SimulationExceptionType.Operation_Conflict,
String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode())); String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode()));
} }
// if (route.isCiControl()) { // if (route.isCiControl()) {
// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode())); // throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode()));
// } // }
}); });
for (Route route : routeList) { for (Route route : routeList) {
// route.setAtsControl(false); // route.setAtsControl(false);
if (route.isArs()) if (route.isArs())
route.setCiControl(true); route.setCiControl(true);
} }
} }
} }
/** /**
* 取消联锁自动触发 * 取消联锁自动触发
*/ */
public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) { public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) {
List<Route> routeList; List<Route> routeList;
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
if (StringUtils.hasText(signalCode)) { if (StringUtils.hasText(signalCode)) {
Signal signal = repository.getByCode(signalCode, Signal.class); Signal signal = repository.getByCode(signalCode, Signal.class);
routeList = signal.getRouteList(); routeList = signal.getRouteList();
} else { } else {
routeList = routeCodes.stream() routeList = routeCodes.stream()
.map(code -> repository.getByCode(code, Route.class)) .map(code -> repository.getByCode(code, Route.class))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
if (!CollectionUtils.isEmpty(routeList)) { if (!CollectionUtils.isEmpty(routeList)) {
for (Route route : routeList) { for (Route route : routeList) {
if (route.isCiControl()) { if (route.isCiControl()) {
route.setCiControl(false); route.setCiControl(false);
route.setAtsControl(false); route.setAtsControl(false);
} }
} }
} }
} }
/** /**
* 设置自动折返进路 * 设置自动折返进路
* *
* @param simulation * @param simulation
* @param cycleCode * @param cycleCode
*/ */
public void setAutoTurnBack(Simulation simulation, String cycleCode) { public void setAutoTurnBack(Simulation simulation, String cycleCode) {
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class); Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
cycle.setSetUp(true); cycle.setSetUp(true);
} }
/** /**
* 取消自动折返进路 * 取消自动折返进路
*/ */
public void cancelAutoTurnBack(Simulation simulation, String cycleCode) { public void cancelAutoTurnBack(Simulation simulation, String cycleCode) {
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class); Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
cycle.setSetUp(false); cycle.setSetUp(false);
} }
/** /**
* 总取消 * 总取消
*/ */
public void totalCancel(Simulation simulation, String signalCode) { public void totalCancel(Simulation simulation, String signalCode) {
// todo 总取消操作有很多种操作方式对应不同的按钮此处都用信号机编号可能不妥 // todo 总取消操作有很多种操作方式对应不同的按钮此处都用信号机编号可能不妥
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class); Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
Route lockedRoute = signal.getLockedRoute(); Route lockedRoute = signal.getLockedRoute();
if (lockedRoute == null) { if (lockedRoute == null) {
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode())); String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode()));
} }
if (!signal.isApproachLock()) { //当接近区段未被占用 if (!signal.isApproachLock()) { //当接近区段未被占用
this.cancelRoute(simulation, signalCode); this.cancelRoute(simulation, signalCode);
} else { } else {
this.routeService.unlockRoute(simulation, lockedRoute); this.routeService.unlockRoute(simulation, lockedRoute);
this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode()); this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode());
// if (signal.isGuideAspect()) { //如果引导信号开启中 // if (signal.isGuideAspect()) { //如果引导信号开启中
// this.ciApiService.closeGuideSignal(simulation, signalCode); // this.ciApiService.closeGuideSignal(simulation, signalCode);
// } else if (signal.isClose()) { //如果信号灯关了 // } else if (signal.isClose()) { //如果信号灯关了
// } else { // } else {
// this.ciApiService.closeSignal(simulation, signalCode); // this.ciApiService.closeSignal(simulation, signalCode);
// } // }
} }
} }
public void cancelRoute(Simulation simulation, String signalCode) { public void cancelRoute(Simulation simulation, String signalCode) {
Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode); Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
if (Objects.nonNull(route)) { if (Objects.nonNull(route)) {
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue( BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
route.isApproachLock(), "进路接近锁闭,无法取消"); route.isApproachLock(), "进路接近锁闭,无法取消");
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue( BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
route.getStart().isGuideAspect(), "引导进路,需要人解进路"); route.getStart().isGuideAspect(), "引导进路,需要人解进路");
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(), BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
String.format("进路[%s]已开启自动通过进路,无法取消", route.debugStr())); String.format("进路[%s]已开启自动通过进路,无法取消", route.debugStr()));
this.ciApiService.unlockRoute(simulation, route.getCode()); BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
} Objects.nonNull(route.getDelayUnlockDevice()), String.format("进路[%s]已经开启延时取消,无法手动取消", route.debugStr()));
} this.ciApiService.unlockRoute(simulation, route.getCode());
}
public void setOverlap(Simulation simulation, String signalCode, String overlapCode) { }
if (signalCode == null || overlapCode == null) {
throw new SimulationException(SimulationExceptionType.Illegal_Argument); public void setOverlap(Simulation simulation, String signalCode, String overlapCode) {
} if (signalCode == null || overlapCode == null) {
this.ciApiService.setOverlap(simulation, signalCode, overlapCode); throw new SimulationException(SimulationExceptionType.Illegal_Argument);
} }
this.ciApiService.setOverlap(simulation, signalCode, overlapCode);
public void conflictRouteSetConfirm(Simulation simulation, SimulationMember member, String routeCode, int way) { }
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(
Route.Conflict_Handle_Way_1 == way || Route.Conflict_Handle_Way_2 == way public void conflictRouteSetConfirm(Simulation simulation, SimulationMember member, String routeCode, int way) {
); BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(
Route route = simulation.getRepository().getByCode(routeCode, Route.class); Route.Conflict_Handle_Way_1 == way || Route.Conflict_Handle_Way_2 == way
AtsAlarm conflictAlarm = route.getConflictAlarm(); );
if (conflictAlarm != null) { Route route = simulation.getRepository().getByCode(routeCode, Route.class);
LocalDateTime systemTime = simulation.getCorrectSystemTime(); AtsAlarm conflictAlarm = route.getConflictAlarm();
conflictAlarm.confirm(systemTime, member, way); if (conflictAlarm != null) {
conflictAlarm.recover(systemTime); LocalDateTime systemTime = simulation.getCorrectSystemTime();
} conflictAlarm.confirm(systemTime, member, way);
} conflictAlarm.recover(systemTime);
} }
}
}

View File

@ -1,238 +1,238 @@
package club.joylink.rtss.simulation.cbtc.CI; package club.joylink.rtss.simulation.cbtc.CI;
import club.joylink.rtss.simulation.cbtc.CI.device.CiDeviceStatusCollector; import club.joylink.rtss.simulation.cbtc.CI.device.CiDeviceStatusCollector;
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService; import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
import club.joylink.rtss.simulation.cbtc.CI.device.CiService; 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.CiSignalControlService;
import club.joylink.rtss.simulation.cbtc.CI.service.assist.StationDirectionService; import club.joylink.rtss.simulation.cbtc.CI.service.assist.StationDirectionService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@Slf4j @Slf4j
@Component @Component
public class CiLogic { public class CiLogic {
@Autowired @Autowired
private CiDeviceStatusCollector deviceStatusCollector; private CiDeviceStatusCollector deviceStatusCollector;
@Autowired @Autowired
private CiRouteService routeService; private CiRouteService routeService;
@Autowired @Autowired
private CiSignalControlService signalControlService; private CiSignalControlService signalControlService;
@Autowired @Autowired
private CiService ciService; private CiService ciService;
@Autowired @Autowired
private StationDirectionService stationDirectionService; private StationDirectionService stationDirectionService;
public void run(Simulation simulation) { public void run(Simulation simulation) {
// 采集真实设备状态 // 采集真实设备状态
deviceStatusCollector.collect(simulation); deviceStatusCollector.collect(simulation);
// 信号机监控控制 // 信号机监控控制
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
for (Signal signal : repository.getSignalList()) { for (Signal signal : repository.getSignalList()) {
signalMonitor(simulation, signal); signalMonitor(simulation, signal);
} }
// 联锁监控逻辑 // 联锁监控逻辑
List<Route> routeList = repository.getRouteList(); List<Route> routeList = repository.getRouteList();
for (Route route : routeList) { for (Route route : routeList) {
interlockMonitor(simulation, route); interlockMonitor(simulation, route);
} }
List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList(); List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList();
for (RouteOverlap routeOverlap : routeOverlapList) { for (RouteOverlap routeOverlap : routeOverlapList) {
overlapMonitor(simulation, routeOverlap); overlapMonitor(simulation, routeOverlap);
} }
// 区间灯点灯逻辑 // 区间灯点灯逻辑
if (simulation.getRepository().getConfig().isRailway()) { if (simulation.getRepository().getConfig().isRailway()) {
// 车站 // 车站
simulation.getRepository().getStationList().stream().forEach(station -> { simulation.getRepository().getStationList().stream().forEach(station -> {
// 允许自律状态刷新 // 允许自律状态刷新
station.refreshAllowAutonomyStatus(); station.refreshAllowAutonomyStatus();
// 发辅助按钮倒计时刷新 // 发辅助按钮倒计时刷新
station.getStationDirectionMap().values().stream() station.getStationDirectionMap().values().stream()
.forEach(stationDirection -> { .forEach(stationDirection -> {
// 判断进路状态是否发生变化 // 判断进路状态是否发生变化
if (stationDirection.monitorRouteChangeStatus()) { if (stationDirection.monitorRouteChangeStatus()) {
stationDirection.modifyRunStatus(); stationDirection.modifyRunStatus();
} }
// 如果倒数结束弹起接发辅助按钮,超过50秒时不再自动抬起 // 如果倒数结束弹起接发辅助按钮,超过50秒时不再自动抬起
if (!stationDirection.isAssistReadyStatus() if (!stationDirection.isAssistReadyStatus()
&& !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime()) && !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime())
&& stationDirection.getCountDown().decrementAndGet() <= 0) { && stationDirection.getCountDown().decrementAndGet() <= 0) {
stationDirection.setDeliverAssistStatus(false); stationDirection.setDeliverAssistStatus(false);
stationDirection.setReceiveAssistStatus(false); stationDirection.setReceiveAssistStatus(false);
stationDirection.getCountDown().set(0); stationDirection.getCountDown().set(0);
} }
// 联锁数据检查 // 联锁数据检查
stationDirectionService.refreshSectionLightStatus(simulation, stationDirection); stationDirectionService.refreshSectionLightStatus(simulation, stationDirection);
}); });
}); });
} }
} }
private void signalMonitor(Simulation simulation, Signal signal) { private void signalMonitor(Simulation simulation, Signal signal) {
signalControlService.controlLightOfSignal(simulation, signal); signalControlService.controlLightOfSignal(simulation, signal);
//控制通过信号机的显示信号机前第一个区段被占用开红灯第二个区段被占用开黄灯否则开绿灯 //控制通过信号机的显示信号机前第一个区段被占用开红灯第二个区段被占用开黄灯否则开绿灯
if (signal.isPassingSignal()) { if (signal.isPassingSignal()) {
if (simulation.getRepository().getConfig().isRailway()) { if (simulation.getRepository().getConfig().isRailway()) {
boolean right = signal.isRight(); boolean right = signal.isRight();
Section section = signal.getSection(); Section section = signal.getSection();
Section one = section.getNextSection(right); Section one = section.getNextSection(right);
if (one == null) { if (one == null) {
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G); signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
return; return;
} }
if (one.isOccupied()) { if (one.isOccupied()) {
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R); signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
return; return;
} }
Section two = one.getNextSection(right); Section two = one.getNextSection(right);
if (two == null) { if (two == null) {
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G); signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
return; return;
} }
if (two.isOccupied()) { if (two.isOccupied()) {
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y); signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
return; return;
} }
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G); signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
} }
} }
} }
/** /**
* 进路监控 * 进路监控
* *
* @param simulation * @param simulation
* @param route * @param route
*/ */
public void interlockMonitor(Simulation simulation, Route route) { public void interlockMonitor(Simulation simulation, Route route) {
MapConfig config = simulation.getRepository().getConfig(); MapConfig config = simulation.getRepository().getConfig();
if (route.isCiControl()) { // 进路联锁自动触发 if (route.isCiControl()) { // 进路联锁自动触发
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) { if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
routeService.setRoute(simulation, route); routeService.setRoute(simulation, route,route.getAspect());
} }
} else if (route.isFleetMode()) { // 联锁自动进路 } else if (route.isFleetMode()) { // 联锁自动进路
if (ciService.isCiRouteTrigger(simulation, route)) { if (ciService.isCiRouteTrigger(simulation, route)) {
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getAspect()); signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getSettedAspect());
} }
} }
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路 if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
if (route.isDelayUnlocking()) { if (route.isDelayUnlocking()) {
routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice()); routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice());
} }
if (route.isSetting()) { if (route.isSetting()) {
routeService.routeSettingProcess(simulation, route); routeService.routeSettingProcess(simulation, route);
} }
if (route.isNormalUnlock()) { if (route.isNormalUnlock()) {
routeService.trainUnlockRoute(simulation, route); routeService.trainUnlockRoute(simulation, route);
} }
if (route.isLock()) { if (route.isLock()) {
// 进路首区段列车占用进路开始解锁 // 进路首区段列车占用进路开始解锁
Section firstLogicSection = route.getFirstLogicSection(); Section firstLogicSection = route.getFirstLogicSection();
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
if (repository.isTrainHeadOccupy(firstLogicSection)) { if (repository.isTrainHeadOccupy(firstLogicSection)) {
trainUnlockStart(simulation, route); trainUnlockStart(simulation, route);
} }
} }
Signal start = route.getStart(); Signal start = route.getStart();
int guideRemain = start.getGuideRemain(); int guideRemain = start.getGuideRemain();
if (guideRemain != 0) { if (guideRemain != 0) {
guideRemain -= SimulationConstants.CI_LOOP_RATE; guideRemain -= SimulationConstants.CI_LOOP_RATE;
if (guideRemain <= 0) { //计时结束关闭信号 if (guideRemain <= 0) { //计时结束关闭信号
start.setGuideRemain(0); start.setGuideRemain(0);
signalControlService.tryControlSignalAspectAccordingLevel(simulation, signalControlService.tryControlSignalAspectAccordingLevel(simulation,
start, start.getDefaultAspect()); start, start.getDefaultAspect());
} else { } else {
start.setGuideRemain(guideRemain); start.setGuideRemain(guideRemain);
} }
} }
if (route.isLock() && !route.isSetting()) { if (route.isLock() && !route.isSetting()) {
ciService.interlockCheck(simulation, route); ciService.interlockCheck(simulation, route);
if (!config.isRailway()) { if (!config.isRailway()) {
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同关闭信号 if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同关闭信号
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr()); CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
signalControlService.tryControlSignalAspectAccordingLevel(simulation, signalControlService.tryControlSignalAspectAccordingLevel(simulation,
start, start.getDefaultAspect()); start, start.getDefaultAspect());
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) { } else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr()); CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
signalControlService.tryControlSignalAspectAccordingLevel(simulation, signalControlService.tryControlSignalAspectAccordingLevel(simulation,
start, route.getAspect()); start, route.getSettedAspect());
} }
} else { } else {
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同关闭信号 if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同关闭信号
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr()); CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
signalControlService.tryControlSignalAspectAccordingLevel(simulation, signalControlService.tryControlSignalAspectAccordingLevel(simulation,
start, start.getDefaultAspect()); start, start.getDefaultAspect());
start.setForcePhysical(true); //大铁线路暂时限制自动重开信号 start.setForcePhysical(true); //大铁线路暂时限制自动重开信号
} else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) { } else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
SignalAspect aspect = route.getAspectOfRailway(); SignalAspect aspect = route.getAspectOfRailway();
if (!Objects.equals(route.getStart().getAspect(), aspect)) { if (!Objects.equals(route.getStart().getAspect(), aspect)) {
signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect); signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect);
} }
} }
} }
} }
// 进路延续保护办理判断 // 进路延续保护办理判断
if (route.isSettingOverlap()) { if (route.isSettingOverlap()) {
ciService.checkAndTrySettingOverlap(simulation, route.getOverlap()); ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
} }
} }
} }
public void trainUnlockStart(Simulation simulation, Route route) { public void trainUnlockStart(Simulation simulation, Route route) {
route.startNormalUnlock(); route.startNormalUnlock();
CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr()); CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr());
signalControlService.tryControlSignalAspectAccordingLevel(simulation, signalControlService.tryControlSignalAspectAccordingLevel(simulation,
route.getStart(), route.getStart().getDefaultAspect()); route.getStart(), route.getStart().getDefaultAspect());
} }
/** /**
* 延续保护进路监控 * 延续保护进路监控
* *
* @param simulation * @param simulation
* @param overlap * @param overlap
*/ */
public void overlapMonitor(Simulation simulation, RouteOverlap overlap) { public void overlapMonitor(Simulation simulation, RouteOverlap overlap) {
MapConfig config = simulation.getRepository().getConfig(); MapConfig config = simulation.getRepository().getConfig();
if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) { if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) {
ciService.checkAndTrySettingOverlap(simulation, overlap); ciService.checkAndTrySettingOverlap(simulation, overlap);
} }
if (overlap.isSetting()) { if (overlap.isSetting()) {
routeService.overlapSettingProcess(simulation, overlap); routeService.overlapSettingProcess(simulation, overlap);
} }
if (overlap.isForbidden()) { if (overlap.isForbidden()) {
routeService.checkAndAllowOverlap(simulation, overlap); routeService.checkAndAllowOverlap(simulation, overlap);
} }
if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) { if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) {
overlap.setLock(false); overlap.setLock(false);
} }
if (overlap.isSectionOverlapLocked()) { if (overlap.isSectionOverlapLocked()) {
if (simulation.getRepository().isTrainParking(overlap.getSection())) { if (simulation.getRepository().isTrainParking(overlap.getSection())) {
CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁", CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁",
overlap.getName(), overlap.getName(),
overlap.getSection().debugStr()); overlap.getSection().debugStr());
overlap.releaseImmediately(); overlap.releaseImmediately();
return; return;
} }
if (overlap.isReleasing()) { if (overlap.isReleasing()) {
overlap.releaseProgress(); overlap.releaseProgress();
} else if (!overlap.isReleasing() && simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) { } else if (!overlap.isReleasing() && simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) {
// 进路首区段列车占用进路开始解锁 // 进路首区段列车占用进路开始解锁
overlap.startReleasing(); overlap.startReleasing();
} }
} }
} }
public void addJobs(Simulation simulation) { public void addJobs(Simulation simulation) {
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE); simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE);
} }
} }

View File

@ -10,6 +10,21 @@ public abstract class DelayUnlockDevice extends MayOutOfOrderDevice {
super(code, name, deviceType); super(code, name, deviceType);
} }
public void delayUnlockStart(Route route,MapConfig mc) {
// route.getType() == Type
int baseDelayTime = route.getDelayReleaseTime();
if(mc.isRailway()){
switch (route.getType()){
case DEPARTURE:
case RECEIVING:
baseDelayTime = 180;
break;
case SHUNTING:
baseDelayTime = 30;
}
}
this.remain = baseDelayTime * 1000;
}
public void delayUnlockStart(Route route) { public void delayUnlockStart(Route route) {
this.remain = route.getDelayReleaseTime() * 1000; this.remain = route.getDelayReleaseTime() * 1000;
} }

View File

@ -318,7 +318,7 @@ public class Signal extends DelayUnlockDevice {
public boolean isMainAspect() { public boolean isMainAspect() {
if (this.lockedRoute != null) { if (this.lockedRoute != null) {
return this.aspect.equals(this.lockedRoute.getAspect()); return this.aspect.equals(this.lockedRoute.getSettedAspect());
} }
return false; return false;
} }

View File

@ -1,177 +1,191 @@
package club.joylink.rtss.simulation.cbtc.data.storage.device; package club.joylink.rtss.simulation.cbtc.data.storage.device;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
import club.joylink.rtss.simulation.cbtc.data.map.Route; 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.Route;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer; import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer; import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Getter; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.NoArgsConstructor; import lombok.Getter;
import lombok.Setter; import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.Objects; import java.time.LocalDateTime;
import java.util.Objects;
@Getter
@Setter @Getter
@NoArgsConstructor @Setter
public class StorageRoute extends StorageDevice { @NoArgsConstructor
public class StorageRoute extends StorageDevice {
/**
* 是否CBTC模式 /**
*/ * 是否CBTC模式
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean cbtcMode; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean cbtcMode;
/**
* ats自动控制 /**
*/ * ats自动控制
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean atsControl; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean atsControl;
/**
* 连续通过进路模式(联锁自动进路)开启 /**
*/ * 连续通过进路模式(联锁自动进路)开启
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean fleetMode; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean fleetMode;
/**
* 自动追踪/联锁自动触发模式开启 /**
*/ * 自动追踪/联锁自动触发模式开启
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean ciControl; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean ciControl;
/**
* 进路是否排列中 /**
*/ * 进路是否排列中
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean setting; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean setting;
private LocalDateTime settingStartTime;
private LocalDateTime settingStartTime;
/**
* 是否引导进路排列 /**
*/ * 是否引导进路排列
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean settingGuide; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean settingGuide;
/**
* 进路是否锁闭 /**
*/ * 进路是否锁闭
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean lock; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean lock;
/** 进路延时解锁设备 */
private String delayUnlockDevice; /** 进路延时解锁设备 */
private String delayUnlockDevice;
/**
* 是否正常解锁中 /**
*/ * 是否正常解锁中
@JsonSerialize(using = Boolean2NumSerializer.class) */
@JsonDeserialize(using = Boolean2NumDeserializer.class) @JsonSerialize(using = Boolean2NumSerializer.class)
private Boolean normalUnlock; @JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean normalUnlock;
private String unlockedSection;
private String unlockedSection;
// public StorageRoute(Route route) {
// super(route.getCode()); /**
// cbtcMode = route.isCbtcMode(); * 该进路办理成功后要开放的信号
// turnBackMode = route.isTurnBackMode(); * <p>
// atsControl = route.isAtsControl(); * 注意每次开始触发办理进路时设置
// fleetMode = route.isFleetMode(); */
// ciControl = route.isCiControl(); private SignalAspect settedAspect;
// setting = route.isSetting();
// settingGuide = route.isSettingGuide(); // public StorageRoute(Route route) {
// lock = route.isLock(); // super(route.getCode());
// canceling = route.isCanceling(); // cbtcMode = route.isCbtcMode();
// normalUnlock = route.isNormalUnlock(); // turnBackMode = route.isTurnBackMode();
// } // atsControl = route.isAtsControl();
// fleetMode = route.isFleetMode();
public StorageRoute(String code) { // ciControl = route.isCiControl();
super(code); // setting = route.isSetting();
} // settingGuide = route.isSettingGuide();
// lock = route.isLock();
public static StorageRoute convert2Storage(Route route) { // canceling = route.isCanceling();
StorageRoute storageRoute = new StorageRoute(route.getCode()); // normalUnlock = route.isNormalUnlock();
if (storageRoute.convert(route)) { // }
return storageRoute;
} public StorageRoute(String code) {
return null; super(code);
} }
@Override public static StorageRoute convert2Storage(Route route) {
public boolean convert(MapElement element) { StorageRoute storageRoute = new StorageRoute(route.getCode());
boolean change = false; if (storageRoute.convert(route)) {
Route route = (Route) element; return storageRoute;
if (!route.isAtsControl()) { }
change = true; return null;
this.setAtsControl(route.isAtsControl()); }
}
if (route.isFleetMode()) { @Override
change = true; public boolean convert(MapElement element) {
this.setFleetMode(route.isFleetMode()); boolean change = false;
} Route route = (Route) element;
if (route.isCiControl()) { if (!route.isAtsControl()) {
change = true; change = true;
this.setCiControl(route.isCiControl()); this.setAtsControl(route.isAtsControl());
} }
if (route.isSetting()) { if (route.isFleetMode()) {
change = true; change = true;
this.setSetting(route.isSetting()); this.setFleetMode(route.isFleetMode());
this.setSettingStartTime(route.getSettingStartTime()); }
} if (route.isCiControl()) {
if (route.isGuideSetting()) { change = true;
change = true; this.setCiControl(route.isCiControl());
this.setSettingGuide(route.isGuideSetting()); }
} if (route.isSetting()) {
if (route.isLock()) { change = true;
change = true; this.setSetting(route.isSetting());
this.setLock(route.isLock()); this.setSettingStartTime(route.getSettingStartTime());
} }
if (route.getDelayUnlockDevice() != null) { if (route.isGuideSetting()) {
change = true; change = true;
this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode()); this.setSettingGuide(route.isGuideSetting());
} }
if (route.isNormalUnlock()) { if (route.isLock()) {
change = true; change = true;
this.setNormalUnlock(route.isNormalUnlock()); this.setLock(route.isLock());
} }
if (Objects.nonNull(route.getUnlockedSection())) { if (route.getDelayUnlockDevice() != null) {
change = true; change = true;
this.setUnlockedSection(route.getUnlockedSection().getCode()); this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode());
} }
return change; if (route.isNormalUnlock()) {
} change = true;
this.setNormalUnlock(route.isNormalUnlock());
@Override }
public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) { if (Objects.nonNull(route.getUnlockedSection())) {
Route route = (Route) element; change = true;
route.setAtsControl(atsControl != null ? atsControl : true); this.setUnlockedSection(route.getUnlockedSection().getCode());
route.setFleetMode(fleetMode != null ? fleetMode : false); }
route.setCiControl(ciControl != null ? ciControl : false); if (Objects.nonNull(route.getSettedAspect())) {
route.setSetting(setting != null? setting : false); change = true;
route.setSettingStartTime(this.settingStartTime); this.setSettedAspect(route.getSettedAspect());
route.setGuideSetting(settingGuide != null? settingGuide : false); }
route.setLock(lock != null ? lock : false);
if (this.delayUnlockDevice != null) { return change;
route.setDelayUnlockDevice((DelayUnlockDevice) repository.getByCode(this.delayUnlockDevice)); }
}
route.setNormalUnlock(normalUnlock != null ? normalUnlock : false); @Override
if (Objects.nonNull(this.unlockedSection)) { public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) {
route.setUnlockedSection(repository.getByCode(this.unlockedSection, Section.class)); Route route = (Route) element;
} route.setAtsControl(atsControl != null ? atsControl : true);
} route.setFleetMode(fleetMode != null ? fleetMode : false);
route.setCiControl(ciControl != null ? ciControl : false);
} route.setSetting(setting != null? setting : false);
route.setSettingStartTime(this.settingStartTime);
route.setGuideSetting(settingGuide != null? settingGuide : false);
route.setLock(lock != null ? lock : false);
if (this.delayUnlockDevice != null) {
route.setDelayUnlockDevice((DelayUnlockDevice) repository.getByCode(this.delayUnlockDevice));
}
route.setNormalUnlock(normalUnlock != null ? normalUnlock : false);
if (Objects.nonNull(this.unlockedSection)) {
route.setUnlockedSection(repository.getByCode(this.unlockedSection, Section.class));
}
route.setSettedAspect(settedAspect);
}
}

View File

@ -1,236 +1,236 @@
package club.joylink.rtss.simulation.cbtc.depot; package club.joylink.rtss.simulation.cbtc.depot;
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool; import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService; import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.command.CommandBO; import club.joylink.rtss.simulation.cbtc.command.CommandBO;
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO; import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.map.Route; import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Signal; import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.data.map.Station; import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan; import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
import lombok.Getter; import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
public class DepotService { public class DepotService {
@Autowired @Autowired
private CiRouteService ciRouteService; private CiRouteService ciRouteService;
@Autowired @Autowired
private TrainOutboundLoadTool trainOutboundLoadTool; private TrainOutboundLoadTool trainOutboundLoadTool;
@Autowired @Autowired
private GroupSimulationService groupSimulationService; private GroupSimulationService groupSimulationService;
@Autowired @Autowired
private ATPService atpService; private ATPService atpService;
public void loadDepotTrain(Simulation simulation) { public void loadDepotTrain(Simulation simulation) {
if (!simulation.getRepository().getConfig().isHandleDepot()) { if (!simulation.getRepository().getConfig().isHandleDepot()) {
return; return;
} }
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap(); Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
simulation.getRepository().getAllVrTrain().stream() simulation.getRepository().getAllVrTrain().stream()
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation)) .collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
.forEach((station, trainList) -> { .forEach((station, trainList) -> {
List<Section> sections = parkingTracksMap.get(station); List<Section> sections = parkingTracksMap.get(station);
// 先加载内侧的停车轨 // 先加载内侧的停车轨
sections.sort(Comparator.comparing(section -> sections.sort(Comparator.comparing(section ->
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection()))); Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
boolean right = sections.get(sections.size() - 1).getLeftSection() == null; boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) { for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
VirtualRealityTrain train = trainList.get(i); VirtualRealityTrain train = trainList.get(i);
Section section = sections.get(i); Section section = sections.get(i);
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right); train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
train.parkingAt(section); train.parkingAt(section);
train.initAsRM(); train.initAsRM();
TrainInfo trainInfo = TrainInfo.constructManualTrain(train); TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
trainInfo.tracking(train); trainInfo.tracking(train);
simulation.getRepository().addOnlineTrain(train); simulation.getRepository().addOnlineTrain(train);
simulation.getRepository().addTrainInfo(trainInfo); simulation.getRepository().addTrainInfo(trainInfo);
} }
}); });
} }
public void addJobs(Simulation simulation) { public void addJobs(Simulation simulation) {
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE); simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
} }
private void run(Simulation simulation) { private void run(Simulation simulation) {
if (!simulation.isPlanRunning()) { if (!simulation.isPlanRunning()) {
return; return;
} }
if (!simulation.getRepository().getConfig().isHandleDepot()) { if (!simulation.getRepository().getConfig().isHandleDepot()) {
trainOutboundLoadTool.loadOutboundTrain(simulation); trainOutboundLoadTool.loadOutboundTrain(simulation);
} else { } else {
timeToDeparture(simulation); timeToDeparture(simulation);
backToParking(simulation); backToParking(simulation);
settingRouteAndMoving(simulation); settingRouteAndMoving(simulation);
arriveDestination(simulation); arriveDestination(simulation);
} }
} }
/** /**
* 根据时间筛选从停车轨自动发车 * 根据时间筛选从停车轨自动发车
*/ */
private void timeToDeparture(Simulation simulation) { private void timeToDeparture(Simulation simulation) {
LocalDateTime systemTime = simulation.getSystemTime(); LocalDateTime systemTime = simulation.getSystemTime();
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) { for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) { if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
continue; continue;
} }
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) { if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
schedulingTrainPlan.getOutDepotTrip().dispatched(); schedulingTrainPlan.getOutDepotTrip().dispatched();
// 保存信息 // 保存信息
VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class); VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class);
Section startSection = train.getHeadPosition().getSection(); Section startSection = train.getHeadPosition().getSection();
Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection(); Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection();
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection); List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
RoutePath routePath = routePaths.get(0); RoutePath routePath = routePaths.get(0);
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false); DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false);
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo); simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
} }
} }
} }
/** /**
* 筛选入库 * 筛选入库
*/ */
private void backToParking(Simulation simulation) { private void backToParking(Simulation simulation) {
for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) { for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) {
if (trainInfo.isInbound() && trainInfo.isParking()) { if (trainInfo.isInbound() && trainInfo.isParking()) {
VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class); VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class);
if (train.getHeadPosition().getSection().isTransferTrack() if (train.getHeadPosition().getSection().isTransferTrack()
&& train.getTailPosition().getSection().isTransferTrack()) { && train.getTailPosition().getSection().isTransferTrack()) {
if (simulation.getRepository().getDepotRunningInfoList().stream() if (simulation.getRepository().getDepotRunningInfoList().stream()
.anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) { .anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) {
continue; continue;
} }
train.initAsRM(); train.initAsRM();
Section startSection = train.getHeadPosition().getSection(); Section startSection = train.getHeadPosition().getSection();
Section endSection = null; Section endSection = null;
for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) { for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) {
if (section.isOccupied()) { if (section.isOccupied()) {
continue; continue;
} }
if (section.getLeftSection() == null || section.getRightSection() == null) { if (section.getLeftSection() == null || section.getRightSection() == null) {
endSection = section; endSection = section;
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) { } else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
endSection = section.getLeftSection(); endSection = section.getLeftSection();
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) { } else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
endSection = section.getRightSection(); endSection = section.getRightSection();
} else { } else {
endSection = section; endSection = section;
} }
break; break;
} }
// train.setTarget(endSection); // train.setTarget(endSection);
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection); List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
if (routePaths == null || routePaths.isEmpty()) { if (routePaths == null || routePaths.isEmpty()) {
return; return;
} }
RoutePath routePath = routePaths.get(0); RoutePath routePath = routePaths.get(0);
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true); DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true);
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo); simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
break; break;
} }
} }
} }
} }
/** /**
* 列车排进路并运行 * 列车排进路并运行
*/ */
private void settingRouteAndMoving(Simulation simulation) { private void settingRouteAndMoving(Simulation simulation) {
for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) { for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) {
Section endSection = depotRunningInfo.getEndSection(); Section endSection = depotRunningInfo.getEndSection();
SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight())); SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight()));
depotRunningInfo.getTrain().setRobotTargetPosition(position); depotRunningInfo.getTrain().setRobotTargetPosition(position);
if (!depotRunningInfo.getRouteList().isEmpty()) { if (!depotRunningInfo.getRouteList().isEmpty()) {
Route route = depotRunningInfo.getRouteList().get(0); Route route = depotRunningInfo.getRouteList().get(0);
if (route.isLock()) { if (route.isLock()) {
depotRunningInfo.getRouteList().remove(0); depotRunningInfo.getRouteList().remove(0);
} }
if (!route.isSetting()) { if (!route.isSetting()) {
ciRouteService.setRoute(simulation, route); ciRouteService.setRoute(simulation, route,route.getAspect());
} }
} }
} }
} }
/** /**
* 判断运行列车是否到达转换轨并升级 * 判断运行列车是否到达转换轨并升级
*/ */
private void arriveDestination(Simulation simulation) { private void arriveDestination(Simulation simulation) {
for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) { for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) {
DepotRunningInfo depotRunningInfo = iterator.next(); DepotRunningInfo depotRunningInfo = iterator.next();
VirtualRealityTrain train = depotRunningInfo.getTrain(); VirtualRealityTrain train = depotRunningInfo.getTrain();
if (depotRunningInfo.isArrival()) { if (depotRunningInfo.isArrival()) {
// 到达 // 到达
iterator.remove(); iterator.remove();
if (depotRunningInfo.in) { if (depotRunningInfo.in) {
atpService.turnDirectionImmediately(train); atpService.turnDirectionImmediately(train);
} else { } else {
// 升级 // 升级
SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER); SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER);
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("preselectionMode", "AM_C"); param.put("preselectionMode", "AM_C");
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode, CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
member.getId(), param); member.getId(), param);
groupSimulationService.command(simulation, commandInitiateVO, member); groupSimulationService.command(simulation, commandInitiateVO, member);
} }
} }
} }
} }
@Getter @Getter
public static class DepotRunningInfo { public static class DepotRunningInfo {
private final List<Route> routeList = new ArrayList<>(); private final List<Route> routeList = new ArrayList<>();
private final Section endSection; private final Section endSection;
private final VirtualRealityTrain train; private final VirtualRealityTrain train;
private final Boolean right; private final Boolean right;
private final Boolean in; private final Boolean in;
public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) { public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) {
this.endSection = endSection; this.endSection = endSection;
this.train = train; this.train = train;
for (Signal signal : routePath.getSignalList()) { for (Signal signal : routePath.getSignalList()) {
for (Route route : signal.getRouteList()) { for (Route route : signal.getRouteList()) {
if (routePath.getRouteList().contains(route)) { if (routePath.getRouteList().contains(route)) {
routeList.add(route); routeList.add(route);
} }
} }
} }
this.right = routePath.isRight(); this.right = routePath.isRight();
this.in = in; this.in = in;
} }
// 列车是否到达终点 // 列车是否到达终点
public boolean isArrival() { public boolean isArrival() {
return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection) return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection)
&& train.getTailPosition().getSection().equals(endSection); && train.getTailPosition().getSection().equals(endSection);
} }
} }
} }

View File

@ -530,7 +530,7 @@ public class ATPService {
public void inbound(Simulation simulation, String groupNumber) { public void inbound(Simulation simulation, String groupNumber) {
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
Section headSection = train.getHeadPosition().getSection(); Section headSection = train.getHeadPosition().getSection();
if (headSection.isTransferTrack() && train.isStop()) { //列车停在折返轨 if (headSection.isTurnBackTrack() && train.isStop()) { //列车停在折返轨
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber()); TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(headSection); List<RoutePath> routePathList = repository.queryRoutePathsByEnd(headSection);
@ -624,6 +624,7 @@ public class ATPService {
} }
} }
} else if (trainMode.isMatchTheDriveMode(DriveMode.AM) && !train.isAMMode()) { } else if (trainMode.isMatchTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
train.getRobotDriveParam().setRun(false); // 关闭机器人自动驾驶
if (!train.isInTheGear(VirtualRealityTrain.Handwheel.ATO)) { if (!train.isInTheGear(VirtualRealityTrain.Handwheel.ATO)) {
this.changeGear(train, VirtualRealityTrain.Handwheel.ATO); this.changeGear(train, VirtualRealityTrain.Handwheel.ATO);
} }

View File

@ -11,6 +11,7 @@ import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.command.CommandBO; import club.joylink.rtss.simulation.cbtc.command.CommandBO;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.constant.SignalModel;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
@ -436,13 +437,31 @@ public class SimulationRobotService {
*/ */
private void robotDrive(Simulation simulation, VirtualRealityTrain train, SectionPosition targetPosition) { private void robotDrive(Simulation simulation, VirtualRealityTrain train, SectionPosition targetPosition) {
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock()) { //如果车门没关
return;
}
SectionPosition headPosition = train.getHeadPosition(); SectionPosition headPosition = train.getHeadPosition();
boolean right = train.isRight(); boolean right = train.isRight();
float speed = train.getSpeed(); float speed = train.getSpeed();
if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock()) { //如果车门没关
return;
}
/**
* 添加车辆停靠车站时车门关闭后向前行驶一点的问题因为车头偏移与目标偏移大于 @seeSimulationConstants.PARK_POINT_MAX_OFFSET位置故修正逻辑如下
* 判断车辆是否停靠车站没有开发的信号没有新车命令如果有其中一项的条件那么车辆可以启动
* begin 2022-08-15
*/
boolean trainPackingForStand = train.isParkingAt();
// headPosition.getSection().getStandList().stream().anyMatch(d->d.isTrainParking());
Signal targetSignal = headPosition.getSection().getSignalOf(right);
boolean closeSignal = false;
if(Objects.nonNull(targetSignal)){
closeSignal = targetSignal.getAspect() == targetSignal.getSignalModel().getDefaultAspect();
}
boolean noCommond = Objects.isNull(train.getRobotDriveParam().getThroughSignal());
if(trainPackingForStand && closeSignal && noCommond){
return;
}
/**
* end 2022-08-15
*/
Float distance = CalculateService.calculateDistance(headPosition, targetPosition, right, true); Float distance = CalculateService.calculateDistance(headPosition, targetPosition, right, true);
if (distance == null || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置 if (distance == null || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置
atoService.doBreakMax(train); atoService.doBreakMax(train);

View File

@ -1,306 +1,307 @@
package club.joylink.rtss.simulation.cbtc.tool; package club.joylink.rtss.simulation.cbtc.tool;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService; import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel; import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication; import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService; import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService; import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
/** /**
* 设备状态修改工具有动作设备不需要动作过程可直接设置为想要的状态 * 设备状态修改工具有动作设备不需要动作过程可直接设置为想要的状态
* warn此工具类只在加载列车或实训生成场景使用正常仿真过程请勿使用 * warn此工具类只在加载列车或实训生成场景使用正常仿真过程请勿使用
*/ */
@Slf4j @Slf4j
@Component @Component
public class DeviceStatusModifyTool { public class DeviceStatusModifyTool {
@Autowired @Autowired
private VirtualRealityDeviceService virtualRealityDeviceService; private VirtualRealityDeviceService virtualRealityDeviceService;
@Autowired @Autowired
private CiRouteService routeService; private CiRouteService routeService;
@Autowired @Autowired
private AtsTrainLoadService atsTrainLoadService; private AtsTrainLoadService atsTrainLoadService;
@Autowired @Autowired
private VRTrainRunningService vrTrainRunningService; private VRTrainRunningService vrTrainRunningService;
/** /**
* 直接开放进路 * 直接开放进路
* *
* @param route * @param route
*/ */
public void openRouteDirect(Simulation simulation, Route route) { public void openRouteDirect(Simulation simulation, Route route) {
// 修改进路涉及的所有道岔元素到指定位置 // 修改进路涉及的所有道岔元素到指定位置
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true); this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
// 修改进路侧防到指定位置 // 修改进路侧防到指定位置
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList()); this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
// 进路元素锁闭 // 进路元素锁闭
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight())); route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
if (route.isSettingOverlap()) { if (route.isSettingOverlap()) {
SectionPath overlapPath = route.selectOverlapElement(); SectionPath overlapPath = route.selectOverlapElement();
if (Objects.nonNull(overlapPath)) { if (Objects.nonNull(overlapPath)) {
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList()); this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false); this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight())); overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList()); this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
route.getOverlap().setLock(true); route.getOverlap().setLock(true);
} }
} }
route.setNormalUnlock(false); route.setNormalUnlock(false);
route.setLock(true); route.setLock(true);
simulation.getRepository().addSettingRoute(route); route.setSettedAspect(route.getAspect());
this.openSignalDirectly(route.getStart(), route.getAspect()); simulation.getRepository().addSettingRoute(route);
route.getStart().setLockedRoute(route); this.openSignalDirectly(route.getStart(), route.getSettedAspect());
} route.getStart().setLockedRoute(route);
}
private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
if (!CollectionUtils.isEmpty(flsList)) { private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
List<SwitchElement> switchElementList = new ArrayList<>(); if (!CollectionUtils.isEmpty(flsList)) {
for (RouteFls routeFls : flsList) { List<SwitchElement> switchElementList = new ArrayList<>();
for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) { for (RouteFls routeFls : flsList) {
SwitchElement pSwitch = flsElement.getPSwitch(); for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) {
if (pSwitch != null) { SwitchElement pSwitch = flsElement.getPSwitch();
switchElementList.add(pSwitch); if (pSwitch != null) {
} else if (flsElement.getFpae() != null) { switchElementList.add(pSwitch);
switchElementList.add(flsElement.getFpae()); } else if (flsElement.getFpae() != null) {
} switchElementList.add(flsElement.getFpae());
} }
} }
for (SwitchElement switchElement : switchElementList) { }
// switchElement.getASwitch().ciUse(switchElement.isNormal()); for (SwitchElement switchElement : switchElementList) {
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal()); // switchElement.getASwitch().ciUse(switchElement.isNormal());
switchElement.getASwitch().fpLock(); this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
} switchElement.getASwitch().fpLock();
} }
} }
}
public void openGuideRouteDirect(Simulation simulation, Route route) {
// 修改进路涉及的所有道岔元素到指定位置 public void openGuideRouteDirect(Simulation simulation, Route route) {
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true); // 修改进路涉及的所有道岔元素到指定位置
// 修改进路侧防到指定位置 this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList()); // 修改进路侧防到指定位置
// 进路元素锁闭 this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight())); // 进路元素锁闭
SectionPath overlapPath = route.selectOverlapElement(); route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
if (Objects.nonNull(overlapPath)) { SectionPath overlapPath = route.selectOverlapElement();
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false); if (Objects.nonNull(overlapPath)) {
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList()); this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight())); this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
} overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
route.setLock(true); }
this.openGuideSignalDirectly(route.getStart()); route.setLock(true);
route.getStart().setLockedRoute(route); this.openGuideSignalDirectly(route.getStart());
} route.getStart().setLockedRoute(route);
}
public void openGuideSignalDirectly(Signal signal) {
VirtualRealitySignal virtualSignal = signal.getVirtualSignal(); public void openGuideSignalDirectly(Signal signal) {
SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect(); VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
virtualSignal.control(guideAspect); SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect();
virtualSignal.finish(); virtualSignal.control(guideAspect);
signal.changeLightType(false); virtualSignal.finish();
signal.setAspect(guideAspect); signal.changeLightType(false);
} signal.setAspect(guideAspect);
}
/**
* 直接开灯(默认逻辑点灯) /**
* * 直接开灯(默认逻辑点灯)
* @param signal *
* @param aspect * @param signal
*/ * @param aspect
private void openSignalDirectly(Signal signal, SignalAspect aspect) { */
VirtualRealitySignal virtualSignal = signal.getVirtualSignal(); private void openSignalDirectly(Signal signal, SignalAspect aspect) {
signal.changeLightType(true); VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
if (virtualSignal != null) { signal.changeLightType(true);
if (signal.isLogicLight()) { if (virtualSignal != null) {
virtualSignal.control(SignalAspect.No); if (signal.isLogicLight()) {
} else { virtualSignal.control(SignalAspect.No);
virtualSignal.control(aspect); } else {
} virtualSignal.control(aspect);
virtualSignal.finish(); }
} virtualSignal.finish();
signal.setAspect(aspect); }
} signal.setAspect(aspect);
}
/**
* 直接关灯(默认逻辑点灯) /**
* * 直接关灯(默认逻辑点灯)
* @param signal *
*/ * @param signal
public void closeSignalDirectly(Signal signal) { */
VirtualRealitySignal virtualSignal = signal.getVirtualSignal(); public void closeSignalDirectly(Signal signal) {
signal.changeLightType(true); VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect(); signal.changeLightType(true);
if (signal.isLogicLight()) { SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect();
virtualSignal.control(SignalAspect.No); if (signal.isLogicLight()) {
} else { virtualSignal.control(SignalAspect.No);
virtualSignal.control(defaultAspect); } else {
} virtualSignal.control(defaultAspect);
virtualSignal.finish(); }
signal.setAspect(defaultAspect); virtualSignal.finish();
} signal.setAspect(defaultAspect);
}
/**
* 批量设置进路道岔位置并锁闭 /**
* * 批量设置进路道岔位置并锁闭
* @param route *
* @param switchList * @param route
* @param routeLock * @param switchList
*/ * @param routeLock
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) { */
if (!CollectionUtils.isEmpty(switchList)) { private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) {
for (SwitchElement switchElement : switchList) { if (!CollectionUtils.isEmpty(switchList)) {
// if (switchElement.getASwitch().isOverlapLock() && for (SwitchElement switchElement : switchList) {
// switchElement.isOnPosition()) { // if (switchElement.getASwitch().isOverlapLock() &&
// continue; // switchElement.isOnPosition()) {
// } // continue;
// switchElement.getASwitch().ciUse(switchElement.isNormal()); // }
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal()); // switchElement.getASwitch().ciUse(switchElement.isNormal());
if (routeLock) { this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
switchElement.getASwitch().routeLock(route); if (routeLock) {
} else { // 延续保护锁闭 switchElement.getASwitch().routeLock(route);
switchElement.getASwitch().overlapLock(); } else { // 延续保护锁闭
} switchElement.getASwitch().overlapLock();
} }
} }
} }
}
/**
* 直接把单个道岔转到指定位置 /**
* * 直接把单个道岔转到指定位置
* @param aSwitch *
* @param normal * @param aSwitch
*/ * @param normal
public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) { */
VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch(); public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) {
if (normal) { VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch();
virtualSwitch.control(VirtualRealitySwitch.Operation.NP); if (normal) {
virtualSwitch.finish(); virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
aSwitch.setPos(SwitchIndication.N); virtualSwitch.finish();
} else { aSwitch.setPos(SwitchIndication.N);
virtualSwitch.control(VirtualRealitySwitch.Operation.RP); } else {
virtualSwitch.finish(); virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
aSwitch.setPos(SwitchIndication.R); virtualSwitch.finish();
} aSwitch.setPos(SwitchIndication.R);
} }
}
/**
* 直接把道岔及其联动道岔转动到指定位置 /**
* * 直接把道岔及其联动道岔转动到指定位置
* @param aSwitch *
* @param normal * @param aSwitch
*/ * @param normal
public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch, boolean normal) { */
SimulationDataRepository repository = simulation.getRepository(); public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch, boolean normal) {
this.setSingleSwitchPositionDirectly(aSwitch, normal); SimulationDataRepository repository = simulation.getRepository();
Switch linkedSwitch = aSwitch.queryLinkedSwitch(); this.setSingleSwitchPositionDirectly(aSwitch, normal);
if (Objects.nonNull(linkedSwitch)) { Switch linkedSwitch = aSwitch.queryLinkedSwitch();
this.setSingleSwitchPositionDirectly(linkedSwitch, normal); if (Objects.nonNull(linkedSwitch)) {
} this.setSingleSwitchPositionDirectly(linkedSwitch, normal);
} }
}
/**
* 直接根据最后一根区段解锁进路 /**
* * 直接根据最后一根区段解锁进路
* @param route *
*/ * @param route
public void routeUnlockByEndSection(Route route, Section tailSection) { */
if (!route.isRouteSection(tailSection)) { public void routeUnlockByEndSection(Route route, Section tailSection) {
// 不是进路区段不解锁 if (!route.isRouteSection(tailSection)) {
return; // 不是进路区段不解锁
} return;
route.startNormalUnlock(); }
// 关闭始端信号机 route.startNormalUnlock();
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect()); // 关闭始端信号机
boolean right = route.getStart().isRight(); openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
// 区段是顺序的(否则会有问题) boolean right = route.getStart().isRight();
List<Section> sectionList = route.getSectionList(); // 区段是顺序的(否则会有问题)
for (Section section : sectionList) { List<Section> sectionList = route.getSectionList();
if (section.isSamePhysical(tailSection.getCode())) { for (Section section : sectionList) {
route.updateUnlockedSection(tailSection); if (section.isSamePhysical(tailSection.getCode())) {
break; route.updateUnlockedSection(tailSection);
} break;
// 直接解锁区段 }
if (section.isSwitchTrack()) { // 如果是道岔区段解锁道岔 // 直接解锁区段
Switch relSwitch = section.getRelSwitch(); if (section.isSwitchTrack()) { // 如果是道岔区段解锁道岔
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) { Switch relSwitch = section.getRelSwitch();
route.updateUnlockedSection(tailSection); if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
break; route.updateUnlockedSection(tailSection);
} break;
if (section.getParent() != null && section.getParent().isCross()) { }
section.getParent().routeUnlocking(route); if (section.getParent() != null && section.getParent().isCross()) {
} section.getParent().routeUnlocking(route);
relSwitch.routeUnlock(route); }
relSwitch.overlapUnLock(); relSwitch.routeUnlock(route);
// 侧防解锁 relSwitch.overlapUnLock();
route.unlockRouteFlsOfSwitch(relSwitch); // 侧防解锁
//检查道岔的联动道岔和计轴关联道岔是否可以解锁 route.unlockRouteFlsOfSwitch(relSwitch);
for (SwitchElement switchElement : route.getSwitchList()) { //检查道岔的联动道岔和计轴关联道岔是否可以解锁
if (switchElement.getASwitch().equals(relSwitch)) { for (SwitchElement switchElement : route.getSwitchList()) {
continue; if (switchElement.getASwitch().equals(relSwitch)) {
} continue;
Switch aSwitch = switchElement.getASwitch(); }
if (route.isRouteSection(aSwitch.getA())) { Switch aSwitch = switchElement.getASwitch();
continue; if (route.isRouteSection(aSwitch.getA())) {
} continue;
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) { }
if (!aSwitch.getA().isRouteLock()) { if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
aSwitch.routeUnlock(route); if (!aSwitch.getA().isRouteLock()) {
aSwitch.overlapUnLock(); aSwitch.routeUnlock(route);
} aSwitch.overlapUnLock();
} }
} }
} else { }
section.routeUnlocking(route); } else {
} section.routeUnlocking(route);
} }
} }
}
public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section, boolean right) {
SimulationDataRepository repository = simulation.getRepository(); public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section, boolean right) {
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class); SimulationDataRepository repository = simulation.getRepository();
if (!section.isPhysical()) { VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
section = section.getParent(); if (!section.isPhysical()) {
} section = section.getParent();
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上"); }
//重叠检测 BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right)); //重叠检测
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false); SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition); SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠"); boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
// 列车上线并构建ATS监控列车信息 BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
train.initManualTrain(headPosition, right); // 列车上线并构建ATS监控列车信息
//设置列车预选模式驾驶模式运行级别 train.initManualTrain(headPosition, right);
if (!headPosition.getSection().anyZcWorking()) { //设置列车预选模式驾驶模式运行级别
train.initAsRM(); if (!headPosition.getSection().anyZcWorking()) {
} else { train.initAsRM();
MapConfig config = repository.getConfig(); } else {
if (RunLevel.ITC.equals(config.getRunMode())) { MapConfig config = repository.getConfig();
train.initAsAM_I(); if (RunLevel.ITC.equals(config.getRunMode())) {
} else if (RunLevel.IL.equals(config.getRunMode())) { train.initAsAM_I();
train.initAsRM(); } else if (RunLevel.IL.equals(config.getRunMode())) {
} train.initAsRM();
} }
TrainInfo trainInfo = TrainInfo.constructManualTrain(train); }
trainInfo.tracking(train); TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
repository.addOnlineTrain(train); trainInfo.tracking(train);
repository.addTrainInfo(trainInfo); repository.addOnlineTrain(train);
} repository.addTrainInfo(trainInfo);
} }
}

View File

@ -37,6 +37,11 @@ public class MapSignalButtonVO {
*/ */
private DirectionLabelEnum labelEnum; private DirectionLabelEnum labelEnum;
/**
* 有计数器
*/
private boolean hasCount;
public enum Type { public enum Type {
/** /**
* 接车按钮 * 接车按钮

View File

@ -1,208 +1,208 @@
server: server:
port: 9000 port: 9000
modbus-tcp: modbus-tcp:
port: 19000 port: 19000
udp: udp:
serverPort: 20002 serverPort: 20002
clientPort: 20001 clientPort: 20001
spring: spring:
profiles: profiles:
active: dev active: dev
application: application:
name: joylink-rtss name: joylink-rtss
jackson: jackson:
date-format: yyyy-MM-dd HH:mm:ss date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8 time-zone: GMT+8
default-property-inclusion: non_null default-property-inclusion: non_null
servlet: servlet:
multipart: multipart:
max-file-size: 10MB max-file-size: 10MB
# JavaMailSender 邮件发送的配置 # JavaMailSender 邮件发送的配置
mail: mail:
host: smtp.exmail.qq.com host: smtp.exmail.qq.com
port: 465 port: 465
username: ServiceEmail@joylink.club username: ServiceEmail@joylink.club
password: wFHcZQFuigKPvpSr password: wFHcZQFuigKPvpSr
properties: properties:
mail: mail:
smtp: smtp:
auth: true auth: true
starttls: starttls:
enable: true enable: true
required: true required: true
socketFactory: socketFactory:
port: 465 port: 465
class: javax.net.ssl.SSLSocketFactory class: javax.net.ssl.SSLSocketFactory
fallback: false fallback: false
datasource: datasource:
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
hikari: hikari:
minimum-idle: 5 # 连接池维护的最小空闲连接数 minimum-idle: 5 # 连接池维护的最小空闲连接数
maximum-pool-size: 10 #配置最大连接池大小 maximum-pool-size: 10 #配置最大连接池大小
auto-commit: true #配置从池返回的连接的默认自动提交行为 auto-commit: true #配置从池返回的连接的默认自动提交行为
idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间单位ms idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间单位ms
pool-name: HikariPool pool-name: HikariPool
max-lifetime: 1800000 # 池中连接关闭后的最长生命周期单位ms max-lifetime: 1800000 # 池中连接关闭后的最长生命周期单位ms
connection-timeout: 30000 # 等待连接的超时时间单位ms connection-timeout: 30000 # 等待连接的超时时间单位ms
mybatis: mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: club.joylink.rtss.entity type-aliases-package: club.joylink.rtss.entity
pagehelper: pagehelper:
helper-dialect: mysql helper-dialect: mysql
reasonable: true reasonable: true
support-methods-arguments: true support-methods-arguments: true
params: count=countSql params: count=countSql
wechat: wechat:
app-id: wx41cb66db5faf330f app-id: wx41cb66db5faf330f
app-secret: eb7199c1e73417be6a4d38b4a848effb app-secret: eb7199c1e73417be6a4d38b4a848effb
domain-uri: https://api.weixin.qq.com domain-uri: https://api.weixin.qq.com
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=http://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=http://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
sp-app-id: wxe9150dbbcbf9440b sp-app-id: wxe9150dbbcbf9440b
sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
sp-app2-id: wxecb0321367be529c sp-app2-id: wxecb0321367be529c
sp-app2-secret: 3c31cb41588f27a78160092249123766 sp-app2-secret: 3c31cb41588f27a78160092249123766
sp-app3-id: wxe6140d5985333338 sp-app3-id: wxe6140d5985333338
sp-app3-secret: 6b7359860c22e3607467df421cd24eef sp-app3-secret: 6b7359860c22e3607467df421cd24eef
wm-base-url: https://joylink.club/oss/joylink/%s?state=%s wm-base-url: https://joylink.club/oss/joylink/%s?state=%s
wx-module-url: http://localhost:9001 wx-module-url: http://localhost:9001
mini: mini:
access-token-task-on: false access-token-task-on: false
app-id: wxe9150dbbcbf9440b app-id: wxe9150dbbcbf9440b
app-secret: 4b5d453e5ec246a3f1b72360c59e4fab app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
tencent-cloud: tencent-cloud:
app-id: 1400093601 app-id: 1400093601
app-key: 4a724df65b2bb7e4dc9b4302693f2485 app-key: 4a724df65b2bb7e4dc9b4302693f2485
domain-uri: https://yun.tim.qq.com/v5/tlssmssvr domain-uri: https://yun.tim.qq.com/v5/tlssmssvr
allow-send: true allow-send: true
common: common:
env: dev env: dev
#修改swgger接口前缀默认为/v2/api-docs #修改swgger接口前缀默认为/v2/api-docs
springfox: springfox:
documentation: documentation:
swagger: swagger:
v2: v2:
path: /swagger/api-docs path: /swagger/api-docs
--- ---
spring: spring:
profiles: dev profiles: dev
datasource: datasource:
url: jdbc:mysql://localhost:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true url: jdbc:mysql://192.168.3.233:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root username: root
password: root password: joylink0503
tencent-cloud: tencent-cloud:
allow-send: false allow-send: false
logging: logging:
file: file:
path: /logs/joylink/rtss path: /logs/joylink/rtss
max-size: 100MB max-size: 100MB
level: level:
club.joylink.rtss: DEBUG club.joylink.rtss: DEBUG
common: common:
env: dev env: dev
license-secret-key: joylink license-secret-key: joylink
--- ---
spring: spring:
profiles: test profiles: test
datasource: datasource:
url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root username: root
password: Joylink@0503 password: Joylink@0503
wechat: wechat:
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: https://joylink.club/jlwxs wx-module-url: https://joylink.club/jlwxs
tencent-cloud: tencent-cloud:
allow-send: false allow-send: false
logging: logging:
file: file:
path: /usr/local/joylink/logs/rtss path: /usr/local/joylink/logs/rtss
level: level:
club.joylink.rtss: INFO club.joylink.rtss: INFO
common: common:
env: test env: test
--- ---
spring: spring:
profiles: local-test profiles: local-test
datasource: datasource:
url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root username: root
password: joylink0503 password: joylink0503
wechat: wechat:
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: https://joylink.club/jlwxs wx-module-url: https://joylink.club/jlwxs
tencent-cloud: tencent-cloud:
allow-send: false allow-send: false
logging: logging:
file: file:
path: /usr/local/joylink/logs/rtss path: /usr/local/joylink/logs/rtss
level: level:
club.joylink.rtss: INFO club.joylink.rtss: INFO
common: common:
env: test env: test
--- ---
spring: spring:
profiles: prd profiles: prd
datasource: datasource:
url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai
username: root username: root
password: joylink@0503 password: joylink@0503
wechat: wechat:
app-id: wx41cb66db5faf330f app-id: wx41cb66db5faf330f
app-secret: eb7199c1e73417be6a4d38b4a848effb app-secret: eb7199c1e73417be6a4d38b4a848effb
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: http://172.21.0.4:9001 wx-module-url: http://172.21.0.4:9001
mini: mini:
access-token-task-on: true access-token-task-on: true
file: file:
path: https://joylink.club/jlfile/api/upload/joylink/avatar path: https://joylink.club/jlfile/api/upload/joylink/avatar
logging: logging:
file: file:
path: /usr/local/joylink/logs/rtss path: /usr/local/joylink/logs/rtss
level: level:
club.joylink.rtss: INFO club.joylink.rtss: INFO
common: common:
env: prd env: prd
--- ---
spring: spring:
profiles: local profiles: local
datasource: datasource:
url: jdbc:mysql://192.168.3.233:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true url: jdbc:mysql://192.168.3.233:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root username: root
password: joylink0503 password: joylink0503
tencent-cloud: tencent-cloud:
allow-send: false allow-send: false
logging: logging:
file: file:
path: /usr/local/joylink/logs/rtss path: /usr/local/joylink/logs/rtss
level: level:
club.joylink.rtss: INFO club.joylink.rtss: INFO
common: common:
env: local env: local
license-secret-key: joylink license-secret-key: joylink