Merge branch 'test' into test-training2
This commit is contained in:
commit
8bf5a4b807
@ -732,6 +732,10 @@ public class Operation {
|
||||
/**
|
||||
* 托管
|
||||
*/
|
||||
Train_Drive(Operation.CLIENT),
|
||||
/**
|
||||
* TODO 托管,由于之前剧本中已包含Train_Trust,暂时留下,后续删除
|
||||
*/
|
||||
Train_Trust(Operation.CLIENT),
|
||||
/**
|
||||
* 连挂
|
||||
|
@ -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)
|
||||
public void trust(Simulation simulation, String groupNumber, DriveParamVO param) {
|
||||
atsTrainService.trust(simulation, groupNumber, param);
|
||||
|
@ -1,318 +1,320 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
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.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.status.RouteStatus;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AtsRouteService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
|
||||
@Autowired
|
||||
private CiApiService ciApiService;
|
||||
|
||||
/**
|
||||
* 进路收人工控
|
||||
*
|
||||
* @param simulation
|
||||
* @param signalCode
|
||||
* @param routeCodeList
|
||||
*/
|
||||
public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
routeCodeList.forEach(routeCode -> {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
route.setAtsControl(false);
|
||||
});
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路交自动控
|
||||
*/
|
||||
public void setRouteAtsControl(Simulation simulation, String signalCode,
|
||||
List<String> routeCodeList, List<Boolean> checkConflictList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
if (!CollectionUtils.isEmpty(checkConflictList)) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(),
|
||||
String.format("进路数和是否检查冲突数量不一致:[%s], [%s]",
|
||||
String.join(",", routeCodeList),
|
||||
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());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routes.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isCiControl(),
|
||||
String.format("信号机[%s]需处于人工控状态", signal.getCode())));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(checkConflictList)) {
|
||||
routes.forEach(route -> route.setAtsControl(true));
|
||||
} else {
|
||||
for (int i = 0; i < routeCodeList.size(); i++) {
|
||||
Route route = repository.getByCode(routeCodeList.get(i), Route.class);
|
||||
boolean checkConflict = checkConflictList.get(i);
|
||||
route.setAtsControl(true);
|
||||
route.setCheckConflict(checkConflict);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode()));
|
||||
}
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询进路状态/模式
|
||||
*/
|
||||
public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
return routeList.stream().map(RouteStatus::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动进路
|
||||
*/
|
||||
public void setCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFlt()) {
|
||||
throw new SimulationException(SimulationExceptionType.Unsupported_Operation,
|
||||
String.format("进路[%s]不能设置车队进路", lockedRoute.getCode()));
|
||||
}
|
||||
if (lockedRoute.isCiControl()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(true);
|
||||
} else {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机");
|
||||
// 筛选最适合的进路,筛选逻辑与办理引导时筛选逻辑类似
|
||||
List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList());
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路");
|
||||
List<Route> collect = fltRoutes.stream()
|
||||
.filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes;
|
||||
}
|
||||
Route route = collect.get(0);
|
||||
Route.CheckFailMessage message = routeService.setRoute(simulation, route);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理");
|
||||
route.setFleetMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动进路
|
||||
*/
|
||||
public void cancelCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (Objects.isNull(lockedRoute)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(false);
|
||||
if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) {
|
||||
routeService.unlockRoute(simulation, lockedRoute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动触发
|
||||
*/
|
||||
public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Route> routeList;
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode()));
|
||||
}
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodeList.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routeList.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isAtsControl(),
|
||||
String.format("信号机[%s]需处于人工控", signal.getCode())));
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.stream().filter(Route::isArs).forEach(route -> {
|
||||
if (route.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode()));
|
||||
}
|
||||
// if (route.isCiControl()) {
|
||||
// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode()));
|
||||
// }
|
||||
});
|
||||
for (Route route : routeList) {
|
||||
// route.setAtsControl(false);
|
||||
if (route.isArs())
|
||||
route.setCiControl(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动触发
|
||||
*/
|
||||
public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) {
|
||||
List<Route> routeList;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodes.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
for (Route route : routeList) {
|
||||
if (route.isCiControl()) {
|
||||
route.setCiControl(false);
|
||||
route.setAtsControl(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动折返进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param cycleCode
|
||||
*/
|
||||
public void setAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消自动折返进路
|
||||
*/
|
||||
public void cancelAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 总取消
|
||||
*/
|
||||
public void totalCancel(Simulation simulation, String signalCode) {
|
||||
// todo 总取消操作有很多种操作方式,对应不同的按钮,此处都用信号机编号可能不妥
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!signal.isApproachLock()) { //当接近区段未被占用
|
||||
this.cancelRoute(simulation, signalCode);
|
||||
} else {
|
||||
this.routeService.unlockRoute(simulation, lockedRoute);
|
||||
this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode());
|
||||
// if (signal.isGuideAspect()) { //如果引导信号开启中
|
||||
// this.ciApiService.closeGuideSignal(simulation, signalCode);
|
||||
// } else if (signal.isClose()) { //如果信号灯关了
|
||||
// } else {
|
||||
// this.ciApiService.closeSignal(simulation, signalCode);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRoute(Simulation simulation, String signalCode) {
|
||||
Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
|
||||
if (Objects.nonNull(route)) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.isApproachLock(), "进路接近锁闭,无法取消");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.getStart().isGuideAspect(), "引导进路,需要人解进路");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
|
||||
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);
|
||||
}
|
||||
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
|
||||
);
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
AtsAlarm conflictAlarm = route.getConflictAlarm();
|
||||
if (conflictAlarm != null) {
|
||||
LocalDateTime systemTime = simulation.getCorrectSystemTime();
|
||||
conflictAlarm.confirm(systemTime, member, way);
|
||||
conflictAlarm.recover(systemTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
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.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.status.RouteStatus;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AtsRouteService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
|
||||
@Autowired
|
||||
private CiApiService ciApiService;
|
||||
|
||||
/**
|
||||
* 进路收人工控
|
||||
*
|
||||
* @param simulation
|
||||
* @param signalCode
|
||||
* @param routeCodeList
|
||||
*/
|
||||
public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
routeCodeList.forEach(routeCode -> {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
route.setAtsControl(false);
|
||||
});
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路交自动控
|
||||
*/
|
||||
public void setRouteAtsControl(Simulation simulation, String signalCode,
|
||||
List<String> routeCodeList, List<Boolean> checkConflictList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
if (!CollectionUtils.isEmpty(checkConflictList)) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(),
|
||||
String.format("进路数和是否检查冲突数量不一致:[%s], [%s]",
|
||||
String.join(",", routeCodeList),
|
||||
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());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routes.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isCiControl(),
|
||||
String.format("信号机[%s]需处于人工控状态", signal.getCode())));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(checkConflictList)) {
|
||||
routes.forEach(route -> route.setAtsControl(true));
|
||||
} else {
|
||||
for (int i = 0; i < routeCodeList.size(); i++) {
|
||||
Route route = repository.getByCode(routeCodeList.get(i), Route.class);
|
||||
boolean checkConflict = checkConflictList.get(i);
|
||||
route.setAtsControl(true);
|
||||
route.setCheckConflict(checkConflict);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode()));
|
||||
}
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询进路状态/模式
|
||||
*/
|
||||
public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
return routeList.stream().map(RouteStatus::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动进路
|
||||
*/
|
||||
public void setCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFlt()) {
|
||||
throw new SimulationException(SimulationExceptionType.Unsupported_Operation,
|
||||
String.format("进路[%s]不能设置车队进路", lockedRoute.getCode()));
|
||||
}
|
||||
if (lockedRoute.isCiControl()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(true);
|
||||
} else {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机");
|
||||
// 筛选最适合的进路,筛选逻辑与办理引导时筛选逻辑类似
|
||||
List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList());
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路");
|
||||
List<Route> collect = fltRoutes.stream()
|
||||
.filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes;
|
||||
}
|
||||
Route route = collect.get(0);
|
||||
Route.CheckFailMessage message = routeService.setRoute(simulation, route,route.getAspect());
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理");
|
||||
route.setFleetMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动进路
|
||||
*/
|
||||
public void cancelCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (Objects.isNull(lockedRoute)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(false);
|
||||
if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) {
|
||||
routeService.unlockRoute(simulation, lockedRoute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动触发
|
||||
*/
|
||||
public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Route> routeList;
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode()));
|
||||
}
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodeList.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routeList.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isAtsControl(),
|
||||
String.format("信号机[%s]需处于人工控", signal.getCode())));
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.stream().filter(Route::isArs).forEach(route -> {
|
||||
if (route.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode()));
|
||||
}
|
||||
// if (route.isCiControl()) {
|
||||
// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode()));
|
||||
// }
|
||||
});
|
||||
for (Route route : routeList) {
|
||||
// route.setAtsControl(false);
|
||||
if (route.isArs())
|
||||
route.setCiControl(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动触发
|
||||
*/
|
||||
public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) {
|
||||
List<Route> routeList;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodes.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
for (Route route : routeList) {
|
||||
if (route.isCiControl()) {
|
||||
route.setCiControl(false);
|
||||
route.setAtsControl(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动折返进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param cycleCode
|
||||
*/
|
||||
public void setAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消自动折返进路
|
||||
*/
|
||||
public void cancelAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 总取消
|
||||
*/
|
||||
public void totalCancel(Simulation simulation, String signalCode) {
|
||||
// todo 总取消操作有很多种操作方式,对应不同的按钮,此处都用信号机编号可能不妥
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!signal.isApproachLock()) { //当接近区段未被占用
|
||||
this.cancelRoute(simulation, signalCode);
|
||||
} else {
|
||||
this.routeService.unlockRoute(simulation, lockedRoute);
|
||||
this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode());
|
||||
// if (signal.isGuideAspect()) { //如果引导信号开启中
|
||||
// this.ciApiService.closeGuideSignal(simulation, signalCode);
|
||||
// } else if (signal.isClose()) { //如果信号灯关了
|
||||
// } else {
|
||||
// this.ciApiService.closeSignal(simulation, signalCode);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRoute(Simulation simulation, String signalCode) {
|
||||
Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
|
||||
if (Objects.nonNull(route)) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.isApproachLock(), "进路接近锁闭,无法取消");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.getStart().isGuideAspect(), "引导进路,需要人解进路");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
|
||||
String.format("进路[%s]已开启自动通过进路,无法取消", route.debugStr()));
|
||||
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);
|
||||
}
|
||||
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
|
||||
);
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
AtsAlarm conflictAlarm = route.getConflictAlarm();
|
||||
if (conflictAlarm != null) {
|
||||
LocalDateTime systemTime = simulation.getCorrectSystemTime();
|
||||
conflictAlarm.confirm(systemTime, member, way);
|
||||
conflictAlarm.recover(systemTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,238 +1,238 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CI;
|
||||
|
||||
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.CiService;
|
||||
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.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiLogic {
|
||||
@Autowired
|
||||
private CiDeviceStatusCollector deviceStatusCollector;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private CiSignalControlService signalControlService;
|
||||
@Autowired
|
||||
private CiService ciService;
|
||||
@Autowired
|
||||
private StationDirectionService stationDirectionService;
|
||||
|
||||
public void run(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
// 信号机监控控制
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
for (Signal signal : repository.getSignalList()) {
|
||||
signalMonitor(simulation, signal);
|
||||
}
|
||||
// 联锁监控逻辑
|
||||
List<Route> routeList = repository.getRouteList();
|
||||
for (Route route : routeList) {
|
||||
interlockMonitor(simulation, route);
|
||||
}
|
||||
List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList();
|
||||
for (RouteOverlap routeOverlap : routeOverlapList) {
|
||||
overlapMonitor(simulation, routeOverlap);
|
||||
}
|
||||
|
||||
// 区间灯点灯逻辑
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
// 车站
|
||||
simulation.getRepository().getStationList().stream().forEach(station -> {
|
||||
// 允许自律状态刷新
|
||||
station.refreshAllowAutonomyStatus();
|
||||
// 接、发辅助按钮倒计时刷新
|
||||
station.getStationDirectionMap().values().stream()
|
||||
.forEach(stationDirection -> {
|
||||
// 判断进路状态是否发生变化
|
||||
if (stationDirection.monitorRouteChangeStatus()) {
|
||||
stationDirection.modifyRunStatus();
|
||||
}
|
||||
// 如果倒数结束弹起接、发辅助按钮,超过50秒时,不再自动抬起
|
||||
if (!stationDirection.isAssistReadyStatus()
|
||||
&& !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime())
|
||||
&& stationDirection.getCountDown().decrementAndGet() <= 0) {
|
||||
stationDirection.setDeliverAssistStatus(false);
|
||||
stationDirection.setReceiveAssistStatus(false);
|
||||
stationDirection.getCountDown().set(0);
|
||||
}
|
||||
// 联锁数据检查
|
||||
stationDirectionService.refreshSectionLightStatus(simulation, stationDirection);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void signalMonitor(Simulation simulation, Signal signal) {
|
||||
signalControlService.controlLightOfSignal(simulation, signal);
|
||||
//控制通过信号机的显示:信号机前第一个区段被占用开红灯;第二个区段被占用开黄灯;否则开绿灯
|
||||
if (signal.isPassingSignal()) {
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param route
|
||||
*/
|
||||
public void interlockMonitor(Simulation simulation, Route route) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (route.isCiControl()) { // 进路联锁自动触发
|
||||
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
|
||||
routeService.setRoute(simulation, route);
|
||||
}
|
||||
} else if (route.isFleetMode()) { // 联锁自动进路
|
||||
if (ciService.isCiRouteTrigger(simulation, route)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getAspect());
|
||||
}
|
||||
}
|
||||
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
|
||||
if (route.isDelayUnlocking()) {
|
||||
routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
routeService.routeSettingProcess(simulation, route);
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
routeService.trainUnlockRoute(simulation, route);
|
||||
}
|
||||
if (route.isLock()) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
Section firstLogicSection = route.getFirstLogicSection();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (repository.isTrainHeadOccupy(firstLogicSection)) {
|
||||
trainUnlockStart(simulation, route);
|
||||
}
|
||||
}
|
||||
Signal start = route.getStart();
|
||||
int guideRemain = start.getGuideRemain();
|
||||
if (guideRemain != 0) {
|
||||
guideRemain -= SimulationConstants.CI_LOOP_RATE;
|
||||
if (guideRemain <= 0) { //计时结束,关闭信号
|
||||
start.setGuideRemain(0);
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else {
|
||||
start.setGuideRemain(guideRemain);
|
||||
}
|
||||
}
|
||||
if (route.isLock() && !route.isSetting()) {
|
||||
ciService.interlockCheck(simulation, route);
|
||||
if (!config.isRailway()) {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, route.getAspect());
|
||||
}
|
||||
} else {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
start.setForcePhysical(true); //大铁线路暂时限制自动重开信号
|
||||
} else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
SignalAspect aspect = route.getAspectOfRailway();
|
||||
if (!Objects.equals(route.getStart().getAspect(), aspect)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 进路延续保护办理判断
|
||||
if (route.isSettingOverlap()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void trainUnlockStart(Simulation simulation, Route route) {
|
||||
route.startNormalUnlock();
|
||||
CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
route.getStart(), route.getStart().getDefaultAspect());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延续保护进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param overlap
|
||||
*/
|
||||
public void overlapMonitor(Simulation simulation, RouteOverlap overlap) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isSetting()) {
|
||||
routeService.overlapSettingProcess(simulation, overlap);
|
||||
}
|
||||
if (overlap.isForbidden()) {
|
||||
routeService.checkAndAllowOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) {
|
||||
overlap.setLock(false);
|
||||
}
|
||||
if (overlap.isSectionOverlapLocked()) {
|
||||
if (simulation.getRepository().isTrainParking(overlap.getSection())) {
|
||||
CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁",
|
||||
overlap.getName(),
|
||||
overlap.getSection().debugStr());
|
||||
overlap.releaseImmediately();
|
||||
return;
|
||||
}
|
||||
if (overlap.isReleasing()) {
|
||||
overlap.releaseProgress();
|
||||
} else if (!overlap.isReleasing() && simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
overlap.startReleasing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.CI;
|
||||
|
||||
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.CiService;
|
||||
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.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiLogic {
|
||||
@Autowired
|
||||
private CiDeviceStatusCollector deviceStatusCollector;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private CiSignalControlService signalControlService;
|
||||
@Autowired
|
||||
private CiService ciService;
|
||||
@Autowired
|
||||
private StationDirectionService stationDirectionService;
|
||||
|
||||
public void run(Simulation simulation) {
|
||||
// 采集真实设备状态
|
||||
deviceStatusCollector.collect(simulation);
|
||||
// 信号机监控控制
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
for (Signal signal : repository.getSignalList()) {
|
||||
signalMonitor(simulation, signal);
|
||||
}
|
||||
// 联锁监控逻辑
|
||||
List<Route> routeList = repository.getRouteList();
|
||||
for (Route route : routeList) {
|
||||
interlockMonitor(simulation, route);
|
||||
}
|
||||
List<RouteOverlap> routeOverlapList = repository.getRouteOverlapList();
|
||||
for (RouteOverlap routeOverlap : routeOverlapList) {
|
||||
overlapMonitor(simulation, routeOverlap);
|
||||
}
|
||||
|
||||
// 区间灯点灯逻辑
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
// 车站
|
||||
simulation.getRepository().getStationList().stream().forEach(station -> {
|
||||
// 允许自律状态刷新
|
||||
station.refreshAllowAutonomyStatus();
|
||||
// 接、发辅助按钮倒计时刷新
|
||||
station.getStationDirectionMap().values().stream()
|
||||
.forEach(stationDirection -> {
|
||||
// 判断进路状态是否发生变化
|
||||
if (stationDirection.monitorRouteChangeStatus()) {
|
||||
stationDirection.modifyRunStatus();
|
||||
}
|
||||
// 如果倒数结束弹起接、发辅助按钮,超过50秒时,不再自动抬起
|
||||
if (!stationDirection.isAssistReadyStatus()
|
||||
&& !stationDirection.assistDurationPass50(simulation.getCorrectSystemTime())
|
||||
&& stationDirection.getCountDown().decrementAndGet() <= 0) {
|
||||
stationDirection.setDeliverAssistStatus(false);
|
||||
stationDirection.setReceiveAssistStatus(false);
|
||||
stationDirection.getCountDown().set(0);
|
||||
}
|
||||
// 联锁数据检查
|
||||
stationDirectionService.refreshSectionLightStatus(simulation, stationDirection);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void signalMonitor(Simulation simulation, Signal signal) {
|
||||
signalControlService.controlLightOfSignal(simulation, signal);
|
||||
//控制通过信号机的显示:信号机前第一个区段被占用开红灯;第二个区段被占用开黄灯;否则开绿灯
|
||||
if (signal.isPassingSignal()) {
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param route
|
||||
*/
|
||||
public void interlockMonitor(Simulation simulation, Route route) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (route.isCiControl()) { // 进路联锁自动触发
|
||||
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
|
||||
routeService.setRoute(simulation, route,route.getAspect());
|
||||
}
|
||||
} else if (route.isFleetMode()) { // 联锁自动进路
|
||||
if (ciService.isCiRouteTrigger(simulation, route)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getSettedAspect());
|
||||
}
|
||||
}
|
||||
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
|
||||
if (route.isDelayUnlocking()) {
|
||||
routeService.delayUnlocking(simulation, route, route.getDelayUnlockDevice());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
routeService.routeSettingProcess(simulation, route);
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
routeService.trainUnlockRoute(simulation, route);
|
||||
}
|
||||
if (route.isLock()) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
Section firstLogicSection = route.getFirstLogicSection();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (repository.isTrainHeadOccupy(firstLogicSection)) {
|
||||
trainUnlockStart(simulation, route);
|
||||
}
|
||||
}
|
||||
Signal start = route.getStart();
|
||||
int guideRemain = start.getGuideRemain();
|
||||
if (guideRemain != 0) {
|
||||
guideRemain -= SimulationConstants.CI_LOOP_RATE;
|
||||
if (guideRemain <= 0) { //计时结束,关闭信号
|
||||
start.setGuideRemain(0);
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else {
|
||||
start.setGuideRemain(guideRemain);
|
||||
}
|
||||
}
|
||||
if (route.isLock() && !route.isSetting()) {
|
||||
ciService.interlockCheck(simulation, route);
|
||||
if (!config.isRailway()) {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, route.getSettedAspect());
|
||||
}
|
||||
} else {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
CiLogic.log.info("进路[{}]联锁条件不满足,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, start.getDefaultAspect());
|
||||
start.setForcePhysical(true); //大铁线路暂时限制自动重开信号
|
||||
} else if (!start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
SignalAspect aspect = route.getAspectOfRailway();
|
||||
if (!Objects.equals(route.getStart().getAspect(), aspect)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, start, aspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 进路延续保护办理判断
|
||||
if (route.isSettingOverlap()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, route.getOverlap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void trainUnlockStart(Simulation simulation, Route route) {
|
||||
route.startNormalUnlock();
|
||||
CiLogic.log.info("进路[{}]因列车进入,关闭信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
route.getStart(), route.getStart().getDefaultAspect());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延续保护进路监控
|
||||
*
|
||||
* @param simulation
|
||||
* @param overlap
|
||||
*/
|
||||
public void overlapMonitor(Simulation simulation, RouteOverlap overlap) {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (config.isOverlapSettingByTrigger() && overlap.isTriggerSectionOccupied()) {
|
||||
ciService.checkAndTrySettingOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isSetting()) {
|
||||
routeService.overlapSettingProcess(simulation, overlap);
|
||||
}
|
||||
if (overlap.isForbidden()) {
|
||||
routeService.checkAndAllowOverlap(simulation, overlap);
|
||||
}
|
||||
if (overlap.isLock() && !ciService.interlockCheck(simulation, overlap)) {
|
||||
overlap.setLock(false);
|
||||
}
|
||||
if (overlap.isSectionOverlapLocked()) {
|
||||
if (simulation.getRepository().isTrainParking(overlap.getSection())) {
|
||||
CiLogic.log.debug("列车停稳,延续保护[{}}],触发区段[{}}]立即解锁",
|
||||
overlap.getName(),
|
||||
overlap.getSection().debugStr());
|
||||
overlap.releaseImmediately();
|
||||
return;
|
||||
}
|
||||
if (overlap.isReleasing()) {
|
||||
overlap.releaseProgress();
|
||||
} else if (!overlap.isReleasing() && simulation.getRepository().isTrainHeadOccupy(overlap.getSection())) {
|
||||
// 进路首区段列车占用,进路开始解锁
|
||||
overlap.startReleasing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,21 @@ public abstract class DelayUnlockDevice extends MayOutOfOrderDevice {
|
||||
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) {
|
||||
this.remain = route.getDelayReleaseTime() * 1000;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -318,7 +318,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
public boolean isMainAspect() {
|
||||
if (this.lockedRoute != null) {
|
||||
return this.aspect.equals(this.lockedRoute.getAspect());
|
||||
return this.aspect.equals(this.lockedRoute.getSettedAspect());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,177 +1,191 @@
|
||||
package club.joylink.rtss.simulation.cbtc.data.storage.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class StorageRoute extends StorageDevice {
|
||||
|
||||
/**
|
||||
* 是否CBTC模式
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean cbtcMode;
|
||||
|
||||
/**
|
||||
* ats自动控制
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean atsControl;
|
||||
|
||||
/**
|
||||
* 连续通过进路模式(联锁自动进路)开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean fleetMode;
|
||||
|
||||
/**
|
||||
* 自动追踪/联锁自动触发模式开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean ciControl;
|
||||
|
||||
/**
|
||||
* 进路是否排列中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean setting;
|
||||
|
||||
private LocalDateTime settingStartTime;
|
||||
|
||||
/**
|
||||
* 是否引导进路排列
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean settingGuide;
|
||||
|
||||
/**
|
||||
* 进路是否锁闭
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean lock;
|
||||
|
||||
/** 进路延时解锁设备 */
|
||||
private String delayUnlockDevice;
|
||||
|
||||
/**
|
||||
* 是否正常解锁中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean normalUnlock;
|
||||
|
||||
private String unlockedSection;
|
||||
|
||||
// public StorageRoute(Route route) {
|
||||
// super(route.getCode());
|
||||
// cbtcMode = route.isCbtcMode();
|
||||
// turnBackMode = route.isTurnBackMode();
|
||||
// atsControl = route.isAtsControl();
|
||||
// fleetMode = route.isFleetMode();
|
||||
// ciControl = route.isCiControl();
|
||||
// setting = route.isSetting();
|
||||
// settingGuide = route.isSettingGuide();
|
||||
// lock = route.isLock();
|
||||
// canceling = route.isCanceling();
|
||||
// normalUnlock = route.isNormalUnlock();
|
||||
// }
|
||||
|
||||
public StorageRoute(String code) {
|
||||
super(code);
|
||||
}
|
||||
|
||||
public static StorageRoute convert2Storage(Route route) {
|
||||
StorageRoute storageRoute = new StorageRoute(route.getCode());
|
||||
if (storageRoute.convert(route)) {
|
||||
return storageRoute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean convert(MapElement element) {
|
||||
boolean change = false;
|
||||
Route route = (Route) element;
|
||||
if (!route.isAtsControl()) {
|
||||
change = true;
|
||||
this.setAtsControl(route.isAtsControl());
|
||||
}
|
||||
if (route.isFleetMode()) {
|
||||
change = true;
|
||||
this.setFleetMode(route.isFleetMode());
|
||||
}
|
||||
if (route.isCiControl()) {
|
||||
change = true;
|
||||
this.setCiControl(route.isCiControl());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
change = true;
|
||||
this.setSetting(route.isSetting());
|
||||
this.setSettingStartTime(route.getSettingStartTime());
|
||||
}
|
||||
if (route.isGuideSetting()) {
|
||||
change = true;
|
||||
this.setSettingGuide(route.isGuideSetting());
|
||||
}
|
||||
if (route.isLock()) {
|
||||
change = true;
|
||||
this.setLock(route.isLock());
|
||||
}
|
||||
if (route.getDelayUnlockDevice() != null) {
|
||||
change = true;
|
||||
this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode());
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
change = true;
|
||||
this.setNormalUnlock(route.isNormalUnlock());
|
||||
}
|
||||
if (Objects.nonNull(route.getUnlockedSection())) {
|
||||
change = true;
|
||||
this.setUnlockedSection(route.getUnlockedSection().getCode());
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.data.storage.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class StorageRoute extends StorageDevice {
|
||||
|
||||
/**
|
||||
* 是否CBTC模式
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean cbtcMode;
|
||||
|
||||
/**
|
||||
* ats自动控制
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean atsControl;
|
||||
|
||||
/**
|
||||
* 连续通过进路模式(联锁自动进路)开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean fleetMode;
|
||||
|
||||
/**
|
||||
* 自动追踪/联锁自动触发模式开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean ciControl;
|
||||
|
||||
/**
|
||||
* 进路是否排列中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean setting;
|
||||
|
||||
private LocalDateTime settingStartTime;
|
||||
|
||||
/**
|
||||
* 是否引导进路排列
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean settingGuide;
|
||||
|
||||
/**
|
||||
* 进路是否锁闭
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean lock;
|
||||
|
||||
/** 进路延时解锁设备 */
|
||||
private String delayUnlockDevice;
|
||||
|
||||
/**
|
||||
* 是否正常解锁中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean normalUnlock;
|
||||
|
||||
private String unlockedSection;
|
||||
|
||||
/**
|
||||
* 该进路办理成功后要开放的信号
|
||||
* <p>
|
||||
* 注意:每次开始触发办理进路时设置
|
||||
*/
|
||||
private SignalAspect settedAspect;
|
||||
|
||||
// public StorageRoute(Route route) {
|
||||
// super(route.getCode());
|
||||
// cbtcMode = route.isCbtcMode();
|
||||
// turnBackMode = route.isTurnBackMode();
|
||||
// atsControl = route.isAtsControl();
|
||||
// fleetMode = route.isFleetMode();
|
||||
// ciControl = route.isCiControl();
|
||||
// setting = route.isSetting();
|
||||
// settingGuide = route.isSettingGuide();
|
||||
// lock = route.isLock();
|
||||
// canceling = route.isCanceling();
|
||||
// normalUnlock = route.isNormalUnlock();
|
||||
// }
|
||||
|
||||
public StorageRoute(String code) {
|
||||
super(code);
|
||||
}
|
||||
|
||||
public static StorageRoute convert2Storage(Route route) {
|
||||
StorageRoute storageRoute = new StorageRoute(route.getCode());
|
||||
if (storageRoute.convert(route)) {
|
||||
return storageRoute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean convert(MapElement element) {
|
||||
boolean change = false;
|
||||
Route route = (Route) element;
|
||||
if (!route.isAtsControl()) {
|
||||
change = true;
|
||||
this.setAtsControl(route.isAtsControl());
|
||||
}
|
||||
if (route.isFleetMode()) {
|
||||
change = true;
|
||||
this.setFleetMode(route.isFleetMode());
|
||||
}
|
||||
if (route.isCiControl()) {
|
||||
change = true;
|
||||
this.setCiControl(route.isCiControl());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
change = true;
|
||||
this.setSetting(route.isSetting());
|
||||
this.setSettingStartTime(route.getSettingStartTime());
|
||||
}
|
||||
if (route.isGuideSetting()) {
|
||||
change = true;
|
||||
this.setSettingGuide(route.isGuideSetting());
|
||||
}
|
||||
if (route.isLock()) {
|
||||
change = true;
|
||||
this.setLock(route.isLock());
|
||||
}
|
||||
if (route.getDelayUnlockDevice() != null) {
|
||||
change = true;
|
||||
this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode());
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
change = true;
|
||||
this.setNormalUnlock(route.isNormalUnlock());
|
||||
}
|
||||
if (Objects.nonNull(route.getUnlockedSection())) {
|
||||
change = true;
|
||||
this.setUnlockedSection(route.getUnlockedSection().getCode());
|
||||
}
|
||||
if (Objects.nonNull(route.getSettedAspect())) {
|
||||
change = true;
|
||||
this.setSettedAspect(route.getSettedAspect());
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,236 +1,236 @@
|
||||
package club.joylink.rtss.simulation.cbtc.depot;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
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.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class DepotService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService ciRouteService;
|
||||
|
||||
@Autowired
|
||||
private TrainOutboundLoadTool trainOutboundLoadTool;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationService groupSimulationService;
|
||||
|
||||
@Autowired
|
||||
private ATPService atpService;
|
||||
|
||||
public void loadDepotTrain(Simulation simulation) {
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
return;
|
||||
}
|
||||
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
|
||||
simulation.getRepository().getAllVrTrain().stream()
|
||||
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
|
||||
.forEach((station, trainList) -> {
|
||||
List<Section> sections = parkingTracksMap.get(station);
|
||||
// 先加载内侧的停车轨
|
||||
sections.sort(Comparator.comparing(section ->
|
||||
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
|
||||
boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
|
||||
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
|
||||
VirtualRealityTrain train = trainList.get(i);
|
||||
Section section = sections.get(i);
|
||||
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
|
||||
train.parkingAt(section);
|
||||
train.initAsRM();
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
simulation.getRepository().addOnlineTrain(train);
|
||||
simulation.getRepository().addTrainInfo(trainInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
|
||||
}
|
||||
|
||||
private void run(Simulation simulation) {
|
||||
if (!simulation.isPlanRunning()) {
|
||||
return;
|
||||
}
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
trainOutboundLoadTool.loadOutboundTrain(simulation);
|
||||
} else {
|
||||
timeToDeparture(simulation);
|
||||
backToParking(simulation);
|
||||
settingRouteAndMoving(simulation);
|
||||
arriveDestination(simulation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间筛选,从停车轨自动发车
|
||||
*/
|
||||
private void timeToDeparture(Simulation simulation) {
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
|
||||
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
|
||||
continue;
|
||||
}
|
||||
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
|
||||
schedulingTrainPlan.getOutDepotTrip().dispatched();
|
||||
// 保存信息
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class);
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection();
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选入库
|
||||
*/
|
||||
private void backToParking(Simulation simulation) {
|
||||
for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) {
|
||||
if (trainInfo.isInbound() && trainInfo.isParking()) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class);
|
||||
if (train.getHeadPosition().getSection().isTransferTrack()
|
||||
&& train.getTailPosition().getSection().isTransferTrack()) {
|
||||
if (simulation.getRepository().getDepotRunningInfoList().stream()
|
||||
.anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) {
|
||||
continue;
|
||||
}
|
||||
train.initAsRM();
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = null;
|
||||
for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) {
|
||||
if (section.isOccupied()) {
|
||||
continue;
|
||||
}
|
||||
if (section.getLeftSection() == null || section.getRightSection() == null) {
|
||||
endSection = section;
|
||||
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
|
||||
endSection = section.getLeftSection();
|
||||
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
|
||||
endSection = section.getRightSection();
|
||||
} else {
|
||||
endSection = section;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// train.setTarget(endSection);
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
if (routePaths == null || routePaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车排进路并运行
|
||||
*/
|
||||
private void settingRouteAndMoving(Simulation simulation) {
|
||||
for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) {
|
||||
Section endSection = depotRunningInfo.getEndSection();
|
||||
SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight()));
|
||||
depotRunningInfo.getTrain().setRobotTargetPosition(position);
|
||||
if (!depotRunningInfo.getRouteList().isEmpty()) {
|
||||
Route route = depotRunningInfo.getRouteList().get(0);
|
||||
if (route.isLock()) {
|
||||
depotRunningInfo.getRouteList().remove(0);
|
||||
}
|
||||
if (!route.isSetting()) {
|
||||
ciRouteService.setRoute(simulation, route);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断运行列车是否到达转换轨并升级
|
||||
*/
|
||||
private void arriveDestination(Simulation simulation) {
|
||||
for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) {
|
||||
DepotRunningInfo depotRunningInfo = iterator.next();
|
||||
VirtualRealityTrain train = depotRunningInfo.getTrain();
|
||||
if (depotRunningInfo.isArrival()) {
|
||||
// 到达
|
||||
iterator.remove();
|
||||
if (depotRunningInfo.in) {
|
||||
atpService.turnDirectionImmediately(train);
|
||||
} else {
|
||||
// 升级
|
||||
SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER);
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("preselectionMode", "AM_C");
|
||||
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
|
||||
member.getId(), param);
|
||||
groupSimulationService.command(simulation, commandInitiateVO, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DepotRunningInfo {
|
||||
|
||||
private final List<Route> routeList = new ArrayList<>();
|
||||
|
||||
private final Section endSection;
|
||||
|
||||
private final VirtualRealityTrain train;
|
||||
|
||||
private final Boolean right;
|
||||
|
||||
private final Boolean in;
|
||||
|
||||
public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) {
|
||||
this.endSection = endSection;
|
||||
this.train = train;
|
||||
for (Signal signal : routePath.getSignalList()) {
|
||||
for (Route route : signal.getRouteList()) {
|
||||
if (routePath.getRouteList().contains(route)) {
|
||||
routeList.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.right = routePath.isRight();
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
// 列车是否到达终点
|
||||
public boolean isArrival() {
|
||||
return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection)
|
||||
&& train.getTailPosition().getSection().equals(endSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.depot;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
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.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class DepotService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService ciRouteService;
|
||||
|
||||
@Autowired
|
||||
private TrainOutboundLoadTool trainOutboundLoadTool;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationService groupSimulationService;
|
||||
|
||||
@Autowired
|
||||
private ATPService atpService;
|
||||
|
||||
public void loadDepotTrain(Simulation simulation) {
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
return;
|
||||
}
|
||||
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
|
||||
simulation.getRepository().getAllVrTrain().stream()
|
||||
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
|
||||
.forEach((station, trainList) -> {
|
||||
List<Section> sections = parkingTracksMap.get(station);
|
||||
// 先加载内侧的停车轨
|
||||
sections.sort(Comparator.comparing(section ->
|
||||
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
|
||||
boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
|
||||
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
|
||||
VirtualRealityTrain train = trainList.get(i);
|
||||
Section section = sections.get(i);
|
||||
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
|
||||
train.parkingAt(section);
|
||||
train.initAsRM();
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
simulation.getRepository().addOnlineTrain(train);
|
||||
simulation.getRepository().addTrainInfo(trainInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
|
||||
}
|
||||
|
||||
private void run(Simulation simulation) {
|
||||
if (!simulation.isPlanRunning()) {
|
||||
return;
|
||||
}
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
trainOutboundLoadTool.loadOutboundTrain(simulation);
|
||||
} else {
|
||||
timeToDeparture(simulation);
|
||||
backToParking(simulation);
|
||||
settingRouteAndMoving(simulation);
|
||||
arriveDestination(simulation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间筛选,从停车轨自动发车
|
||||
*/
|
||||
private void timeToDeparture(Simulation simulation) {
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
|
||||
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
|
||||
continue;
|
||||
}
|
||||
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
|
||||
schedulingTrainPlan.getOutDepotTrip().dispatched();
|
||||
// 保存信息
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class);
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection();
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选入库
|
||||
*/
|
||||
private void backToParking(Simulation simulation) {
|
||||
for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) {
|
||||
if (trainInfo.isInbound() && trainInfo.isParking()) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class);
|
||||
if (train.getHeadPosition().getSection().isTransferTrack()
|
||||
&& train.getTailPosition().getSection().isTransferTrack()) {
|
||||
if (simulation.getRepository().getDepotRunningInfoList().stream()
|
||||
.anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) {
|
||||
continue;
|
||||
}
|
||||
train.initAsRM();
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = null;
|
||||
for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) {
|
||||
if (section.isOccupied()) {
|
||||
continue;
|
||||
}
|
||||
if (section.getLeftSection() == null || section.getRightSection() == null) {
|
||||
endSection = section;
|
||||
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
|
||||
endSection = section.getLeftSection();
|
||||
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
|
||||
endSection = section.getRightSection();
|
||||
} else {
|
||||
endSection = section;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// train.setTarget(endSection);
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
if (routePaths == null || routePaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车排进路并运行
|
||||
*/
|
||||
private void settingRouteAndMoving(Simulation simulation) {
|
||||
for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) {
|
||||
Section endSection = depotRunningInfo.getEndSection();
|
||||
SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight()));
|
||||
depotRunningInfo.getTrain().setRobotTargetPosition(position);
|
||||
if (!depotRunningInfo.getRouteList().isEmpty()) {
|
||||
Route route = depotRunningInfo.getRouteList().get(0);
|
||||
if (route.isLock()) {
|
||||
depotRunningInfo.getRouteList().remove(0);
|
||||
}
|
||||
if (!route.isSetting()) {
|
||||
ciRouteService.setRoute(simulation, route,route.getAspect());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断运行列车是否到达转换轨并升级
|
||||
*/
|
||||
private void arriveDestination(Simulation simulation) {
|
||||
for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) {
|
||||
DepotRunningInfo depotRunningInfo = iterator.next();
|
||||
VirtualRealityTrain train = depotRunningInfo.getTrain();
|
||||
if (depotRunningInfo.isArrival()) {
|
||||
// 到达
|
||||
iterator.remove();
|
||||
if (depotRunningInfo.in) {
|
||||
atpService.turnDirectionImmediately(train);
|
||||
} else {
|
||||
// 升级
|
||||
SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER);
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("preselectionMode", "AM_C");
|
||||
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
|
||||
member.getId(), param);
|
||||
groupSimulationService.command(simulation, commandInitiateVO, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DepotRunningInfo {
|
||||
|
||||
private final List<Route> routeList = new ArrayList<>();
|
||||
|
||||
private final Section endSection;
|
||||
|
||||
private final VirtualRealityTrain train;
|
||||
|
||||
private final Boolean right;
|
||||
|
||||
private final Boolean in;
|
||||
|
||||
public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) {
|
||||
this.endSection = endSection;
|
||||
this.train = train;
|
||||
for (Signal signal : routePath.getSignalList()) {
|
||||
for (Route route : signal.getRouteList()) {
|
||||
if (routePath.getRouteList().contains(route)) {
|
||||
routeList.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.right = routePath.isRight();
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
// 列车是否到达终点
|
||||
public boolean isArrival() {
|
||||
return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection)
|
||||
&& train.getTailPosition().getSection().equals(endSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -530,7 +530,7 @@ public class ATPService {
|
||||
public void inbound(Simulation simulation, String groupNumber) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber);
|
||||
Section headSection = train.getHeadPosition().getSection();
|
||||
if (headSection.isTransferTrack() && train.isStop()) { //列车停在折返轨
|
||||
if (headSection.isTurnBackTrack() && train.isStop()) { //列车停在折返轨
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
|
||||
List<RoutePath> routePathList = repository.queryRoutePathsByEnd(headSection);
|
||||
@ -624,6 +624,7 @@ public class ATPService {
|
||||
}
|
||||
}
|
||||
} else if (trainMode.isMatchTheDriveMode(DriveMode.AM) && !train.isAMMode()) {
|
||||
train.getRobotDriveParam().setRun(false); // 关闭机器人自动驾驶
|
||||
if (!train.isInTheGear(VirtualRealityTrain.Handwheel.ATO)) {
|
||||
this.changeGear(train, VirtualRealityTrain.Handwheel.ATO);
|
||||
}
|
||||
|
@ -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.command.CommandBO;
|
||||
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.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
@ -436,13 +437,31 @@ public class SimulationRobotService {
|
||||
*/
|
||||
private void robotDrive(Simulation simulation, VirtualRealityTrain train, SectionPosition targetPosition) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock()) { //如果车门没关
|
||||
return;
|
||||
}
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
boolean right = train.isRight();
|
||||
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);
|
||||
if (distance == null || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置
|
||||
atoService.doBreakMax(train);
|
||||
|
@ -1,306 +1,307 @@
|
||||
package club.joylink.rtss.simulation.cbtc.tool;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
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.VirtualRealitySwitch;
|
||||
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.VirtualRealityDeviceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 设备状态修改工具(有动作设备不需要动作过程可直接设置为想要的状态)
|
||||
* warn:此工具类只在加载列车或实训生成场景使用,正常仿真过程请勿使用
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DeviceStatusModifyTool {
|
||||
@Autowired
|
||||
private VirtualRealityDeviceService virtualRealityDeviceService;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private AtsTrainLoadService atsTrainLoadService;
|
||||
@Autowired
|
||||
private VRTrainRunningService vrTrainRunningService;
|
||||
|
||||
/**
|
||||
* 直接开放进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void openRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
if (route.isSettingOverlap()) {
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
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());
|
||||
route.getOverlap().setLock(true);
|
||||
}
|
||||
}
|
||||
route.setNormalUnlock(false);
|
||||
route.setLock(true);
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
this.openSignalDirectly(route.getStart(), route.getAspect());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
List<SwitchElement> switchElementList = new ArrayList<>();
|
||||
for (RouteFls routeFls : flsList) {
|
||||
for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) {
|
||||
SwitchElement pSwitch = flsElement.getPSwitch();
|
||||
if (pSwitch != null) {
|
||||
switchElementList.add(pSwitch);
|
||||
} else if (flsElement.getFpae() != null) {
|
||||
switchElementList.add(flsElement.getFpae());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SwitchElement switchElement : switchElementList) {
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
switchElement.getASwitch().fpLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openGuideRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
}
|
||||
route.setLock(true);
|
||||
this.openGuideSignalDirectly(route.getStart());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
public void openGuideSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect();
|
||||
virtualSignal.control(guideAspect);
|
||||
virtualSignal.finish();
|
||||
signal.changeLightType(false);
|
||||
signal.setAspect(guideAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接开灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
* @param aspect
|
||||
*/
|
||||
private void openSignalDirectly(Signal signal, SignalAspect aspect) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
if (virtualSignal != null) {
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(aspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
}
|
||||
signal.setAspect(aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接关灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
*/
|
||||
public void closeSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect();
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(defaultAspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
signal.setAspect(defaultAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置进路道岔位置并锁闭
|
||||
*
|
||||
* @param route
|
||||
* @param switchList
|
||||
* @param routeLock
|
||||
*/
|
||||
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) {
|
||||
if (!CollectionUtils.isEmpty(switchList)) {
|
||||
for (SwitchElement switchElement : switchList) {
|
||||
// if (switchElement.getASwitch().isOverlapLock() &&
|
||||
// switchElement.isOnPosition()) {
|
||||
// continue;
|
||||
// }
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
if (routeLock) {
|
||||
switchElement.getASwitch().routeLock(route);
|
||||
} else { // 延续保护锁闭
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把单个道岔转到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) {
|
||||
VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch();
|
||||
if (normal) {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.N);
|
||||
} else {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.R);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把道岔及其联动道岔转动到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch, boolean normal) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
this.setSingleSwitchPositionDirectly(aSwitch, normal);
|
||||
Switch linkedSwitch = aSwitch.queryLinkedSwitch();
|
||||
if (Objects.nonNull(linkedSwitch)) {
|
||||
this.setSingleSwitchPositionDirectly(linkedSwitch, normal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接根据最后一根区段解锁进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void routeUnlockByEndSection(Route route, Section tailSection) {
|
||||
if (!route.isRouteSection(tailSection)) {
|
||||
// 不是进路区段,不解锁
|
||||
return;
|
||||
}
|
||||
route.startNormalUnlock();
|
||||
// 关闭始端信号机
|
||||
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
|
||||
boolean right = route.getStart().isRight();
|
||||
// 区段是顺序的(否则会有问题)
|
||||
List<Section> sectionList = route.getSectionList();
|
||||
for (Section section : sectionList) {
|
||||
if (section.isSamePhysical(tailSection.getCode())) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
// 直接解锁区段
|
||||
if (section.isSwitchTrack()) { // 如果是道岔区段,解锁道岔
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
if (section.getParent() != null && section.getParent().isCross()) {
|
||||
section.getParent().routeUnlocking(route);
|
||||
}
|
||||
relSwitch.routeUnlock(route);
|
||||
relSwitch.overlapUnLock();
|
||||
// 侧防解锁
|
||||
route.unlockRouteFlsOfSwitch(relSwitch);
|
||||
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
|
||||
for (SwitchElement switchElement : route.getSwitchList()) {
|
||||
if (switchElement.getASwitch().equals(relSwitch)) {
|
||||
continue;
|
||||
}
|
||||
Switch aSwitch = switchElement.getASwitch();
|
||||
if (route.isRouteSection(aSwitch.getA())) {
|
||||
continue;
|
||||
}
|
||||
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
|
||||
if (!aSwitch.getA().isRouteLock()) {
|
||||
aSwitch.routeUnlock(route);
|
||||
aSwitch.overlapUnLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.routeUnlocking(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section, boolean right) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!section.isPhysical()) {
|
||||
section = section.getParent();
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
|
||||
//重叠检测
|
||||
SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
|
||||
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||
// 列车上线并构建ATS监控列车信息
|
||||
train.initManualTrain(headPosition, right);
|
||||
//设置列车预选模式、驾驶模式、运行级别
|
||||
if (!headPosition.getSection().anyZcWorking()) {
|
||||
train.initAsRM();
|
||||
} else {
|
||||
MapConfig config = repository.getConfig();
|
||||
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||
train.initAsAM_I();
|
||||
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||
train.initAsRM();
|
||||
}
|
||||
}
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
repository.addOnlineTrain(train);
|
||||
repository.addTrainInfo(trainInfo);
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.tool;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
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.VirtualRealitySwitch;
|
||||
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.VirtualRealityDeviceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 设备状态修改工具(有动作设备不需要动作过程可直接设置为想要的状态)
|
||||
* warn:此工具类只在加载列车或实训生成场景使用,正常仿真过程请勿使用
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DeviceStatusModifyTool {
|
||||
@Autowired
|
||||
private VirtualRealityDeviceService virtualRealityDeviceService;
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
@Autowired
|
||||
private AtsTrainLoadService atsTrainLoadService;
|
||||
@Autowired
|
||||
private VRTrainRunningService vrTrainRunningService;
|
||||
|
||||
/**
|
||||
* 直接开放进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void openRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
if (route.isSettingOverlap()) {
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
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());
|
||||
route.getOverlap().setLock(true);
|
||||
}
|
||||
}
|
||||
route.setNormalUnlock(false);
|
||||
route.setLock(true);
|
||||
route.setSettedAspect(route.getAspect());
|
||||
simulation.getRepository().addSettingRoute(route);
|
||||
this.openSignalDirectly(route.getStart(), route.getSettedAspect());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
private void batchSetRouteFlsSwitchPositionAndLock(List<RouteFls> flsList) {
|
||||
if (!CollectionUtils.isEmpty(flsList)) {
|
||||
List<SwitchElement> switchElementList = new ArrayList<>();
|
||||
for (RouteFls routeFls : flsList) {
|
||||
for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) {
|
||||
SwitchElement pSwitch = flsElement.getPSwitch();
|
||||
if (pSwitch != null) {
|
||||
switchElementList.add(pSwitch);
|
||||
} else if (flsElement.getFpae() != null) {
|
||||
switchElementList.add(flsElement.getFpae());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SwitchElement switchElement : switchElementList) {
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
switchElement.getASwitch().fpLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openGuideRouteDirect(Simulation simulation, Route route) {
|
||||
// 修改进路涉及的所有道岔元素到指定位置
|
||||
this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true);
|
||||
// 修改进路侧防到指定位置
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList());
|
||||
// 进路元素锁闭
|
||||
route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight()));
|
||||
SectionPath overlapPath = route.selectOverlapElement();
|
||||
if (Objects.nonNull(overlapPath)) {
|
||||
this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false);
|
||||
this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList());
|
||||
overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight()));
|
||||
}
|
||||
route.setLock(true);
|
||||
this.openGuideSignalDirectly(route.getStart());
|
||||
route.getStart().setLockedRoute(route);
|
||||
}
|
||||
|
||||
public void openGuideSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
SignalAspect guideAspect = virtualSignal.getModel().getGuideAspect();
|
||||
virtualSignal.control(guideAspect);
|
||||
virtualSignal.finish();
|
||||
signal.changeLightType(false);
|
||||
signal.setAspect(guideAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接开灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
* @param aspect
|
||||
*/
|
||||
private void openSignalDirectly(Signal signal, SignalAspect aspect) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
if (virtualSignal != null) {
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(aspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
}
|
||||
signal.setAspect(aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接关灯(默认逻辑点灯)
|
||||
*
|
||||
* @param signal
|
||||
*/
|
||||
public void closeSignalDirectly(Signal signal) {
|
||||
VirtualRealitySignal virtualSignal = signal.getVirtualSignal();
|
||||
signal.changeLightType(true);
|
||||
SignalAspect defaultAspect = virtualSignal.getModel().getDefaultAspect();
|
||||
if (signal.isLogicLight()) {
|
||||
virtualSignal.control(SignalAspect.No);
|
||||
} else {
|
||||
virtualSignal.control(defaultAspect);
|
||||
}
|
||||
virtualSignal.finish();
|
||||
signal.setAspect(defaultAspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置进路道岔位置并锁闭
|
||||
*
|
||||
* @param route
|
||||
* @param switchList
|
||||
* @param routeLock
|
||||
*/
|
||||
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) {
|
||||
if (!CollectionUtils.isEmpty(switchList)) {
|
||||
for (SwitchElement switchElement : switchList) {
|
||||
// if (switchElement.getASwitch().isOverlapLock() &&
|
||||
// switchElement.isOnPosition()) {
|
||||
// continue;
|
||||
// }
|
||||
// switchElement.getASwitch().ciUse(switchElement.isNormal());
|
||||
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
|
||||
if (routeLock) {
|
||||
switchElement.getASwitch().routeLock(route);
|
||||
} else { // 延续保护锁闭
|
||||
switchElement.getASwitch().overlapLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把单个道岔转到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) {
|
||||
VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch();
|
||||
if (normal) {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.N);
|
||||
} else {
|
||||
virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
|
||||
virtualSwitch.finish();
|
||||
aSwitch.setPos(SwitchIndication.R);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接把道岔及其联动道岔转动到指定位置
|
||||
*
|
||||
* @param aSwitch
|
||||
* @param normal
|
||||
*/
|
||||
public void setCoupleSwitchPositionDirectly(Simulation simulation, Switch aSwitch, boolean normal) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
this.setSingleSwitchPositionDirectly(aSwitch, normal);
|
||||
Switch linkedSwitch = aSwitch.queryLinkedSwitch();
|
||||
if (Objects.nonNull(linkedSwitch)) {
|
||||
this.setSingleSwitchPositionDirectly(linkedSwitch, normal);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接根据最后一根区段解锁进路
|
||||
*
|
||||
* @param route
|
||||
*/
|
||||
public void routeUnlockByEndSection(Route route, Section tailSection) {
|
||||
if (!route.isRouteSection(tailSection)) {
|
||||
// 不是进路区段,不解锁
|
||||
return;
|
||||
}
|
||||
route.startNormalUnlock();
|
||||
// 关闭始端信号机
|
||||
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
|
||||
boolean right = route.getStart().isRight();
|
||||
// 区段是顺序的(否则会有问题)
|
||||
List<Section> sectionList = route.getSectionList();
|
||||
for (Section section : sectionList) {
|
||||
if (section.isSamePhysical(tailSection.getCode())) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
// 直接解锁区段
|
||||
if (section.isSwitchTrack()) { // 如果是道岔区段,解锁道岔
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
|
||||
route.updateUnlockedSection(tailSection);
|
||||
break;
|
||||
}
|
||||
if (section.getParent() != null && section.getParent().isCross()) {
|
||||
section.getParent().routeUnlocking(route);
|
||||
}
|
||||
relSwitch.routeUnlock(route);
|
||||
relSwitch.overlapUnLock();
|
||||
// 侧防解锁
|
||||
route.unlockRouteFlsOfSwitch(relSwitch);
|
||||
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
|
||||
for (SwitchElement switchElement : route.getSwitchList()) {
|
||||
if (switchElement.getASwitch().equals(relSwitch)) {
|
||||
continue;
|
||||
}
|
||||
Switch aSwitch = switchElement.getASwitch();
|
||||
if (route.isRouteSection(aSwitch.getA())) {
|
||||
continue;
|
||||
}
|
||||
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
|
||||
if (!aSwitch.getA().isRouteLock()) {
|
||||
aSwitch.routeUnlock(route);
|
||||
aSwitch.overlapUnLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.routeUnlocking(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadManualTrainOfGroup(Simulation simulation, String groupNumber, Section section, boolean right) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
if (!section.isPhysical()) {
|
||||
section = section.getParent();
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
|
||||
//重叠检测
|
||||
SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
|
||||
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||
// 列车上线并构建ATS监控列车信息
|
||||
train.initManualTrain(headPosition, right);
|
||||
//设置列车预选模式、驾驶模式、运行级别
|
||||
if (!headPosition.getSection().anyZcWorking()) {
|
||||
train.initAsRM();
|
||||
} else {
|
||||
MapConfig config = repository.getConfig();
|
||||
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||
train.initAsAM_I();
|
||||
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||
train.initAsRM();
|
||||
}
|
||||
}
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
repository.addOnlineTrain(train);
|
||||
repository.addTrainInfo(trainInfo);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,11 @@ public class MapSignalButtonVO {
|
||||
*/
|
||||
private DirectionLabelEnum labelEnum;
|
||||
|
||||
/**
|
||||
* 有计数器?
|
||||
*/
|
||||
private boolean hasCount;
|
||||
|
||||
public enum Type {
|
||||
/**
|
||||
* 接车按钮
|
||||
|
@ -1,208 +1,208 @@
|
||||
server:
|
||||
port: 9000
|
||||
|
||||
modbus-tcp:
|
||||
port: 19000
|
||||
|
||||
udp:
|
||||
serverPort: 20002
|
||||
clientPort: 20001
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
application:
|
||||
name: joylink-rtss
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
time-zone: GMT+8
|
||||
default-property-inclusion: non_null
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
# JavaMailSender 邮件发送的配置
|
||||
mail:
|
||||
host: smtp.exmail.qq.com
|
||||
port: 465
|
||||
username: ServiceEmail@joylink.club
|
||||
password: wFHcZQFuigKPvpSr
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
socketFactory:
|
||||
port: 465
|
||||
class: javax.net.ssl.SSLSocketFactory
|
||||
fallback: false
|
||||
datasource:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
minimum-idle: 5 # 连接池维护的最小空闲连接数
|
||||
maximum-pool-size: 10 #配置最大连接池大小
|
||||
auto-commit: true #配置从池返回的连接的默认自动提交行为
|
||||
idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间,单位ms
|
||||
pool-name: HikariPool
|
||||
max-lifetime: 1800000 # 池中连接关闭后的最长生命周期,单位ms
|
||||
connection-timeout: 30000 # 等待连接的超时时间,单位ms
|
||||
mybatis:
|
||||
mapper-locations: classpath:mybatis/mapper/*.xml
|
||||
type-aliases-package: club.joylink.rtss.entity
|
||||
|
||||
pagehelper:
|
||||
helper-dialect: mysql
|
||||
reasonable: true
|
||||
support-methods-arguments: true
|
||||
params: count=countSql
|
||||
|
||||
wechat:
|
||||
app-id: wx41cb66db5faf330f
|
||||
app-secret: eb7199c1e73417be6a4d38b4a848effb
|
||||
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
|
||||
sp-app-id: wxe9150dbbcbf9440b
|
||||
sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
|
||||
sp-app2-id: wxecb0321367be529c
|
||||
sp-app2-secret: 3c31cb41588f27a78160092249123766
|
||||
sp-app3-id: wxe6140d5985333338
|
||||
sp-app3-secret: 6b7359860c22e3607467df421cd24eef
|
||||
wm-base-url: https://joylink.club/oss/joylink/%s?state=%s
|
||||
wx-module-url: http://localhost:9001
|
||||
mini:
|
||||
access-token-task-on: false
|
||||
app-id: wxe9150dbbcbf9440b
|
||||
app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
|
||||
|
||||
tencent-cloud:
|
||||
app-id: 1400093601
|
||||
app-key: 4a724df65b2bb7e4dc9b4302693f2485
|
||||
domain-uri: https://yun.tim.qq.com/v5/tlssmssvr
|
||||
allow-send: true
|
||||
|
||||
common:
|
||||
env: dev
|
||||
|
||||
#修改swgger接口前缀,默认为/v2/api-docs
|
||||
springfox:
|
||||
documentation:
|
||||
swagger:
|
||||
v2:
|
||||
path: /swagger/api-docs
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: dev
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /logs/joylink/rtss
|
||||
max-size: 100MB
|
||||
level:
|
||||
club.joylink.rtss: DEBUG
|
||||
|
||||
common:
|
||||
env: dev
|
||||
license-secret-key: joylink
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: test
|
||||
datasource:
|
||||
url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: Joylink@0503
|
||||
|
||||
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-module-url: https://joylink.club/jlwxs
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: test
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: local-test
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: joylink0503
|
||||
|
||||
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-module-url: https://joylink.club/jlwxs
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: test
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: prd
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: joylink@0503
|
||||
wechat:
|
||||
app-id: wx41cb66db5faf330f
|
||||
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-module-url: http://172.21.0.4:9001
|
||||
mini:
|
||||
access-token-task-on: true
|
||||
|
||||
file:
|
||||
path: https://joylink.club/jlfile/api/upload/joylink/avatar
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: prd
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: local
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.3.233:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: joylink0503
|
||||
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: local
|
||||
license-secret-key: joylink
|
||||
server:
|
||||
port: 9000
|
||||
|
||||
modbus-tcp:
|
||||
port: 19000
|
||||
|
||||
udp:
|
||||
serverPort: 20002
|
||||
clientPort: 20001
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
application:
|
||||
name: joylink-rtss
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
time-zone: GMT+8
|
||||
default-property-inclusion: non_null
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
# JavaMailSender 邮件发送的配置
|
||||
mail:
|
||||
host: smtp.exmail.qq.com
|
||||
port: 465
|
||||
username: ServiceEmail@joylink.club
|
||||
password: wFHcZQFuigKPvpSr
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
auth: true
|
||||
starttls:
|
||||
enable: true
|
||||
required: true
|
||||
socketFactory:
|
||||
port: 465
|
||||
class: javax.net.ssl.SSLSocketFactory
|
||||
fallback: false
|
||||
datasource:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
minimum-idle: 5 # 连接池维护的最小空闲连接数
|
||||
maximum-pool-size: 10 #配置最大连接池大小
|
||||
auto-commit: true #配置从池返回的连接的默认自动提交行为
|
||||
idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间,单位ms
|
||||
pool-name: HikariPool
|
||||
max-lifetime: 1800000 # 池中连接关闭后的最长生命周期,单位ms
|
||||
connection-timeout: 30000 # 等待连接的超时时间,单位ms
|
||||
mybatis:
|
||||
mapper-locations: classpath:mybatis/mapper/*.xml
|
||||
type-aliases-package: club.joylink.rtss.entity
|
||||
|
||||
pagehelper:
|
||||
helper-dialect: mysql
|
||||
reasonable: true
|
||||
support-methods-arguments: true
|
||||
params: count=countSql
|
||||
|
||||
wechat:
|
||||
app-id: wx41cb66db5faf330f
|
||||
app-secret: eb7199c1e73417be6a4d38b4a848effb
|
||||
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
|
||||
sp-app-id: wxe9150dbbcbf9440b
|
||||
sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
|
||||
sp-app2-id: wxecb0321367be529c
|
||||
sp-app2-secret: 3c31cb41588f27a78160092249123766
|
||||
sp-app3-id: wxe6140d5985333338
|
||||
sp-app3-secret: 6b7359860c22e3607467df421cd24eef
|
||||
wm-base-url: https://joylink.club/oss/joylink/%s?state=%s
|
||||
wx-module-url: http://localhost:9001
|
||||
mini:
|
||||
access-token-task-on: false
|
||||
app-id: wxe9150dbbcbf9440b
|
||||
app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
|
||||
|
||||
tencent-cloud:
|
||||
app-id: 1400093601
|
||||
app-key: 4a724df65b2bb7e4dc9b4302693f2485
|
||||
domain-uri: https://yun.tim.qq.com/v5/tlssmssvr
|
||||
allow-send: true
|
||||
|
||||
common:
|
||||
env: dev
|
||||
|
||||
#修改swgger接口前缀,默认为/v2/api-docs
|
||||
springfox:
|
||||
documentation:
|
||||
swagger:
|
||||
v2:
|
||||
path: /swagger/api-docs
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: dev
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.3.233:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: joylink0503
|
||||
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /logs/joylink/rtss
|
||||
max-size: 100MB
|
||||
level:
|
||||
club.joylink.rtss: DEBUG
|
||||
|
||||
common:
|
||||
env: dev
|
||||
license-secret-key: joylink
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: test
|
||||
datasource:
|
||||
url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: Joylink@0503
|
||||
|
||||
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-module-url: https://joylink.club/jlwxs
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: test
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: local-test
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: joylink0503
|
||||
|
||||
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-module-url: https://joylink.club/jlwxs
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: test
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: prd
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai
|
||||
username: root
|
||||
password: joylink@0503
|
||||
wechat:
|
||||
app-id: wx41cb66db5faf330f
|
||||
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-module-url: http://172.21.0.4:9001
|
||||
mini:
|
||||
access-token-task-on: true
|
||||
|
||||
file:
|
||||
path: https://joylink.club/jlfile/api/upload/joylink/avatar
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: prd
|
||||
|
||||
---
|
||||
spring:
|
||||
profiles: local
|
||||
datasource:
|
||||
url: jdbc:mysql://192.168.3.233:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: joylink0503
|
||||
|
||||
tencent-cloud:
|
||||
allow-send: false
|
||||
|
||||
logging:
|
||||
file:
|
||||
path: /usr/local/joylink/logs/rtss
|
||||
level:
|
||||
club.joylink.rtss: INFO
|
||||
|
||||
common:
|
||||
env: local
|
||||
license-secret-key: joylink
|
||||
|
Loading…
Reference in New Issue
Block a user