diff --git a/src/main/java/club/joylink/rtss/services/draftData/RoutingGenerator.java b/src/main/java/club/joylink/rtss/services/draftData/RoutingGenerator.java index fccbf57d6..8cf80b69e 100644 --- a/src/main/java/club/joylink/rtss/services/draftData/RoutingGenerator.java +++ b/src/main/java/club/joylink/rtss/services/draftData/RoutingGenerator.java @@ -201,6 +201,7 @@ public class RoutingGenerator { start.getStation().getName(), start.getName(), end.getStation().getName(), end.getName()); if (pathsList.size() > 0) { + List
path = pathsList.get(0); if (pathsList.size() > 1) { log.warn(String.format("从[%s]的交路找到超过一个路径", name)); for (int i = 0; i < pathsList.size(); i++) { @@ -210,7 +211,13 @@ public class RoutingGenerator { } else { // 找到,构建 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(); Routing routing = new Routing(name, destinationCode); @@ -219,7 +226,7 @@ public class RoutingGenerator { routing.setEndStation(end.getStation()); routing.setEndSection(end); routing.setRight(right); - routing.setViaSectionList(pathsList.get(0)); + routing.setViaSectionList(path); return routing; } else { // 未找到 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java index d60505d06..7b8ab1a92 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java @@ -975,10 +975,6 @@ public class GroupSimulationServiceImpl implements GroupSimulationService { if (Project.CGY.name().equals(mapDetail.getProjectCode())) { //成都工业所有资源免费 return true; } - if (userVO.getCompanyId() != null) { - String mapProject = mapDetail.getProjectCode(); - return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject)); - } List ups = iUserPermissionService.getSimulationUserPermission(userVO, mapId, prdType); if (!CollectionUtils.isEmpty(ups)) { if (!MapPrdTypeEnum.JOINT.getCode().equals(prdType)) { @@ -989,6 +985,10 @@ public class GroupSimulationServiceImpl implements GroupSimulationService { return true; } } + if (userVO.getCompanyId() != null) { + String mapProject = mapDetail.getProjectCode(); + return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject)); + } return false; } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java new file mode 100644 index 000000000..cfde6f98c --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/AtsLogicService.java @@ -0,0 +1,10 @@ +package club.joylink.rtss.simulation.rt.ATS; + +import org.springframework.stereotype.Component; + +/** + * ATS逻辑 + */ +@Component +public class AtsLogicService { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsDevice.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsDevice.java new file mode 100644 index 000000000..6a3b45ee6 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsDevice.java @@ -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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java new file mode 100644 index 000000000..ffdd1849b --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRepository.java @@ -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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRoute.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRoute.java new file mode 100644 index 000000000..2c9dbe25c --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRoute.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRunPlan.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRunPlan.java new file mode 100644 index 000000000..92e2a38ad --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsRunPlan.java @@ -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> serviceMap; + /** + * 发车轨道的服务车次计划 + * key-区段id + * value-此区段发车的服务车次计划 + */ + Map> endTripMap; + + public AtsTripPlan queryNextTripPlanOfPlan(AtsTripPlan atsTripPlan) { + return this.queryNextTripPlanOfEnd(atsTripPlan.getEndSection().getId(), atsTripPlan.getEndTime()); + } + + public AtsTripPlan queryNextTripPlanOfEnd(String endId, LocalTime time) { + List 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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSection.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSection.java new file mode 100644 index 000000000..c72949d4d --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSection.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java new file mode 100644 index 000000000..67c3a536f --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSignal.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStand.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStand.java new file mode 100644 index 000000000..604a81754 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStand.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStation.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStation.java new file mode 100644 index 000000000..0841aaa96 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStation.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStationPlan.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStationPlan.java new file mode 100644 index 000000000..5a2a7d01b --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsStationPlan.java @@ -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;// 停靠时长 +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java new file mode 100644 index 000000000..4673837a8 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsSwitch.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTrain.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTrain.java new file mode 100644 index 000000000..e792c6ce9 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTrain.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTripPlan.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTripPlan.java new file mode 100644 index 000000000..c2746947f --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsTripPlan.java @@ -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 stationPlanList; + boolean depart; // 是否已经发车 +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsUnitPath.java b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsUnitPath.java new file mode 100644 index 000000000..7df8727bd --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ATS/bo/AtsUnitPath.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.ATS.bo; + +public class AtsUnitPath { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java index 7cdb51f97..ec74fb74a 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilLogicService.java @@ -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.RtSimulation; -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.SrPSD; -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.SrdApiService; +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.SrSignal; +import club.joylink.rtss.simulation.rt.SRD.bo.SrSwitch; import club.joylink.rtss.vo.client.map.MapVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java index 9c31f9fe5..fcb519225 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/CilRouteLogicService.java @@ -1,14 +1,14 @@ 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.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.stereotype.Component; -import java.util.HashSet; import java.util.List; -import java.util.Set; @Component 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 switchPositionList = pathElement.getSwitchPositionList(); + for (CilSwitchPosition cilSwitchPosition : switchPositionList) { + cilSwitchPosition.routeUse(); + } + List flsList = pathElement.getFlsList(); + for (CilFls cilFls : flsList) { + List 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 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 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) { 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 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 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 switchPositionList = pathElement.getSwitchPositionList(); + for (CilSwitchPosition cilSwitchPosition : switchPositionList) { + if (!cilSwitchPosition.isOnPosition() || !cilSwitchPosition.getCilSwitch().isRl()) { + return level; + } + } + // 进路区段检查 + List sectionList = pathElement.getSectionList(); + for (CilSection section : sectionList) { + if (!section.isRl()) { + return level; + } + } + // 进路内道岔到位,达到引导级别 + level = CilSignal.LEVEL_2; + // 进路侧防检查 + List flsList = pathElement.getFlsList(); + for (CilFls cilFls : flsList) { + List 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(); List switchPositionList = pathElement.getSwitchPositionList(); boolean onPosition = true; for (CilSwitchPosition cilSwitchPosition : switchPositionList) { - CilSwitch cilSwitch = cilSwitchPosition.getCilSwitch(); - if (cilSwitch.getRouteUseToPosition() == CilDevice.NONE) { - cilSwitch.routeUse(cilSwitchPosition.getPosition()); - if (!cilSwitchPosition.isOnPosition()) { - this.srdApiService.turnSwitch(rtSimulation, cilSwitch.getId(), cilSwitchPosition.getPosition()); + this.turnSwitch(rtSimulation, cilSwitchPosition); + } + // 进路侧防道岔 + List flsList = pathElement.getFlsList(); + for (CilFls cilFls : flsList) { + List 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) { - CilRoutePathElement pathElement = cilRoute.getPathElement(); - Set handledSwitchSet = new HashSet<>(); + private void routeLockPathDevices(CilRoute cilRoute, CilRoutePathElement pathElement) { + // 进路内道岔锁闭 + List 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 flsList = pathElement.getFlsList(); + for (CilFls cilFls : flsList) { + List firstLevelList = cilFls.getFirstLevelList(); + for (CilFls.FlsElement flsElement : firstLevelList) { + flsElement.lock(); + } + } + // 进路内区段锁闭 List sectionList = pathElement.getSectionList(); for (CilSection cilSection : sectionList) { CilSwitch belongSwitch = cilSection.getBelongSwitch(); 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; } List relateList = cilSection.getRelateList(); @@ -88,12 +362,48 @@ public class CilRouteLogicService { } } + private void overlapLockPathDevices(CilOverlap overlap, CilRoutePathElement pathElement) { + // 进路内道岔锁闭 + List 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 sectionList = pathElement.getSectionList(); + for (CilSection cilSection : sectionList) { + CilSwitch belongSwitch = cilSection.getBelongSwitch(); + if (belongSwitch != null) { + continue; + } + List relateList = cilSection.getRelateList(); + if (relateList.isEmpty()) { + cilSection.lockByOverlap(overlap); + } else { + for (CilSection section : relateList) { + section.lockByOverlap(overlap); + } + } + } + } + /** * 进路监控 * @param cilRoute */ private void watchRoute(CilRoute cilRoute) { - if (cilRoute.isOpen()) { + if (cilRoute.isOpenAspect()) { } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilFls.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilFls.java index 4c2f00a68..6188a9ee5 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilFls.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilFls.java @@ -24,6 +24,7 @@ public class CilFls { this.name = name; } + @Getter public static class FlsElement { CilSwitchPosition pp; // 防护道岔 CilSignal ps; // 防护信号 @@ -38,5 +39,14 @@ public class CilFls { this.ps = ps; 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(); + } + } } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilOverlap.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilOverlap.java index be4823b0b..d5a5bbbe1 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilOverlap.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilOverlap.java @@ -1,14 +1,25 @@ package club.joylink.rtss.simulation.rt.CIL.bo; +import lombok.Getter; + import java.util.List; +@Getter public class CilOverlap extends CilDevice { + boolean right; + CilSignal start; CilSection releaseSection; List pathElementList; - int releaseTime; + int releaseTime; // 延续保护解锁时间 + + CilRoutePathElement selectedPath; // 选择出所需办理的路径 public CilOverlap(String id, String name) { super(id, name); } + + public void updateSelectedPath(CilRoutePathElement cilRoutePathElement) { + this.selectedPath = cilRoutePathElement; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java index 340c7e996..bfaa01507 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepository.java @@ -84,4 +84,8 @@ public class CilRepository extends SimulationRepository { public List getSupervisedRouteList() { return new ArrayList<>(this.supervisedRouteMap.values()); } + + public void addSupervisedRoute(CilRoute cilRoute) { + this.supervisedRouteMap.put(cilRoute.getId(), cilRoute); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepositoryBuilder.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepositoryBuilder.java index 77ef5f339..d102bc16f 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepositoryBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRepositoryBuilder.java @@ -204,9 +204,11 @@ public class CilRepositoryBuilder { CilSection cilSection = sectionMap.get(overlapVO.getUnlockSectionCode()); BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(cilSection, String.format("不存在id为[%s]的区段", overlapVO.getUnlockSectionCode())); - cilOverlap.releaseSection = cilSection; - cilOverlap.releaseTime = overlapVO.getUnlockTime(); 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, String.format("不存在id为[%s]的信号机", overlapVO.getSignalCode())); cilOverlap.pathElementList = buildPathElementList(cilSignal, overlapVO.getPathList(), sectionMap, switchMap, flsMap); diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java index 5e874d23c..9e14b92cc 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilRoute.java @@ -2,11 +2,15 @@ package club.joylink.rtss.simulation.rt.CIL.bo; import lombok.Getter; +import java.time.LocalDateTime; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; @Getter public class CilRoute extends CilDevice { + CilServer cilServer; int type; // 进路类型 public static final int TYPE_ATP = 1; public static final int TYPE_GROUND = 2; @@ -15,7 +19,7 @@ public class CilRoute extends CilDevice { CilSignal start; CilSignal end; CilRoutePathElement pathElement; - CilOverlap overlap; + CilOverlap overlap; // 延续保护 boolean ars; // ATS自排 boolean arc; // 自动追踪/联锁自动触发 boolean flt; // 车队/自动进路 @@ -29,6 +33,9 @@ public class CilRoute extends CilDevice { public static final int SA_YELLOW = 3; public static final int SA_GUIDE = 4; //引导信号,黄红灯显示 + Map waitTurnMap = new ConcurrentHashMap<>(); // 进路办理中待转换的道岔 + Map waitOnPositionMap = new ConcurrentHashMap<>(); // 进路办理中待转换到位的道岔 + LocalDateTime stageStartTime; int stage; // 进路当前所处逻辑阶段 public static final int STAGE_NONE = 0; // 无 public static final int STAGE_SETTING = 1; // 建立阶段 @@ -44,13 +51,26 @@ public class CilRoute extends CilDevice { super(id, name); } - public boolean isOpen() { + public boolean isOpenAspect() { return this.start.getSignalAspect() == CilSignal.GREEN || this.start.getSignalAspect() == CilSignal.YELLOW; } - public boolean isGuide() { + public boolean isGuideAspect() { 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(); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java index f9d608036..5181d9443 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSection.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.rt.CIL.bo; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import lombok.Getter; import java.util.ArrayList; @@ -10,16 +11,15 @@ import java.util.Objects; public class CilSection extends CilDevice { CilSection parent; - List relateList = new ArrayList<>(); - List reverseList = new ArrayList<>(); + List relateList = new ArrayList<>(); // 关联的子区段,顺序 + List reverseList = new ArrayList<>(); // 关联的子区段,逆序 CilSwitch belongSwitch; - CilSignal leftSignal; - CilSignal rightSignal; boolean axcOccupy; String routeId; // 锁闭进路的id boolean rl; // 进路锁闭 boolean lr; // 进路锁闭方向,true-右向,false-左向 + boolean ol; // 延续保护锁闭 public CilSection(String id, String name) { super(id, name); @@ -41,4 +41,14 @@ public class CilSection extends CilDevice { 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(); + } + } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilServer.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilServer.java index 8039b4d15..d03b4ec95 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilServer.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilServer.java @@ -2,9 +2,21 @@ package club.joylink.rtss.simulation.rt.CIL.bo; 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; public CilServer(String id, String name) { super(id, name); + this.mode = M_CTC; + } + + public boolean isCtcMode() { + return this.mode == M_CTC; + } + + public boolean isReserveMode() { + return this.mode == M_RS; } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java index a14e34de8..277ba3dc4 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSignal.java @@ -1,6 +1,6 @@ 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 java.util.List; @@ -18,10 +18,12 @@ public class CilSignal extends CilDevice { public static final int YELLOW = 3; // 黄灯信号(侧向通行) public static final int GUIDE = 4; // 引导信号(正线为黄红) boolean logic; + boolean forceLight; // 强制点灯 boolean bl; // 封锁 boolean rbl; // 重复封锁 - int forceLight; + boolean uta; // 未装备列车接近 + int level; public static final int LEVEL_1 = 1; //关闭/非监控级 public static final int LEVEL_2 = 2; //引导级 @@ -33,11 +35,25 @@ public class CilSignal extends CilDevice { } public void updateByDeviceState(int state) { - if (state == SrSignal.CLOSE) { + if (state == SrSignal.OFF) { this.logic = true; } else { this.logic = false; 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; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java index 9364ba04e..ebed965e2 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitch.java @@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.rt.CIL.bo; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import lombok.Getter; +import java.util.Objects; + @Getter public class CilSwitch extends CilDevice { @@ -20,6 +22,7 @@ public class CilSwitch extends CilDevice { boolean bl; // 封锁 boolean sl; // 单锁 + String routeId; // 锁闭进路的id boolean rl; // 进路锁闭 boolean ol; // 延续保护锁闭 boolean fl; // 侧防锁闭 @@ -53,4 +56,27 @@ public class CilSwitch extends CilDevice { BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(NORMAL == position || REVERSE == 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; + } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitchPosition.java b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitchPosition.java index e34a91a65..0cb4d2e41 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitchPosition.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/CIL/bo/CilSwitchPosition.java @@ -23,4 +23,12 @@ public class CilSwitchPosition { public boolean isOnPosition() { return this.cilSwitch.position == this.position; } + + public void routeUse() { + this.cilSwitch.routeUse(this.position); + } + + public boolean isNormalPosition() { + return CilSwitch.NORMAL == this.position; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/DEPOT/DepotLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/DEPOT/DepotLogicService.java new file mode 100644 index 000000000..68b92dd97 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/DEPOT/DepotLogicService.java @@ -0,0 +1,10 @@ +package club.joylink.rtss.simulation.rt.DEPOT; + +import org.springframework.stereotype.Component; + +/** + * 车辆段/停车场逻辑 + */ +@Component +public class DepotLogicService { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulation.java b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulation.java index a9c1f2fe0..bebfb04ab 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulation.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulation.java @@ -3,13 +3,20 @@ package club.joylink.rtss.simulation.rt; import club.joylink.rtss.simulation.Simulation; import lombok.Getter; +import java.time.LocalDateTime; + @Getter public class RtSimulation extends Simulation { + public static final int TIME_OFFSET_HOUR = 2; public RtSimulation(String id) { super(id); } + public LocalDateTime convertToSystemTime(LocalDateTime dateTime) { + return dateTime.minusHours(TIME_OFFSET_HOUR); + } + @Override public String debugStr() { return String.format("轨道交通仿真[%s]", getId()); diff --git a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java index 74f00c6ef..6b939cfed 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/RtSimulationService.java @@ -2,7 +2,7 @@ package club.joylink.rtss.simulation.rt; import club.joylink.rtss.services.MapService; 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.client.map.MapVO; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java new file mode 100644 index 000000000..8bfa4777e --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdApiService.java @@ -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 queryAllAxc(RtSimulation rtSimulation) { + SrdRepository repository = this.getSrdRepository(rtSimulation); + return repository.getAxcList(); + } + + public List queryAllSwitch(RtSimulation rtSimulation) { + SrdRepository repository = this.getSrdRepository(rtSimulation); + return repository.getSwitchList(); + } + + public List queryAllSignal(RtSimulation rtSimulation) { + SrdRepository repository = this.getSrdRepository(rtSimulation); + return repository.getSignalList(); + } + + public List 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) { + // 发送信号机变更 + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdLogicService.java new file mode 100644 index 000000000..9001244cc --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/SrdLogicService.java @@ -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 turnoutList = repository.getSwitchList(); + for (SrSwitch turnout : turnoutList) { + if (turnout.isControlByReal()) { + continue; + } + if (turnout.isTurning()) { + turnout.tryFinishTurning(systemTime); + } + } + // 屏蔽门开/闭 + List psdList = repository.getPsdList(); + for (SrPSD psd : psdList) { + if (psd.isControlByReal()) { + continue; + } + if (psd.isTurning()) { + psd.tryFinishTurning(systemTime); + } + } + // 信号机控制 + List signalList = repository.getSignalList(); + for (SrSignal signal : signalList) { + if (signal.isControlByReal()) { + continue; + } + if (signal.isTurning()) { + signal.tryFinishTurning(systemTime); + } + } + } + + public void srTrainRun(SrdRepository repository) { + List 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 occupiedTrackSet = new HashSet<>(); + TrackPosition tailPosition = this.calculatePosition(np, srTrain.getLen(), !right, occupiedTrackSet); + srTrain.updatePositionAndSpeed(np, tailPosition, cv); + // 更新计轴占用 + Set oldOccupiedTrackSet = new HashSet<>(); + this.calculatePosition(position, srTrain.getLen(), !right, oldOccupiedTrackSet); + Set 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 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); + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/DeviceType.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/DeviceType.java new file mode 100644 index 000000000..ce8cd28f6 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/DeviceType.java @@ -0,0 +1,16 @@ +package club.joylink.rtss.simulation.rt.SRD.bo; + +public enum DeviceType { + /** 计轴器 */ + AXC, + /** 道岔 */ + TURNOUT, + /** 信号机 */ + SIGNAL, + /** 站台屏蔽门 */ + PSD, + TRAIN, + /** 轨道 */ + TRACK + +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrAXC.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrAXC.java new file mode 100644 index 000000000..9ac080201 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrAXC.java @@ -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) { + + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrDevice.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrDevice.java new file mode 100644 index 000000000..6611532b7 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrDevice.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrPSD.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrPSD.java new file mode 100644 index 000000000..baa280e87 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrPSD.java @@ -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)); + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSignal.java new file mode 100644 index 000000000..9b0b143de --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSignal.java @@ -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)); + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSwitch.java new file mode 100644 index 000000000..cfbc31b2d --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrSwitch.java @@ -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)); + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrack.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrack.java new file mode 100644 index 000000000..3d95aa9c8 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrack.java @@ -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); + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrain.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrain.java new file mode 100644 index 000000000..178b8421f --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrTrain.java @@ -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) { + + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepository.java new file mode 100644 index 000000000..efc178420 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepository.java @@ -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 trackMap; + Map axcMap; + Map switchMap; + Map signalMap; + Map psdMap; + Map 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 getTrainList() { + return new ArrayList<>(this.trainMap.values()); + } + + public List getSwitchList() { + return new ArrayList<>(this.switchMap.values()); + } + + public List getPsdList() { + return new ArrayList<>(this.psdMap.values()); + } + + public List getSignalList() { + return new ArrayList<>(this.signalMap.values()); + } + + @Override + public void initState() { + + } + + public List 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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepositoryBuilder.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepositoryBuilder.java new file mode 100644 index 000000000..3d82ddd94 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/SrdRepositoryBuilder.java @@ -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 sectionList, Map trackMap, Map 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 signalList, + Map signalMap, + Map 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 switchList, + Map turnoutMap, + Map 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 sectionList, + Map trackMap, + Map 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 switchList, Map turnoutMap) { + for (MapSwitchVO switchVO : switchList) { + SrSwitch srSwitch = new SrSwitch(switchVO.getCode()); + turnoutMap.put(srSwitch.getId(), srSwitch); + } + } + + private static void buildSignal(List signalList, Map signalMap) { + for (MapSignalNewVO signalVO : signalList) { + SrSignal srSignal = new SrSignal(signalVO.getCode()); + + signalMap.put(srSignal.getId(), srSignal); + } + } + + private static void buildSrPsd(List psdList, Map psdMap) { + for (MapPSDVO psdVO : psdList) { + SrPSD srPSD = new SrPSD(psdVO.getCode()); + psdMap.put(srPSD.getId(), srPSD); + } + } + + private static void buildTrain(List trainList, Map trainMap) { + for (MapTrainVO trainVO : trainList) { + MapTrainModelVO trainModel = trainVO.getTrainModel(); + SrTrain srTrain = new SrTrain(trainVO.getGroupNumber(), (int) (trainModel.getLength() * 1000)); + trainMap.put(srTrain.getId(), srTrain); + } + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/TrackPosition.java b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/TrackPosition.java new file mode 100644 index 000000000..d6d3dd10b --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/SRD/bo/TrackPosition.java @@ -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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/TL/TlLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/TL/TlLogicService.java new file mode 100644 index 000000000..cb2bf42b9 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/TL/TlLogicService.java @@ -0,0 +1,10 @@ +package club.joylink.rtss.simulation.rt.TL; + +import org.springframework.stereotype.Component; + +/** + * 车载逻辑 + */ +@Component +public class TlLogicService { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlPsd.java b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlPsd.java new file mode 100644 index 000000000..aeb1cabef --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlPsd.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.TL.bo; + +public class TlPsd { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlRepository.java new file mode 100644 index 000000000..5bf8f2a89 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlRepository.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.TL.bo; + +public class TlRepository { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlTrain.java b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlTrain.java new file mode 100644 index 000000000..eed57c706 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/TL/bo/TlTrain.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.TL.bo; + +public class TlTrain { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/TrainLoadService.java b/src/main/java/club/joylink/rtss/simulation/rt/TrainLoadService.java new file mode 100644 index 000000000..305097ed9 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/TrainLoadService.java @@ -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 loadTripList = this.queryLoadTrips(rtSimulation, dateTime); + q = loadTripList.size(); + return q; + } + + private List queryLoadTrips(RtSimulation rtSimulation, LocalDateTime dateTime) { + LocalTime time = dateTime.toLocalTime(); + AtsRepository atsRepository = rtSimulation.getRepository(AtsRepository.NAME, AtsRepository.class); + AtsRunPlan runPlan = atsRepository.getRunPlan(); + List loadTripList = new ArrayList<>(); + // 查询需加载列车计划车次逻辑: + // 遍历终端发车计划列表,如下情况即为需要加载: + // 1,指定时间在计划开始和结束时间之间; + // 2,指定时间大于此计划开始时间,小于此计划终点区段终端下一计划开始时间; + Map> endTripMap = runPlan.getEndTripMap(); + for (List 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 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 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 {// 在此次计划和下一计划间,可能是备用车也可能是折返车 + } + } + } + +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/ZcLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/ZcLogicService.java new file mode 100644 index 000000000..91454fbef --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/ZcLogicService.java @@ -0,0 +1,10 @@ +package club.joylink.rtss.simulation.rt.ZC; + +import org.springframework.stereotype.Component; + +/** + * 区域控制器逻辑 + */ +@Component +public class ZcLogicService { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcDevice.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcDevice.java new file mode 100644 index 000000000..3a7763667 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcDevice.java @@ -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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcOverlap.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcOverlap.java new file mode 100644 index 000000000..b2bf9e6bb --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcOverlap.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRepository.java new file mode 100644 index 000000000..690f66b47 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRepository.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.ZC.bo; + +public class ZcRepository { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRoute.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRoute.java new file mode 100644 index 000000000..7069768ac --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcRoute.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcSection.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcSection.java new file mode 100644 index 000000000..4eddc24bf --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcSection.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcStand.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcStand.java new file mode 100644 index 000000000..25d2610da --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcStand.java @@ -0,0 +1,4 @@ +package club.joylink.rtss.simulation.rt.ZC.bo; + +public class ZcStand { +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcTrain.java b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcTrain.java new file mode 100644 index 000000000..ab2bcdaba --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/rt/ZC/bo/ZcTrain.java @@ -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); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdApiService.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdApiService.java index 16a3db82c..8bfa4777e 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdApiService.java @@ -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.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 java.time.LocalDateTime; import java.util.List; @Component @@ -39,12 +40,53 @@ public class SrdApiService { 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) { - srSwitch.turnToNormal(rtSimulation.getSystemTime()); + startTurn = srSwitch.turnToNormal(rtSimulation.getSystemTime()); } else if (SrSwitch.REVERSE == position) { - srSwitch.turnToReverse(rtSimulation.getSystemTime()); + 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) { + // 发送信号机变更 + } } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdLogicService.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdLogicService.java index 200654079..9001244cc 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdLogicService.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/SrdLogicService.java @@ -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.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 lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/DeviceType.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/DeviceType.java index 649a24049..ce8cd28f6 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/DeviceType.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/DeviceType.java @@ -1,4 +1,4 @@ -package club.joylink.rtss.simulation.rt.srd.bo; +package club.joylink.rtss.simulation.rt.SRD.bo; public enum DeviceType { /** 计轴器 */ diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrAXC.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrAXC.java index 2a810b171..9ac080201 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrAXC.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrAXC.java @@ -1,4 +1,4 @@ -package club.joylink.rtss.simulation.rt.srd.bo; +package club.joylink.rtss.simulation.rt.SRD.bo; /** * 虚拟真实计轴器(Axle counter) diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrDevice.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrDevice.java index 8f2c07115..6611532b7 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrDevice.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrDevice.java @@ -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 lombok.Getter; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrPSD.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrPSD.java index 651a21ab8..baa280e87 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrPSD.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrPSD.java @@ -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.util.concurrent.TimeUnit; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSignal.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSignal.java index 450eaeabd..9b0b143de 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSignal.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSignal.java @@ -1,4 +1,4 @@ -package club.joylink.rtss.simulation.rt.srd.bo; +package club.joylink.rtss.simulation.rt.SRD.bo; import lombok.Getter; @@ -22,8 +22,8 @@ public class SrSignal extends SrDevice { */ int offset; - int state = CLOSE; - public static final int CLOSE = 0; // 关闭 + 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; // 黄灯信号(侧向通行) @@ -54,7 +54,7 @@ public class SrSignal extends SrDevice { } public void close(LocalDateTime systemTime) { - this.startTurn(systemTime, CLOSE); + this.startTurn(systemTime, OFF); } public void openRed(LocalDateTime systemTime) { @@ -91,7 +91,7 @@ public class SrSignal extends SrDevice { } @Override 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; } else { throw new IllegalArgumentException(String.format("无效的道岔状态:[%s]", state)); diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSwitch.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSwitch.java index bbd4d2faa..cfbc31b2d 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSwitch.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrSwitch.java @@ -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.util.concurrent.TimeUnit; @@ -66,18 +66,20 @@ public class SrSwitch extends SrDevice { return NONE != this.command.get(); } - public void turnToNormal(LocalDateTime systemTime) { - if (this.isNormalPosition()) { - return; + public boolean turnToNormal(LocalDateTime systemTime) { + if (this.isNormalPosition() || this.command.get() == NORMAL) { + return false; } this.startTurn(systemTime, NORMAL); + return true; } - public void turnToReverse(LocalDateTime systemTime) { - if (this.isReversePosition()) { - return; + 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) { diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrack.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrack.java index c35b68efb..3d95aa9c8 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrack.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrack.java @@ -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 lombok.Getter; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrain.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrain.java index a1e187d9a..178b8421f 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrain.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrTrain.java @@ -1,4 +1,4 @@ -package club.joylink.rtss.simulation.rt.srd.bo; +package club.joylink.rtss.simulation.rt.SRD.bo; import lombok.Getter; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepository.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepository.java index aef6395de..efc178420 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepository.java @@ -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.simulation.SimulationRepository; @@ -58,4 +58,10 @@ public class SrdRepository extends SimulationRepository { 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; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepositoryBuilder.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepositoryBuilder.java index be3d35a4c..3d82ddd94 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepositoryBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/SrdRepositoryBuilder.java @@ -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.vo.client.map.MapSwitchVO; diff --git a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/TrackPosition.java b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/TrackPosition.java index 963d22def..d6d3dd10b 100644 --- a/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/TrackPosition.java +++ b/src/main/java/club/joylink/rtss/simulation/rt/srd/bo/TrackPosition.java @@ -1,4 +1,4 @@ -package club.joylink.rtss.simulation.rt.srd.bo; +package club.joylink.rtss.simulation.rt.SRD.bo; public class TrackPosition { SrTrack track;