Merge remote-tracking branch 'origin/test' into master-huawei

This commit is contained in:
joylink_zhangsai 2021-10-26 18:46:42 +08:00
commit aacca91bb8
105 changed files with 1723 additions and 347 deletions

View File

@ -0,0 +1,16 @@
package club.joylink.rtss.configuration.configProp;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix="udp")
@Getter
@Setter
public class UDPConfig {
private int serverPort;
private int clientPort;
}

View File

@ -40,6 +40,8 @@ public enum Project {
RICHOR,
/** 中航锐创(实训室,连设备,设备登录) */
RICHOR_JOINT,
/** 上饶沙盘 */
SR_SANDBOX,
;
public static boolean isDefault(Project project) {

View File

@ -12,6 +12,8 @@ import java.util.List;
public enum ProjectDeviceType {
/* -----------plc device start---------- */
/** 区段 */
SECTION,
/** 道岔 */
SWITCH,
/** 信号机 */
@ -28,6 +30,10 @@ public enum ProjectDeviceType {
PLC_GATEWAY,
/** 单元控制器 */
DCU,
/** UDP下位机 */
UDP_LOW,
/** UDP客户端 */
UDP_CLIENT,
/* -----------plc device end---------- */
/* -----------client device start---------- */
@ -57,6 +63,8 @@ public enum ProjectDeviceType {
CCTV,
/** 虚拟电子沙盘 */
SANDBOX,
/** 派班工作站 */
SCHEDULING,
/* -----------client device end---------- */
;
@ -66,8 +74,11 @@ public enum ProjectDeviceType {
PSD,
PSL,
IBP,
SECTION,
SWITCH,
SIGNAL,
DCU);
DCU,
UDP_LOW,
UDP_CLIENT);
}
}

View File

@ -231,9 +231,15 @@ public class DeviceController {
this.deviceService.addOrUpdateSdyDeviceConfig(accountVO);
}
@PostMapping("/richor/addOrUpdate")
public void addOrUpdateRichorDeviceConfig(@RequestAttribute(name = AuthenticateInterceptor.LOGIN_USER_KEY)
@PostMapping("/zjd/addOrUpdate")
public void addOrUpdateZjdDeviceConfig(@RequestAttribute(name = AuthenticateInterceptor.LOGIN_USER_KEY)
AccountVO accountVO) {
this.deviceService.addOrUpdateRichorDeviceConfig(accountVO);
}
@PostMapping("/sr/addOrUpdate/{mapId}")
public void addOrUpdateSrDeviceConfig(@RequestAttribute(name = AuthenticateInterceptor.LOGIN_USER_KEY)
AccountVO accountVO, @PathVariable Long mapId) {
this.deviceService.addOrUpdateSrDeviceConfig(accountVO, mapId);
}
}

View File

@ -292,7 +292,7 @@ public class VirtualRealityIbpService implements IVirtualRealityIbpService {
element.setOn(stands.stream().allMatch(Stand::isEmergencyClosed) || sd);
break;
case gmLight:
element.setOn(stands.stream().allMatch(stand -> stand.getPsd().isClose()) || sd);
element.setOn(stands.stream().allMatch(stand -> stand.getPsd().isCloseAndLock()) || sd);
break;
case kmLight:
element.setOn(!stands.stream().allMatch(stand -> stand.getPsd().isClose()) || sd);

View File

@ -290,7 +290,8 @@ public class AuthenticateService implements IAuthenticateService {
case LW:
case DEPOT:
case DRIVE:
case CW: {
case CW:
case SCHEDULING:{
// 工作站登录
this.projectJointSimulationService.handleWorkStationLogin(loginUserInfo);
break;

View File

@ -1,6 +1,5 @@
package club.joylink.rtss.services.draftData;
import club.joylink.rtss.entity.DraftMapRoute;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
@ -1981,8 +1980,8 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
SectionPath npPath = tempPath.cloneNew();// 定位路径
npPath.addSection(relSwitch.getB());
npPath.addSwitchElement(new SwitchElement(relSwitch, true));
// 没有侧防联动道岔存在
if (!config.isGenerateFls() && Objects.nonNull(linkedSwitch)) {
// 联动道岔存在
if (Objects.nonNull(linkedSwitch)) {
npPath.addSwitchElement(new SwitchElement(linkedSwitch, true));
}
getRoutePathOfDepot(startSignal, relSwitch.getB().getSectionOf(right), npPath, routePathList, config, errorList);
@ -1991,7 +1990,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
rpPath.addSwitchElement(new SwitchElement(relSwitch, false));
// 如果是同一道岔计轴添加另一道岔定位
Switch otherSwitch = relSwitch.queryAxleRelatedOtherSwitch();
if (!config.isGenerateFls() && Objects.nonNull(otherSwitch) && relSwitch.isBConnectTo(otherSwitch)) {
if (Objects.nonNull(otherSwitch) && relSwitch.isBConnectTo(otherSwitch)) {
rpPath.addSwitchElement(new SwitchElement(otherSwitch, true));
// 另一道岔联动道岔也需要
Switch otherLinkSwitch = otherSwitch.queryLinkedSwitch();
@ -2005,7 +2004,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
tempPath.addSection(relSwitch.getA());
tempPath.addSwitchElement(new SwitchElement(relSwitch, true));
// 没有侧防且联动道岔存在
if (!config.isGenerateFls() && Objects.nonNull(linkedSwitch)) {
if (Objects.nonNull(linkedSwitch)) {
tempPath.addSwitchElement(new SwitchElement(linkedSwitch, true));
}
getRoutePathOfDepot(startSignal, relSwitch.getA().getSectionOf(right), tempPath, routePathList, config, errorList);
@ -2015,7 +2014,7 @@ public class DraftMapCiDataGeneratorImpl implements DraftMapCiDataGenerator {
tempPath.addSwitchElement(new SwitchElement(relSwitch, false));
// 如果是同一道岔计轴添加另一道岔定位
Switch otherSwitch = relSwitch.queryAxleRelatedOtherSwitch();
if (!config.isGenerateFls() && Objects.nonNull(otherSwitch)) {
if (Objects.nonNull(otherSwitch)) {
tempPath.addSwitchElement(new SwitchElement(otherSwitch, true));
// 另一道岔联动道岔也需要
Switch otherLinkSwitch = otherSwitch.queryLinkedSwitch();

View File

@ -4,7 +4,11 @@ import club.joylink.rtss.vo.client.PageVO;
import club.joylink.rtss.vo.map.logic.MapRouteFlankProtectionNewVO;
import club.joylink.rtss.vo.map.query.MapRouteFlankProtectionQueryVO;
import java.util.List;
public interface DraftMapFlankProtectionService {
List<MapRouteFlankProtectionNewVO> queryAll(long mapId);
void create(MapRouteFlankProtectionNewVO flankProtectionNewVO);
PageVO<MapRouteFlankProtectionNewVO> pagingQueryFlankProtections(Long mapId, MapRouteFlankProtectionQueryVO queryVO);

View File

@ -14,6 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
@Slf4j
@Service
public class DraftMapFlankProtectionServiceImpl implements DraftMapFlankProtectionService {
@ -21,6 +23,14 @@ public class DraftMapFlankProtectionServiceImpl implements DraftMapFlankProtecti
@Autowired
private DraftMapRouteFlankProtectionDAO draftMapRouteFlankProtectionDAO;
@Override
public List<MapRouteFlankProtectionNewVO> queryAll(long mapId) {
DraftMapRouteFlankProtectionExample example = new DraftMapRouteFlankProtectionExample();
example.createCriteria().andMapIdEqualTo(mapId);
List<DraftMapRouteFlankProtection> list = draftMapRouteFlankProtectionDAO.selectByExampleWithBLOBs(example);
return MapRouteFlankProtectionNewVO.convert2VOList(list);
}
@Override
public void create(MapRouteFlankProtectionNewVO flankProtectionNewVO) {
// 编号/名称查重
@ -42,6 +52,9 @@ public class DraftMapFlankProtectionServiceImpl implements DraftMapFlankProtecti
if (StringUtils.hasText(queryVO.getName())) {
criteria.andNameLike(String.format("%%%s%%", queryVO.getName()));
}
if (StringUtils.hasText(queryVO.getCode())) {
criteria.andCodeLike(String.format("%%%s%%", queryVO.getCode()));
}
Page<DraftMapRouteFlankProtection> fpPageList = (Page<DraftMapRouteFlankProtection>) this.draftMapRouteFlankProtectionDAO.selectByExample(example);
return PageVO.convert(fpPageList, MapRouteFlankProtectionNewVO.convert2VOList(fpPageList.getResult()));
}

View File

@ -1,16 +1,7 @@
package club.joylink.rtss.services.draftData;
import club.joylink.rtss.vo.map.*;
import club.joylink.rtss.vo.map.logic.MapAutoReentryVO;
import club.joylink.rtss.vo.map.logic.MapAutoSignalNewVO;
import club.joylink.rtss.vo.map.logic.MapDestinationCodeDefinitionVO;
import club.joylink.rtss.vo.map.logic.MapOverlapVO;
import club.joylink.rtss.vo.map.logic.MapRouteFlankProtectionNewVO;
import club.joylink.rtss.vo.map.logic.MapRouteNewVO;
import club.joylink.rtss.vo.map.logic.MapRoutingDataVO;
import club.joylink.rtss.vo.map.logic.MapSignalApproachSectionVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
import club.joylink.rtss.vo.map.logic.MapStationRunLevelVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.logic.*;
import java.util.List;
@ -22,6 +13,11 @@ public interface DraftMapService {
*/
MapVO getDraftMapData(Long mapId);
/**
* 获取草稿地图的数据包含逻辑数据
*/
MapVO getDraftMapDataDetail(long mapId);
/**
* 清理旧的联锁数据并保存新联锁数据
* @param mapId

View File

@ -3,17 +3,9 @@ package club.joylink.rtss.services.draftData;
import club.joylink.rtss.dao.*;
import club.joylink.rtss.entity.*;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.map.*;
import club.joylink.rtss.vo.map.logic.MapAutoReentryVO;
import club.joylink.rtss.vo.map.logic.MapAutoSignalNewVO;
import club.joylink.rtss.vo.map.logic.MapDestinationCodeDefinitionVO;
import club.joylink.rtss.vo.map.logic.MapOverlapVO;
import club.joylink.rtss.vo.map.logic.MapRouteFlankProtectionNewVO;
import club.joylink.rtss.vo.map.logic.MapRouteNewVO;
import club.joylink.rtss.vo.map.logic.MapRoutingDataVO;
import club.joylink.rtss.vo.map.logic.MapSignalApproachSectionVO;
import club.joylink.rtss.vo.map.logic.MapStationParkingTimeVO;
import club.joylink.rtss.vo.map.logic.MapStationRunLevelVO;
import club.joylink.rtss.vo.map.MapLogicDataNewVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.logic.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -46,6 +38,21 @@ public class DraftMapServiceImpl implements DraftMapService {
@Autowired
private DraftMapParkingTimeDAO draftMapParkingTimeDAO;
@Autowired
private DraftMapRouteService draftMapRouteService;
@Autowired
private RunLevelService runLevelService;
@Autowired
private ParkTimeService parkTimeService;
@Autowired
private DraftMapOverrunService draftMapOverrunService;
@Autowired
private DraftMapOverlapService draftMapOverlapService;
@Autowired
private DraftMapFlankProtectionService draftMapFlankProtectionService;
@Autowired
private DraftMapSignalApproachSectionService draftMapSignalApproachSectionService;
@Override
public MapVO getDraftMapData(Long mapId) {
DraftMapWithBLOBs draftMap = this.draftMapDAO.selectByPrimaryKey(mapId);
@ -53,6 +60,25 @@ public class DraftMapServiceImpl implements DraftMapService {
return mapVO;
}
@Override
public MapVO getDraftMapDataDetail(long mapId) {
MapVO map = getDraftMapData(mapId);
MapLogicDataNewVO logicDataNew = new MapLogicDataNewVO();
logicDataNew.setRouteList(draftMapRouteService.queryAllRoutes(mapId));
logicDataNew.setRunLevelList(runLevelService.queryAll(mapId));
logicDataNew.setParkingTimeList(parkTimeService.queryAll(mapId));
logicDataNew.setOverrunList(draftMapOverrunService.queryAll(mapId));
logicDataNew.setOverlapList(draftMapOverlapService.queryAll(mapId));
logicDataNew.setFlankProtectionList(draftMapFlankProtectionService.queryAll(mapId));
// logicDataNew.setDestinationCodeDefinitionList(); 后续补上
// logicDataNew.setAutoSignalList(); 待补
// logicDataNew.setAutoReentryList(); 待补
// logicDataNew.setRoutingList(); 待补
logicDataNew.setSignalApproachSectionList(draftMapSignalApproachSectionService.queryAll(mapId));
map.setLogicDataNew(logicDataNew);
return map;
}
@Transactional
@Override
public void cleanAndSaveCiData(Long mapId,

View File

@ -8,11 +8,10 @@ import club.joylink.rtss.simulation.cbtc.data.CalculateService;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.map.logic.MapRoutingDataVO;
import club.joylink.rtss.vo.map.MapRoutingSectionNewVO;
import club.joylink.rtss.vo.map.logic.MapStationRunLevelVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.logic.MapRoutingDataVO;
import club.joylink.rtss.vo.map.logic.MapStationRunLevelVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -78,10 +77,10 @@ public class RunLevelService {
public List<MapStationRunLevelVO> generate(Long mapId) {
// 先校验地图基础数据
MapVO mapVO = this.draftMapService.getDraftMapData(mapId);
SimulationBuilder.SimulationDeviceBuildResult buildResult = SimulationBuilder.checkAndBuildBasicMapData(mapVO);
BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionEmpty(buildResult.getErrMsgList(),
String.format("地图基础数据有错误: %s", JsonUtils.writeValueAsString(buildResult.getErrMsgList())));
MapVO mapVO = this.draftMapService.getDraftMapDataDetail(mapId);
SimulationBuilder.SimulationDeviceBuildResult buildResult = SimulationBuilder.checkAndBuildMapData(mapVO);
// BusinessExceptionAssertEnum.DATA_ERROR.assertCollectionEmpty(buildResult.getErrMsgList(),
// String.format("地图基础数据有错误: %s", JsonUtils.writeValueAsString(buildResult.getErrMsgList())));
Map<String, MapElement> deviceMap = buildResult.getDeviceMap();
List<MapRoutingDataVO> routingDataVOList = this.draftMapService.queryRoutings(mapId);
List<MapStationRunLevelVO> runLevelVOList = this.generateRunLevels(routingDataVOList, deviceMap);

View File

@ -181,4 +181,6 @@ public interface DeviceService {
void addOrUpdateSdyDeviceConfig(AccountVO accountVO);
void addOrUpdateRichorDeviceConfig(AccountVO accountVO);
void addOrUpdateSrDeviceConfig(AccountVO accountVO, Long mapId);
}

View File

@ -6,6 +6,8 @@ import club.joylink.rtss.dao.ProjectDeviceDAO;
import club.joylink.rtss.entity.ProjectDevice;
import club.joylink.rtss.entity.ProjectDeviceExample;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.IMapService;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO;
import club.joylink.rtss.vo.client.PageVO;
@ -17,7 +19,15 @@ import club.joylink.rtss.vo.client.project.richor.ZjdPsdConfigVO;
import club.joylink.rtss.vo.client.project.richor.ZjdPslConfigVO;
import club.joylink.rtss.vo.client.project.sdy.SdyPsdConfigVO;
import club.joylink.rtss.vo.client.project.sdy.SdyPslConfigVO;
import club.joylink.rtss.vo.client.project.sr.SrSectionConfigVO;
import club.joylink.rtss.vo.client.project.sr.SrSignalConfigVO;
import club.joylink.rtss.vo.client.project.sr.SrSwitchConfigVO;
import club.joylink.rtss.vo.client.project.xty.XtyPsdConfigVO;
import club.joylink.rtss.vo.map.MapGraphDataNewVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.graph.MapSectionNewVO;
import club.joylink.rtss.vo.map.graph.MapSignalNewVO;
import club.joylink.rtss.vo.map.graph.MapSwitchVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
@ -37,6 +47,9 @@ public class DeviceServiceImpl implements DeviceService {
@Autowired
private ProjectDeviceDAO projectDeviceDAO;
@Autowired
private IMapService iMapService;
@Override
public PageVO<ProjectDeviceVO> pagingQuery(ProjectDevicePageQueryVO queryVO,
LoginUserInfoVO userLoginInfo) {
@ -391,19 +404,106 @@ public class DeviceServiceImpl implements DeviceService {
.map(Enum::name).collect(Collectors.toList()));
this.projectDeviceDAO.deleteByExample(example);
// 保存新配置
List<ProjectDevice> list = this.buildRichorProjectDevices(accountVO);
List<ProjectDevice> list = this.buildZjdProjectDevices(accountVO);
for (ProjectDevice projectDevice : list) {
this.projectDeviceDAO.insert(projectDevice);
}
}
private List<ProjectDevice> buildRichorProjectDevices(AccountVO accountVO) {
@Override
public void addOrUpdateSrDeviceConfig(AccountVO accountVO, Long mapId) {
// 删除旧配置
ProjectDeviceExample example = new ProjectDeviceExample();
example.createCriteria()
.andProjectCodeEqualTo(Project.SR_SANDBOX.name())
.andTypeIn(ProjectDeviceType.PlcDeviceList().stream()
.map(Enum::name).collect(Collectors.toList()));
this.projectDeviceDAO.deleteByExample(example);
// 保存新配置
List<ProjectDevice> list = this.buildSrProjectDevices(accountVO, mapId);
for (ProjectDevice projectDevice : list) {
this.projectDeviceDAO.insert(projectDevice);
}
}
private List<ProjectDevice> buildSrProjectDevices(AccountVO accountVO, long mapId) {
LocalDateTime now = LocalDateTime.now();
List<ProjectDevice> list = new ArrayList<>();
//UDP下位机
ProjectDevice udp = new ProjectDevice();
udp.setProjectCode(Project.SR_SANDBOX.name());
udp.setCode("sr-udp");
udp.setType(ProjectDeviceType.UDP_LOW.name());
udp.setCreator(accountVO.getId());
udp.setCreateTime(now);
UDPLowConfigVO udpConfigVO = new UDPLowConfigVO("", 10086);
udp.setConfig(udpConfigVO.toJson());
list.add(udp);
//UDP客户端
ProjectDevice udpClient = new ProjectDevice();
udpClient.setProjectCode(Project.SR_SANDBOX.name());
udpClient.setCode("sr-udp-client");
udpClient.setType(ProjectDeviceType.UDP_CLIENT.name());
udpClient.setCreator(accountVO.getId());
udpClient.setCreateTime(now);
UDPClientConfigVO udpClientConfigVO = new UDPClientConfigVO("192.168.8.109", 10000);
udpClient.setConfig(JsonUtils.writeValueAsString(udpClientConfigVO));
list.add(udpClient);
/*-------------------- 地图设备 --------------------*/
MapVO map = iMapService.getMapDetail(mapId);
MapGraphDataNewVO graphDataNew = map.getGraphDataNew();
//信号机
for (MapSignalNewVO mapSignalNewVO : graphDataNew.getSignalList()) {
if (StringUtils.hasText(mapSignalNewVO.getSrCode())) {
ProjectDevice signal = new ProjectDevice();
signal.setProjectCode(Project.SR_SANDBOX.name());
signal.setCode("sr-signal-" + mapSignalNewVO.getCode());
signal.setType(ProjectDeviceType.SIGNAL.name());
signal.setCreator(accountVO.getId());
signal.setCreateTime(now);
SrSignalConfigVO configVO = new SrSignalConfigVO(mapSignalNewVO.getCode(), mapSignalNewVO.getSrCode());
signal.setConfig(JsonUtils.writeValueAsString(configVO));
list.add(signal);
}
}
//道岔
for (MapSwitchVO mapSwitchVO : graphDataNew.getSwitchList()) {
if (StringUtils.hasText(mapSwitchVO.getSrCode())) {
ProjectDevice aSwitch = new ProjectDevice();
aSwitch.setProjectCode(Project.SR_SANDBOX.name());
aSwitch.setCode("sr-switch-" + mapSwitchVO.getCode());
aSwitch.setType(ProjectDeviceType.SWITCH.name());
aSwitch.setCreator(accountVO.getId());
aSwitch.setCreateTime(now);
SrSwitchConfigVO configVO = new SrSwitchConfigVO(mapSwitchVO.getCode(), mapSwitchVO.getSrCode());
aSwitch.setConfig(JsonUtils.writeValueAsString(configVO));
list.add(aSwitch);
}
}
//区段
for (MapSectionNewVO mapSectionNewVO : graphDataNew.getSectionList()) {
if (StringUtils.hasText(mapSectionNewVO.getSrCode())) {
ProjectDevice section = new ProjectDevice();
section.setProjectCode(Project.SR_SANDBOX.name());
section.setCode("sr-section-" + mapSectionNewVO.getCode());
section.setType(ProjectDeviceType.SECTION.name());
section.setCreator(accountVO.getId());
section.setCreateTime(now);
SrSectionConfigVO configVO = new SrSectionConfigVO(mapSectionNewVO.getCode(), mapSectionNewVO.getSrCode());
section.setConfig(JsonUtils.writeValueAsString(configVO));
list.add(section);
}
}
return list;
}
private List<ProjectDevice> buildZjdProjectDevices(AccountVO accountVO) {
LocalDateTime now = LocalDateTime.now();
List<ProjectDevice> list = new ArrayList<>();
// PLC网关
ProjectDevice plcGateway = new ProjectDevice();
plcGateway.setProjectCode(Project.RICHOR_JOINT.name());
plcGateway.setCode("richorJoint-gateway");
plcGateway.setCode("zjd-gateway");
plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name());
plcGateway.setCreator(accountVO.getId());
plcGateway.setCreateTime(now);
@ -413,7 +513,7 @@ public class DeviceServiceImpl implements DeviceService {
// 屏蔽门
ProjectDevice psd = new ProjectDevice();
psd.setProjectCode(Project.RICHOR_JOINT.name());
psd.setCode("richorJoint-psd");
psd.setCode("zjd-psd");
psd.setType(ProjectDeviceType.PSD.name());
psd.setCreator(accountVO.getId());
psd.setCreateTime(now);
@ -423,7 +523,7 @@ public class DeviceServiceImpl implements DeviceService {
// IBP盘
ProjectDevice ibp = new ProjectDevice();
ibp.setProjectCode(Project.RICHOR_JOINT.name());
ibp.setCode("richorJoint-ibp");
ibp.setCode("zjd-ibp");
ibp.setType(ProjectDeviceType.IBP.name());
ibp.setCreator(accountVO.getId());
ibp.setCreateTime(now);
@ -433,7 +533,7 @@ public class DeviceServiceImpl implements DeviceService {
// PSL
ProjectDevice psl = new ProjectDevice();
psl.setProjectCode(Project.RICHOR_JOINT.name());
psl.setCode("richorJoint-psl");
psl.setCode("zjd-psl");
psl.setType(ProjectDeviceType.PSL.name());
psl.setCreator(accountVO.getId());
psl.setCreateTime(now);

View File

@ -12,7 +12,7 @@ import club.joylink.rtss.vo.client.training.TrainingStepVO;
import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO;
import club.joylink.rtss.vo.client.training.definition.OperatePlaceholderVO;
import club.joylink.rtss.vo.client.training.definition.OperateStepVO;
import club.joylink.rtss.vo.map.*;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.graph.MapAutomaticRouteButtonVO;
import club.joylink.rtss.vo.map.graph.MapCycleButtonVO;
import club.joylink.rtss.vo.map.graph.MapTotalGuideLockButtonVO;
@ -121,9 +121,11 @@ public interface GeneratorNew {
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {
stepList.get(0).setDeviceCode(((Route) mapDevice).getStart().getCode());
} else {
if (!"bar".equals(stepList.get(0).getDeviceType())) { //为处理转为站控实训操作正确但结束实训判为错误的bug
stepList.get(0).setDeviceCode(mapDevice.getCode());
}
}
}
Map<String, OperatePlaceholderVO> placeholderVOMap = operateDefinitionVO.getPlaceholderVOMap();
// 设置定位
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {

View File

@ -213,6 +213,7 @@ public class SignalGeneratorNew implements GeneratorNew {
}
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
this.deviceStatusModifyTool.closeSignalDirectly(route.getStart());
signal.setForbidden(true);
trainingVOList.add(this.build(config, simulation, signal,null, operateDefinitionVO));
// 仿真重置
this.resetSimulation(simulation);

View File

@ -7,7 +7,6 @@ import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsSectionService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter;
import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool;
import club.joylink.rtss.vo.client.training.TrainingNewVO;
import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO;
@ -97,12 +96,13 @@ public class SwitchGeneratorNew implements GeneratorNew {
break;
}
case Switch_Axle_Pre_Reset:{
aSwitch.setPreReset(false);
VirtualRealitySectionAxleCounter virtualAxleCounter = aSwitch.getA().getParent().getVirtualAxleCounter();
virtualAxleCounter.setOccupy(true);
virtualAxleCounter.setPreReset(false);
virtualAxleCounter.setLeftCount(3);
virtualAxleCounter.setRightCount(3);
Switch.SwitchFault.AXLE_FAULT.apply(aSwitch);
// aSwitch.setPreReset(false);
// VirtualRealitySectionAxleCounter virtualAxleCounter = aSwitch.getA().getParent().getVirtualAxleCounter();
// virtualAxleCounter.setOccupy(true);
// virtualAxleCounter.setPreReset(false);
// virtualAxleCounter.setLeftCount(0);
// virtualAxleCounter.setRightCount(3);
break;
}
case Switch_Confirm_Axis_Valid:{

View File

@ -142,12 +142,6 @@ public class SimulationManager {
}
}
public void addSimulationMember(String id, SimulationMember member) {
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotNull(member);
Simulation simulation = this.getById(id);
simulation.addSimulationMember(member);
}
public void memberPlayedByUser(String id, String memberId, String userId) {
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(memberId);
Simulation simulation = this.getById(id);

View File

@ -46,6 +46,8 @@ public class GroundAtpApiServiceImpl implements GroundAtpApiService {
for (Section section : trainAtpSectionList) {
if (section.getParent() != null) {
clearList.add(section.getParent());
} else {
clearList.add(section);
}
}
if (train.isCommunicable()) {
@ -64,9 +66,7 @@ public class GroundAtpApiServiceImpl implements GroundAtpApiService {
}
// 先清除占用
for (Section section : clearList) {
for (Section logic : section.getLogicList()) {
logic.clearOccupy();
}
section.clearOccupy();
}
// 通信车占用
ctSectionsMap.forEach(((train, sections) -> {

View File

@ -1,7 +1,14 @@
package club.joylink.rtss.simulation.cbtc.ATS.data;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;
public class AtsMessage {
private static final AtomicInteger Id_Generator = new AtomicInteger(0);
private Integer id;
private LocalDateTime time;
}

View File

@ -73,10 +73,15 @@ public class OperateMethod {
}
} else if (Map.class.isAssignableFrom(parameter.getType())) {
args[i] = JsonUtils.read(JsonUtils.writeValueAsString(param.get(parameter.getName())), parameter.getType());
} else {
Object value = param.get(parameter.getName());
if (value != null) {
args[i] = JsonUtils.read(JsonUtils.writeValueAsString(value), parameter.getType());
} else {
args[i] = JsonUtils.read(JsonUtils.writeValueAsString(param), parameter.getType());
}
}
}
return args;
}
}

View File

@ -390,6 +390,8 @@ public class Operation {
Train_Cancel_Deviation,
/** 列车调度 */
Train_Regulation,
/** 计算行车间隔 */
Train_Calculate_Interval,
//--------------------------- 司机 ---------------------------
/** 改变列车的牵引/制动力 */

View File

@ -4,6 +4,8 @@ import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler;
import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.IntervalCalculateParam;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.IntervalCalculateResult;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.RegulationParam;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.TrainTypeUpdateParam;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
@ -22,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@OperateHandler
@ -388,4 +389,9 @@ public class TrainOperateHandler {
public void regulation(Simulation simulation, String groupNumber, BusinessConsts.Regulation regulation, RegulationParam regulationParam) {
atsTrainService.regulation(simulation, groupNumber, regulation, regulationParam);
}
@OperateHandlerMapping(type = Operation.Type.Train_Calculate_Interval)
public IntervalCalculateResult calculateInterval(Simulation simulation, IntervalCalculateParam calculateParam) {
return atsTrainService.calculateInterval(simulation, calculateParam.getTrainNumber(), calculateParam.getInterval());
}
}

View File

@ -0,0 +1,14 @@
package club.joylink.rtss.simulation.cbtc.ATS.operation.vo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class IntervalCalculateParam {
private Integer trainNumber;
private Integer interval;
}

View File

@ -0,0 +1,16 @@
package club.joylink.rtss.simulation.cbtc.ATS.operation.vo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class IntervalCalculateResult {
private int trainNumber;
private int intervalTime;
private int min;
private int avg;
private int max;
}

View File

@ -13,6 +13,11 @@ import java.util.Map;
@Setter
@NoArgsConstructor
public class RegulationParam {
/**
* 间隔时间
*/
private Integer intervalTime;
/**
* 列车停站时间
* k - standCode

View File

@ -22,7 +22,6 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
@ -230,7 +229,7 @@ public class AtsStandService {
"没有列车在该站台停靠");
}
// 站台DTI置为零
stand.earlyDepart();
stand.earlyDepart(simulation.getSystemTime());
}
/**

View File

@ -255,13 +255,18 @@ public class AtsStationService {
} else {
deviceStation = station.getDeviceStation();
}
//确认控制权现在属于该成员
BusinessExceptionAssertEnum.INVALID_OPERATION.assertTrue((member.isDispatcher() && station.isCenterControl())
|| (member.isStationSupervisor() && station.isStandControl()),
String.format("车站[%s]所属设备集中站[%s]当前控制权不在成员[%s]手中", station.getCode(), deviceStation.getCode(), member.getId()));
SimulationDataRepository repository = simulation.getRepository();
Set<Station> stations = repository.getStationsByDeviceStations(deviceStation);
boolean canSurrender = false;
if (member.isDispatcher() && deviceStation.isCenterControl()) {
canSurrender = true;
} else if (member.isStationSupervisor() && deviceStation.isLocalControl()) {
if (stations.stream().anyMatch(sta -> Objects.equals(sta, member.getDevice()))) {
canSurrender = true;
}
}
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(canSurrender,
String.format("成员[%s]无权交出设备集中站[%s]的控制权", member.getId(), deviceStation.debugStr()));
stations.forEach(Station::surrenderControl);
}
@ -279,6 +284,26 @@ public class AtsStationService {
} else {
deviceStation = station.getDeviceStation();
}
if ((member.isDispatcher() && deviceStation.isCenterControl())
|| (member.isStationSupervisor() && deviceStation.isLocalControl())) { //已是期望的控制模式
return;
}
SimulationDataRepository repository = simulation.getRepository();
Set<Station> stations = repository.getStationsByDeviceStations(deviceStation);
if (member.isDispatcher()) {
if (!deviceStation.isSurrenderControl()) {
List<SimulationMember> stationMember = simulation.getSimulationMembersByDevice(deviceStation);
if (!CollectionUtils.isEmpty(stationMember)) {
boolean allDispatchersAreRobots = stationMember.stream().allMatch(SimulationMember::isRobot);
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
.assertTrue(allDispatchersAreRobots,
String.format("车站[%s]控制权未交出", deviceStation.debugStr()));
}
}
stations.forEach(Station::occControl);
} else if (member.isStationSupervisor()) {
if (!deviceStation.isSurrenderControl()) {
List<SimulationMember> dispatchers = simulation.querySimulationMembersOfRole(SimulationMember.Type.DISPATCHER);
if (!CollectionUtils.isEmpty(dispatchers)) {
boolean allDispatchersAreRobots = dispatchers.stream().allMatch(SimulationMember::isRobot);
@ -286,11 +311,7 @@ public class AtsStationService {
.assertTrue(allDispatchersAreRobots,
String.format("车站[%s]控制权未交出", deviceStation.debugStr()));
}
SimulationDataRepository repository = simulation.getRepository();
Set<Station> stations = repository.getStationsByDeviceStations(deviceStation);
if (member.isDispatcher()) {
stations.forEach(Station::occControl);
} else if (member.isStationSupervisor()) {
}
stations.forEach(Station::localControl);
}
}

View File

@ -3,6 +3,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsRouteSelectService;
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
import club.joylink.rtss.simulation.cbtc.CI.CiLogic;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService;
@ -38,6 +39,8 @@ import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component
@ -69,6 +72,9 @@ public class AtsTrainLoadService {
@Qualifier("atsPlanTrainRouteSelectServiceImpl")
private AtsRouteSelectService atsRouteSelectService;
@Autowired
private CiApiService ciApiService;
public int getGivenTimeCouldLoadedTrainNumber(Simulation simulation, LocalTime time) {
List<TrainLoadParam2> list = this.getCurrentAllNeedLoadTrain(simulation, time);
return list.size();
@ -396,16 +402,16 @@ public class AtsTrainLoadService {
log.debug(String.format("实际加载列车数量:[%s]", loadedList.size()));
// 处理加载到折返轨的重叠列车
this.handleTurnBackCollisionTrainByTripPlan(simulation, loadedList);
// 列车进路排列
this.setTrainRouteByTripPlan(simulation, loadedList);
// 重叠列车处理
this.handleCollision(simulation, loadedList);
// 车次计划发车状态
this.updateTripPlanStatus(simulation);
// 列车上线并构建ATS监控列车信息
this.trainOnlineAndBuildSupervise(simulation, loadedList);
// 办理ats选择的进路
this.setRoutesThatSelectedByAts(simulation);
List<TrainInfo> superviseList = this.trainOnlineAndBuildSupervise(simulation, loadedList);
// 列车进路排列
this.setTrainRouteByTripPlan(simulation, loadedList, superviseList);
// // 办理ats选择的进路
// this.setRoutesThatSelectedByAts(simulation);
// 计算移动授权
// this.maService.calculateMaOfCtcTrains(simulation);
// this.zcLogicLoop.run(simulation);
@ -438,10 +444,17 @@ public class AtsTrainLoadService {
SimulationDataRepository repository = simulation.getRepository();
for (TrainInfo trainInfo : repository.getSuperviseTrainList()) {
VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber());
if (train.isStop())
continue;
//筛选其它进路
Route route = atsRouteSelectService.select(simulation, trainInfo);
if (route == null)
continue;
if (route.getStart().getSection().getCode().equals(trainInfo.getPlanStandTrack())) //进路始端信号机所在区段是列车的计划区段
continue;
Route.CheckFailMessage checkFailMessage = ciApiService.routeSettingCheck(simulation, route.getCode());
if (checkFailMessage != null)
continue;
VirtualRealityTrain thatTrain = map.get(route);
if (thatTrain != null) {
if (train.isRight() == thatTrain.isRight()) {
@ -492,7 +505,8 @@ public class AtsTrainLoadService {
}
}
private void trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) {
private List<TrainInfo> trainOnlineAndBuildSupervise(Simulation simulation, List<VirtualRealityTrain> loadedList) {
List<TrainInfo> superviseList = new ArrayList<>();
SimulationDataRepository repository = simulation.getRepository();
for (VirtualRealityTrain train : loadedList) {
// 构建监控列车信息
@ -544,8 +558,10 @@ public class AtsTrainLoadService {
}
trainInfo.tracking(train);
repository.addTrainInfo(trainInfo);
superviseList.add(trainInfo);
}
repository.addOnlineTrainList(loadedList);
return superviseList;
}
private boolean isOnSectionStopPoint(SectionPosition headPosition, Section section, boolean right) {
@ -635,8 +651,16 @@ public class AtsTrainLoadService {
return collisionList;
}
private void setTrainRouteByTripPlan(Simulation simulation, List<VirtualRealityTrain> loadedList) {
private void setTrainRouteByTripPlan(Simulation simulation, List<VirtualRealityTrain> loadedList, List<TrainInfo> superviseList) {
SimulationDataRepository repository = simulation.getRepository();
Map<String, TrainInfo> trainInfoMap = superviseList.stream()
.collect(Collectors.toMap(TrainInfo::getCode, Function.identity()));
// 按运行计划时间排序
loadedList.sort((train1, train2) -> {
TripPlan tripPlan1 = repository.getTripPlan(train1.getServiceNumber(), train1.getTripNumber());
TripPlan tripPlan2 = repository.getTripPlan(train2.getServiceNumber(), train2.getTripNumber());
return TripPlan.compare(tripPlan1, tripPlan2);
});
for (VirtualRealityTrain train : loadedList) {
Section headSection = train.getHeadPosition().getSection();
boolean right = train.isRight();
@ -647,18 +671,61 @@ public class AtsTrainLoadService {
for (int i = 1; i < viaSectionList.size(); i++) {
Section start = viaSectionList.get(i - 1);
Section end = viaSectionList.get(i);
// 取相邻两区段的路径单元查询进路
RoutePath routePath = this.selectDefaultRoutePath(repository, start, end);
Route route = routePath.queryRouteContainsSection(train.isCommunicable(), headSection, repository.getConfig());
if (Objects.nonNull(route)) {
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 进路设置为正常解锁
this.ciLogic.trainUnlockStart(simulation, route);
// // 根据列车位置直接进路正常解锁
// this.deviceStatusModifyTool.routeUnlockByEndSection(route, tailPosition.getSection());
TrainInfo trainInfo = trainInfoMap.get(train.getCode());
if (trainInfo.getPlanStandTrack() == null) {
break;
}
if (!end.getCode().equals(trainInfo.getPlanStandTrack())) {
continue;
}
Section tailSection = tailPosition.getSection();
// 取相邻两区段的路径单元查询进路
RoutePath routePath = this.selectDefaultRoutePath(repository, start, end);
if (!routePath.isPathSection(tailSection)) {
if (i - 2 >= 0) {
Section pre = viaSectionList.get(i - 2);
RoutePath preRoutePath = this.selectDefaultRoutePath(repository, pre, start);
Route route = preRoutePath.queryRouteContainsSection(train.isCommunicable(), tailSection, repository.getConfig());
if (route != null) {
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 根据列车位置直接进路正常解锁
this.deviceStatusModifyTool.routeUnlockByEndSection(route, tailSection);
}
}
}
List<Route> routeList = routePath.getRouteList();
Set<String> handledRouteStarts = new HashSet<>();
for (Route route : routeList) {
if (handledRouteStarts.contains(route.getStart().getCode())) {
continue;
}
if (route.isRouteSection(tailSection) || route.isRouteSection(headSection)) {
Route selected = routePath.selectDefaultRouteOfStart(route.getStart(), train.isCommunicable(), repository.getConfig());
if (selected != null) {
handledRouteStarts.add(route.getStart().getCode());
// 排列好进路
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
// 根据列车位置直接进路正常解锁
Section unlockTo = tailSection;
if (!route.isRouteSection(tailSection)) {
unlockTo = headSection;
}
this.deviceStatusModifyTool.routeUnlockByEndSection(route, unlockTo);
}
} else if (!train.isStop() && route.getStart().isApproachSection(headSection.getCode())) {
// 排列好进路
Route aheadRoute = routePath.selectDefaultRouteOfStart(route.getStart(), train.isCommunicable(), repository.getConfig());
if (aheadRoute != null) {
Route.CheckFailMessage message = ciApiService.routeSettingCheck(simulation, aheadRoute.getCode());
if (message == null) {
this.deviceStatusModifyTool.openRouteDirect(simulation, aheadRoute);
}
}
break;
}
}
break;
}
}
}

View File

@ -1,5 +1,7 @@
package club.joylink.rtss.simulation.cbtc.ATS.service;
import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.RegulationParam;
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsTriggerRouteService;
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsRealRunRecordService;
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsTrainStageHandler;
@ -7,6 +9,7 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.map.StationParkTime;
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan;
@ -23,6 +26,7 @@ import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Slf4j
@ -136,10 +140,16 @@ public class AtsTrainMonitorService {
this.realRunRecordService.recordTrainRealRun(simulation, train, station, standTrack, true);
train.updateArriveInfo(systemTime.toLocalTime(), station, standTrack);
if (!CollectionUtils.isEmpty(standTrack.getStandList())) {
int parkTime = this.atsStandService.trainParkingAndGetParkTime(simulation, standTrack, train.getGroupNumber());
Integer pt = findParkingTimeFromRegulation(simulation, train, standTrack);
int parkTime;
if (pt != null) {
parkTime = pt;
} else {
parkTime = this.atsStandService.trainParkingAndGetParkTime(simulation, standTrack, train.getGroupNumber());
if (parkTime < 0) {
parkTime = this.getParkTimeOf(simulation, train, standTrack);
}
}
this.atsStandService.updateStandParkTime(standTrack, parkTime);
if (standTrack.isNormalStandTrack()) {
train.updateEstimatedLeaveInfo(standTrack, systemTime.toLocalTime().plusSeconds(parkTime));
@ -151,6 +161,38 @@ public class AtsTrainMonitorService {
}
}
private Integer findParkingTimeFromRegulation(Simulation simulation, TrainInfo train, Section standTrack) {
BusinessConsts.Regulation regulation = train.getRegulation();
if (regulation == null)
return null;
Stand stand = standTrack.getStandList().get(0);
RegulationParam regulationParam = train.getRegulationParam();
Integer parkingTime;
switch (regulation) {
case TIME_TABLE_REGULATION:
return null;
case HEADWAY_REGULATION_FRONT:
case HEADWAY_REGULATION_FRONT_AND_BACK:
// LocalDateTime lastTrainDepartTime = stand.getLastTrainDepartTime();
// if (lastTrainDepartTime == null)
// return null;
// int seconds = (int) Duration.between(lastTrainDepartTime, simulation.getSystemTime()).getSeconds();
// parkingTime = regulationParam.getIntervalTime() - seconds;
return null;
case REGULATION_OFF:
Map<String, Integer> parkTimeMap = regulationParam.getParkTimeMap();
parkingTime = parkTimeMap.get(stand.getCode());
break;
default:
throw new IllegalStateException("Unexpected value: " + regulation);
}
if (parkingTime != null) {
return Math.min(20, parkingTime);
} else {
return null;
}
}
/**
* 获取列车停站时间
* @param simulation

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.ATS.service;
import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.IntervalCalculateResult;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.RegulationParam;
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsHeadTrainStageService;
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsPlanTrainStageService;
@ -952,67 +953,48 @@ public class AtsTrainService {
public void regulation(Simulation simulation, String groupNumber, BusinessConsts.Regulation regulation, RegulationParam regulationParam) {
SimulationDataRepository repository = simulation.getRepository();
switch (regulation) {
case TIME_TABLE_REGULATION: {
if (StringUtils.hasText(groupNumber)) {
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber);
trainInfo.setAtsAutoAdjust(true);
} else {
repository.getSuperviseTrainList().forEach(trainInfo ->
trainInfo.setAtsAutoAdjust(true));
}
case TIME_TABLE_REGULATION:
break;
}
case HEADWAY_REGULATION_FRONT:
break;
case HEADWAY_REGULATION_FRONT_AND_BACK:
BusinessExceptionAssertEnum.INVALID_OPERATION
.assertNotNull(regulationParam.getIntervalTime(), "间隔时间不能为空");
repository.setIntervalTime(regulationParam.getIntervalTime());
return;
case REGULATION_OFF:
break;
case REGULATION_OFF: {
default:
throw new IllegalStateException("Unexpected value: " + regulation);
}
if (StringUtils.hasText(groupNumber)) {
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber);
trainInfo.setAtsAutoAdjust(false);
trainInfo.updateRegulation(regulation, regulationParam);
} else {
repository.getSuperviseTrainList().forEach(trainInfo ->
trainInfo.setAtsAutoAdjust(false));
trainInfo.updateRegulation(regulation, regulationParam));
}
if (regulationParam == null)
break;
if (!CollectionUtils.isEmpty(regulationParam.getParkTimeMap())) {
regulationParam.getParkTimeMap().forEach((k, v) -> {
atsStandService.setParkTime(simulation, k, v, true, groupNumber);
});
}
if (!CollectionUtils.isEmpty(regulationParam.getRunTimeMap())) {
regulationParam.getRunTimeMap().forEach((k, v) -> {
atsStandService.setRunTime(simulation, k, v, true, groupNumber);
});
}
if (!CollectionUtils.isEmpty(regulationParam.getSkipMap())) {
regulationParam.getSkipMap().forEach((k, v) -> {
if (StringUtils.hasText(groupNumber)) {
Stand stand = repository.getByCode(k, Stand.class);
if (v) {
if (!stand.isAllSkip()) {
atsStandService.setJumpStop(simulation, k, groupNumber);
repository.setIntervalTime(null);
}
public IntervalCalculateResult calculateInterval(Simulation simulation, Integer trainNumber, Integer interval) {
IntervalCalculateResult result = new IntervalCalculateResult();
if (trainNumber != null) {
result.setTrainNumber(trainNumber);
int avgIntervalTime = 360 / trainNumber;
result.setAvg(avgIntervalTime);
result.setMin((int) (avgIntervalTime * 0.66));
result.setMax((int) (avgIntervalTime * 1.33));
result.setIntervalTime(avgIntervalTime);
} else if (interval != null){
result.setIntervalTime(interval);
int avgTrainNumber = 360 / interval;
result.setAvg(avgTrainNumber);
result.setMin(Math.max(0, avgTrainNumber - 1));
result.setMax(avgTrainNumber + 1);
result.setTrainNumber(avgTrainNumber);
} else {
if (stand.isAllSkip()) {
atsStandService.cancelJumpStop(simulation, k, null);
repository.getAllVrTrain().forEach(train ->
atsStandService.setJumpStop(simulation, k, train.getGroupNumber()));
}
atsStandService.cancelJumpStop(simulation, k, groupNumber);
}
} else {
if (v) {
atsStandService.setJumpStop(simulation, k, null);
} else {
atsStandService.cancelJumpStop(simulation, k, null);
}
}
});
}
break;
}
throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("参数异常");
}
return result;
}
}

View File

@ -53,8 +53,16 @@ public class AtsPlanTrainStageService implements AtsStageService {
}
LocalDateTime systemTime = simulation.getSystemTime();
if (systemTime.toLocalTime().plusSeconds(90).isAfter(tripPlan.getStartTime())) {
// Integer intervalTime = repository.getIntervalTime();
// LocalDateTime lastDepartTime = repository.getLastDepartTime();
// if (intervalTime != null && lastDepartTime != null) {
// if (systemTime.isBefore(lastDepartTime.plusSeconds(intervalTime))) {
// return;
// }
// }
StationPlan nextPlan = tripPlan.getSecondStationPlan();
this.updateNextPlan(simulation, trainInfo, tripPlan, nextPlan);
// repository.setLastDepartTime(systemTime);
}
}
}
@ -194,7 +202,7 @@ public class AtsPlanTrainStageService implements AtsStageService {
}
int planRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime);
int adjustRunTime = planRunTime;
if (!turnBack && !outbound && config.isAdjustOperationAutomatically()) {
if (!turnBack && !outbound && config.isAdjustOperationAutomatically() && trainInfo.isAtsAutoAdjust()) {
startTime = systemTime.toLocalTime();
adjustRunTime = (int) ChronoUnit.SECONDS.between(startTime, endTime);
}

View File

@ -250,7 +250,7 @@ public class CiApiServiceImpl2 implements CiApiService {
@Override
public void switchSectionFaultUnlock(Simulation simulation, String switchCode) {
Switch aSwitch = simulation.getRepository().getByCode(switchCode, Switch.class);
if (!aSwitch.isLocked())
if (!aSwitch.isLocked() && aSwitch.getAllSections().stream().noneMatch(Section::isFaultLock))
return;
List<Route> lockedRouteList = simulation.getRepository().queryAllLockedRoute();
Route lockedRoute = null;

View File

@ -13,7 +13,10 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
@ -308,7 +311,7 @@ public class CiRouteService {
}
if (section.isSwitchTrack()) {
Switch relSwitch = section.getRelSwitch();
relSwitch.routeUnlock();
relSwitch.routeUnlock(route);
RouteFls routeFls = route.queryRouteFlsOfSwitch(relSwitch);
if (routeFls != null) {
routeFls.unlock();
@ -432,7 +435,6 @@ public class CiRouteService {
if (!Objects.equals(route.getUnlockedSection(), section)) {
continue;
}
Switch relSwitch = section.getRelSwitch();
if (section.isOccupied()) {
// 区段逻辑占用且有逻辑区段
// log.warn("进路[{}]区段[{}]逐段解锁", route.debugStr(), section.debugStr());
@ -454,13 +456,13 @@ public class CiRouteService {
}
allUnlock = false;
break;
} else {
} else { // 区段不再占用
if (section.isSwitchTrack()) { // 如果是道岔区段解锁道岔
section.routeUnlocking(route);
if (section.getParent() != null && section.getParent().isCross()) {
section.getParent().routeUnlocking(route);
}
relSwitch.routeUnlock();
Switch relSwitch = section.getRelSwitch();
relSwitch.routeUnlock(route);
relSwitch.overlapUnLock();
// 侧防解锁
route.unlockRouteFlsOfSwitch(relSwitch);
@ -475,7 +477,7 @@ public class CiRouteService {
}
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
if (!aSwitch.getA().isRouteLock()) {
aSwitch.routeUnlock();
aSwitch.routeUnlock(route);
aSwitch.overlapUnLock();
}
}

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.simulation.cbtc.CI.device;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -145,7 +144,7 @@ public class CiService {
}
// 道岔位置一致检查
for (SwitchElement element : route.getSwitchList()) {
if (!element.isOnPosition()) {
if (!element.isOnPosition() || !element.getASwitch().isRouteLockBy(route)) {
// log.debug("进路{}连锁条件检查失败:道岔{}位置{}",
// route.debugStr(),
// element.getASwitch().debugStr(), element.getASwitch().getPos());

View File

@ -1,7 +1,8 @@
package club.joylink.rtss.simulation.cbtc.CI.device;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
@ -100,7 +101,7 @@ public class CiSwitchControlService {
if (vrSwitch.isPosN()) {
return this.turn2ReversePosition(simulation, aSwitch);
} else if (vrSwitch.isPosR()) {
return this.turn2ReversePosition(simulation, aSwitch);
return this.turn2NormalPosition(simulation, aSwitch);
}
}
return this.turn2NormalPosition(simulation, aSwitch);

View File

@ -19,8 +19,8 @@ import club.joylink.rtss.vo.client.runplan.PlanTripNumberVO;
import club.joylink.rtss.vo.client.runplan.RunPlanEChartsDataVO;
import club.joylink.rtss.vo.client.runplan.RunPlanVO;
import club.joylink.rtss.vo.client.simulationv1.*;
import club.joylink.rtss.vo.map.graph.MapStationNewVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.graph.MapStationNewVO;
import java.time.LocalDateTime;
import java.time.LocalTime;
@ -280,4 +280,6 @@ public interface GroupSimulationService {
void confirmHasPermission(AccountVO accountVO, Long mapId, String prdType);
boolean hasPermission(AccountVO accountVO, Long mapId, String prdType);
List<Simulation> querySimulations();
}

View File

@ -62,8 +62,8 @@ import club.joylink.rtss.vo.client.script.ScriptVO;
import club.joylink.rtss.vo.client.simulationv1.*;
import club.joylink.rtss.vo.client.training.TrainingNewVO;
import club.joylink.rtss.vo.client.userPermission.UserPermissionVO;
import club.joylink.rtss.vo.map.graph.MapStationNewVO;
import club.joylink.rtss.vo.map.MapVO;
import club.joylink.rtss.vo.map.graph.MapStationNewVO;
import club.joylink.rtss.websocket.StompMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -1073,6 +1073,11 @@ public class GroupSimulationServiceImpl implements GroupSimulationService {
return false;
}
@Override
public List<Simulation> querySimulations() {
return groupSimulationCache.queryAllSimulation();
}
private boolean isThirdAccountHasPermission(AccountVO accountVO, List<UserPermissionVO> ups, Long mapId, String prdType) {
if (accountVO.isThirdChildAccount()) {
List<LoginUserInfoVO> loginInfos = this.loginSessionManager.getAllLoginUserInfos();

View File

@ -9,7 +9,7 @@ import club.joylink.rtss.services.auth.ProjectDeviceLogoutEvent;
import club.joylink.rtss.services.auth.UserLogoutEvent;
import club.joylink.rtss.services.project.DeviceService;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.device.real.SimulationRealDeviceThread;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.SimulationRealDeviceThread;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1IbpConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1PscConfig;
@ -17,6 +17,10 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1Ps
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.richor.ZjdIbpConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.richor.ZjdPslConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.xty.XtyPsdConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSectionConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSignalConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSwitchConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceThread;
import club.joylink.rtss.simulation.cbtc.event.SimulationUserEnterEvent;
import club.joylink.rtss.simulation.cbtc.member.MemberManager;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
@ -25,7 +29,6 @@ import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO;
import club.joylink.rtss.vo.client.project.LwConfigVO;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.richor.ZjdPslConfigVO;
import club.joylink.rtss.vo.map.MapVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -64,6 +67,9 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation
@Autowired
private SimulationRealDeviceThread simulationRealDeviceThread;
@Autowired
private UDPRealDeviceThread udpRealDeviceThread;
@Override
public Simulation createSimulation(LoginUserInfoVO loginUserInfo) {
Project project = loginUserInfo.getProject();
@ -101,6 +107,7 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation
simulation.setRealDeviceList(realDeviceList);
if (!CollectionUtils.isEmpty(realDeviceList)) {
simulationRealDeviceThread.addJobs(simulation);
udpRealDeviceThread.addJobs(simulation);
}
for (RealDeviceConfig realDevice : realDeviceList) {
if (ProjectDeviceType.PLC_GATEWAY.equals(realDevice.getDeviceType())) {
@ -146,6 +153,16 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation
return ((ZjdPslConfig) config).getConfigVO().getPslCode();
}
}
case SR_SANDBOX: {
switch (config.getDeviceType()) {
case SIGNAL:
return ((SrSignalConfig) config).getConfigVO().getVrCode();
case SECTION:
return ((SrSectionConfig) config).getConfigVO().getVrCode();
case SWITCH:
return ((SrSwitchConfig) config).getConfigVO().getVrCode();
}
}
}
return null;
}
@ -213,6 +230,9 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation
this.memberManager.playRole(simulation, loginUserInfo.getAccountVO().getId(), depoter.getId());
break;
}
case SCHEDULING:{
}
}
loginUserInfo.setGroup(simulation.getId());
}

View File

@ -25,7 +25,6 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.simulation.cbtc.member.SimulationUser;
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
import club.joylink.rtss.simulation.rt.iscs.IscsStatusPublisher;
import club.joylink.rtss.simulation.vo.SimulationInfoVO;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.client.fault.FaultRuleVO;
@ -329,6 +328,27 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
return null;
}
public RealDeviceConfig queryOneRealDevice(ProjectDeviceType type) {
if (!CollectionUtils.isEmpty(realDeviceList)) {
for (RealDeviceConfig config : realDeviceList) {
if (Objects.equals(type, config.getDeviceType())) {
return config;
}
}
}
return null;
}
public List<RealDeviceConfig> queryAllRealDevice(ProjectDeviceType type) {
if (CollectionUtils.isEmpty(realDeviceList)) {
return Collections.emptyList();
} else {
return realDeviceList.stream()
.filter(config -> Objects.equals(config.getDeviceType(), type))
.collect(Collectors.toList());
}
}
public void pushModbusFuture(DeviceQueryFuture future) {
this.deviceQueryFutureQueue.add(future);
}
@ -652,5 +672,6 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
String commandExecuteRun = "commandExecuteRun";
String pslStatus = "pslStatus";
String ibpJob = "ibpJob";
String udpRealDevice = "udpRealDevice";
}
}

View File

@ -312,6 +312,9 @@ public class InterlockBuilder2 {
route.setFlt(mapRouteVO.isFlt());
route.setArs(mapRouteVO.isArc());
route.setAspect(mapRouteVO.getAspect());
if (route.getAspect() == null) {
errMsgList.add(String.format("进路%s没有配置信号显示", route.debugStr()));
}
MapSectionPathVO sectionPathVO = new MapSectionPathVO(route.getStart().isRight(), mapRouteVO.getRouteSectionList(), mapRouteVO.getRouteSwitchList());
List<String> errorList = new ArrayList<>();
SectionPath sectionPath = checkAndBuildSectionPath(sectionPathVO, elementMap, errorList);

View File

@ -1,17 +1,12 @@
package club.joylink.rtss.simulation.cbtc.build;
import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.entity.Ibp;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.constant.SignalModel;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption;
import club.joylink.rtss.simulation.cbtc.data.vr.*;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.ibp.IbpData;
import club.joylink.rtss.vo.client.ibp.IbpQueryVO;
import club.joylink.rtss.vo.client.ibp.IbpVO;
import club.joylink.rtss.vo.map.MapGraphDataNewVO;
import club.joylink.rtss.vo.map.graph.*;
import lombok.extern.slf4j.Slf4j;
@ -1007,8 +1002,8 @@ public class MapDeviceBuilder {
section.setFirstTurnBack(sectionVO.isFirstTurnBack());
section.setTransferTrack(sectionVO.isTransferTrack());
if (section.isTransferTrack()) {
if (section.isTurnBackTrack() || section.isStandTrack()) {
errMsgList.add(String.format("区段[%s(%s)]是转换轨,就不能再设置为站台轨或折返轨",
if (section.isStandTrack()) {
errMsgList.add(String.format("区段[%s(%s)]是转换轨,就不能再设置为站台轨",
section.getName(), section.getCode()));
}
}

View File

@ -700,8 +700,8 @@ public class CalculateService {
return;
}
if (iter > iterTimes) {
warnList.add(String.format("进路路径[%s]未找到:迭代100次,最后区段为[%s]",
routePath.debugStr(), routePath.getLastSection().debugStr()));
warnList.add(String.format("进路路径[%s]未找到:迭代[%s]次,最后区段为[%s]",
routePath.debugStr(), iterTimes, routePath.getLastSection().debugStr()));
return;
}
Section end = routePath.getEnd();

View File

@ -6,7 +6,6 @@ import club.joylink.rtss.simulation.cbtc.communication.vo.TrainHmiDisplay;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import club.joylink.rtss.simulation.cbtc.data.plan.RealRun;
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan;
import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan;
import club.joylink.rtss.simulation.cbtc.data.status.DeviceStatus;
import club.joylink.rtss.simulation.cbtc.data.status.IbpStatus;
@ -28,7 +27,7 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@ -222,6 +221,16 @@ public class SimulationDataRepository {
*/
private List<RunPlanTripVO> changeTrips = new CopyOnWriteArrayList<>();
/**
* 间隔时间/s
*/
private Integer intervalTime;
/**
* 最后发车的列车的发车时间
*/
private LocalDateTime lastDepartTime;
public void addChangeTrips(Collection<RunPlanTripVO> trips) {
this.changeTrips.addAll(trips);
}

View File

@ -5,11 +5,11 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import io.netty.util.internal.ConcurrentSet;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@ -157,10 +157,8 @@ public class Stand extends MayOutOfOrderDevice {
private boolean closed;
/**
* 折返路径策略
*/
// private boolean routeStrategy;
/** 最后一辆列车的发车时间 */
private LocalDateTime lastTrainDepartTime;
// ---------------------------- method -------------------------------------
@Override
@ -285,16 +283,6 @@ public class Stand extends MayOutOfOrderDevice {
return Objects.nonNull(this.psd) && this.psd.isInterlockRelease();
}
public synchronized void parkTrain(Integer parkTime) {
this.trainParking = true;
this.remainTime = parkTime;
}
public synchronized void trainLeave() {
this.trainParking = false;
this.remainTime = 0;
}
public boolean isPsdSafe() {
if (Objects.isNull(this.psd)) {
return true;
@ -326,11 +314,8 @@ public class Stand extends MayOutOfOrderDevice {
this.closed = true;
}
public boolean turnBackTypeNonDefault() {
return !Objects.equals(typeStrategy, TurnBackType.DEFAULT);
}
public void earlyDepart() {
public void earlyDepart(LocalDateTime systemTime) {
this.lastTrainDepartTime = systemTime;
this.setRemainTime(0);
}
@ -346,10 +331,6 @@ public class Stand extends MayOutOfOrderDevice {
this.runTimeMap.put(groupNumber, runLevelTime);
}
public void clearTrainRunTime() {
this.runTimeMap.clear();
}
/**
* 站台折返类型策略
*/

View File

@ -13,7 +13,6 @@ import lombok.NonNull;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@ -475,7 +474,7 @@ public class Station extends MayOutOfOrderDevice {
/**
* 是否站控
*/
public boolean isStandControl() {
public boolean isLocalControl() {
return Objects.equals(ControlMode.Local, this.controlMode);
}
@ -498,11 +497,11 @@ public class Station extends MayOutOfOrderDevice {
*/
public boolean underStandControl() {
if (isCentralized())
return isStandControl();
return isLocalControl();
if (hasControlMode) {
return isStandControl();
return isLocalControl();
} else {
return deviceStation.isStandControl();
return deviceStation.isLocalControl();
}
}

View File

@ -210,7 +210,8 @@ public class Switch extends DelayUnlockDevice {
this.route = route;
}
public void routeUnlock() {
public void routeUnlock(Route route) {
if (this.isRouteLockBy(route)) {
this.a.routeUnlocking(this.route);
this.b.routeUnlocking(this.route);
this.c.routeUnlocking(this.route);
@ -218,6 +219,11 @@ public class Switch extends DelayUnlockDevice {
this.route = null;
this.checkAndResetUsePosition();
}
}
public boolean isRouteLockBy(Route route) {
return this.routeLock && this.route.equals(route);
}
private void checkAndResetUsePosition() {
if (this.routeLock || this.fpLock || this.overlapLock ||
@ -387,7 +393,7 @@ public class Switch extends DelayUnlockDevice {
}
public void faultUnlock() {
this.routeUnlock();
this.routeUnlock(this.route);
this.overlapUnLock();
this.fpUnlock();
}

View File

@ -447,4 +447,42 @@ public class TripPlan {
}
}
}
/**
* 按计划时间先后顺序排序对于同向的按到某个都达到的站的时间排序对于不同向的默认向右在前
* @param list
*/
public static void sort(List<TripPlan> list) {
list.sort(TripPlan::compare);
}
/**
* 比较车次计划先后顺序, 对于同向的按到某个都达到的站的时间排序对于不同向的默认向右在前
* @param plan1
* @param plan2
* @return
*/
public static int compare(TripPlan plan1, TripPlan plan2) {
if (plan1.isRight() != plan2.isRight()) {
if (plan2.isRight()) {
return 1;
} else {
return -1;
}
} else {
List<StationPlan> spList1 = plan1.getPlanList();
List<StationPlan> spList2 = plan2.getPlanList();
StationPlan stationPlan1 = spList1.get(spList1.size() - 1);
StationPlan stationPlan2 = plan2.queryStationPlan(stationPlan1.getStation());
if (stationPlan2 != null) {
return stationPlan1.getArriveTime().compareTo(stationPlan2.getArriveTime());
}
stationPlan2 = spList2.get(spList2.size() - 1);
stationPlan1 = plan1.queryStationPlan(stationPlan2.getStation());
if (stationPlan1 != null) {
return stationPlan1.getArriveTime().compareTo(stationPlan2.getArriveTime());
}
}
return plan1.getStartTime().compareTo(plan2.getStartTime());
}
}

View File

@ -4,6 +4,7 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.MayOutOfOrderDevice;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
@ -34,6 +35,8 @@ public class StorageSection extends StorageDelayUnlockDevice {
@JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean routeLock;
private String route;
/**
* 锁闭方向
*/
@ -129,6 +132,11 @@ public class StorageSection extends StorageDelayUnlockDevice {
change = true;
storageSection.setRouteLock(section.isRouteLock());
}
Route route = section.getRoute();
if (route != null) {
change = true;
storageSection.setRoute(route.getCode());
}
if (section.isLockRight()) {
change = true;
storageSection.setLockRight(section.isLockRight());
@ -185,6 +193,7 @@ public class StorageSection extends StorageDelayUnlockDevice {
Section section = (Section) element;
section.setBlockade(blockade != null ? blockade : false);
section.setRouteLock(routeLock != null ? routeLock : false);
section.setRoute(route == null ? null : repository.getByCode(route, Route.class));
section.setLockRight(lockRight != null ? lockRight : false);
section.setOverlapLock(overlapLock != null ? overlapLock : false);
section.setCtOccupied(ctOccupied != null ? ctOccupied : false);

View File

@ -56,6 +56,10 @@ public class StorageSignal extends StorageDelayUnlockDevice {
private SignalAspect aspect;
@JsonSerialize(using = Boolean2NumSerializer.class)
@JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean forbidden;
/**
* 绿灯开放
*/
@ -122,6 +126,10 @@ public class StorageSignal extends StorageDelayUnlockDevice {
change = true;
storageSignal.setAspect(signal.getAspect());
}
if (signal.isForbidden()) {
change = true;
storageSignal.setForbidden(signal.isForbidden());
}
if (signal.getRemain() > 0) {
change = true;
storageSignal.saveFrom(signal);
@ -154,6 +162,7 @@ public class StorageSignal extends StorageDelayUnlockDevice {
if (aspect != null) {
signal.setAspect(aspect);
}
signal.setForbidden(this.forbidden == null ? false : this.forbidden);
if (this.getRemain() > 0) {
this.recoverTo(signal, repository);
}

View File

@ -5,6 +5,7 @@ import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.MayOutOfOrderDevice;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
@ -40,6 +41,8 @@ public class StorageSwitch extends StorageDelayUnlockDevice {
@JsonDeserialize(using = Boolean2NumDeserializer.class)
private Boolean routeLock;
private String route;
/**
* 是否进路侧防锁闭
*/
@ -92,6 +95,11 @@ public class StorageSwitch extends StorageDelayUnlockDevice {
change = true;
storageSwitch.setRouteLock(s.isRouteLock());
}
Route route = s.getRoute();
if (route != null) {
change = true;
storageSwitch.setRoute(route.getCode());
}
if (s.isFpLock()) {
change = true;
storageSwitch.setFpLock(s.isFpLock());
@ -133,6 +141,7 @@ public class StorageSwitch extends StorageDelayUnlockDevice {
s.setSingleLock(singleLock != null ? singleLock : false);
s.setBlockade(blockade != null ? blockade : false);
s.setRouteLock(routeLock != null ? routeLock : false);
s.setRoute(route == null ? null : repository.getByCode(route, Route.class));
s.setOverlapLock(overlapLock != null ? overlapLock : false);
s.setMasterGuideLock(masterGuideLock != null ? masterGuideLock : false);
if (pos != null) {

View File

@ -39,6 +39,16 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
*/
private DriveMode driveMode;
/**
* 临时预选模式
*/
private VirtualRealityTrain.PreselectionMode tempPreselectionMode;
/**
* 预选模式
*/
private VirtualRealityTrain.PreselectionMode preselectionMode;
/**
* 服务号
*/
@ -257,6 +267,8 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
this.groupNumber = train.getGroupNumber();
this.runLevel = train.getRunLevel();
this.driveMode = train.getDriveMode();
this.tempPreselectionMode = train.getTempPreselectionMode();
this.preselectionMode = train.getPreselectionMode();
this.serviceNumber = train.getServiceNumber();
this.tripNumber = train.getTripNumber();
this.destinationCode = train.getDestinationCode();
@ -331,6 +343,8 @@ public class StorageVirtualRealityTrain extends StorageVirtualRealityDeviceStatu
VirtualRealityTrain train = (VirtualRealityTrain) vrDevice;
train.setRunLevel(runLevel);
train.setDriveMode(driveMode);
train.setTempPreselectionMode(tempPreselectionMode);
train.setPreselectionMode(preselectionMode);
train.setServiceNumber(serviceNumber);
train.setTripNumber(tripNumber);
train.setDestinationCode(destinationCode);

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.support;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.data.map.*;
import lombok.Getter;
import org.springframework.util.CollectionUtils;
@ -431,4 +430,47 @@ public class RoutePath {
}
return false;
}
/**
* 根据始端信号机选择此进路路径所需的进路对于哈尔滨的进路根据通信和进路是否ATP判断其他取延续保护默认定位进路
* PS:和现在ATS筛选进路方式一致
* @param signal
* @param communicable
* @param config
* @return
*/
public Route selectDefaultRouteOfStart(Signal signal, boolean communicable, MapConfig config) {
List<Route> triggerList = new ArrayList<>();
for (Route route : this.routeList) {
if (route.getStart().equals(signal) && !route.isTurnBack() &&
!triggerList.contains(route) && route.isAtsControl()) {
if (config.isRouteLikeHa1()) {
if (communicable && route.isAtp()) {
triggerList.add(route);
} else if (!communicable && route.isGround()) {
triggerList.add(route);
}
} else {
triggerList.add(route);
}
}
}
//选择要触发的进路
Route route = null;
if (triggerList.size() == 1) {
route = triggerList.get(0);
} else if (triggerList.size() > 1) {
// 取第一个延续保护道岔定位的
for (Route temp : triggerList) {
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
if (switchList.get(0).isNormal()) {
route = temp;
break;
} else {
route = temp;
}
}
}
return route;
}
}

View File

@ -1,6 +1,8 @@
package club.joylink.rtss.simulation.cbtc.data.vo;
import club.joylink.rtss.constants.BusinessConsts;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.RegulationParam;
import club.joylink.rtss.simulation.cbtc.constant.*;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.*;
@ -260,9 +262,11 @@ public class TrainInfo extends MapElement {
/** 通信是否正常 */
private boolean communicable;
/** ats自动调整 */
@Setter
private boolean atsAutoAdjust = true;
/** 调度策略 */
private BusinessConsts.Regulation regulation;
/** 调度参数 */
private RegulationParam regulationParam;
public TrainInfo(String groupNumber) {
super(groupNumber, DeviceType.TRAIN);
@ -634,4 +638,13 @@ public class TrainInfo extends MapElement {
public void updateParking(boolean parking) {
this.parking = parking;
}
public void updateRegulation(BusinessConsts.Regulation regulation, RegulationParam regulationParam) {
this.regulation = regulation;
this.regulationParam = regulationParam;
}
public boolean isAtsAutoAdjust() {
return this.regulation == null || BusinessConsts.Regulation.TIME_TABLE_REGULATION.equals(this.regulation);
}
}

View File

@ -2,7 +2,6 @@ package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
public class IscsIbpStatusVO extends IscsStatusVO {
@ -12,26 +11,27 @@ public class IscsIbpStatusVO extends IscsStatusVO {
/** 下行状态 */
private DirectionalStatus downStatus;
public IscsIbpStatusVO(String code, DeviceType deviceType,
public IscsIbpStatusVO(String code, String stationCode,
DirectionalStatus upStatus, DirectionalStatus downStatus) {
super(code, deviceType);
super(code, IscsStatusVO.DeviceType.IBP, stationCode);
this.upStatus = upStatus;
this.downStatus = downStatus;
}
@Getter
@NoArgsConstructor
public static class DirectionalStatus {
/** 操作允许 */
private boolean operate;
private boolean operate = true;
/** 开门命令 */
private boolean openCommand;
private boolean openCommand = true;
/** 开边门命令 */
private boolean openSideCommand;
private boolean openSideCommand = true;
/** 关门命令 */
private boolean closeCommand;
private boolean closeCommand = true;
public DirectionalStatus(boolean operate, boolean openCommand,
boolean openSideCommand, boolean closeCommand) {

View File

@ -1,6 +1,7 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
public class IscsPsdStatusVO extends IscsStatusVO{
@ -8,9 +9,9 @@ public class IscsPsdStatusVO extends IscsStatusVO{
private DirectionalStatus downStatus;
public IscsPsdStatusVO(String code, DeviceType deviceType,
public IscsPsdStatusVO(String code, String stationCode,
DirectionalStatus upStatus, DirectionalStatus downStatus) {
super(code, deviceType);
super(code, IscsStatusVO.DeviceType.SLIDING_DOOR, stationCode);
this.upStatus = upStatus;
this.downStatus = downStatus;
}
@ -23,10 +24,11 @@ public class IscsPsdStatusVO extends IscsStatusVO{
}
@Getter
@NoArgsConstructor
public static class DirectionalStatus {
private Status status;
private Status status = Status.CLOSE;
private boolean isolationMode;
private boolean isolationMode = true;
public DirectionalStatus(Status status, boolean isolationMode) {
this.status = status;

View File

@ -2,7 +2,6 @@ package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
public class IscsPslStatusVO extends IscsStatusVO{
@ -10,26 +9,27 @@ public class IscsPslStatusVO extends IscsStatusVO{
private DirectionalStatus downStatus;
public IscsPslStatusVO(String code, DeviceType deviceType, DirectionalStatus upStatus,
DirectionalStatus downStatus) {
super(code, deviceType);
public IscsPslStatusVO(String code, String stationCode,
DirectionalStatus upStatus, DirectionalStatus downStatus) {
super(code, IscsStatusVO.DeviceType.PSL, stationCode);
this.upStatus = upStatus;
this.downStatus = downStatus;
}
@Getter
@NoArgsConstructor
public static class DirectionalStatus {
/** 操作允许 */
private boolean operate;
private boolean operate = true;
/** 开门命令 */
private boolean openCommand;
private boolean openCommand = true;
/** 关门命令 */
private boolean closeCommand;
private boolean closeCommand = true;
/** 互锁解除 */
private boolean interlockRelease;
private boolean interlockRelease = true;
public DirectionalStatus(boolean operate, boolean openCommand,
boolean closeCommand, boolean interlockRelease) {

View File

@ -1,8 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
public class IscsSafetyCircleStatusVO extends IscsStatusVO{
@ -10,9 +8,9 @@ public class IscsSafetyCircleStatusVO extends IscsStatusVO{
private DirectionalStatus downStatus;
public IscsSafetyCircleStatusVO(String code, DeviceType deviceType,
public IscsSafetyCircleStatusVO(String code, DeviceType deviceType, String stationCode,
DirectionalStatus upStatus, DirectionalStatus downStatus) {
super(code, deviceType);
super(code, deviceType, stationCode);
this.upStatus = upStatus;
this.downStatus = downStatus;
}

View File

@ -9,9 +9,12 @@ public class IscsStatusVO extends Watchable {
private DeviceType deviceType;
public IscsStatusVO(String code, DeviceType deviceType) {
private String stationCode;
public IscsStatusVO(String code, DeviceType deviceType, String stationCode) {
this.code = code;
this.deviceType = deviceType;
this.stationCode = stationCode;
}
public enum DeviceType {

View File

@ -65,6 +65,19 @@ public class SimulationRealDeviceConnectManager {
}
break;
}
case SECTION: {
VirtualRealityDevice vrDevice = simulation.getRepository().getVRByCode(deviceCode);
if (MapElement.DeviceType.AXLE_COUNTER.equals(vrDevice.getDeviceType())) {
typeEqual = true;
MapNamedElement old = realDevice.getMapElement();
if (Objects.nonNull(old)) {
((VirtualRealitySectionAxleCounter) old).updateRealDevice(null);
}
vrDevice.updateRealDevice(realDevice);
realDevice.connect(vrDevice);
}
break;
}
case PSC:
case PSD: {
VirtualRealityDevice vrDevice = simulation.getRepository().getVRByCode(deviceCode);

View File

@ -1,4 +1,4 @@
package club.joylink.rtss.simulation.cbtc.device.real;
package club.joylink.rtss.simulation.cbtc.device.real.modbustcp;
import club.joylink.rtss.constants.Project;
import club.joylink.rtss.constants.ProjectDeviceType;
@ -7,7 +7,6 @@ import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.*;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.PlcGateway;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.device.virtual.VirtualRealityDeviceService;
@ -18,7 +17,6 @@ import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@ -89,8 +87,6 @@ public class SimulationRealDeviceThread {
}
}
@Async("realDeviceExecutor")
// @Scheduled(fixedRate = Query_Rate)
public void queryDeviceStatus(Simulation simulation) {
PlcGateway plcGateway = simulation.queryPlcGatewayDevice();
if (Objects.isNull(plcGateway)) {
@ -108,8 +104,6 @@ public class SimulationRealDeviceThread {
}
}
@Async("realDeviceExecutor")
// @Scheduled(fixedRate = 100)
public void UpdateDeviceStatusByCollection(Simulation simulation) {
Queue<DeviceQueryFuture> futureQueue = simulation.getDeviceQueryFutureQueue();
DeviceQueryFuture deviceQueryFuture = futureQueue.peek();
@ -171,8 +165,8 @@ public class SimulationRealDeviceThread {
}
public void addJobs(Simulation simulation) {
simulation.addJobIfAbsent(Simulation.JobName.controlDevice, () -> this.controlDevice(simulation), SimulationConstants.VRD_LOOP_RATE);
simulation.addJobIfAbsent(Simulation.JobName.queryDeviceStatus, () -> this.queryDeviceStatus(simulation), Query_Rate);
simulation.addJobIfAbsent(Simulation.JobName.UpdateDeviceStatusByCollection, () -> this.UpdateDeviceStatusByCollection(simulation), 100);
simulation.addFixedRateJob(Simulation.JobName.controlDevice, () -> this.controlDevice(simulation), SimulationConstants.VRD_LOOP_RATE);
simulation.addFixedRateJob(Simulation.JobName.queryDeviceStatus, () -> this.queryDeviceStatus(simulation), Query_Rate);
simulation.addFixedRateJob(Simulation.JobName.UpdateDeviceStatusByCollection, () -> this.UpdateDeviceStatusByCollection(simulation), 100);
}
}

View File

@ -5,7 +5,6 @@ import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsIbpStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.PlcGatewayService;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.RealDeviceService;
@ -51,12 +50,6 @@ public class ZjdIbpServiceImpl implements RealDeviceService {
plcGatewayService.writeSingleCoil(baseAddr, configVO.getW_xx_jjtcd(), false, channel);
}
public static void main(String[] args) {
int addr = 2;
int bit = 9;
System.out.println((addr + 1) * 16 + (bit + 8) % 16);
}
@Override
public void handle(Simulation simulation, RealDeviceConfig deviceConfig, ByteBuf byteBuf) {
PlcGateway plcGateway = simulation.queryPlcGatewayDevice();
@ -133,23 +126,6 @@ public class ZjdIbpServiceImpl implements RealDeviceService {
boolean sxjjtcd = vrIbp.query(VirtualRealityIbp.Mean.jjtcLight, true).stream()
.allMatch(VirtualRealityIbp.IbpElement::isOn);
plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_sx_jjtcd(), w_sx_jjtcd, sxjjtcd, channel);
// //输出
// if (r_sd) {
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_sx_kcd(), w_sx_kcd, true, channel);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_sx_jjtcd(), w_sx_jjtcd, true, channel);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_xx_kcd(), w_xx_kcd, true, channel);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_xx_jjtcd(), w_xx_jjtcd, true, channel);
// } else {
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_fmq(), w_fmq, false, channel);
// boolean upHoldTrain = upStands.stream().anyMatch(Stand::isIbpHoldTrain);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_sx_kcd(), w_sx_kcd, upHoldTrain, channel);
// boolean upEc = upStands.stream().anyMatch(Stand::isEmergencyClosed);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_sx_jjtcd(), w_sx_jjtcd, upEc, channel);
// boolean downHoldTrain = downStands.stream().anyMatch(Stand::isIbpHoldTrain);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_xx_kcd(), w_xx_kcd, downHoldTrain, channel);
// boolean downEc = downStands.stream().anyMatch(Stand::isEmergencyClosed);
// plcGatewayService.checkEqualAndWriteSingleCoil(baseAddr, configVO.getW_xx_jjtcd(), w_xx_jjtcd, downEc, channel);
// }
//ISCS状态
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
String iscsCode = configVO.getIscsCode();
@ -158,7 +134,8 @@ public class ZjdIbpServiceImpl implements RealDeviceService {
if (iscsStatus == null) {
IscsIbpStatusVO.DirectionalStatus downStatus =
new IscsIbpStatusVO.DirectionalStatus(r_sx_czyx, r_sx_km, false, r_sx_gm);
iscsStatus = new IscsIbpStatusVO(iscsCode, IscsStatusVO.DeviceType.IBP, null, downStatus);
iscsStatus = new IscsIbpStatusVO(iscsCode,
vrIbp.getStation().getCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);

View File

@ -3,7 +3,6 @@ package club.joylink.rtss.simulation.cbtc.device.real.modbustcp.richor;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPsdStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsStatusVO;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.RealDeviceService;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.rt.iscs.IscsStatusPublisher;
@ -63,10 +62,10 @@ public class ZjdPsdServiceImpl implements RealDeviceService {
}
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
IscsPsdStatusVO iscsStatus = (IscsPsdStatusVO) iscsRepository.findStatus(iscsCode);
boolean change = false;
boolean change;
if (iscsStatus == null) {
IscsPsdStatusVO.DirectionalStatus downStatus = new IscsPsdStatusVO.DirectionalStatus(status, r_sx_glms);
iscsStatus = new IscsPsdStatusVO(iscsCode, IscsStatusVO.DeviceType.SLIDING_DOOR, null, downStatus);
iscsStatus = new IscsPsdStatusVO(iscsCode, configVO.getStationCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);

View File

@ -5,7 +5,6 @@ import club.joylink.rtss.simulation.cbtc.CI.device.CiStandService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPslStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.RealDeviceService;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
@ -57,7 +56,8 @@ public class ZjdPslServiceImpl implements RealDeviceService {
boolean change;
if (iscsStatus == null) {
IscsPslStatusVO.DirectionalStatus downStatus = new IscsPslStatusVO.DirectionalStatus(r_sx_czyx, r_sx_km, r_sx_gm, r_sx_hsjc);
iscsStatus = new IscsPslStatusVO(iscsCode, IscsStatusVO.DeviceType.PSL, null, downStatus);
iscsStatus = new IscsPslStatusVO(iscsCode,
vrPsl.getStand().getStation().getCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);

View File

@ -0,0 +1,21 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.sr.SrSectionConfigVO;
import lombok.Getter;
import java.util.Objects;
@Getter
public class SrSectionConfig extends RealDeviceConfig {
private SrSectionConfigVO configVO;
public SrSectionConfig(ProjectDeviceVO projectDevice) {
super(projectDevice);
if (Objects.nonNull(projectDevice.getConfig())) {
this.configVO = JsonUtils.read(projectDevice.getConfig(), SrSectionConfigVO.class);
}
}
}

View File

@ -0,0 +1,58 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.constants.ProjectDeviceType;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPClientConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPLowConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceService;
import io.netty.buffer.ByteBuf;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class SrSectionServiceImpl implements UDPRealDeviceService {
@Override
public boolean isMatch(RealDeviceConfig realDevice) {
return realDevice instanceof UDPClientConfig;
}
@Override
public void control(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) {
}
@Override
public void init(Simulation simulation, UDPLowConfig udpConfig, RealDeviceConfig realDevice) {
}
@Override
public void handle(Simulation simulation, ByteBuf msg) {
byte[] data = new byte[msg.readableBytes()];
if (data.length < 4)
return;
msg.readBytes(data);
if (Byte.toUnsignedInt(data[1]) != 137)
return;
Map<String, VirtualRealitySectionAxleCounter> map = simulation.queryAllRealDevice(ProjectDeviceType.SECTION).stream()
.map(config -> (SrSectionConfig) config)
.collect(Collectors.toMap(config -> config.getConfigVO().getSandboxCode(),
config -> (VirtualRealitySectionAxleCounter) config.getMapElement()));
for (int i = 3, dataLength = data.length; i < dataLength; i+=2) {
int code = Byte.toUnsignedInt(data[i - 1]);
VirtualRealitySectionAxleCounter axle = map.get(String.valueOf(code));
if (axle != null) {
int n = Byte.toUnsignedInt(data[i]);
if (n == 170) {
axle.setOccupy(true);
} else if (n == 85) {
axle.setOccupy(false);
}
}
}
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.sr.SrSignalConfigVO;
import lombok.Getter;
import java.util.Objects;
@Getter
public class SrSignalConfig extends RealDeviceConfig {
private SrSignalConfigVO configVO;
public SrSignalConfig(ProjectDeviceVO projectDevice) {
super(projectDevice);
if (Objects.nonNull(projectDevice.getConfig())) {
this.configVO = JsonUtils.read(projectDevice.getConfig(), SrSignalConfigVO.class);
}
}
}

View File

@ -0,0 +1,131 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPClient;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPLowConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceService;
import io.netty.buffer.ByteBuf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class SrSignalServiceImpl implements UDPRealDeviceService {
@Autowired
private UDPClient udpClient;
@Override
public boolean isMatch(RealDeviceConfig realDevice) {
return realDevice instanceof SrSignalConfig;
}
@Override
public void control(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) {
SrSignalConfig config = (SrSignalConfig) realDevice;
//控制vr设备
VirtualRealitySignal vrSignal = (VirtualRealitySignal) realDevice.getMapElement();
SignalAspect aspect = vrSignal.getAspect();
SignalAspect command = vrSignal.getCommand();
if (Objects.equals(aspect, command)) {
return;
}
if (vrSignal.getRemain() > 0) {
vrSignal.turning(SimulationConstants.VRD_LOOP_RATE);
}
//控制沙盘设备
aspect = vrSignal.getAspect();
if (aspect == null || udpLowConfig == null) {
return;
}
byte[] data = buildData(aspect, config);
if (data == null)
return;
udpClient.write(udpLowConfig.getAddr(), data);
}
@Override
public void init(Simulation simulation, UDPLowConfig udpConfig, RealDeviceConfig realDevice) {
SrSignalConfig config = (SrSignalConfig) realDevice;
VirtualRealitySignal vrSignal = (VirtualRealitySignal) config.getMapElement();
byte[] data = buildData(vrSignal.getAspect(), config);
udpClient.write(udpConfig.getAddr(), data);
}
@Override
public void handle(Simulation simulation, ByteBuf msg) {
}
private byte[] buildData(SignalAspect aspect, SrSignalConfig config) {
if (aspect == null)
return null;
byte[] data = new byte[5];
data[1] = (byte) 203;
data[2] = (byte) Integer.parseInt(config.getConfigVO().getSandboxCode());
switch (aspect) {
case No:
case R:
case RF:
data[3] = (byte) 0;
break;
case G:
case GF:
data[3] = (byte) 1;
break;
case Y:
case YF:
data[3] = (byte) 2;
break;
case W:
case WF:
data[3] = (byte) 6;
break;
case B:
data[3] = (byte) 7;
break;
case GG:
data[3] = (byte) 5;
break;
case GY:
data[3] = (byte) 4;
break;
case YY:
data[3] = (byte) 3;
break;
case RY:
case RW:
return null;
default:
return null;
}
switch (aspect) {
case No:
case R:
case G:
case Y:
case W:
case B:
case RY:
case RW:
case GG:
case GY:
case YY:
data[4] = (byte) 0;
break;
case RF:
case YF:
case GF:
case WF:
data[4] = (byte) 1;
break;
default:
throw new IllegalStateException("Unexpected value: " + aspect);
}
return data;
}
}

View File

@ -0,0 +1,21 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.sr.SrSwitchConfigVO;
import lombok.Getter;
import java.util.Objects;
@Getter
public class SrSwitchConfig extends RealDeviceConfig {
private SrSwitchConfigVO configVO;
public SrSwitchConfig(ProjectDeviceVO projectDevice) {
super(projectDevice);
if (Objects.nonNull(projectDevice.getConfig())) {
this.configVO = JsonUtils.read(projectDevice.getConfig(), SrSwitchConfigVO.class);
}
}
}

View File

@ -0,0 +1,75 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.Sr;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPClient;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPLowConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceService;
import io.netty.buffer.ByteBuf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SrSwitchServiceImpl implements UDPRealDeviceService {
@Autowired
private UDPClient udpClient;
@Override
public boolean isMatch(RealDeviceConfig realDevice) {
return realDevice instanceof SrSwitchConfig;
}
@Override
public void control(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) {
SrSwitchConfig config = (SrSwitchConfig) realDevice;
//控制vr设备
VirtualRealitySwitch vrSwitch = (VirtualRealitySwitch) realDevice.getMapElement();
if (vrSwitch.getRemain() > 0) {
vrSwitch.turning(SimulationConstants.VRD_LOOP_RATE);
}
//控制沙盘设备
SwitchIndication p = vrSwitch.getP();
if (p == null || udpLowConfig == null) {
return;
}
byte[] data = buildData(p, config);
if (data == null)
return;
udpClient.write(udpLowConfig.getAddr(), data);
}
@Override
public void init(Simulation simulation, UDPLowConfig udpConfig, RealDeviceConfig realDevice) {
}
@Override
public void handle(Simulation simulation, ByteBuf msg) {
}
private byte[] buildData(SwitchIndication p, SrSwitchConfig config) {
if (p == null)
return null;
byte[] data = new byte[4];
data[1] = (byte) 208;
data[2] = (byte) Integer.parseInt(config.getConfigVO().getSandboxCode());
switch (p) {
case N:
data[3] = (byte) 0;
break;
case R:
data[3] = (byte) 1;
break;
case NO:
case EX:
return null;
default:
throw new IllegalStateException("Unexpected value: " + p);
}
return data;
}
}

View File

@ -0,0 +1,76 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.configuration.configProp.UDPConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
@Component
@Slf4j
public class UDPClient implements ApplicationRunner {
@Autowired
private UDPConfig udpConfig;
private Channel channel;
@Override
public void run(ApplicationArguments args) throws Exception {
this.start();
}
public void start() throws InterruptedException {
Bootstrap bootstrap = new Bootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
bootstrap.group(group)
.channel(NioDatagramChannel.class)
.handler(new ChannelInitializer<NioDatagramChannel>() {
@Override
protected void initChannel(NioDatagramChannel channel) {
}
});
ChannelFuture future = bootstrap.bind(udpConfig.getClientPort()).sync();
Channel channel = future.channel();
this.channel = channel;
if(future.isSuccess()) {
log.info(String.format("udp client start on port [%s]", this.udpConfig.getClientPort()));
} else {
log.error("udp server start failed", future.cause());
}
}
public void write(byte[] ip, int port, byte[] msg) {
try {
if (channel != null && channel.isWritable()) {
InetAddress inetAddress = InetAddress.getByAddress(ip);
InetSocketAddress addr = new InetSocketAddress(inetAddress, port);
write(addr, msg);
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public void write(InetSocketAddress addr, byte[] msg) {
if (channel != null && channel.isWritable() && addr != null) {
ByteBuf byteBuf = Unpooled.copiedBuffer(msg);
DatagramPacket data = new DatagramPacket(byteBuf, addr);
channel.writeAndFlush(data);
}
}
}

View File

@ -0,0 +1,20 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.UDPClientConfigVO;
import lombok.Getter;
import org.springframework.util.StringUtils;
@Getter
public class UDPClientConfig extends RealDeviceConfig {
private UDPClientConfigVO configVO;
public UDPClientConfig(ProjectDeviceVO projectDevice) {
super(projectDevice);
if (StringUtils.hasText(projectDevice.getConfig())) {
this.configVO = JsonUtils.read(projectDevice.getConfig(), UDPClientConfigVO.class);
}
}
}

View File

@ -0,0 +1,50 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.ProjectDeviceVO;
import club.joylink.rtss.vo.client.project.UDPLowConfigVO;
import lombok.Getter;
import org.springframework.util.StringUtils;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
@Getter
public class UDPLowConfig extends RealDeviceConfig {
private UDPLowConfigVO configVO;
private byte[] ip;
private Integer port;
private InetSocketAddress addr;
public UDPLowConfig(ProjectDeviceVO projectDevice) {
super(projectDevice);
if (StringUtils.hasText(projectDevice.getConfig())) {
this.configVO = JsonUtils.read(projectDevice.getConfig(), UDPLowConfigVO.class);
String ipStr = configVO.getIp();
if (StringUtils.hasText(ipStr)) {
String[] split = ipStr.split("\\.");
BusinessExceptionAssertEnum.DATA_ERROR.assertEquals(split.length, 4);
ip = new byte[4];
for (int i = 0; i < 4; i++) {
ip[i] = (byte) Integer.parseInt(split[i]);
}
}
this.port = configVO.getPort();
//构建地址
if (ip != null && port != null) {
try {
InetAddress inetAddress = InetAddress.getByAddress(ip);
addr = new InetSocketAddress(inetAddress, port);
} catch (UnknownHostException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(e);
}
}
}
}
}

View File

@ -0,0 +1,15 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import io.netty.buffer.ByteBuf;
public interface UDPRealDeviceService {
boolean isMatch(RealDeviceConfig realDevice);
void control(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice);
void init(Simulation simulation, UDPLowConfig udpConfig, RealDeviceConfig realDevice);
void handle(Simulation simulation, ByteBuf msg);
}

View File

@ -0,0 +1,25 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class UDPRealDeviceServiceManager implements ApplicationContextAware {
private List<UDPRealDeviceService> serviceList;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, UDPRealDeviceService> deviceServiceMap = applicationContext.getBeansOfType(UDPRealDeviceService.class);
this.serviceList = new ArrayList<>(deviceServiceMap.values());
}
public List<UDPRealDeviceService> getServiceList() {
return this.serviceList;
}
}

View File

@ -0,0 +1,96 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.constants.ProjectDeviceType;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.PlcGateway;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig;
import club.joylink.rtss.simulation.cbtc.event.SimulationResetEvent;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
public class UDPRealDeviceThread {
@Autowired
private UDPRealDeviceServiceManager udpRealDeviceServiceManager;
@Autowired
private GroupSimulationService groupSimulationService;
@EventListener
public void simulationReset(SimulationResetEvent event) {
Simulation simulation = event.getSimulation();
List<RealDeviceConfig> realDeviceList = simulation.getRealDeviceList();
if (CollectionUtils.isEmpty(realDeviceList))
return;
UDPLowConfig udpConfig = (UDPLowConfig) simulation.queryOneRealDevice(ProjectDeviceType.UDP_LOW);
if (udpConfig == null)
return;
for (RealDeviceConfig realDevice : realDeviceList) {
if (realDevice instanceof PlcGateway) {
continue;
}
for (UDPRealDeviceService realDeviceService : this.udpRealDeviceServiceManager.getServiceList()) {
if (realDeviceService.isMatch(realDevice)) {
realDeviceService.init(simulation, udpConfig, realDevice);
}
}
}
}
public void run(Simulation simulation) {
List<RealDeviceConfig> realDeviceList = simulation.getRealDeviceList();
if (CollectionUtils.isEmpty(realDeviceList))
return;
List<UDPRealDeviceService> serviceList = udpRealDeviceServiceManager.getServiceList();
if (CollectionUtils.isEmpty(serviceList))
return;
UDPLowConfig udpLowConfig = null;
for (RealDeviceConfig realDeviceConfig : realDeviceList) {
if (ProjectDeviceType.UDP_LOW.equals(realDeviceConfig.getDeviceType())) {
udpLowConfig = (UDPLowConfig) realDeviceConfig;
break;
}
}
for (RealDeviceConfig config : realDeviceList) {
for (UDPRealDeviceService service : serviceList) {
if (service.isMatch(config)) {
service.control(simulation, udpLowConfig, config);
}
}
}
}
public void handleData(String ip, int port, ByteBuf data) {
List<Simulation> simulations = groupSimulationService.querySimulations();
for (Simulation simulation : simulations) {
List<RealDeviceConfig> realDeviceList = simulation.getRealDeviceList();
if (CollectionUtils.isEmpty(realDeviceList))
continue;
UDPClientConfig udpClientConfig = (UDPClientConfig) simulation.queryOneRealDevice(ProjectDeviceType.UDP_CLIENT);
if (udpClientConfig != null && Objects.equals(ip, udpClientConfig.getConfigVO().getIp())
&& Objects.equals(port, udpClientConfig.getConfigVO().getPort())) {
for (UDPRealDeviceService udpRealDeviceService : this.udpRealDeviceServiceManager.getServiceList()) {
if (udpRealDeviceService.isMatch(udpClientConfig)) {
udpRealDeviceService.handle(simulation, data);
}
}
break;
}
}
}
public void addJobs(Simulation simulation) {
simulation.addFixedRateJob(Simulation.JobName.udpRealDevice,
() -> this.run(simulation), SimulationConstants.VRD_LOOP_RATE);
}
}

View File

@ -0,0 +1,51 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp;
import club.joylink.rtss.configuration.configProp.UDPConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.handler.UDPMessageHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class UDPServer implements ApplicationRunner {
@Autowired
private UDPConfig udpConfig;
@Autowired
private UDPMessageHandler udpMessageHandler;
@Override
public void run(ApplicationArguments args) throws Exception {
this.start();
}
public void start() throws InterruptedException {
Bootstrap bootstrap = new Bootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
bootstrap.group(group)
.channel(NioDatagramChannel.class)
.handler(new ChannelInitializer<NioDatagramChannel>() {
@Override
protected void initChannel(NioDatagramChannel channel) {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(udpMessageHandler);
}
});
ChannelFuture future = bootstrap.bind(udpConfig.getServerPort()).sync();
if(future.isSuccess()) {
log.info(String.format("udp server start on port [%s]", this.udpConfig.getServerPort()));
} else {
log.error("udp server start failed", future.cause());
}
}
}

View File

@ -0,0 +1,29 @@
package club.joylink.rtss.simulation.cbtc.device.real.udp.handler;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceThread;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
@Component
public class UDPMessageHandler extends SimpleChannelInboundHandler<DatagramPacket> {
@Autowired
private UDPRealDeviceThread udpRealDeviceThread;
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket datagramPacket) {
InetSocketAddress sender = datagramPacket.sender();
String ip = sender.getHostString();
int port = sender.getPort();
ByteBuf content = datagramPacket.content();
udpRealDeviceThread.handleData(ip, port, content);
// System.out.println("收到消息:" + datagramPacket.content().toString(StandardCharsets.UTF_8));
// ByteBuf byteBuf = Unpooled.copiedBuffer("hi".getBytes());
// ctx.writeAndFlush(new DatagramPacket(byteBuf, datagramPacket.sender()));
}
}

View File

@ -43,7 +43,6 @@ public class VRDeviceLogicLoop {
/**
* 更新列车实际占压的计轴区段
* @param simulation
*/
public void updateTrainOccupySection(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
@ -63,20 +62,24 @@ public class VRDeviceLogicLoop {
/**
* 更新区段占用状态
* @param oldOccupyList
* @param occupySectionList
* @param right
*/
private void updateAxleCounterOccupied(List<Section> oldOccupyList,
List<Section> occupySectionList, boolean right) {
// 非占用区段出清
if (!CollectionUtils.isEmpty(oldOccupyList)) { // 筛选出已经出清的区段,更新为非占用状态
oldOccupyList.removeAll(occupySectionList);
oldOccupyList.forEach(section ->
section.getVirtualAxleCounter().clear());
oldOccupyList.forEach(section -> {
if (!section.getVirtualAxleCounter().isConnectReal()) {
section.getVirtualAxleCounter().clear();
}
});
}
// 所有计轴区段计轴占用即非通信车占用
occupySectionList.forEach(section -> section.getVirtualAxleCounter().occupied(right));
occupySectionList.forEach(section -> {
if (!section.getVirtualAxleCounter().isConnectReal()) {
section.getVirtualAxleCounter().occupied(right);
}
});
}
public void addJobs(Simulation simulation) {

View File

@ -64,6 +64,8 @@ public class MemberManager {
this.addRole(simulation, SimulationMember.Type.PARKING_LOT_SIGNAL_BUILDING);
// 上级部门
this.addRole(simulation, SimulationMember.Type.PARENT_DEPARTMENT);
// 派班员
this.addRole(simulation, SimulationMember.Type.SCHEDULING);
}
/**
@ -110,7 +112,8 @@ public class MemberManager {
SimulationMember.Type type,
String name, MapElement device) {
switch (type) {
case DISPATCHER:{
case DISPATCHER:
case SCHEDULING: {
break;
}
case DEPOT_DISPATCHER:{

View File

@ -127,6 +127,8 @@ public class SimulationMember extends club.joylink.rtss.simulation.SimulationMem
PARKING_LOT_SIGNAL_BUILDING,
/** 上级部门 */
PARENT_DEPARTMENT,
/** 派班员 */
SCHEDULING
}
public enum Gender {

View File

@ -95,9 +95,6 @@ public class PassengerFlowSimulateService {
this.removeJobs(simulation);
}
// @Async("nsExecutor")
// @EventListener
/**
* @return 客流初始化成功
*/

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.robot;
import club.joylink.rtss.services.IVoiceService;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
@ -15,7 +16,6 @@ import club.joylink.rtss.simulation.cbtc.event.SimulationConversationExitEvent;
import club.joylink.rtss.simulation.cbtc.event.SimulationOperationMessageEvent;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
import club.joylink.rtss.services.IVoiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@ -63,7 +63,6 @@ public class RobotListenerHandler {
}
}
// @Async("nsExecutor")
// @EventListener
// public void handleEvent(SimulationATPAutoCancelEBEvent event) {
// VirtualRealityTrain train = event.getTrain();

View File

@ -154,10 +154,10 @@ public class DeviceStatusModifyTool {
private void batchSetRouteSwitchPositionAndLock(Route route, List<SwitchElement> switchList, boolean routeLock) {
if (!CollectionUtils.isEmpty(switchList)) {
for (SwitchElement switchElement : switchList) {
if (switchElement.getASwitch().isOverlapLock() &&
switchElement.isOnPosition()) {
continue;
}
// if (switchElement.getASwitch().isOverlapLock() &&
// switchElement.isOnPosition()) {
// continue;
// }
// switchElement.getASwitch().ciUse(switchElement.isNormal());
this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal());
if (routeLock) {
@ -181,7 +181,7 @@ public class DeviceStatusModifyTool {
virtualSwitch.finish();
aSwitch.setPos(SwitchIndication.N);
} else {
virtualSwitch.control(VirtualRealitySwitch.Operation.NP);
virtualSwitch.control(VirtualRealitySwitch.Operation.RP);
virtualSwitch.finish();
aSwitch.setPos(SwitchIndication.R);
}
@ -204,25 +204,37 @@ public class DeviceStatusModifyTool {
/**
* 直接根据最后一根区段解锁进路
* @param route
* @param endOccupied
*/
public void routeUnlockByEndSection(Route route, Section endOccupied) {
if (!route.isRouteSection(endOccupied)) {
public void routeUnlockByEndSection(Route route, Section tailSection) {
if (!route.isRouteSection(tailSection)) {
// 不是进路区段不解锁
return;
}
route.startNormalUnlock();
// 关闭始端信号机
openSignalDirectly(route.getStart(), route.getStart().getSignalModel().getDefaultAspect());
boolean right = route.getStart().isRight();
// 区段是顺序的(否则会有问题)
List<Section> sectionList = route.getSectionList();
for (Section section : sectionList) {
if (section.isSamePhysical(endOccupied.getCode())) {
if (section.isSamePhysical(tailSection.getCode())) {
route.updateUnlockedSection(tailSection);
break;
}
// 直接解锁区段
if (section.isSwitchTrack() && !section.getParent().isOccupied()) { // 如果是道岔区段解锁道岔
if (section.isSwitchTrack()) { // 如果是道岔区段解锁道岔
Switch relSwitch = section.getRelSwitch();
section.routeUnlocking(route);
relSwitch.routeUnlock();
if (tailSection.isSwitchTrack() && tailSection.getRelSwitch().equals(relSwitch)) {
route.updateUnlockedSection(tailSection);
break;
}
if (section.getParent() != null && section.getParent().isCross()) {
section.getParent().routeUnlocking(route);
}
relSwitch.routeUnlock(route);
relSwitch.overlapUnLock();
// 侧防解锁
route.unlockRouteFlsOfSwitch(relSwitch);
//检查道岔的联动道岔和计轴关联道岔是否可以解锁
for (SwitchElement switchElement : route.getSwitchList()) {
if (switchElement.getASwitch().equals(relSwitch)) {
@ -234,7 +246,8 @@ public class DeviceStatusModifyTool {
}
if (relSwitch.isLinkedSwitch(aSwitch) || relSwitch.isBConnectTo(aSwitch)) {
if (!aSwitch.getA().isRouteLock()) {
aSwitch.routeUnlock();
aSwitch.routeUnlock(route);
aSwitch.overlapUnLock();
}
}
}

View File

@ -4,15 +4,20 @@ import club.joylink.rtss.simulation.Simulation;
import club.joylink.rtss.simulation.SimulationTriggerMessagePublisher;
import club.joylink.rtss.simulation.Watchable;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import com.sun.source.tree.ReturnTree;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsIbpStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPsdStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPslStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsStatusVO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class IscsStatusPublisher extends SimulationTriggerMessagePublisher {
public static final String Name = "iscs";
public static final String Destination = String.format("%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", "psd");
public static final String Destination = String.format("%s/%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", "psd", "{stationCode}");
club.joylink.rtss.simulation.cbtc.Simulation simulation;
public IscsStatusPublisher(club.joylink.rtss.simulation.cbtc.Simulation simulation) {
@ -22,13 +27,31 @@ public class IscsStatusPublisher extends SimulationTriggerMessagePublisher {
@Override
public Object buildMessageOfSubscribe(String destination) {
List<String> list = this.getDestinationParamsMap().get(destination);
String s = list.get(1);
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
return iscsRepository.getAllStatus();
Collection<IscsStatusVO> allStatus = iscsRepository.getAllStatus();
List<IscsStatusVO> collect = allStatus.stream().filter(status -> status.getStationCode().equals(s)).collect(Collectors.toList());
if (collect.isEmpty()) {
collect.add(new IscsPsdStatusVO("", s, new IscsPsdStatusVO.DirectionalStatus(),
new IscsPsdStatusVO.DirectionalStatus()));
collect.add(new IscsPslStatusVO("", s, new IscsPslStatusVO.DirectionalStatus(),
new IscsPslStatusVO.DirectionalStatus()));
collect.add(new IscsIbpStatusVO("", s, new IscsIbpStatusVO.DirectionalStatus(),
new IscsIbpStatusVO.DirectionalStatus()));
}
return collect;
}
@Override
public List<String> getNeedBuildDestination(Watchable watchable) {
return new ArrayList<>(this.getDestinationParamsMap().keySet());
List<String> list = new ArrayList<>();
this.getDestinationParamsMap().forEach((destination, param) -> {
if (param.get(1).equals(((IscsStatusVO) watchable).getStationCode())) {
list.add(destination);
}
});
return list;
}
@Override

View File

@ -15,6 +15,11 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.richor.ZjdPslConf
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.sdy.SdyPsdConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.sdy.SdyPslConfig;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.xty.XtyPsdConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSectionConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSignalConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.Sr.SrSwitchConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPClientConfig;
import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPLowConfig;
import club.joylink.rtss.util.JsonUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
@ -108,7 +113,10 @@ public class ProjectDeviceVO {
return sdyDeviceConfigConvert(voList);
}
case RICHOR_JOINT: {
return richorJointDeviceConfigConvert(voList);
return zjdDeviceConfigConvert(voList);
}
case SR_SANDBOX: {
return srSandboxDeviceConfigConvert(voList);
}
}
}
@ -116,7 +124,31 @@ public class ProjectDeviceVO {
return list;
}
private static List<RealDeviceConfig> richorJointDeviceConfigConvert(List<ProjectDeviceVO> voList) {
private static List<RealDeviceConfig> srSandboxDeviceConfigConvert(List<ProjectDeviceVO> voList) {
List<RealDeviceConfig> list = new ArrayList<>();
for (ProjectDeviceVO deviceVO : voList) {
switch (deviceVO.getType()) {
case UDP_LOW:
list.add(new UDPLowConfig(deviceVO));
break;
case UDP_CLIENT:
list.add(new UDPClientConfig(deviceVO));
break;
case SIGNAL:
list.add(new SrSignalConfig(deviceVO));
break;
case SECTION:
list.add(new SrSectionConfig(deviceVO));
break;
case SWITCH:
list.add(new SrSwitchConfig(deviceVO));
break;
}
}
return list;
}
private static List<RealDeviceConfig> zjdDeviceConfigConvert(List<ProjectDeviceVO> voList) {
List<RealDeviceConfig> list = new ArrayList<>();
for (ProjectDeviceVO deviceVO : voList) {
switch (deviceVO.getType()) {

View File

@ -0,0 +1,19 @@
package club.joylink.rtss.vo.client.project;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class UDPClientConfigVO {
private String ip;
private Integer port;
public UDPClientConfigVO(String ip, Integer port) {
this.ip = ip;
this.port = port;
}
}

View File

@ -0,0 +1,27 @@
package club.joylink.rtss.vo.client.project;
import club.joylink.rtss.util.JsonUtils;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* UDP下位机配置
*/
@Getter
@Setter
@NoArgsConstructor
public class UDPLowConfigVO {
private String ip;
private Integer port;
public UDPLowConfigVO(String ip, Integer port) {
this.ip = ip;
this.port = port;
}
public String toJson() {
return JsonUtils.writeValueAsString(this);
}
}

View File

@ -1,8 +1,6 @@
package club.joylink.rtss.vo.client.project.gzb;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;

View File

@ -1,8 +1,6 @@
package club.joylink.rtss.vo.client.project.gzb;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;

View File

@ -1,10 +1,7 @@
package club.joylink.rtss.vo.client.project.richor;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter

View File

@ -1,14 +1,9 @@
package club.joylink.rtss.vo.client.project.richor;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
public class ZjdPsdConfigVO extends RealConfigVO {
@ -18,6 +13,8 @@ public class ZjdPsdConfigVO extends RealConfigVO {
// @NotBlank(message = "关联的站台屏蔽门code不能为空")
// private String psdCode;
private String stationCode = "Station25166";
/**
* 关联的ISCS元素的code
*/

View File

@ -1,10 +1,7 @@
package club.joylink.rtss.vo.client.project.richor;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter

View File

@ -1,10 +1,7 @@
package club.joylink.rtss.vo.client.project.sdy;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.validation.constraints.NotBlank;

View File

@ -1,10 +1,7 @@
package club.joylink.rtss.vo.client.project.sdy;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter

View File

@ -0,0 +1,19 @@
package club.joylink.rtss.vo.client.project.sr;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class SrSectionConfigVO {
private String vrCode;
private String sandboxCode;
public SrSectionConfigVO(String vrCode, String sandboxCode) {
this.vrCode = vrCode;
this.sandboxCode = sandboxCode;
}
}

View File

@ -0,0 +1,19 @@
package club.joylink.rtss.vo.client.project.sr;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class SrSignalConfigVO {
private String vrCode;
private String sandboxCode;
public SrSignalConfigVO(String vrCode, String sandboxCode) {
this.vrCode = vrCode;
this.sandboxCode = sandboxCode;
}
}

View File

@ -0,0 +1,19 @@
package club.joylink.rtss.vo.client.project.sr;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class SrSwitchConfigVO {
private String vrCode;
private String sandboxCode;
public SrSwitchConfigVO(String vrCode, String sandboxCode) {
this.vrCode = vrCode;
this.sandboxCode = sandboxCode;
}
}

View File

@ -1,10 +1,7 @@
package club.joylink.rtss.vo.client.project.xty;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.client.project.RealConfigVO;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.validation.constraints.NotBlank;

View File

@ -22,4 +22,10 @@ public class DisplayVO {
* 修正设备绘图点位置
*/
private List<AmendPoints> amendPointsList;
private Double offsetX;
private Double offsetY;
private Double scaleRate;
}

Some files were not shown because too many files have changed in this diff Show More