Merge remote-tracking branch 'origin/test' into test1
This commit is contained in:
commit
83d7238b11
@ -201,6 +201,7 @@ public class RoutingGenerator {
|
|||||||
start.getStation().getName(), start.getName(),
|
start.getStation().getName(), start.getName(),
|
||||||
end.getStation().getName(), end.getName());
|
end.getStation().getName(), end.getName());
|
||||||
if (pathsList.size() > 0) {
|
if (pathsList.size() > 0) {
|
||||||
|
List<Section> path = pathsList.get(0);
|
||||||
if (pathsList.size() > 1) {
|
if (pathsList.size() > 1) {
|
||||||
log.warn(String.format("从[%s]的交路找到超过一个路径", name));
|
log.warn(String.format("从[%s]的交路找到超过一个路径", name));
|
||||||
for (int i = 0; i < pathsList.size(); i++) {
|
for (int i = 0; i < pathsList.size(); i++) {
|
||||||
@ -210,7 +211,13 @@ public class RoutingGenerator {
|
|||||||
} else {
|
} else {
|
||||||
// 找到,构建
|
// 找到,构建
|
||||||
log.info(String.format("从[%s]的交路找到:[%s]",
|
log.info(String.format("从[%s]的交路找到:[%s]",
|
||||||
name, this.buildRoutingPathString(pathsList.get(0))));
|
name, this.buildRoutingPathString(path)));
|
||||||
|
}
|
||||||
|
if (path.size() == 2) {
|
||||||
|
if (!path.get(0).isNormalStandTrack() || !path.get(1).isNormalStandTrack()) {
|
||||||
|
log.info(String.format("从[%s]的交路不构建:交路至少包含两个车站站台轨", name));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String destinationCode = end.getDestinationCode();
|
String destinationCode = end.getDestinationCode();
|
||||||
Routing routing = new Routing(name, destinationCode);
|
Routing routing = new Routing(name, destinationCode);
|
||||||
@ -219,7 +226,7 @@ public class RoutingGenerator {
|
|||||||
routing.setEndStation(end.getStation());
|
routing.setEndStation(end.getStation());
|
||||||
routing.setEndSection(end);
|
routing.setEndSection(end);
|
||||||
routing.setRight(right);
|
routing.setRight(right);
|
||||||
routing.setViaSectionList(pathsList.get(0));
|
routing.setViaSectionList(path);
|
||||||
return routing;
|
return routing;
|
||||||
} else {
|
} else {
|
||||||
// 未找到
|
// 未找到
|
||||||
|
@ -975,10 +975,6 @@ public class GroupSimulationServiceImpl implements GroupSimulationService {
|
|||||||
if (Project.CGY.name().equals(mapDetail.getProjectCode())) { //成都工业所有资源免费
|
if (Project.CGY.name().equals(mapDetail.getProjectCode())) { //成都工业所有资源免费
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (userVO.getCompanyId() != null) {
|
|
||||||
String mapProject = mapDetail.getProjectCode();
|
|
||||||
return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject));
|
|
||||||
}
|
|
||||||
List<UserPermissionVO> ups = iUserPermissionService.getSimulationUserPermission(userVO, mapId, prdType);
|
List<UserPermissionVO> ups = iUserPermissionService.getSimulationUserPermission(userVO, mapId, prdType);
|
||||||
if (!CollectionUtils.isEmpty(ups)) {
|
if (!CollectionUtils.isEmpty(ups)) {
|
||||||
if (!MapPrdTypeEnum.JOINT.getCode().equals(prdType)) {
|
if (!MapPrdTypeEnum.JOINT.getCode().equals(prdType)) {
|
||||||
@ -989,6 +985,10 @@ public class GroupSimulationServiceImpl implements GroupSimulationService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (userVO.getCompanyId() != null) {
|
||||||
|
String mapProject = mapDetail.getProjectCode();
|
||||||
|
return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ATS逻辑
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class AtsLogicService {
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class AtsDevice {
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
public AtsDevice(String id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.simulation.SimulationRepository;
|
||||||
|
|
||||||
|
public class AtsRepository extends SimulationRepository {
|
||||||
|
public static final String NAME = "ATS";
|
||||||
|
|
||||||
|
AtsRunPlan runPlan;
|
||||||
|
|
||||||
|
public AtsRepository() {
|
||||||
|
super(NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initState() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public AtsRunPlan getRunPlan() {
|
||||||
|
return runPlan;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsRoute extends AtsDevice {
|
||||||
|
public AtsRoute(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class AtsRunPlan {
|
||||||
|
/**
|
||||||
|
* 服务下的服务车次计划
|
||||||
|
* key-服务号
|
||||||
|
* value-服务车次计划
|
||||||
|
*/
|
||||||
|
Map<String, List<AtsTripPlan>> serviceMap;
|
||||||
|
/**
|
||||||
|
* 发车轨道的服务车次计划
|
||||||
|
* key-区段id
|
||||||
|
* value-此区段发车的服务车次计划
|
||||||
|
*/
|
||||||
|
Map<String, List<AtsTripPlan>> endTripMap;
|
||||||
|
|
||||||
|
public AtsTripPlan queryNextTripPlanOfPlan(AtsTripPlan atsTripPlan) {
|
||||||
|
return this.queryNextTripPlanOfEnd(atsTripPlan.getEndSection().getId(), atsTripPlan.getEndTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AtsTripPlan queryNextTripPlanOfEnd(String endId, LocalTime time) {
|
||||||
|
List<AtsTripPlan> tripPlanList = this.endTripMap.get(endId);
|
||||||
|
AtsTripPlan next = null;
|
||||||
|
if (tripPlanList != null) {
|
||||||
|
// tripPlanList需要按时间从小到大排序
|
||||||
|
for (AtsTripPlan atsTripPlan : tripPlanList) {
|
||||||
|
if (!time.isAfter(atsTripPlan.getStartTime())) {
|
||||||
|
next = atsTripPlan;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsSection extends AtsDevice {
|
||||||
|
public AtsSection(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsSignal extends AtsDevice {
|
||||||
|
public AtsSignal(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsStand extends AtsDevice {
|
||||||
|
public AtsStand(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsStation extends AtsDevice {
|
||||||
|
public AtsStation(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class AtsStationPlan {
|
||||||
|
AtsStation station;
|
||||||
|
AtsSection section;
|
||||||
|
LocalTime arriveTime;// 到站时间
|
||||||
|
LocalTime leaveTime;// 出发时间
|
||||||
|
int parkTime;// 停靠时长
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsSwitch extends AtsDevice {
|
||||||
|
public AtsSwitch(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsTrain extends AtsDevice {
|
||||||
|
public AtsTrain(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class AtsTripPlan {
|
||||||
|
String sn;// 服务号/表号
|
||||||
|
String tn;// 车次号/圈数
|
||||||
|
String dn;// 目的地号
|
||||||
|
boolean in;// 回库
|
||||||
|
boolean out;// 出库
|
||||||
|
boolean spare;// 备用
|
||||||
|
AtsStation startStation;
|
||||||
|
AtsSection startSection;
|
||||||
|
LocalTime startTime;
|
||||||
|
AtsStation endStation;
|
||||||
|
AtsSection endSection;
|
||||||
|
LocalTime endTime;
|
||||||
|
List<AtsStationPlan> stationPlanList;
|
||||||
|
boolean depart; // 是否已经发车
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ATS.bo;
|
||||||
|
|
||||||
|
public class AtsUnitPath {
|
||||||
|
}
|
@ -2,11 +2,11 @@ package club.joylink.rtss.simulation.rt.CIL;
|
|||||||
|
|
||||||
import club.joylink.rtss.simulation.rt.CIL.bo.*;
|
import club.joylink.rtss.simulation.rt.CIL.bo.*;
|
||||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
import club.joylink.rtss.simulation.rt.srd.SrdApiService;
|
import club.joylink.rtss.simulation.rt.SRD.SrdApiService;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.SrAXC;
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrAXC;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.SrPSD;
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrPSD;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.SrSignal;
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.SrSwitch;
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrSwitch;
|
||||||
import club.joylink.rtss.vo.client.map.MapVO;
|
import club.joylink.rtss.vo.client.map.MapVO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package club.joylink.rtss.simulation.rt.CIL;
|
package club.joylink.rtss.simulation.rt.CIL;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.simulation.rt.CIL.bo.*;
|
import club.joylink.rtss.simulation.rt.CIL.bo.*;
|
||||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
import club.joylink.rtss.simulation.rt.srd.SrdApiService;
|
import club.joylink.rtss.simulation.rt.SRD.SrdApiService;
|
||||||
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class CilRouteLogicService {
|
public class CilRouteLogicService {
|
||||||
@ -30,51 +30,325 @@ public class CilRouteLogicService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排列进路接口,包括办理冲突检查和选出延续保护及一些初始化工作
|
||||||
|
* @param rtSimulation
|
||||||
|
* @param cilRoute
|
||||||
|
* @return 是否办理
|
||||||
|
*/
|
||||||
|
public boolean setRoute(RtSimulation rtSimulation, CilRoute cilRoute) {
|
||||||
|
// 检查
|
||||||
|
// 延续保护选择
|
||||||
|
this.selectRouteOverlap(cilRoute);
|
||||||
|
// 其他初始化
|
||||||
|
// 道岔征用
|
||||||
|
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
||||||
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
cilSwitchPosition.routeUse();
|
||||||
|
}
|
||||||
|
List<CilFls> flsList = pathElement.getFlsList();
|
||||||
|
for (CilFls cilFls : flsList) {
|
||||||
|
List<CilFls.FlsElement> firstLevelList = cilFls.getFirstLevelList();
|
||||||
|
for (CilFls.FlsElement flsElement : firstLevelList) {
|
||||||
|
CilSwitchPosition pp = flsElement.getPp();
|
||||||
|
if (pp != null) {
|
||||||
|
pp.routeUse();
|
||||||
|
}
|
||||||
|
CilSwitchPosition pae = flsElement.getPae();
|
||||||
|
if (pae != null) {
|
||||||
|
pae.routeUse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 开始办理
|
||||||
|
cilRoute.startSetting(rtSimulation.getSystemTime());
|
||||||
|
CilRepository cilRepository = rtSimulation.getRepository(CilRepository.NAME, CilRepository.class);
|
||||||
|
cilRepository.addSupervisedRoute(cilRoute);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectRouteOverlap(CilRoute cilRoute) {
|
||||||
|
CilOverlap overlap = cilRoute.getOverlap();
|
||||||
|
if (overlap != null) {
|
||||||
|
List<CilRoutePathElement> pathElementList = overlap.getPathElementList();
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionNotEmpty(pathElementList);
|
||||||
|
if (pathElementList.size() == 1) {
|
||||||
|
overlap.updateSelectedPath(pathElementList.get(0));
|
||||||
|
} else { // 多于一个,筛选(暂时选择逻辑为所有道岔在指定位置,若无,取直向)
|
||||||
|
CilRoutePathElement straight = null;
|
||||||
|
CilRoutePathElement selected = null;
|
||||||
|
for (CilRoutePathElement cilRoutePathElement : pathElementList) {
|
||||||
|
boolean select = true;
|
||||||
|
boolean line = true; // 是否直向
|
||||||
|
List<CilSwitchPosition> switchPositionList = cilRoutePathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
if (!cilSwitchPosition.isNormalPosition()) {
|
||||||
|
line = false;
|
||||||
|
}
|
||||||
|
if (!cilSwitchPosition.isOnPosition()) {
|
||||||
|
select = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line) {
|
||||||
|
straight = cilRoutePathElement;
|
||||||
|
}
|
||||||
|
if (select) {
|
||||||
|
selected = cilRoutePathElement;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selected != null) {
|
||||||
|
overlap.updateSelectedPath(selected);
|
||||||
|
} else {
|
||||||
|
overlap.updateSelectedPath(straight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void settingProgress(RtSimulation rtSimulation, CilRoute cilRoute, CilConfig config) {
|
private void settingProgress(RtSimulation rtSimulation, CilRoute cilRoute, CilConfig config) {
|
||||||
if (config.isLockFirst()) {
|
if (config.isLockFirst()) {
|
||||||
// 预先锁闭进路区段
|
// 预先锁闭进路区段
|
||||||
this.lockRouteSections(cilRoute);
|
this.lockRouteDevices(cilRoute);
|
||||||
}
|
}
|
||||||
// 进路道岔征用
|
// 进路道岔征用
|
||||||
|
this.turnSwitch(rtSimulation, cilRoute);
|
||||||
|
if (!config.isLockFirst()) {
|
||||||
|
// 检查道岔是否到位,到位锁闭进路,否则返回
|
||||||
|
boolean onPosition = this.checkSwitchOnPosition(cilRoute);
|
||||||
|
if (onPosition) {
|
||||||
|
this.lockRouteDevices(cilRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int level = this.levelCheck(cilRoute);
|
||||||
|
// 根据级别和模式控制信号显示
|
||||||
|
this.controlSignalAspectByLevel(rtSimulation, cilRoute, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSwitchOnPosition(CilRoute cilRoute) {
|
||||||
|
boolean onPosition = true;
|
||||||
|
// 检查进路内道岔
|
||||||
|
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
||||||
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
if (!cilSwitchPosition.isOnPosition()) {
|
||||||
|
onPosition = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cilRoute.isPreparedForCtc()) {
|
||||||
|
// 如果是为非CTC车准备的进路,还需检查延续保护
|
||||||
|
CilOverlap overlap = cilRoute.getOverlap();
|
||||||
|
CilRoutePathElement selectedPath = overlap.getSelectedPath();
|
||||||
|
List<CilSwitchPosition> overlapSwitchPositionList = selectedPath.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : overlapSwitchPositionList) {
|
||||||
|
if (!cilSwitchPosition.isOnPosition()) {
|
||||||
|
onPosition = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return onPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void controlSignalAspectByLevel(RtSimulation rtSimulation, CilRoute cilRoute, int level) {
|
||||||
|
CilSignal start = cilRoute.getStart();
|
||||||
|
start.updateLevel(level);
|
||||||
|
Integer aspect = null;
|
||||||
|
switch (level) {
|
||||||
|
case CilSignal.LEVEL_1:
|
||||||
|
case CilSignal.LEVEL_2: {
|
||||||
|
if (!cilRoute.isPreparedForCtc() || start.isForceLight()) {
|
||||||
|
if (start.getSignalAspect() != CilSignal.RED) {
|
||||||
|
aspect = SrSignal.RED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!start.isLogic()) {
|
||||||
|
aspect = SrSignal.OFF;
|
||||||
|
} else {
|
||||||
|
start.setAspect(CilSignal.RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CilSignal.LEVEL_3:{
|
||||||
|
if (cilRoute.isPreparedForCtc()) {
|
||||||
|
if (start.isForceLight()) {
|
||||||
|
if (start.getSignalAspect() != cilRoute.getSignalAspect()) {
|
||||||
|
aspect = cilRoute.getSignalAspect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!start.isLogic()) {
|
||||||
|
aspect = SrSignal.OFF;
|
||||||
|
} else {
|
||||||
|
start.setAspect(cilRoute.getSignalAspect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CilSignal.LEVEL_4:{
|
||||||
|
if (!cilRoute.isPreparedForCtc() || start.isForceLight()) {
|
||||||
|
if (start.getSignalAspect() != cilRoute.getSignalAspect()) {
|
||||||
|
aspect = cilRoute.getSignalAspect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!start.isLogic()) {
|
||||||
|
aspect = SrSignal.OFF;
|
||||||
|
} else {
|
||||||
|
start.setAspect(cilRoute.getSignalAspect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aspect != null) {
|
||||||
|
this.srdApiService.changeSignalLight(rtSimulation, start.getId(), aspect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int levelCheck(CilRoute cilRoute) {
|
||||||
|
int level = CilSignal.LEVEL_1;
|
||||||
|
// 进路内道岔检查
|
||||||
|
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
||||||
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
if (!cilSwitchPosition.isOnPosition() || !cilSwitchPosition.getCilSwitch().isRl()) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路区段检查
|
||||||
|
List<CilSection> sectionList = pathElement.getSectionList();
|
||||||
|
for (CilSection section : sectionList) {
|
||||||
|
if (!section.isRl()) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路内道岔到位,达到引导级别
|
||||||
|
level = CilSignal.LEVEL_2;
|
||||||
|
// 进路侧防检查
|
||||||
|
List<CilFls> flsList = pathElement.getFlsList();
|
||||||
|
for (CilFls cilFls : flsList) {
|
||||||
|
List<CilFls.FlsElement> firstLevelList = cilFls.getFirstLevelList();
|
||||||
|
for (CilFls.FlsElement flsElement : firstLevelList) {
|
||||||
|
CilSwitchPosition pp = flsElement.getPp();
|
||||||
|
if (pp != null && !pp.isOnPosition()) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
CilSwitchPosition pae = flsElement.getPae();
|
||||||
|
if (pae != null && !pae.isOnPosition()) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
CilSignal ps = flsElement.getPs();
|
||||||
|
if (ps != null && !ps.isForbidAspect()) {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路侧防满足,达到移动闭塞信号级别
|
||||||
|
level = CilSignal.LEVEL_3;
|
||||||
|
// 进路空闲情况,延续保护检查
|
||||||
|
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进路征用并转换道岔
|
||||||
|
*
|
||||||
|
* @param rtSimulation
|
||||||
|
* @param cilRoute
|
||||||
|
* @return 是否所有道岔已经转换到位
|
||||||
|
*/
|
||||||
|
private void turnSwitch(RtSimulation rtSimulation, CilRoute cilRoute) {
|
||||||
|
// 进路内道岔
|
||||||
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
||||||
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
boolean onPosition = true;
|
boolean onPosition = true;
|
||||||
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch();
|
this.turnSwitch(rtSimulation, cilSwitchPosition);
|
||||||
if (cilSwitch.getRouteUseToPosition() == CilDevice.NONE) {
|
}
|
||||||
cilSwitch.routeUse(cilSwitchPosition.getPosition());
|
// 进路侧防道岔
|
||||||
if (!cilSwitchPosition.isOnPosition()) {
|
List<CilFls> flsList = pathElement.getFlsList();
|
||||||
this.srdApiService.turnSwitch(rtSimulation, cilSwitch.getId(), cilSwitchPosition.getPosition());
|
for (CilFls cilFls : flsList) {
|
||||||
|
List<CilFls.FlsElement> firstLevelList = cilFls.getFirstLevelList();
|
||||||
|
for (CilFls.FlsElement flsElement : firstLevelList) {
|
||||||
|
CilSwitchPosition pp = flsElement.getPp();
|
||||||
|
if (pp != null) {
|
||||||
|
this.turnSwitch(rtSimulation, pp);
|
||||||
|
}
|
||||||
|
CilSwitchPosition pae = flsElement.getPae();
|
||||||
|
if (pae != null) {
|
||||||
|
this.turnSwitch(rtSimulation, pae);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cilSwitchPosition.isOnPosition()) {
|
|
||||||
onPosition = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (onPosition) { // 道岔已经转到位
|
// 延续保护道岔
|
||||||
|
// 延续保护侧防道岔
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param rtSimulation
|
||||||
|
* @param cilSwitchPosition
|
||||||
|
* @return 是否转换命令已经发出
|
||||||
|
*/
|
||||||
|
private boolean turnSwitch(RtSimulation rtSimulation, CilSwitchPosition cilSwitchPosition) {
|
||||||
|
CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch();
|
||||||
|
if (!cilSwitchPosition.isOnPosition()) {
|
||||||
|
if (cilSwitch.isRl() || cilSwitch.isSl() || cilSwitch.isOccupy()) { // 道岔进路锁闭/单锁/占用,不转换道岔
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.srdApiService.turnSwitch(rtSimulation, cilSwitch.getId(), cilSwitchPosition.getPosition());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockRouteDevices(CilRoute cilRoute) {
|
||||||
|
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
||||||
|
this.routeLockPathDevices(cilRoute, pathElement);
|
||||||
|
// 延续保护锁闭
|
||||||
|
CilOverlap overlap = cilRoute.getOverlap();
|
||||||
|
if (overlap != null) {
|
||||||
|
CilRoutePathElement selectedPath = overlap.getSelectedPath();
|
||||||
|
if (selectedPath != null) {
|
||||||
|
this.overlapLockPathDevices(overlap, selectedPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void lockRouteSections(CilRoute cilRoute) {
|
private void routeLockPathDevices(CilRoute cilRoute, CilRoutePathElement pathElement) {
|
||||||
CilRoutePathElement pathElement = cilRoute.getPathElement();
|
// 进路内道岔锁闭
|
||||||
Set<String> handledSwitchSet = new HashSet<>();
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch();
|
||||||
|
cilSwitch.getA().lockByRoute(cilRoute);
|
||||||
|
if (cilSwitchPosition.isOnPosition()) {
|
||||||
|
cilSwitch.lockByRoute(cilRoute);
|
||||||
|
if (cilSwitch.isNormalPosition()) {
|
||||||
|
cilSwitch.getB().lockByRoute(cilRoute);
|
||||||
|
} else {
|
||||||
|
cilSwitch.getC().lockByRoute(cilRoute);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cilSwitch.getB().lockByRoute(cilRoute);
|
||||||
|
cilSwitch.getC().lockByRoute(cilRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路侧防道岔锁闭
|
||||||
|
List<CilFls> flsList = pathElement.getFlsList();
|
||||||
|
for (CilFls cilFls : flsList) {
|
||||||
|
List<CilFls.FlsElement> firstLevelList = cilFls.getFirstLevelList();
|
||||||
|
for (CilFls.FlsElement flsElement : firstLevelList) {
|
||||||
|
flsElement.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路内区段锁闭
|
||||||
List<CilSection> sectionList = pathElement.getSectionList();
|
List<CilSection> sectionList = pathElement.getSectionList();
|
||||||
for (CilSection cilSection : sectionList) {
|
for (CilSection cilSection : sectionList) {
|
||||||
CilSwitch belongSwitch = cilSection.getBelongSwitch();
|
CilSwitch belongSwitch = cilSection.getBelongSwitch();
|
||||||
if (belongSwitch != null) {
|
if (belongSwitch != null) {
|
||||||
if (!handledSwitchSet.contains(belongSwitch.getId())) {
|
|
||||||
handledSwitchSet.add(belongSwitch.getId());
|
|
||||||
belongSwitch.getA().lockByRoute(cilRoute);
|
|
||||||
if (belongSwitch.isNormalPosition()) {
|
|
||||||
belongSwitch.getB().lockByRoute(cilRoute);
|
|
||||||
} else if (belongSwitch.isReversePosition()) {
|
|
||||||
belongSwitch.getC().lockByRoute(cilRoute);
|
|
||||||
} else {
|
|
||||||
belongSwitch.getB().lockByRoute(cilRoute);
|
|
||||||
belongSwitch.getC().lockByRoute(cilRoute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<CilSection> relateList = cilSection.getRelateList();
|
List<CilSection> relateList = cilSection.getRelateList();
|
||||||
@ -88,12 +362,48 @@ public class CilRouteLogicService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void overlapLockPathDevices(CilOverlap overlap, CilRoutePathElement pathElement) {
|
||||||
|
// 进路内道岔锁闭
|
||||||
|
List<CilSwitchPosition> switchPositionList = pathElement.getSwitchPositionList();
|
||||||
|
for (CilSwitchPosition cilSwitchPosition : switchPositionList) {
|
||||||
|
CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch();
|
||||||
|
cilSwitch.getA().lockByOverlap(overlap);
|
||||||
|
if (cilSwitchPosition.isOnPosition()) {
|
||||||
|
cilSwitch.lockByOverlap(overlap);
|
||||||
|
if (cilSwitch.isNormalPosition()) {
|
||||||
|
cilSwitch.getB().lockByOverlap(overlap);
|
||||||
|
} else {
|
||||||
|
cilSwitch.getC().lockByOverlap(overlap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cilSwitch.getB().lockByOverlap(overlap);
|
||||||
|
cilSwitch.getC().lockByOverlap(overlap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 进路内区段锁闭
|
||||||
|
List<CilSection> sectionList = pathElement.getSectionList();
|
||||||
|
for (CilSection cilSection : sectionList) {
|
||||||
|
CilSwitch belongSwitch = cilSection.getBelongSwitch();
|
||||||
|
if (belongSwitch != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<CilSection> relateList = cilSection.getRelateList();
|
||||||
|
if (relateList.isEmpty()) {
|
||||||
|
cilSection.lockByOverlap(overlap);
|
||||||
|
} else {
|
||||||
|
for (CilSection section : relateList) {
|
||||||
|
section.lockByOverlap(overlap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 进路监控
|
* 进路监控
|
||||||
* @param cilRoute
|
* @param cilRoute
|
||||||
*/
|
*/
|
||||||
private void watchRoute(CilRoute cilRoute) {
|
private void watchRoute(CilRoute cilRoute) {
|
||||||
if (cilRoute.isOpen()) {
|
if (cilRoute.isOpenAspect()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ public class CilFls {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
public static class FlsElement {
|
public static class FlsElement {
|
||||||
CilSwitchPosition pp; // 防护道岔
|
CilSwitchPosition pp; // 防护道岔
|
||||||
CilSignal ps; // 防护信号
|
CilSignal ps; // 防护信号
|
||||||
@ -38,5 +39,14 @@ public class CilFls {
|
|||||||
this.ps = ps;
|
this.ps = ps;
|
||||||
this.pae = pae;
|
this.pae = pae;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void lock() {
|
||||||
|
if (this.pp != null && this.pp.isOnPosition()) {
|
||||||
|
this.pp.getCilSwitch().flankLock();
|
||||||
|
}
|
||||||
|
if (this.pae != null && this.pae.isOnPosition()) {
|
||||||
|
this.pae.getCilSwitch().flankLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
package club.joylink.rtss.simulation.rt.CIL.bo;
|
package club.joylink.rtss.simulation.rt.CIL.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
public class CilOverlap extends CilDevice {
|
public class CilOverlap extends CilDevice {
|
||||||
|
|
||||||
|
boolean right;
|
||||||
|
CilSignal start;
|
||||||
CilSection releaseSection;
|
CilSection releaseSection;
|
||||||
List<CilRoutePathElement> pathElementList;
|
List<CilRoutePathElement> pathElementList;
|
||||||
int releaseTime;
|
int releaseTime; // 延续保护解锁时间
|
||||||
|
|
||||||
|
CilRoutePathElement selectedPath; // 选择出所需办理的路径
|
||||||
|
|
||||||
public CilOverlap(String id, String name) {
|
public CilOverlap(String id, String name) {
|
||||||
super(id, name);
|
super(id, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateSelectedPath(CilRoutePathElement cilRoutePathElement) {
|
||||||
|
this.selectedPath = cilRoutePathElement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,4 +84,8 @@ public class CilRepository extends SimulationRepository {
|
|||||||
public List<CilRoute> getSupervisedRouteList() {
|
public List<CilRoute> getSupervisedRouteList() {
|
||||||
return new ArrayList<>(this.supervisedRouteMap.values());
|
return new ArrayList<>(this.supervisedRouteMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSupervisedRoute(CilRoute cilRoute) {
|
||||||
|
this.supervisedRouteMap.put(cilRoute.getId(), cilRoute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,9 +204,11 @@ public class CilRepositoryBuilder {
|
|||||||
CilSection cilSection = sectionMap.get(overlapVO.getUnlockSectionCode());
|
CilSection cilSection = sectionMap.get(overlapVO.getUnlockSectionCode());
|
||||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(cilSection,
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(cilSection,
|
||||||
String.format("不存在id为[%s]的区段", overlapVO.getUnlockSectionCode()));
|
String.format("不存在id为[%s]的区段", overlapVO.getUnlockSectionCode()));
|
||||||
cilOverlap.releaseSection = cilSection;
|
|
||||||
cilOverlap.releaseTime = overlapVO.getUnlockTime();
|
|
||||||
CilSignal cilSignal = signalMap.get(overlapVO.getSignalCode());
|
CilSignal cilSignal = signalMap.get(overlapVO.getSignalCode());
|
||||||
|
cilOverlap.releaseSection = cilSection;
|
||||||
|
cilOverlap.start = cilSignal;
|
||||||
|
cilOverlap.right = cilSignal.isRight();
|
||||||
|
cilOverlap.releaseTime = overlapVO.getUnlockTime();
|
||||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(cilSignal,
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(cilSignal,
|
||||||
String.format("不存在id为[%s]的信号机", overlapVO.getSignalCode()));
|
String.format("不存在id为[%s]的信号机", overlapVO.getSignalCode()));
|
||||||
cilOverlap.pathElementList = buildPathElementList(cilSignal, overlapVO.getPathList(), sectionMap, switchMap, flsMap);
|
cilOverlap.pathElementList = buildPathElementList(cilSignal, overlapVO.getPathList(), sectionMap, switchMap, flsMap);
|
||||||
|
@ -2,11 +2,15 @@ package club.joylink.rtss.simulation.rt.CIL.bo;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class CilRoute extends CilDevice {
|
public class CilRoute extends CilDevice {
|
||||||
|
|
||||||
|
CilServer cilServer;
|
||||||
int type; // 进路类型
|
int type; // 进路类型
|
||||||
public static final int TYPE_ATP = 1;
|
public static final int TYPE_ATP = 1;
|
||||||
public static final int TYPE_GROUND = 2;
|
public static final int TYPE_GROUND = 2;
|
||||||
@ -15,7 +19,7 @@ public class CilRoute extends CilDevice {
|
|||||||
CilSignal start;
|
CilSignal start;
|
||||||
CilSignal end;
|
CilSignal end;
|
||||||
CilRoutePathElement pathElement;
|
CilRoutePathElement pathElement;
|
||||||
CilOverlap overlap;
|
CilOverlap overlap; // 延续保护
|
||||||
boolean ars; // ATS自排
|
boolean ars; // ATS自排
|
||||||
boolean arc; // 自动追踪/联锁自动触发
|
boolean arc; // 自动追踪/联锁自动触发
|
||||||
boolean flt; // 车队/自动进路
|
boolean flt; // 车队/自动进路
|
||||||
@ -29,6 +33,9 @@ public class CilRoute extends CilDevice {
|
|||||||
public static final int SA_YELLOW = 3;
|
public static final int SA_YELLOW = 3;
|
||||||
public static final int SA_GUIDE = 4; //引导信号,黄红灯显示
|
public static final int SA_GUIDE = 4; //引导信号,黄红灯显示
|
||||||
|
|
||||||
|
Map<String, CilSwitchPosition> waitTurnMap = new ConcurrentHashMap<>(); // 进路办理中待转换的道岔
|
||||||
|
Map<String, CilSwitchPosition> waitOnPositionMap = new ConcurrentHashMap<>(); // 进路办理中待转换到位的道岔
|
||||||
|
LocalDateTime stageStartTime;
|
||||||
int stage; // 进路当前所处逻辑阶段
|
int stage; // 进路当前所处逻辑阶段
|
||||||
public static final int STAGE_NONE = 0; // 无
|
public static final int STAGE_NONE = 0; // 无
|
||||||
public static final int STAGE_SETTING = 1; // 建立阶段
|
public static final int STAGE_SETTING = 1; // 建立阶段
|
||||||
@ -44,13 +51,26 @@ public class CilRoute extends CilDevice {
|
|||||||
super(id, name);
|
super(id, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpen() {
|
public boolean isOpenAspect() {
|
||||||
return this.start.getSignalAspect() == CilSignal.GREEN
|
return this.start.getSignalAspect() == CilSignal.GREEN
|
||||||
||
|
||
|
||||||
this.start.getSignalAspect() == CilSignal.YELLOW;
|
this.start.getSignalAspect() == CilSignal.YELLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGuide() {
|
public boolean isGuideAspect() {
|
||||||
return this.start.getSignalAspect() == CilSignal.GUIDE;
|
return this.start.getSignalAspect() == CilSignal.GUIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startSetting(LocalDateTime systemTime) {
|
||||||
|
this.stageStartTime = systemTime;
|
||||||
|
this.stage = STAGE_SETTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWaitTurnSwitch(CilSwitchPosition cilSwitchPosition) {
|
||||||
|
this.waitTurnMap.put(cilSwitchPosition.getCilSwitch().getId(), cilSwitchPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPreparedForCtc() {
|
||||||
|
return this.cilServer.isCtcMode() && !this.start.isUta();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package club.joylink.rtss.simulation.rt.CIL.bo;
|
package club.joylink.rtss.simulation.rt.CIL.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -10,16 +11,15 @@ import java.util.Objects;
|
|||||||
public class CilSection extends CilDevice {
|
public class CilSection extends CilDevice {
|
||||||
|
|
||||||
CilSection parent;
|
CilSection parent;
|
||||||
List<CilSection> relateList = new ArrayList<>();
|
List<CilSection> relateList = new ArrayList<>(); // 关联的子区段,顺序
|
||||||
List<CilSection> reverseList = new ArrayList<>();
|
List<CilSection> reverseList = new ArrayList<>(); // 关联的子区段,逆序
|
||||||
CilSwitch belongSwitch;
|
CilSwitch belongSwitch;
|
||||||
CilSignal leftSignal;
|
|
||||||
CilSignal rightSignal;
|
|
||||||
|
|
||||||
boolean axcOccupy;
|
boolean axcOccupy;
|
||||||
String routeId; // 锁闭进路的id
|
String routeId; // 锁闭进路的id
|
||||||
boolean rl; // 进路锁闭
|
boolean rl; // 进路锁闭
|
||||||
boolean lr; // 进路锁闭方向,true-右向,false-左向
|
boolean lr; // 进路锁闭方向,true-右向,false-左向
|
||||||
|
boolean ol; // 延续保护锁闭
|
||||||
|
|
||||||
public CilSection(String id, String name) {
|
public CilSection(String id, String name) {
|
||||||
super(id, name);
|
super(id, name);
|
||||||
@ -41,4 +41,14 @@ public class CilSection extends CilDevice {
|
|||||||
this.lr = cilRoute.start.isRight();
|
this.lr = cilRoute.start.isRight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void lockByOverlap(CilOverlap overlap) {
|
||||||
|
if (!this.ol) {
|
||||||
|
this.ol = true;
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(this.rl && this.lr != overlap.isRight());
|
||||||
|
if (this.lr != overlap.isRight()) {
|
||||||
|
this.lr = overlap.isRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,21 @@ package club.joylink.rtss.simulation.rt.CIL.bo;
|
|||||||
|
|
||||||
public class CilServer extends CilDevice {
|
public class CilServer extends CilDevice {
|
||||||
|
|
||||||
|
int mode; // 联锁服务运行模式:CTC/后备
|
||||||
|
public static final int M_CTC = 1; // CBTC模式
|
||||||
|
public static final int M_RS = 2; // 后备模式
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
public CilServer(String id, String name) {
|
public CilServer(String id, String name) {
|
||||||
super(id, name);
|
super(id, name);
|
||||||
|
this.mode = M_CTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCtcMode() {
|
||||||
|
return this.mode == M_CTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReserveMode() {
|
||||||
|
return this.mode == M_RS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package club.joylink.rtss.simulation.rt.CIL.bo;
|
package club.joylink.rtss.simulation.rt.CIL.bo;
|
||||||
|
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.SrSignal;
|
import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,10 +18,12 @@ public class CilSignal extends CilDevice {
|
|||||||
public static final int YELLOW = 3; // 黄灯信号(侧向通行)
|
public static final int YELLOW = 3; // 黄灯信号(侧向通行)
|
||||||
public static final int GUIDE = 4; // 引导信号(正线为黄红)
|
public static final int GUIDE = 4; // 引导信号(正线为黄红)
|
||||||
boolean logic;
|
boolean logic;
|
||||||
|
boolean forceLight; // 强制点灯
|
||||||
boolean bl; // 封锁
|
boolean bl; // 封锁
|
||||||
boolean rbl; // 重复封锁
|
boolean rbl; // 重复封锁
|
||||||
|
|
||||||
int forceLight;
|
boolean uta; // 未装备列车接近
|
||||||
|
|
||||||
int level;
|
int level;
|
||||||
public static final int LEVEL_1 = 1; //关闭/非监控级
|
public static final int LEVEL_1 = 1; //关闭/非监控级
|
||||||
public static final int LEVEL_2 = 2; //引导级
|
public static final int LEVEL_2 = 2; //引导级
|
||||||
@ -33,11 +35,25 @@ public class CilSignal extends CilDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateByDeviceState(int state) {
|
public void updateByDeviceState(int state) {
|
||||||
if (state == SrSignal.CLOSE) {
|
if (state == SrSignal.OFF) {
|
||||||
this.logic = true;
|
this.logic = true;
|
||||||
} else {
|
} else {
|
||||||
this.logic = false;
|
this.logic = false;
|
||||||
this.signalAspect = state;
|
this.signalAspect = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isForbidAspect() {
|
||||||
|
return this.signalAspect == RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLevel(int level) {
|
||||||
|
if (this.level != level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAspect(int signalAspect) {
|
||||||
|
this.signalAspect = signalAspect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.rt.CIL.bo;
|
|||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class CilSwitch extends CilDevice {
|
public class CilSwitch extends CilDevice {
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ public class CilSwitch extends CilDevice {
|
|||||||
|
|
||||||
boolean bl; // 封锁
|
boolean bl; // 封锁
|
||||||
boolean sl; // 单锁
|
boolean sl; // 单锁
|
||||||
|
String routeId; // 锁闭进路的id
|
||||||
boolean rl; // 进路锁闭
|
boolean rl; // 进路锁闭
|
||||||
boolean ol; // 延续保护锁闭
|
boolean ol; // 延续保护锁闭
|
||||||
boolean fl; // 侧防锁闭
|
boolean fl; // 侧防锁闭
|
||||||
@ -53,4 +56,27 @@ public class CilSwitch extends CilDevice {
|
|||||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(NORMAL == position || REVERSE == position);
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(NORMAL == position || REVERSE == position);
|
||||||
this.routeUseToPosition = position;
|
this.routeUseToPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOccupy() {
|
||||||
|
return this.a.axcOccupy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lockByRoute(CilRoute cilRoute) {
|
||||||
|
if (!Objects.equals(cilRoute.getId(), this.routeId)) {
|
||||||
|
this.routeId = cilRoute.getId();
|
||||||
|
this.rl = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lockByOverlap(CilOverlap overlap) {
|
||||||
|
if (!this.ol) {
|
||||||
|
this.ol = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flankLock() {
|
||||||
|
if (!this.fl) {
|
||||||
|
this.fl = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,4 +23,12 @@ public class CilSwitchPosition {
|
|||||||
public boolean isOnPosition() {
|
public boolean isOnPosition() {
|
||||||
return this.cilSwitch.position == this.position;
|
return this.cilSwitch.position == this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void routeUse() {
|
||||||
|
this.cilSwitch.routeUse(this.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNormalPosition() {
|
||||||
|
return CilSwitch.NORMAL == this.position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.DEPOT;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆段/停车场逻辑
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DepotLogicService {
|
||||||
|
}
|
@ -3,13 +3,20 @@ package club.joylink.rtss.simulation.rt;
|
|||||||
import club.joylink.rtss.simulation.Simulation;
|
import club.joylink.rtss.simulation.Simulation;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class RtSimulation extends Simulation<RtSimulationUser, RtSimulationMember> {
|
public class RtSimulation extends Simulation<RtSimulationUser, RtSimulationMember> {
|
||||||
|
public static final int TIME_OFFSET_HOUR = 2;
|
||||||
|
|
||||||
public RtSimulation(String id) {
|
public RtSimulation(String id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDateTime convertToSystemTime(LocalDateTime dateTime) {
|
||||||
|
return dateTime.minusHours(TIME_OFFSET_HOUR);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String debugStr() {
|
public String debugStr() {
|
||||||
return String.format("轨道交通仿真[%s]", getId());
|
return String.format("轨道交通仿真[%s]", getId());
|
||||||
|
@ -2,7 +2,7 @@ package club.joylink.rtss.simulation.rt;
|
|||||||
|
|
||||||
import club.joylink.rtss.services.MapService;
|
import club.joylink.rtss.services.MapService;
|
||||||
import club.joylink.rtss.simulation.SimulationManager;
|
import club.joylink.rtss.simulation.SimulationManager;
|
||||||
import club.joylink.rtss.simulation.rt.srd.SrdLogicService;
|
import club.joylink.rtss.simulation.rt.SRD.SrdLogicService;
|
||||||
import club.joylink.rtss.vo.UserVO;
|
import club.joylink.rtss.vo.UserVO;
|
||||||
import club.joylink.rtss.vo.client.map.MapVO;
|
import club.joylink.rtss.vo.client.map.MapVO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
|
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SrdApiService {
|
||||||
|
|
||||||
|
private SrdRepository getSrdRepository(RtSimulation rtSimulation) {
|
||||||
|
SrdRepository repository = rtSimulation.getRepository(SrdRepository.NAME, SrdRepository.class);
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(repository);
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrAXC> queryAllAxc(RtSimulation rtSimulation) {
|
||||||
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
|
return repository.getAxcList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrSwitch> queryAllSwitch(RtSimulation rtSimulation) {
|
||||||
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
|
return repository.getSwitchList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrSignal> queryAllSignal(RtSimulation rtSimulation) {
|
||||||
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
|
return repository.getSignalList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrPSD> queryAllPsd(RtSimulation rtSimulation) {
|
||||||
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
|
return repository.getPsdList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turnSwitch(RtSimulation rtSimulation, String switchId, int position) {
|
||||||
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
|
SrSwitch srSwitch = repository.getSwitchById(switchId);
|
||||||
|
boolean startTurn = false;
|
||||||
|
if (SrSwitch.NORMAL == position) {
|
||||||
|
startTurn = srSwitch.turnToNormal(rtSimulation.getSystemTime());
|
||||||
|
} else if (SrSwitch.REVERSE == position) {
|
||||||
|
startTurn = srSwitch.turnToReverse(rtSimulation.getSystemTime());
|
||||||
|
} else {
|
||||||
|
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception();
|
||||||
|
}
|
||||||
|
if (startTurn) {
|
||||||
|
// 发送道岔开始转换
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeSignalLight(RtSimulation rtSimulation, String id, int aspect) {
|
||||||
|
SrdRepository srdRepository = this.getSrdRepository(rtSimulation);
|
||||||
|
SrSignal srSignal = srdRepository.getSignalById(id);
|
||||||
|
boolean change = false;
|
||||||
|
if (srSignal.getState() != aspect) {
|
||||||
|
LocalDateTime systemTime = rtSimulation.getSystemTime();
|
||||||
|
switch (aspect) {
|
||||||
|
case SrSignal.OFF:{
|
||||||
|
srSignal.close(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.RED:{
|
||||||
|
srSignal.openRed(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.GREEN:{
|
||||||
|
srSignal.openGreen(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.YELLOW: {
|
||||||
|
srSignal.openYellow(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.GUIDE: {
|
||||||
|
srSignal.openGuide(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("无效的信号机显示:[%s]", aspect));
|
||||||
|
}
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
if (change) {
|
||||||
|
// 发送信号机变更
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
|
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||||
|
import club.joylink.rtss.vo.client.map.MapVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实设备运行逻辑
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class SrdLogicService {
|
||||||
|
public static final int TRAIN_RUN_RATE = 20; // 列车运行逻辑频率
|
||||||
|
public static final int DEVICE_RUN_RATE = 500; // 其他设备逻辑频率
|
||||||
|
|
||||||
|
public void buildRepository(RtSimulation rtSimulation, MapVO mapVO) {
|
||||||
|
SrdRepository srdRepository = SrdRepositoryBuilder.buildFrom(mapVO);
|
||||||
|
rtSimulation.addRepository(srdRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addJobs(RtSimulation rtSimulation) {
|
||||||
|
rtSimulation.addJob("srTrainRun",
|
||||||
|
() -> this.srTrainRun(rtSimulation.getRepository(SrdRepository.NAME, SrdRepository.class)),
|
||||||
|
TRAIN_RUN_RATE);
|
||||||
|
rtSimulation.addJob("srDeviceLogic",
|
||||||
|
() -> this.srDeviceLogic(rtSimulation.getRepository(SrdRepository.NAME, SrdRepository.class), rtSimulation.getSystemTime()),
|
||||||
|
DEVICE_RUN_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void srDeviceLogic(SrdRepository repository, LocalDateTime systemTime) {
|
||||||
|
// 道岔转动
|
||||||
|
List<SrSwitch> turnoutList = repository.getSwitchList();
|
||||||
|
for (SrSwitch turnout : turnoutList) {
|
||||||
|
if (turnout.isControlByReal()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (turnout.isTurning()) {
|
||||||
|
turnout.tryFinishTurning(systemTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 屏蔽门开/闭
|
||||||
|
List<SrPSD> psdList = repository.getPsdList();
|
||||||
|
for (SrPSD psd : psdList) {
|
||||||
|
if (psd.isControlByReal()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (psd.isTurning()) {
|
||||||
|
psd.tryFinishTurning(systemTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 信号机控制
|
||||||
|
List<SrSignal> signalList = repository.getSignalList();
|
||||||
|
for (SrSignal signal : signalList) {
|
||||||
|
if (signal.isControlByReal()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (signal.isTurning()) {
|
||||||
|
signal.tryFinishTurning(systemTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void srTrainRun(SrdRepository repository) {
|
||||||
|
List<SrTrain> trainList = repository.getTrainList();
|
||||||
|
for (SrTrain srTrain : trainList) {
|
||||||
|
if (!srTrain.isUsing()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 计算列车加速度,更新列车速度,计算列车运行距离,更新列车位置
|
||||||
|
boolean right = srTrain.isRight();
|
||||||
|
TrackPosition position = srTrain.getHeadPosition();
|
||||||
|
int cv = this.calculateSpeed(srTrain);
|
||||||
|
int s = this.calculateLen(srTrain, cv, TRAIN_RUN_RATE);
|
||||||
|
TrackPosition np = calculatePosition(position, s, right, new HashSet<>());
|
||||||
|
if (np.equals(position) && cv != 0) {
|
||||||
|
cv = 0;
|
||||||
|
}
|
||||||
|
Set<SrTrack> occupiedTrackSet = new HashSet<>();
|
||||||
|
TrackPosition tailPosition = this.calculatePosition(np, srTrain.getLen(), !right, occupiedTrackSet);
|
||||||
|
srTrain.updatePositionAndSpeed(np, tailPosition, cv);
|
||||||
|
// 更新计轴占用
|
||||||
|
Set<SrTrack> oldOccupiedTrackSet = new HashSet<>();
|
||||||
|
this.calculatePosition(position, srTrain.getLen(), !right, oldOccupiedTrackSet);
|
||||||
|
Set<SrTrack> clearList = new HashSet<>(oldOccupiedTrackSet);
|
||||||
|
clearList.removeAll(occupiedTrackSet);
|
||||||
|
for (SrTrack srTrack : clearList) {
|
||||||
|
srTrack.getAxc().clear();
|
||||||
|
}
|
||||||
|
for (SrTrack srTrack : occupiedTrackSet) {
|
||||||
|
srTrack.getAxc().occupy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateLen(SrTrain srTrain, int cv, int time) {
|
||||||
|
int s = cv * time;
|
||||||
|
return s * srTrain.getGear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateSpeed(SrTrain srTrain) {
|
||||||
|
long speed = srTrain.getSpeed();
|
||||||
|
int wa = (int) (10 + speed * 0.001 + speed * speed * 0.0000003); // 阻力所产生的反向加速度
|
||||||
|
int pa = 0;
|
||||||
|
if (srTrain.isEb()) {
|
||||||
|
pa = SrTrain.ES_DEC;
|
||||||
|
} else {
|
||||||
|
pa = srTrain.getP() >= 0 ? srTrain.getP() * SrTrain.MAX_ACC : srTrain.getP() * SrTrain.MAX_DEC;
|
||||||
|
}
|
||||||
|
int a = pa - wa;
|
||||||
|
int cv = (int) (speed + a * TRAIN_RUN_RATE); // 当前速度
|
||||||
|
if (cv < 0) {
|
||||||
|
cv = 0;
|
||||||
|
}
|
||||||
|
if (srTrain.isNeutralGear() && cv > 0) { // 空档位
|
||||||
|
cv = 0;
|
||||||
|
}
|
||||||
|
return cv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param position 起始位置
|
||||||
|
* @param s 距离
|
||||||
|
* @param right 方向
|
||||||
|
* @param trackSet 从position往方向[right]经过距离[s]所经过的轨道列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private TrackPosition calculatePosition(TrackPosition position, int s, boolean right, Set<SrTrack> trackSet) {
|
||||||
|
if (s == 0) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
SrTrack track = position.getTrack();
|
||||||
|
int offset = position.getOffset();
|
||||||
|
if (right) {
|
||||||
|
offset += s;
|
||||||
|
} else {
|
||||||
|
offset -= s;
|
||||||
|
}
|
||||||
|
SrTrack base = track;
|
||||||
|
trackSet.add(base);
|
||||||
|
int iter = 0;
|
||||||
|
while (offset < 0 || offset > base.getLen()) {
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(iter < 10);
|
||||||
|
++iter;
|
||||||
|
SrTrack nextTrack = base.queryNextTrack(right);
|
||||||
|
if (nextTrack == null) { // 下一区段为空,到达尽头或道岔失表处
|
||||||
|
log.debug(String.format("区段[%s][%s]区段不存在",base.debugStr(), right?"右向":"左向"));
|
||||||
|
if (offset < 0) {
|
||||||
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
offset = base.getLen();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (right) {
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(offset > base.getLen());
|
||||||
|
offset -= base.getLen();
|
||||||
|
} else {
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(offset < 0);
|
||||||
|
offset += nextTrack.getLen();
|
||||||
|
}
|
||||||
|
base = nextTrack;
|
||||||
|
trackSet.add(nextTrack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TrackPosition(base, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
public enum DeviceType {
|
||||||
|
/** 计轴器 */
|
||||||
|
AXC,
|
||||||
|
/** 道岔 */
|
||||||
|
TURNOUT,
|
||||||
|
/** 信号机 */
|
||||||
|
SIGNAL,
|
||||||
|
/** 站台屏蔽门 */
|
||||||
|
PSD,
|
||||||
|
TRAIN,
|
||||||
|
/** 轨道 */
|
||||||
|
TRACK
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实计轴器(Axle counter)
|
||||||
|
*/
|
||||||
|
public class SrAXC extends SrDevice {
|
||||||
|
|
||||||
|
int state = OFF;
|
||||||
|
public static final int OFF = 0;//出清
|
||||||
|
public static final int ON = 1;//占用
|
||||||
|
|
||||||
|
public SrAXC(String id) {
|
||||||
|
super(id, DeviceType.AXC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
this.state = OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void occupy() {
|
||||||
|
if (this.state != ON) {
|
||||||
|
this.state=ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOccupy() {
|
||||||
|
return this.state == ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.simulation.Debug;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实设备抽象父类
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public abstract class SrDevice implements Debug {
|
||||||
|
String id;
|
||||||
|
DeviceType deviceType;
|
||||||
|
/**
|
||||||
|
* 是否由真实设备控制
|
||||||
|
*/
|
||||||
|
boolean controlByReal;
|
||||||
|
|
||||||
|
public SrDevice() {}
|
||||||
|
|
||||||
|
public SrDevice(String id, DeviceType deviceType) {
|
||||||
|
this.id = id;
|
||||||
|
this.deviceType = deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void applyState(int state);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String debugStr() {
|
||||||
|
return String.format("%s:%s", this.deviceType, this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
SrDevice srDevice = (SrDevice) o;
|
||||||
|
return Objects.equals(id, srDevice.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实屏蔽门(Platform screen door)
|
||||||
|
*/
|
||||||
|
public class SrPSD extends SrDevice {
|
||||||
|
public static final int turnTime = 3000; // 默认开关门时间,单位ms
|
||||||
|
|
||||||
|
int state = CLOSE_LOCK;
|
||||||
|
public static final int CLOSE_LOCK = 1;//关闭且锁闭
|
||||||
|
public static final int CLOSED = 2;//关闭未锁闭
|
||||||
|
public static final int TURNING = 3;//转换中
|
||||||
|
public static final int OPEN_FINISH = 4;//打开到位
|
||||||
|
|
||||||
|
AtomicInteger command = new AtomicInteger(NONE);
|
||||||
|
public static final int NONE = 0;//无动作
|
||||||
|
/**
|
||||||
|
* 转换完成时间
|
||||||
|
*/
|
||||||
|
LocalDateTime finishTime;
|
||||||
|
|
||||||
|
public SrPSD(String id) {
|
||||||
|
super(id, DeviceType.PSD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTurning() {
|
||||||
|
return NONE != this.command.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, OPEN_FINISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, CLOSE_LOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startTurn(LocalDateTime systemTime, int command) {
|
||||||
|
this.finishTime = systemTime.plusNanos(TimeUnit.MILLISECONDS.toNanos(turnTime));
|
||||||
|
this.command.set(command);
|
||||||
|
this.state = TURNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryFinishTurning(LocalDateTime systemTime) {
|
||||||
|
if (this.finishTime != null && systemTime.compareTo(this.finishTime) >= 0) {
|
||||||
|
this.turnFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turnFinish() {
|
||||||
|
this.state = this.command.get();
|
||||||
|
this.command.set(NONE);
|
||||||
|
this.finishTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
if (CLOSE_LOCK == state || CLOSED == state || TURNING == state || OPEN_FINISH == state) {
|
||||||
|
this.state = state;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(String.format("无效的屏蔽门状态:[%s]", state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实信号机
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class SrSignal extends SrDevice {
|
||||||
|
public static final int turnTime = 500; // 默认转换时间,单位ms
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所在区段
|
||||||
|
*/
|
||||||
|
SrTrack track;
|
||||||
|
/**
|
||||||
|
* 所在区段偏移量,单位mm
|
||||||
|
*/
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
int state = OFF;
|
||||||
|
public static final int OFF = 0; // 关闭
|
||||||
|
public static final int RED = 1; // 红灯信号(禁止信号)
|
||||||
|
public static final int GREEN = 2; // 绿灯信号(直向通行)
|
||||||
|
public static final int YELLOW = 3; // 黄灯信号(侧向通行)
|
||||||
|
public static final int GUIDE = 4; // 引导信号(正线为黄红)
|
||||||
|
|
||||||
|
AtomicInteger command = new AtomicInteger(NONE);
|
||||||
|
public static final int NONE = 0;
|
||||||
|
/**
|
||||||
|
* 转换完成时间
|
||||||
|
*/
|
||||||
|
LocalDateTime finishTime;
|
||||||
|
|
||||||
|
public SrSignal(String id) {
|
||||||
|
super(id, DeviceType.SIGNAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrackAndOffset(SrTrack srTrack, int offset) {
|
||||||
|
this.track = srTrack;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTurning() {
|
||||||
|
return NONE != this.command.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openRed(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openGreen(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openYellow(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, YELLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openGuide(LocalDateTime systemTime) {
|
||||||
|
this.startTurn(systemTime, GUIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startTurn(LocalDateTime systemTime, int command) {
|
||||||
|
this.finishTime = systemTime.plusNanos(TimeUnit.MILLISECONDS.toNanos(turnTime));
|
||||||
|
this.command.set(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryFinishTurning(LocalDateTime systemTime) {
|
||||||
|
if (this.finishTime != null && systemTime.compareTo(this.finishTime) >= 0) {
|
||||||
|
this.turnFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turnFinish() {
|
||||||
|
this.state = this.command.get();
|
||||||
|
this.command.set(NONE);
|
||||||
|
this.finishTime = null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
if (OFF == state || RED == state || GREEN == state || YELLOW == state || GUIDE == state) {
|
||||||
|
this.state = state;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(String.format("无效的道岔状态:[%s]", state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实道岔
|
||||||
|
*/
|
||||||
|
public class SrSwitch extends SrDevice {
|
||||||
|
public static final int turnTime = 3000; // 默认转换时间
|
||||||
|
|
||||||
|
SrTrack a;
|
||||||
|
SrTrack b;
|
||||||
|
SrTrack c;
|
||||||
|
|
||||||
|
int state = NORMAL;
|
||||||
|
public static final int LOST = 0; // 失表
|
||||||
|
public static final int NORMAL = 1; // 定位
|
||||||
|
public static final int REVERSE = 2; // 反位
|
||||||
|
public static final int SQUEEZING = 4; // 挤叉
|
||||||
|
|
||||||
|
AtomicInteger command = new AtomicInteger(NONE);
|
||||||
|
public static final int NONE = 0;
|
||||||
|
/**
|
||||||
|
* 转换完成时间
|
||||||
|
*/
|
||||||
|
LocalDateTime finishTime;
|
||||||
|
|
||||||
|
public SrSwitch(String id) {
|
||||||
|
super(id, DeviceType.TURNOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTracks(SrTrack a, SrTrack b, SrTrack c) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
this.c = c;
|
||||||
|
a.srSwitch = this;
|
||||||
|
b.srSwitch = this;
|
||||||
|
c.srSwitch = this;
|
||||||
|
if (this.a.leftTrack == null && this.a.rightTrack == null) {
|
||||||
|
throw new IllegalStateException("道岔a区段两端都没有关联的区段");
|
||||||
|
}
|
||||||
|
if (this.a.leftTrack != null) { // a左侧存在
|
||||||
|
this.a.setRightTrack(this.b);
|
||||||
|
this.a.setRightFlankTrack(this.c);
|
||||||
|
} else { // a右侧存在
|
||||||
|
this.a.setLeftTrack(this.b);
|
||||||
|
this.a.setLeftFlankTrack(this.c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNormalPosition() {
|
||||||
|
return NORMAL == this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReversePosition() {
|
||||||
|
return REVERSE == this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTurning() {
|
||||||
|
return NONE != this.command.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean turnToNormal(LocalDateTime systemTime) {
|
||||||
|
if (this.isNormalPosition() || this.command.get() == NORMAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.startTurn(systemTime, NORMAL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean turnToReverse(LocalDateTime systemTime) {
|
||||||
|
if (this.isReversePosition() || this.command.get() == REVERSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.startTurn(systemTime, REVERSE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startTurn(LocalDateTime systemTime, int command) {
|
||||||
|
this.finishTime = systemTime.plusNanos(TimeUnit.MILLISECONDS.toNanos(turnTime));
|
||||||
|
this.command.set(command);
|
||||||
|
this.state = LOST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryFinishTurning(LocalDateTime systemTime) {
|
||||||
|
if (this.finishTime != null && systemTime.compareTo(this.finishTime) >= 0) {
|
||||||
|
this.turnFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void turnFinish() {
|
||||||
|
this.state = this.command.get();
|
||||||
|
this.command.set(NONE);
|
||||||
|
this.finishTime = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
if (NORMAL == state || REVERSE == state || LOST == state) {
|
||||||
|
this.state = state;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(String.format("无效的道岔状态:[%s]", state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.simulation.Debug;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实轨道区段
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class SrTrack extends SrDevice implements Debug {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
/**
|
||||||
|
* 轨道长度,单位mm
|
||||||
|
*/
|
||||||
|
int len;
|
||||||
|
/**
|
||||||
|
* 计轴器
|
||||||
|
*/
|
||||||
|
SrAXC axc;
|
||||||
|
/**
|
||||||
|
* 左侧直向轨道(可能为null)
|
||||||
|
*/
|
||||||
|
SrTrack leftTrack;
|
||||||
|
/**
|
||||||
|
* 左侧侧向轨道(非道岔的都为null)
|
||||||
|
*/
|
||||||
|
SrTrack leftFlankTrack;
|
||||||
|
/**
|
||||||
|
* 右侧轨道(可能为null)
|
||||||
|
*/
|
||||||
|
SrTrack rightTrack;
|
||||||
|
/**
|
||||||
|
* 右侧侧向轨道(非道岔的都为null)
|
||||||
|
*/
|
||||||
|
SrTrack rightFlankTrack;
|
||||||
|
/**
|
||||||
|
* 关联的道岔(是道岔区段才会关联,否则为null)
|
||||||
|
*/
|
||||||
|
SrSwitch srSwitch;
|
||||||
|
|
||||||
|
public SrTrack(String id) {
|
||||||
|
super(id, DeviceType.TRACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAxc(SrAXC axc) {
|
||||||
|
this.axc = axc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftTrack(SrTrack left) {
|
||||||
|
this.leftTrack = left;
|
||||||
|
left.setRightTrack(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftFlankTrack(SrTrack leftFlank) {
|
||||||
|
this.leftFlankTrack = leftFlank;
|
||||||
|
leftFlank.setRightTrack(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightTrack(SrTrack right) {
|
||||||
|
this.rightTrack = right;
|
||||||
|
right.setLeftTrack(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightFlankTrack(SrTrack rightFlank) {
|
||||||
|
this.rightFlankTrack = rightFlank;
|
||||||
|
rightFlank.setLeftTrack(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSrSwitch(SrSwitch srSwitch) {
|
||||||
|
this.srSwitch = srSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SrTrack queryNextTrack(boolean right) {
|
||||||
|
if (this.srSwitch != null) {
|
||||||
|
if (this.srSwitch.isNormalPosition()) {
|
||||||
|
return right ? this.rightTrack : this.leftTrack;
|
||||||
|
} else if (this.srSwitch.isReversePosition()) {
|
||||||
|
if (right) {
|
||||||
|
if (this.rightFlankTrack != null) {
|
||||||
|
return this.rightFlankTrack;
|
||||||
|
} else {
|
||||||
|
return this.rightTrack;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.leftFlankTrack != null) {
|
||||||
|
return this.leftFlankTrack;
|
||||||
|
} else {
|
||||||
|
return this.leftTrack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return right ? this.rightTrack : this.leftTrack;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String debugStr() {
|
||||||
|
return String.format("%s(%s)", this.name, this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 虚拟真实列车
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class SrTrain extends SrDevice {
|
||||||
|
/**
|
||||||
|
* 是否使用中
|
||||||
|
*/
|
||||||
|
boolean using;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列车长度,单位mm
|
||||||
|
*/
|
||||||
|
int len;
|
||||||
|
/**
|
||||||
|
* 列车质量,单位:吨
|
||||||
|
*/
|
||||||
|
int mass = 224;
|
||||||
|
/**
|
||||||
|
* 最大加速度, 单位mm/s2
|
||||||
|
*/
|
||||||
|
public static final int MAX_ACC = 1600;
|
||||||
|
/**
|
||||||
|
* 最大常用制动加速度, 单位mm/s2
|
||||||
|
*/
|
||||||
|
public static final int MAX_DEC = -1200;
|
||||||
|
/**
|
||||||
|
* 紧急制动加速度, 单位mm/s2
|
||||||
|
*/
|
||||||
|
public static final int ES_DEC = -1500;
|
||||||
|
/**
|
||||||
|
* 功率-100 <= p <= 100
|
||||||
|
*/
|
||||||
|
int p;
|
||||||
|
/**
|
||||||
|
* 是否紧急制动
|
||||||
|
*/
|
||||||
|
boolean eb;
|
||||||
|
/**
|
||||||
|
* 列车速度,单位mm/s
|
||||||
|
*/
|
||||||
|
int speed;
|
||||||
|
/**
|
||||||
|
* 列车方向
|
||||||
|
*/
|
||||||
|
boolean right;
|
||||||
|
/**
|
||||||
|
* 档位
|
||||||
|
*/
|
||||||
|
int gear;
|
||||||
|
public static final int NEUTRAL = 0; //空挡
|
||||||
|
public static final int FORWARD = 1; //前进挡
|
||||||
|
public static final int REVERSE = -1; //后退档
|
||||||
|
/**
|
||||||
|
* 列车头位置
|
||||||
|
*/
|
||||||
|
TrackPosition headPosition;
|
||||||
|
/**
|
||||||
|
* 列车尾位置
|
||||||
|
*/
|
||||||
|
TrackPosition tailPosition;
|
||||||
|
public SrTrain(String id, int len) {
|
||||||
|
super(id, DeviceType.TRAIN);
|
||||||
|
this.len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNeutralGear() {
|
||||||
|
return NEUTRAL == this.gear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePositionAndSpeed(TrackPosition headPosition, TrackPosition tailPosition, int v) {
|
||||||
|
this.headPosition = headPosition;
|
||||||
|
this.tailPosition = tailPosition;
|
||||||
|
this.speed = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyState(int state) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
|
import club.joylink.rtss.simulation.SimulationRepository;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SrdRepository extends SimulationRepository {
|
||||||
|
public static final String NAME = "SDR";
|
||||||
|
|
||||||
|
Map<String, SrTrack> trackMap;
|
||||||
|
Map<String, SrAXC> axcMap;
|
||||||
|
Map<String, SrSwitch> switchMap;
|
||||||
|
Map<String, SrSignal> signalMap;
|
||||||
|
Map<String, SrPSD> psdMap;
|
||||||
|
Map<String, SrTrain> trainMap;
|
||||||
|
|
||||||
|
public SrdRepository() {
|
||||||
|
super(NAME);
|
||||||
|
this.trackMap = new HashMap<>();
|
||||||
|
this.axcMap = new HashMap<>();
|
||||||
|
this.switchMap = new HashMap<>();
|
||||||
|
this.signalMap = new HashMap<>();
|
||||||
|
this.psdMap = new HashMap<>();
|
||||||
|
this.trainMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrTrain> getTrainList() {
|
||||||
|
return new ArrayList<>(this.trainMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrSwitch> getSwitchList() {
|
||||||
|
return new ArrayList<>(this.switchMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrPSD> getPsdList() {
|
||||||
|
return new ArrayList<>(this.psdMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrSignal> getSignalList() {
|
||||||
|
return new ArrayList<>(this.signalMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initState() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SrAXC> getAxcList() {
|
||||||
|
return new ArrayList<>(this.axcMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SrSwitch getSwitchById(String id) {
|
||||||
|
SrSwitch srSwitch = this.switchMap.get(id);
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(srSwitch);
|
||||||
|
return srSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SrSignal getSignalById(String id) {
|
||||||
|
SrSignal srSignal = this.signalMap.get(id);
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(srSignal);
|
||||||
|
return srSignal;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
|
import club.joylink.rtss.vo.client.map.MapSwitchVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.MapTrainModelVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.MapTrainVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.MapVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.newmap.MapGraphDataNewVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.newmap.MapPSDVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.newmap.MapSectionNewVO;
|
||||||
|
import club.joylink.rtss.vo.client.map.newmap.MapSignalNewVO;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class SrdRepositoryBuilder {
|
||||||
|
|
||||||
|
public static SrdRepository buildFrom(MapVO mapVO) {
|
||||||
|
SrdRepository srdRepository = new SrdRepository();
|
||||||
|
MapGraphDataNewVO graphDataNew = mapVO.getGraphDataNew();
|
||||||
|
buildTrackAndAxc(graphDataNew.getSectionList(), srdRepository.trackMap, srdRepository.axcMap);
|
||||||
|
buildTurnout(graphDataNew.getSwitchList(), srdRepository.switchMap);
|
||||||
|
buildSignal(graphDataNew.getSignalList(), srdRepository.signalMap);
|
||||||
|
buildSrPsd(graphDataNew.getPsdList(), srdRepository.psdMap);
|
||||||
|
buildTrain(graphDataNew.getTrainList(), srdRepository.trainMap);
|
||||||
|
// 关系构建
|
||||||
|
buildRelationOfTrackAndAxc(graphDataNew.getSectionList(), srdRepository.trackMap, srdRepository.axcMap);
|
||||||
|
buildRelationOfTurnoutAndTrack(graphDataNew.getSwitchList(), srdRepository.switchMap, srdRepository.trackMap);
|
||||||
|
buildRelationOfSignalAndTrack(graphDataNew.getSignalList(), srdRepository.signalMap, srdRepository.trackMap);
|
||||||
|
return srdRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildRelationOfTrackAndAxc(List<MapSectionNewVO> sectionList, Map<String, SrTrack> trackMap, Map<String, SrAXC> axcMap) {
|
||||||
|
for (MapSectionNewVO sectionVO : sectionList) {
|
||||||
|
SrTrack srTrack = trackMap.get(sectionVO.getCode());
|
||||||
|
if (srTrack == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 构建轨道关联关系
|
||||||
|
if (StringUtils.hasText(sectionVO.getLeftSectionCode())) {
|
||||||
|
SrTrack left = trackMap.get(sectionVO.getLeftSectionCode());
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(left,
|
||||||
|
String.format("区段[%s]的左关联区段[%s]不存在", srTrack.getId(), sectionVO.getLeftSectionCode()));
|
||||||
|
srTrack.setLeftTrack(left);
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(sectionVO.getRightSectionCode())) {
|
||||||
|
SrTrack right = trackMap.get(sectionVO.getRightSectionCode());
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(right,
|
||||||
|
String.format("区段[%s]的右关联区段[%s]不存在", srTrack.getId(), sectionVO.getRightSectionCode()));
|
||||||
|
srTrack.setRightTrack(right);
|
||||||
|
}
|
||||||
|
// 构建轨道和计轴关系
|
||||||
|
SrAXC axc;
|
||||||
|
if (StringUtils.hasText(sectionVO.getParentCode())) {
|
||||||
|
axc = axcMap.get(sectionVO.getParentCode());
|
||||||
|
} else {
|
||||||
|
axc = axcMap.get(sectionVO.getCode());
|
||||||
|
}
|
||||||
|
srTrack.setAxc(axc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildRelationOfSignalAndTrack(List<MapSignalNewVO> signalList,
|
||||||
|
Map<String, SrSignal> signalMap,
|
||||||
|
Map<String, SrTrack> trackMap) {
|
||||||
|
for (MapSignalNewVO signalVO : signalList) {
|
||||||
|
SrSignal srSignal = signalMap.get(signalVO.getCode());
|
||||||
|
SrTrack srTrack = trackMap.get(signalVO.getSectionCode());
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(srTrack,
|
||||||
|
String.format("信号机[%s]关联区段[%s]不存在", signalVO.getCode(), signalVO.getSectionCode()));
|
||||||
|
Float sectionOffset = signalVO.getSectionOffset();
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(sectionOffset >= 0,
|
||||||
|
String.format("信号机[%s]区段偏移量小于0", signalVO.getCode()));
|
||||||
|
srSignal.setTrackAndOffset(srTrack, (int) (sectionOffset*1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildRelationOfTurnoutAndTrack(List<MapSwitchVO> switchList,
|
||||||
|
Map<String, SrSwitch> turnoutMap,
|
||||||
|
Map<String, SrTrack> trackMap) {
|
||||||
|
for (MapSwitchVO switchVO : switchList) {
|
||||||
|
SrTrack a = trackMap.get(switchVO.getSectionACode());
|
||||||
|
SrTrack b = trackMap.get(switchVO.getSectionBCode());
|
||||||
|
SrTrack c = trackMap.get(switchVO.getSectionCCode());
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(a,
|
||||||
|
String.format("道岔[%s]关联区段A[%s]不存在", switchVO.getCode(), switchVO.getSectionACode()));
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(b,
|
||||||
|
String.format("道岔[%s]关联区段B[%s]不存在", switchVO.getCode(), switchVO.getSectionBCode()));
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(c,
|
||||||
|
String.format("道岔[%s]关联区段C[%s]不存在", switchVO.getCode(), switchVO.getSectionCCode()));
|
||||||
|
SrSwitch turnout = turnoutMap.get(switchVO.getCode());
|
||||||
|
turnout.setTracks(a, b, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildTrackAndAxc(List<MapSectionNewVO> sectionList,
|
||||||
|
Map<String, SrTrack> trackMap,
|
||||||
|
Map<String, SrAXC> axcMap) {
|
||||||
|
for (MapSectionNewVO sectionVO : sectionList) {
|
||||||
|
if (Objects.equals(sectionVO.getType(), "02")) { // 逻辑区段
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Objects.equals(sectionVO.getType(), "04")) { // 道岔计轴
|
||||||
|
// 只创建计轴器
|
||||||
|
SrAXC srAXC = new SrAXC(sectionVO.getCode());
|
||||||
|
axcMap.put(srAXC.getId(), srAXC);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 创建轨道
|
||||||
|
SrTrack srTrack = new SrTrack(sectionVO.getCode());
|
||||||
|
trackMap.put(srTrack.getId(), srTrack);
|
||||||
|
BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(sectionVO.getLengthFact() > 0,
|
||||||
|
String.format("区段[%s(%s)]未设置实际长度或长度小于等于0", sectionVO.getName(), sectionVO.getCode()));
|
||||||
|
srTrack.len = ((int) (sectionVO.getLengthFact() * 1000));
|
||||||
|
|
||||||
|
// 创建计轴器
|
||||||
|
SrAXC srAXC = new SrAXC(sectionVO.getCode());
|
||||||
|
axcMap.put(srAXC.getId(), srAXC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildTurnout(List<MapSwitchVO> switchList, Map<String, SrSwitch> turnoutMap) {
|
||||||
|
for (MapSwitchVO switchVO : switchList) {
|
||||||
|
SrSwitch srSwitch = new SrSwitch(switchVO.getCode());
|
||||||
|
turnoutMap.put(srSwitch.getId(), srSwitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildSignal(List<MapSignalNewVO> signalList, Map<String, SrSignal> signalMap) {
|
||||||
|
for (MapSignalNewVO signalVO : signalList) {
|
||||||
|
SrSignal srSignal = new SrSignal(signalVO.getCode());
|
||||||
|
|
||||||
|
signalMap.put(srSignal.getId(), srSignal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildSrPsd(List<MapPSDVO> psdList, Map<String, SrPSD> psdMap) {
|
||||||
|
for (MapPSDVO psdVO : psdList) {
|
||||||
|
SrPSD srPSD = new SrPSD(psdVO.getCode());
|
||||||
|
psdMap.put(srPSD.getId(), srPSD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildTrain(List<MapTrainVO> trainList, Map<String, SrTrain> trainMap) {
|
||||||
|
for (MapTrainVO trainVO : trainList) {
|
||||||
|
MapTrainModelVO trainModel = trainVO.getTrainModel();
|
||||||
|
SrTrain srTrain = new SrTrain(trainVO.getGroupNumber(), (int) (trainModel.getLength() * 1000));
|
||||||
|
trainMap.put(srTrain.getId(), srTrain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
|
public class TrackPosition {
|
||||||
|
SrTrack track;
|
||||||
|
/**
|
||||||
|
* 轨道偏移量,单位mm
|
||||||
|
*/
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
public TrackPosition(SrTrack track, int offset) {
|
||||||
|
this.track = track;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SrTrack getTrack() {
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.TL;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车载逻辑
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TlLogicService {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.TL.bo;
|
||||||
|
|
||||||
|
public class TlPsd {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.TL.bo;
|
||||||
|
|
||||||
|
public class TlRepository {
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.TL.bo;
|
||||||
|
|
||||||
|
public class TlTrain {
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt;
|
||||||
|
|
||||||
|
import club.joylink.rtss.simulation.rt.ATS.bo.AtsRepository;
|
||||||
|
import club.joylink.rtss.simulation.rt.ATS.bo.AtsRunPlan;
|
||||||
|
import club.joylink.rtss.simulation.rt.ATS.bo.AtsStationPlan;
|
||||||
|
import club.joylink.rtss.simulation.rt.ATS.bo.AtsTripPlan;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TrainLoadService {
|
||||||
|
|
||||||
|
public int queryLoadQuantity(RtSimulation rtSimulation, LocalDateTime dateTime) {
|
||||||
|
int q = 0;
|
||||||
|
List<AtsTripPlan> loadTripList = this.queryLoadTrips(rtSimulation, dateTime);
|
||||||
|
q = loadTripList.size();
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AtsTripPlan> queryLoadTrips(RtSimulation rtSimulation, LocalDateTime dateTime) {
|
||||||
|
LocalTime time = dateTime.toLocalTime();
|
||||||
|
AtsRepository atsRepository = rtSimulation.getRepository(AtsRepository.NAME, AtsRepository.class);
|
||||||
|
AtsRunPlan runPlan = atsRepository.getRunPlan();
|
||||||
|
List<AtsTripPlan> loadTripList = new ArrayList<>();
|
||||||
|
// 查询需加载列车计划车次逻辑:
|
||||||
|
// 遍历终端发车计划列表,如下情况即为需要加载:
|
||||||
|
// 1,指定时间在计划开始和结束时间之间;
|
||||||
|
// 2,指定时间大于此计划开始时间,小于此计划终点区段终端下一计划开始时间;
|
||||||
|
Map<String, List<AtsTripPlan>> endTripMap = runPlan.getEndTripMap();
|
||||||
|
for (List<AtsTripPlan> tripPlanList : endTripMap.values()) {
|
||||||
|
for (AtsTripPlan atsTripPlan : tripPlanList) {
|
||||||
|
if (!time.isBefore(atsTripPlan.getStartTime())) { // 时间超过车次发车时间
|
||||||
|
if (time.isBefore(atsTripPlan.getEndTime())) {
|
||||||
|
loadTripList.add(atsTripPlan);
|
||||||
|
} else { // 时间超过车次终到时间,判断终端下一发车时间是否在指定时间之后
|
||||||
|
if (atsTripPlan.isIn()) { // 回库计划,不加载
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AtsTripPlan nextTripPlan = runPlan.queryNextTripPlanOfPlan(atsTripPlan);
|
||||||
|
if (nextTripPlan == null || time.isBefore(nextTripPlan.getStartTime())) {
|
||||||
|
loadTripList.add(atsTripPlan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loadTripList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runAsPlan(RtSimulation rtSimulation, LocalDateTime dateTime) {
|
||||||
|
LocalDateTime systemTime = rtSimulation.convertToSystemTime(dateTime);
|
||||||
|
List<AtsTripPlan> loadTripList = this.queryLoadTrips(rtSimulation, systemTime);
|
||||||
|
loadTripList.sort(Comparator.comparing(AtsTripPlan::getStartTime)); // 按时间排序
|
||||||
|
LocalTime time = systemTime.toLocalTime();
|
||||||
|
for (AtsTripPlan tripPlan : loadTripList) {
|
||||||
|
if (!time.isAfter(tripPlan.getEndTime())) {// 在车次计划中
|
||||||
|
List<AtsStationPlan> stationPlanList = tripPlan.getStationPlanList();
|
||||||
|
AtsStationPlan firstStationPlan = stationPlanList.get(0);
|
||||||
|
AtsStationPlan lastStationPlan = stationPlanList.get(stationPlanList.size() - 1);
|
||||||
|
if (time.isBefore(firstStationPlan.getArriveTime())) {
|
||||||
|
// 开始区段到第一车站站台轨运行
|
||||||
|
} else if (time.isAfter(lastStationPlan.getLeaveTime())) {
|
||||||
|
// 终点车站站台轨到折返区段运行
|
||||||
|
} else {
|
||||||
|
// 站台停车或站间运行
|
||||||
|
for (int i = 0; i < stationPlanList.size(); i++) {
|
||||||
|
AtsStationPlan plan = stationPlanList.get(i);
|
||||||
|
if (!time.isAfter(plan.getLeaveTime())) {
|
||||||
|
// 站台停车/不停站列车正好经过站台位置
|
||||||
|
break;
|
||||||
|
} else if(i+1 < stationPlanList.size()) {
|
||||||
|
AtsStationPlan nextPlan = stationPlanList.get(i + 1);
|
||||||
|
if (time.isBefore(nextPlan.getArriveTime())) {
|
||||||
|
// 站间
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {// 在此次计划和下一计划间,可能是备用车也可能是折返车
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域控制器逻辑
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ZcLogicService {
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class ZcDevice {
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
public ZcDevice(String id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcOverlap extends ZcDevice {
|
||||||
|
public ZcOverlap(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcRepository {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcRoute extends ZcDevice {
|
||||||
|
public ZcRoute(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcSection extends ZcDevice {
|
||||||
|
public ZcSection(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcStand {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package club.joylink.rtss.simulation.rt.ZC.bo;
|
||||||
|
|
||||||
|
public class ZcTrain extends ZcDevice {
|
||||||
|
public ZcTrain(String id, String name) {
|
||||||
|
super(id, name);
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd;
|
package club.joylink.rtss.simulation.rt.SRD;
|
||||||
|
|
||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.*;
|
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -39,12 +40,53 @@ public class SrdApiService {
|
|||||||
public void turnSwitch(RtSimulation rtSimulation, String switchId, int position) {
|
public void turnSwitch(RtSimulation rtSimulation, String switchId, int position) {
|
||||||
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
SrdRepository repository = this.getSrdRepository(rtSimulation);
|
||||||
SrSwitch srSwitch = repository.getSwitchById(switchId);
|
SrSwitch srSwitch = repository.getSwitchById(switchId);
|
||||||
|
boolean startTurn = false;
|
||||||
if (SrSwitch.NORMAL == position) {
|
if (SrSwitch.NORMAL == position) {
|
||||||
srSwitch.turnToNormal(rtSimulation.getSystemTime());
|
startTurn = srSwitch.turnToNormal(rtSimulation.getSystemTime());
|
||||||
} else if (SrSwitch.REVERSE == position) {
|
} else if (SrSwitch.REVERSE == position) {
|
||||||
srSwitch.turnToReverse(rtSimulation.getSystemTime());
|
startTurn = srSwitch.turnToReverse(rtSimulation.getSystemTime());
|
||||||
} else {
|
} else {
|
||||||
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception();
|
throw BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.exception();
|
||||||
}
|
}
|
||||||
|
if (startTurn) {
|
||||||
|
// 发送道岔开始转换
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeSignalLight(RtSimulation rtSimulation, String id, int aspect) {
|
||||||
|
SrdRepository srdRepository = this.getSrdRepository(rtSimulation);
|
||||||
|
SrSignal srSignal = srdRepository.getSignalById(id);
|
||||||
|
boolean change = false;
|
||||||
|
if (srSignal.getState() != aspect) {
|
||||||
|
LocalDateTime systemTime = rtSimulation.getSystemTime();
|
||||||
|
switch (aspect) {
|
||||||
|
case SrSignal.OFF:{
|
||||||
|
srSignal.close(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.RED:{
|
||||||
|
srSignal.openRed(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.GREEN:{
|
||||||
|
srSignal.openGreen(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.YELLOW: {
|
||||||
|
srSignal.openYellow(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SrSignal.GUIDE: {
|
||||||
|
srSignal.openGuide(systemTime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("无效的信号机显示:[%s]", aspect));
|
||||||
|
}
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
if (change) {
|
||||||
|
// 发送信号机变更
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd;
|
package club.joylink.rtss.simulation.rt.SRD;
|
||||||
|
|
||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||||
import club.joylink.rtss.simulation.rt.srd.bo.*;
|
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||||
import club.joylink.rtss.vo.client.map.MapVO;
|
import club.joylink.rtss.vo.client.map.MapVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
public enum DeviceType {
|
public enum DeviceType {
|
||||||
/** 计轴器 */
|
/** 计轴器 */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 虚拟真实计轴器(Axle counter)
|
* 虚拟真实计轴器(Axle counter)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import club.joylink.rtss.simulation.Debug;
|
import club.joylink.rtss.simulation.Debug;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ -22,8 +22,8 @@ public class SrSignal extends SrDevice {
|
|||||||
*/
|
*/
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
int state = CLOSE;
|
int state = OFF;
|
||||||
public static final int CLOSE = 0; // 关闭
|
public static final int OFF = 0; // 关闭
|
||||||
public static final int RED = 1; // 红灯信号(禁止信号)
|
public static final int RED = 1; // 红灯信号(禁止信号)
|
||||||
public static final int GREEN = 2; // 绿灯信号(直向通行)
|
public static final int GREEN = 2; // 绿灯信号(直向通行)
|
||||||
public static final int YELLOW = 3; // 黄灯信号(侧向通行)
|
public static final int YELLOW = 3; // 黄灯信号(侧向通行)
|
||||||
@ -54,7 +54,7 @@ public class SrSignal extends SrDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void close(LocalDateTime systemTime) {
|
public void close(LocalDateTime systemTime) {
|
||||||
this.startTurn(systemTime, CLOSE);
|
this.startTurn(systemTime, OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openRed(LocalDateTime systemTime) {
|
public void openRed(LocalDateTime systemTime) {
|
||||||
@ -91,7 +91,7 @@ public class SrSignal extends SrDevice {
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void applyState(int state) {
|
public void applyState(int state) {
|
||||||
if (CLOSE == state || RED == state || GREEN == state || YELLOW == state || GUIDE == state) {
|
if (OFF == state || RED == state || GREEN == state || YELLOW == state || GUIDE == state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(String.format("无效的道岔状态:[%s]", state));
|
throw new IllegalArgumentException(String.format("无效的道岔状态:[%s]", state));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -66,18 +66,20 @@ public class SrSwitch extends SrDevice {
|
|||||||
return NONE != this.command.get();
|
return NONE != this.command.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void turnToNormal(LocalDateTime systemTime) {
|
public boolean turnToNormal(LocalDateTime systemTime) {
|
||||||
if (this.isNormalPosition()) {
|
if (this.isNormalPosition() || this.command.get() == NORMAL) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
this.startTurn(systemTime, NORMAL);
|
this.startTurn(systemTime, NORMAL);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void turnToReverse(LocalDateTime systemTime) {
|
public boolean turnToReverse(LocalDateTime systemTime) {
|
||||||
if (this.isReversePosition()) {
|
if (this.isReversePosition() || this.command.get() == REVERSE) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
this.startTurn(systemTime, REVERSE);
|
this.startTurn(systemTime, REVERSE);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startTurn(LocalDateTime systemTime, int command) {
|
private void startTurn(LocalDateTime systemTime, int command) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import club.joylink.rtss.simulation.Debug;
|
import club.joylink.rtss.simulation.Debug;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.simulation.SimulationRepository;
|
import club.joylink.rtss.simulation.SimulationRepository;
|
||||||
@ -58,4 +58,10 @@ public class SrdRepository extends SimulationRepository {
|
|||||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(srSwitch);
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(srSwitch);
|
||||||
return srSwitch;
|
return srSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SrSignal getSignalById(String id) {
|
||||||
|
SrSignal srSignal = this.signalMap.get(id);
|
||||||
|
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(srSignal);
|
||||||
|
return srSignal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||||
import club.joylink.rtss.vo.client.map.MapSwitchVO;
|
import club.joylink.rtss.vo.client.map.MapSwitchVO;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.rtss.simulation.rt.srd.bo;
|
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||||
|
|
||||||
public class TrackPosition {
|
public class TrackPosition {
|
||||||
SrTrack track;
|
SrTrack track;
|
||||||
|
Loading…
Reference in New Issue
Block a user