diff --git a/src/main/java/club/joylink/rtss/constants/ProjectCode.java b/src/main/java/club/joylink/rtss/constants/ProjectCode.java new file mode 100644 index 000000000..34c74bd79 --- /dev/null +++ b/src/main/java/club/joylink/rtss/constants/ProjectCode.java @@ -0,0 +1,8 @@ +package club.joylink.rtss.constants; + +public interface ProjectCode { + + String THAILAND_SANDBOX = "THAILAND_SANDBOX"; + String SR_SANDBOX = "SR_SANDBOX"; + +} diff --git a/src/main/java/club/joylink/rtss/controller/project/DeviceController.java b/src/main/java/club/joylink/rtss/controller/project/DeviceController.java index 0d2bbe5fe..c8e4bed07 100644 --- a/src/main/java/club/joylink/rtss/controller/project/DeviceController.java +++ b/src/main/java/club/joylink/rtss/controller/project/DeviceController.java @@ -7,12 +7,32 @@ import club.joylink.rtss.services.project.DeviceService; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.project.*; +import club.joylink.rtss.vo.client.project.IbpConfigVO; +import club.joylink.rtss.vo.client.project.LswConfigVO; +import club.joylink.rtss.vo.client.project.LwConfigVO; +import club.joylink.rtss.vo.client.project.PlcGatewayConfigVO; +import club.joylink.rtss.vo.client.project.ProjectDevicePageQueryVO; +import club.joylink.rtss.vo.client.project.ProjectDeviceVO; +import club.joylink.rtss.vo.client.project.PscConfigVO; +import club.joylink.rtss.vo.client.project.PsdConfigVO; +import club.joylink.rtss.vo.client.project.PslConfigVO; +import club.joylink.rtss.vo.client.project.RelationLoginConfigVO; +import club.joylink.rtss.vo.client.project.SignalConfigVO; +import club.joylink.rtss.vo.client.project.SwitchConfigVO; +import club.joylink.rtss.vo.client.project.VrIbpConfigVO; +import club.joylink.rtss.vo.client.project.VrpsdConfigVO; +import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; /** * 项目设备管理接口(新) @@ -258,4 +278,10 @@ public class DeviceController { AccountVO accountVO) { this.deviceService.addOrUpdateSayDeviceConfig(accountVO); } + + @PostMapping("/thailand/addOrUpdate/{mapId}") + public void addOrUpdateThailandDeviceConfig(@RequestAttribute(name = AuthenticateInterceptor.LOGIN_USER_KEY) + AccountVO accountVO, @PathVariable Long mapId) { + this.deviceService.addOrUpdateThailandDeviceConfig(accountVO, mapId); + } } diff --git a/src/main/java/club/joylink/rtss/services/project/DeviceService.java b/src/main/java/club/joylink/rtss/services/project/DeviceService.java index a276f44bd..704a78314 100644 --- a/src/main/java/club/joylink/rtss/services/project/DeviceService.java +++ b/src/main/java/club/joylink/rtss/services/project/DeviceService.java @@ -4,8 +4,20 @@ import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.PageVO; -import club.joylink.rtss.vo.client.project.*; - +import club.joylink.rtss.vo.client.project.IbpConfigVO; +import club.joylink.rtss.vo.client.project.LswConfigVO; +import club.joylink.rtss.vo.client.project.LwConfigVO; +import club.joylink.rtss.vo.client.project.PlcGatewayConfigVO; +import club.joylink.rtss.vo.client.project.ProjectDevicePageQueryVO; +import club.joylink.rtss.vo.client.project.ProjectDeviceVO; +import club.joylink.rtss.vo.client.project.PscConfigVO; +import club.joylink.rtss.vo.client.project.PsdConfigVO; +import club.joylink.rtss.vo.client.project.PslConfigVO; +import club.joylink.rtss.vo.client.project.RelationLoginConfigVO; +import club.joylink.rtss.vo.client.project.SignalConfigVO; +import club.joylink.rtss.vo.client.project.SwitchConfigVO; +import club.joylink.rtss.vo.client.project.VrIbpConfigVO; +import club.joylink.rtss.vo.client.project.VrpsdConfigVO; import java.util.List; public interface DeviceService { @@ -216,4 +228,6 @@ public interface DeviceService { void addOrUpdateHhcjDeviceConfig(AccountVO accountVO); void addOrUpdateSayDeviceConfig(AccountVO accountVO); + + void addOrUpdateThailandDeviceConfig(AccountVO accountVO, Long mapId); } diff --git a/src/main/java/club/joylink/rtss/services/project/DeviceServiceImpl.java b/src/main/java/club/joylink/rtss/services/project/DeviceServiceImpl.java index 1ad4839aa..165dd0e38 100644 --- a/src/main/java/club/joylink/rtss/services/project/DeviceServiceImpl.java +++ b/src/main/java/club/joylink/rtss/services/project/DeviceServiceImpl.java @@ -1,17 +1,35 @@ package club.joylink.rtss.services.project; import club.joylink.rtss.constants.Project; +import club.joylink.rtss.constants.ProjectCode; import club.joylink.rtss.constants.ProjectDeviceType; 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.simulation.cbtc.device.real.udp.thailand.service.ThailandSignalServiceImpl; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service.ThailandSwitchServiceImpl; 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; -import club.joylink.rtss.vo.client.project.*; +import club.joylink.rtss.vo.client.project.IbpConfigVO; +import club.joylink.rtss.vo.client.project.LswConfigVO; +import club.joylink.rtss.vo.client.project.LwConfigVO; +import club.joylink.rtss.vo.client.project.PlcGatewayConfigVO; +import club.joylink.rtss.vo.client.project.ProjectDevicePageQueryVO; +import club.joylink.rtss.vo.client.project.ProjectDeviceVO; +import club.joylink.rtss.vo.client.project.PscConfigVO; +import club.joylink.rtss.vo.client.project.PsdConfigVO; +import club.joylink.rtss.vo.client.project.PslConfigVO; +import club.joylink.rtss.vo.client.project.RelationLoginConfigVO; +import club.joylink.rtss.vo.client.project.SignalConfigVO; +import club.joylink.rtss.vo.client.project.SwitchConfigVO; +import club.joylink.rtss.vo.client.project.UDPClientConfigVO; +import club.joylink.rtss.vo.client.project.UDPLowConfigVO; +import club.joylink.rtss.vo.client.project.VrIbpConfigVO; +import club.joylink.rtss.vo.client.project.VrpsdConfigVO; import club.joylink.rtss.vo.client.project.gzb.GzbSignalConfigVO; import club.joylink.rtss.vo.client.project.gzb.GzbSwitchConfigVO; import club.joylink.rtss.vo.client.project.hhcj.HhcjIbpConfigVO; @@ -19,13 +37,20 @@ import club.joylink.rtss.vo.client.project.hhcj.HhcjPsdConfigVO; import club.joylink.rtss.vo.client.project.richor.ZjdIbpConfigVO; 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.say.*; +import club.joylink.rtss.vo.client.project.say.SayIbpConfigVO; +import club.joylink.rtss.vo.client.project.say.SayPsdConfigVO; +import club.joylink.rtss.vo.client.project.say.SaySectionConfigVO; +import club.joylink.rtss.vo.client.project.say.SaySignalConfigVO; +import club.joylink.rtss.vo.client.project.say.SaySwitchConfigVO; 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.sr.SrTrainConfigVO; +import club.joylink.rtss.vo.client.project.thailand.ThailandSectionConfigVO; +import club.joylink.rtss.vo.client.project.thailand.ThailandSwitchConfigVO; +import club.joylink.rtss.vo.client.project.thailand.ThailandTrainConfigVO; import club.joylink.rtss.vo.client.project.xty.XtyPsdConfigVO; import club.joylink.rtss.vo.map.MapGraphDataNewVO; import club.joylink.rtss.vo.map.MapVO; @@ -33,808 +58,979 @@ 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 club.joylink.rtss.vo.map.graph.MapTrainVO; -import club.joylink.rtss.vo.project.ProjectVO; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; @Service public class DeviceServiceImpl implements DeviceService { - @Autowired - private ProjectDeviceDAO projectDeviceDAO; + @Autowired + private ProjectDeviceDAO projectDeviceDAO; - @Autowired - private IMapService iMapService; + @Autowired + private IMapService iMapService; - // 修改项目编码 20221009 - @Override - public PageVO pagingQuery(ProjectDevicePageQueryVO queryVO) { - ProjectDeviceExample example = new ProjectDeviceExample(); - ProjectDeviceExample.Criteria criteria = example.createCriteria(); - if (StringUtils.hasText(queryVO.getProjectCode())) { - criteria.andProjectCodeEqualTo(queryVO.getProjectCode()); - } - if (StringUtils.hasText(queryVO.getCode())) { - criteria.andCodeLike(String.format("%%%s%%", queryVO.getCode())); - } - if (Objects.nonNull(queryVO.getType())) { - criteria.andTypeEqualTo(queryVO.getType().name()); - } - PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize()); - Page projectDevices = (Page) this.projectDeviceDAO.selectByExample(example); - List projectDeviceVOS = ProjectDeviceVO.convert2VOList(projectDevices.getResult()); - return PageVO.convert(projectDevices, projectDeviceVOS); + // 修改项目编码 20221009 + @Override + public PageVO pagingQuery(ProjectDevicePageQueryVO queryVO) { + ProjectDeviceExample example = new ProjectDeviceExample(); + ProjectDeviceExample.Criteria criteria = example.createCriteria(); + if (StringUtils.hasText(queryVO.getProjectCode())) { + criteria.andProjectCodeEqualTo(queryVO.getProjectCode()); } - - @Override - public boolean isDeviceCodeExist(String project, String code) { - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria().andProjectCodeEqualTo(project).andCodeEqualTo(code); - if (this.projectDeviceDAO.countByExample(example) > 0) { - return true; - } - return false; + if (StringUtils.hasText(queryVO.getCode())) { + criteria.andCodeLike(String.format("%%%s%%", queryVO.getCode())); } - - @Override - public String create(ProjectDeviceVO deviceVO, LoginUserInfoVO userLoginInfo) { - ProjectDevice projectDevice = deviceVO.buildDB(); - projectDevice.setCreator(userLoginInfo.getAccountVO().getId()); - projectDevice.setCreateTime(LocalDateTime.now()); - this.projectDeviceDAO.insert(projectDevice); - return String.valueOf(projectDevice.getId()); + if (Objects.nonNull(queryVO.getType())) { + criteria.andTypeEqualTo(queryVO.getType().name()); } + PageHelper.startPage(queryVO.getPageNum(), queryVO.getPageSize()); + Page projectDevices = (Page) this.projectDeviceDAO.selectByExample( + example); + List projectDeviceVOS = ProjectDeviceVO.convert2VOList( + projectDevices.getResult()); + return PageVO.convert(projectDevices, projectDeviceVOS); + } - @Override - public ProjectDeviceVO getDeviceBaseInfoById(Long id) { - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andIdEqualTo(id); - List projectDevices = this.projectDeviceDAO.selectByExample(example); - BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertCollectionNotEmpty(projectDevices, - String.format("id为[%s]的设备不存在")); - ProjectDevice projectDevice = projectDevices.get(0); - ProjectDeviceVO projectDeviceVO = new ProjectDeviceVO(projectDevice); - return projectDeviceVO; + @Override + public boolean isDeviceCodeExist(String project, String code) { + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria().andProjectCodeEqualTo(project).andCodeEqualTo(code); + if (this.projectDeviceDAO.countByExample(example) > 0) { + return true; } + return false; + } - @Override - public void updatePlcGatewayConfig(Long id, PlcGatewayConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PLC_GATEWAY, - String.format("设备[%s(%s)]不是PLC网关,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public String create(ProjectDeviceVO deviceVO, LoginUserInfoVO userLoginInfo) { + ProjectDevice projectDevice = deviceVO.buildDB(); + projectDevice.setCreator(userLoginInfo.getAccountVO().getId()); + projectDevice.setCreateTime(LocalDateTime.now()); + this.projectDeviceDAO.insert(projectDevice); + return String.valueOf(projectDevice.getId()); + } + + @Override + public ProjectDeviceVO getDeviceBaseInfoById(Long id) { + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andIdEqualTo(id); + List projectDevices = this.projectDeviceDAO.selectByExample(example); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertCollectionNotEmpty(projectDevices, + String.format("id为[%s]的设备不存在")); + ProjectDevice projectDevice = projectDevices.get(0); + ProjectDeviceVO projectDeviceVO = new ProjectDeviceVO(projectDevice); + return projectDeviceVO; + } + + @Override + public void updatePlcGatewayConfig(Long id, PlcGatewayConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PLC_GATEWAY, + String.format("设备[%s(%s)]不是PLC网关,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateSwitchConfig(Long id, SwitchConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SWITCH, + String.format("设备[%s(%s)]不是道岔,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateSignalConfig(Long id, SignalConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SIGNAL, + String.format("设备[%s(%s)]不是信号机,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updatePscConfig(Long id, PscConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSC, + String.format("设备[%s(%s)]不是屏蔽门控制柜,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updatePsdConfig(Long id, PsdConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSD, + String.format("设备[%s(%s)]不是屏蔽门,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updatePslConfig(Long id, PslConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSL, + String.format("设备[%s(%s)]不是屏蔽门控制盒,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateIbpConfig(Long id, IbpConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.IBP, + String.format("设备[%s(%s)]不是IBP盘,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateVrIbpConfig(Long id, VrIbpConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.VR_IBP, + String.format("设备[%s(%s)]不是虚拟IBP盘,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateLwConfig(Long id, LwConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.LW, + String.format("设备[%s(%s)]不是现地工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateLswConfig(Long id, LswConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.LSW, + String.format("设备[%s(%s)]不是大屏工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateCctvConfig(Long id, RelationLoginConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.CCTV, + String.format("设备[%s(%s)]不是CCTV工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateSandboxConfig(Long id, RelationLoginConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SANDBOX, + String.format("设备[%s(%s)]不是电子沙盘工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateIscsLwConfig(Long id, RelationLoginConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ISCS_LW, + String.format("设备[%s(%s)]不是现地综合监控工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateIscsCwConfig(Long id, RelationLoginConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ISCS_CW, + String.format("设备[%s(%s)]不是中心综合监控工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateVrpsdConfig(Long id, VrpsdConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.VR_PSD, + String.format("设备[%s(%s)]不是虚拟屏蔽门工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateIlwConfig(Long id, RelationLoginConfigVO configVO) { + ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( + ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ILW, + String.format("设备[%s(%s)]不是联锁工作站,不能更新", device.getCode(), device.getType())); + device.setConfig(configVO.toJson()); + this.projectDeviceDAO.updateByPrimaryKeySelective(device); + } + + @Override + public void updateConfig(ProjectDeviceVO projectDeviceVO) { + ProjectDevice entity = getEntityById(projectDeviceVO.getId()); + check(entity, projectDeviceVO); + entity.setConfig(projectDeviceVO.getConfig()); + projectDeviceDAO.updateByPrimaryKeyWithBLOBs(entity); + } + + private ProjectDevice getEntityById(long id) { + return projectDeviceDAO.selectByPrimaryKey(id); + } + + private void check(ProjectDevice entity, ProjectDeviceVO projectDeviceVO) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getProjectCode(), + projectDeviceVO.getProject()); + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getCode(), + projectDeviceVO.getCode()); + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getType(), + projectDeviceVO.getType().name()); + } + + @Override + public void delete(Long id) { + this.projectDeviceDAO.deleteByPrimaryKey(id); + } + + @Override + public List queryByType(ProjectDeviceType type, String project) { + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotEquals(project, + Project.DEFAULT.name(), + String.format("项目[%s]没有权限", project)); + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria().andProjectCodeEqualTo(project).andTypeEqualTo(type.name()); + List projectDevices = this.projectDeviceDAO.selectByExample(example); + return ProjectDeviceVO.convert2VOList(projectDevices); + } + + @Override + public ProjectDeviceVO getDeviceDetailInfoById(Long id) { + ProjectDevice projectDevice = this.projectDeviceDAO.selectByPrimaryKey(id); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(projectDevice, + String.format("id为[%s]的设备不存在", id)); + return new ProjectDeviceVO(projectDevice); + } + + /** + * TODO 20220922 用于替换上方方法 占位 + */ + @Override + public ProjectDeviceVO getDeviceDetailInfoOf(String project, String deviceCode) { + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria().andProjectCodeEqualTo(project).andCodeEqualTo(deviceCode); + List projectDevices = this.projectDeviceDAO.selectByExampleWithBLOBs(example); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertCollectionNotEmpty(projectDevices, + String.format("[project:%s,code:%s]的设备不存在", project, deviceCode)); + return new ProjectDeviceVO(projectDevices.get(0)); + } + + @Override + public List queryDetailByTypes(List typeList, + String project) { + if (CollectionUtils.isEmpty(typeList)) { + throw new IllegalArgumentException("ProjectDeviceType list cannot empty"); } + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(project) + .andTypeIn(typeList.stream().map(Enum::name).collect(Collectors.toList())); + List list = this.projectDeviceDAO.selectByExampleWithBLOBs(example); + return ProjectDeviceVO.convert2VOList(list); + } - @Override - public void updateSwitchConfig(Long id, SwitchConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SWITCH, - String.format("设备[%s(%s)]不是道岔,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateXtyDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.XTY.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildXtyProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updateSignalConfig(Long id, SignalConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SIGNAL, - String.format("设备[%s(%s)]不是信号机,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + private List buildXtyProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(Project.XTY.name()); + plcGateway.setCode("xty-gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 32); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // 屏蔽门 + ProjectDevice psd = new ProjectDevice(); + psd.setProjectCode(Project.XTY.name()); + psd.setCode("xty-psd"); + psd.setType(ProjectDeviceType.PSD.name()); + psd.setCreator(accountVO.getId()); + psd.setCreateTime(now); + XtyPsdConfigVO psdConfigVO = new XtyPsdConfigVO(); + psd.setConfig(psdConfigVO.toJson()); + list.add(psd); + return list; + } + + @Override + public void addOrUpdateGzbDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.GZB.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildGzbProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updatePscConfig(Long id, PscConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSC, - String.format("设备[%s(%s)]不是屏蔽门控制柜,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateSdyDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.SDY.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildSdyProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updatePsdConfig(Long id, PsdConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSD, - String.format("设备[%s(%s)]不是屏蔽门,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateRichorDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.RICHOR_JOINT.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildZjdProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updatePslConfig(Long id, PslConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.PSL, - String.format("设备[%s(%s)]不是屏蔽门控制盒,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @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 list = this.buildSrProjectDevices(accountVO, mapId); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updateIbpConfig(Long id, IbpConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.IBP, - String.format("设备[%s(%s)]不是IBP盘,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateHhcjDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.RICHOR_HHCJ.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildHhcjProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updateVrIbpConfig(Long id, VrIbpConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.VR_IBP, - String.format("设备[%s(%s)]不是虚拟IBP盘,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateSayDeviceConfig(AccountVO accountVO) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(Project.SAY.name()) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildSayProjectDevices(accountVO); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updateLwConfig(Long id, LwConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.LW, - String.format("设备[%s(%s)]不是现地工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); + @Override + public void addOrUpdateThailandDeviceConfig(AccountVO accountVO, Long mapId) { + // 删除旧配置 + ProjectDeviceExample example = new ProjectDeviceExample(); + example.createCriteria() + .andProjectCodeEqualTo(ProjectCode.THAILAND_SANDBOX) + .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name) + .collect(Collectors.toList())); + this.projectDeviceDAO.deleteByExample(example); + // 保存新配置 + List list = this.buildThailandProjectDevices(accountVO, mapId); + for (ProjectDevice projectDevice : list) { + this.projectDeviceDAO.insert(projectDevice); } + } - @Override - public void updateLswConfig(Long id, LswConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.LSW, - String.format("设备[%s(%s)]不是大屏工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } + private List buildSayProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + String projectCode = Project.SAY.name(); + String prefix = "say-"; + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(projectCode); + plcGateway.setCode(prefix + "gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 256); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // IBP盘 + ProjectDevice ibp = new ProjectDevice(); + ibp.setProjectCode(projectCode); + ibp.setCode(prefix + "ibp"); + ibp.setType(ProjectDeviceType.IBP.name()); + ibp.setCreator(accountVO.getId()); + ibp.setCreateTime(now); + SayIbpConfigVO ibpConfigVO = new SayIbpConfigVO(); + ibp.setConfig(ibpConfigVO.toJson()); + list.add(ibp); + //PSD + ProjectDevice psd = new ProjectDevice(); + psd.setProjectCode(projectCode); + psd.setCode(prefix + "psd"); + psd.setType(ProjectDeviceType.PSD.name()); + psd.setCreator(accountVO.getId()); + psd.setCreateTime(now); + SayPsdConfigVO sayPsdConfigVO = new SayPsdConfigVO(); + psd.setConfig(sayPsdConfigVO.toJson()); + list.add(psd); + //SIGNAL + ProjectDevice signal = new ProjectDevice(); + signal.setProjectCode(projectCode); + signal.setCode(prefix + "signal"); + signal.setType(ProjectDeviceType.SIGNAL.name()); + signal.setCreator(accountVO.getId()); + signal.setCreateTime(now); + signal.setConfig(new SaySignalConfigVO().toJson()); + list.add(signal); + //SWITCH + ProjectDevice aSwitch = new ProjectDevice(); + aSwitch.setProjectCode(projectCode); + aSwitch.setCode(prefix + "switch"); + aSwitch.setType(ProjectDeviceType.SWITCH.name()); + aSwitch.setCreator(accountVO.getId()); + aSwitch.setCreateTime(now); + aSwitch.setConfig(new SaySwitchConfigVO().toJson()); + list.add(aSwitch); + //SECTION + ProjectDevice section = new ProjectDevice(); + section.setProjectCode(projectCode); + section.setCode(prefix + "section"); + section.setType(ProjectDeviceType.SECTION.name()); + section.setCreator(accountVO.getId()); + section.setCreateTime(now); + section.setConfig(new SaySectionConfigVO().toJson()); + list.add(section); - @Override - public void updateCctvConfig(Long id, RelationLoginConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.CCTV, - String.format("设备[%s(%s)]不是CCTV工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } + return list; + } - @Override - public void updateSandboxConfig(Long id, RelationLoginConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.SANDBOX, - String.format("设备[%s(%s)]不是电子沙盘工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } + private List buildHhcjProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(Project.RICHOR_HHCJ.name()); + plcGateway.setCode("hhcj-gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 304); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // IBP盘 + ProjectDevice ibp = new ProjectDevice(); + ibp.setProjectCode(Project.RICHOR_HHCJ.name()); + ibp.setCode("hhcj-ibp"); + ibp.setType(ProjectDeviceType.IBP.name()); + ibp.setCreator(accountVO.getId()); + ibp.setCreateTime(now); + HhcjIbpConfigVO ibpConfigVO = new HhcjIbpConfigVO(); + ibp.setConfig(ibpConfigVO.toJson()); + list.add(ibp); + // PSD + ProjectDevice psd = new ProjectDevice(); + psd.setProjectCode(Project.RICHOR_HHCJ.name()); + psd.setCode("hhcj-psd"); + psd.setType(ProjectDeviceType.PSD.name()); + psd.setCreator(accountVO.getId()); + psd.setCreateTime(now); + HhcjPsdConfigVO psdConfigVO = new HhcjPsdConfigVO(); + psd.setConfig(psdConfigVO.toJson()); + list.add(psd); - @Override - public void updateIscsLwConfig(Long id, RelationLoginConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ISCS_LW, - String.format("设备[%s(%s)]不是现地综合监控工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } + return list; + } - @Override - public void updateIscsCwConfig(Long id, RelationLoginConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ISCS_CW, - String.format("设备[%s(%s)]不是中心综合监控工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } - - @Override - public void updateVrpsdConfig(Long id, VrpsdConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.VR_PSD, - String.format("设备[%s(%s)]不是虚拟屏蔽门工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } - - @Override - public void updateIlwConfig(Long id, RelationLoginConfigVO configVO) { - ProjectDevice device = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.INVALID_OPERATION.assertEquals( - ProjectDeviceType.valueOf(device.getType()), ProjectDeviceType.ILW, - String.format("设备[%s(%s)]不是联锁工作站,不能更新", device.getCode(), device.getType())); - device.setConfig(configVO.toJson()); - this.projectDeviceDAO.updateByPrimaryKeySelective(device); - } - - @Override - public void updateConfig(ProjectDeviceVO projectDeviceVO) { - ProjectDevice entity = getEntityById(projectDeviceVO.getId()); - check(entity, projectDeviceVO); - entity.setConfig(projectDeviceVO.getConfig()); - projectDeviceDAO.updateByPrimaryKeyWithBLOBs(entity); - } - - private ProjectDevice getEntityById(long id) { - return projectDeviceDAO.selectByPrimaryKey(id); - } - - private void check(ProjectDevice entity, ProjectDeviceVO projectDeviceVO) { - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getProjectCode(), projectDeviceVO.getProject()); - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getCode(), projectDeviceVO.getCode()); - BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertEquals(entity.getType(), projectDeviceVO.getType().name()); - } - - @Override - public void delete(Long id) { - this.projectDeviceDAO.deleteByPrimaryKey(id); - } - - @Override - public List queryByType(ProjectDeviceType type, String project) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotEquals(project, Project.DEFAULT.name(), - String.format("项目[%s]没有权限", project)); - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria().andProjectCodeEqualTo(project).andTypeEqualTo(type.name()); - List projectDevices = this.projectDeviceDAO.selectByExample(example); - return ProjectDeviceVO.convert2VOList(projectDevices); - } - - @Override - public ProjectDeviceVO getDeviceDetailInfoById(Long id) { - ProjectDevice projectDevice = this.projectDeviceDAO.selectByPrimaryKey(id); - BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(projectDevice, String.format("id为[%s]的设备不存在", id)); - return new ProjectDeviceVO(projectDevice); - } - - /** - * TODO 20220922 用于替换上方方法 占位 - */ - @Override - public ProjectDeviceVO getDeviceDetailInfoOf(String project, String deviceCode) { - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria().andProjectCodeEqualTo(project).andCodeEqualTo(deviceCode); - List projectDevices = this.projectDeviceDAO.selectByExampleWithBLOBs(example); - BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertCollectionNotEmpty(projectDevices, - String.format("[project:%s,code:%s]的设备不存在", project, deviceCode)); - return new ProjectDeviceVO(projectDevices.get(0)); - } - - @Override - public List queryDetailByTypes(List typeList, String project) { - if (CollectionUtils.isEmpty(typeList)) { - throw new IllegalArgumentException("ProjectDeviceType list cannot empty"); - } - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(project) - .andTypeIn(typeList.stream().map(Enum::name).collect(Collectors.toList())); - List list = this.projectDeviceDAO.selectByExampleWithBLOBs(example); - return ProjectDeviceVO.convert2VOList(list); - } - - @Override - public void addOrUpdateXtyDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.XTY.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildXtyProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - private List buildXtyProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(Project.XTY.name()); - plcGateway.setCode("xty-gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 32); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // 屏蔽门 - ProjectDevice psd = new ProjectDevice(); - psd.setProjectCode(Project.XTY.name()); - psd.setCode("xty-psd"); - psd.setType(ProjectDeviceType.PSD.name()); - psd.setCreator(accountVO.getId()); - psd.setCreateTime(now); - XtyPsdConfigVO psdConfigVO = new XtyPsdConfigVO(); - psd.setConfig(psdConfigVO.toJson()); - list.add(psd); - return list; - } - - @Override - public void addOrUpdateGzbDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.GZB.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildGzbProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - @Override - public void addOrUpdateSdyDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.SDY.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildSdyProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - @Override - public void addOrUpdateRichorDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.RICHOR_JOINT.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildZjdProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - @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 list = this.buildSrProjectDevices(accountVO, mapId); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - @Override - public void addOrUpdateHhcjDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.RICHOR_HHCJ.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildHhcjProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - @Override - public void addOrUpdateSayDeviceConfig(AccountVO accountVO) { - // 删除旧配置 - ProjectDeviceExample example = new ProjectDeviceExample(); - example.createCriteria() - .andProjectCodeEqualTo(Project.SAY.name()) - .andTypeIn(ProjectDeviceType.PlcDeviceList().stream().map(Enum::name).collect(Collectors.toList())); - this.projectDeviceDAO.deleteByExample(example); - // 保存新配置 - List list = this.buildSayProjectDevices(accountVO); - for (ProjectDevice projectDevice : list) { - this.projectDeviceDAO.insert(projectDevice); - } - } - - private List buildSayProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); - String projectCode = Project.SAY.name(); - String prefix = "say-"; - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(projectCode); - plcGateway.setCode(prefix + "gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 256); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // IBP盘 - ProjectDevice ibp = new ProjectDevice(); - ibp.setProjectCode(projectCode); - ibp.setCode(prefix + "ibp"); - ibp.setType(ProjectDeviceType.IBP.name()); - ibp.setCreator(accountVO.getId()); - ibp.setCreateTime(now); - SayIbpConfigVO ibpConfigVO = new SayIbpConfigVO(); - ibp.setConfig(ibpConfigVO.toJson()); - list.add(ibp); - //PSD - ProjectDevice psd = new ProjectDevice(); - psd.setProjectCode(projectCode); - psd.setCode(prefix + "psd"); - psd.setType(ProjectDeviceType.PSD.name()); - psd.setCreator(accountVO.getId()); - psd.setCreateTime(now); - SayPsdConfigVO sayPsdConfigVO = new SayPsdConfigVO(); - psd.setConfig(sayPsdConfigVO.toJson()); - list.add(psd); - //SIGNAL + private List buildSrProjectDevices(AccountVO accountVO, long mapId) { + LocalDateTime now = LocalDateTime.now(); + List 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("192.168.0.110", 44449); + 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.0.110", 44449); + 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(projectCode); - signal.setCode(prefix + "signal"); + signal.setProjectCode(Project.SR_SANDBOX.name()); + signal.setCode("sr-signal-" + mapSignalNewVO.getCode()); signal.setType(ProjectDeviceType.SIGNAL.name()); signal.setCreator(accountVO.getId()); signal.setCreateTime(now); - signal.setConfig(new SaySignalConfigVO().toJson()); + SrSignalConfigVO configVO = new SrSignalConfigVO(mapSignalNewVO.getCode(), + mapSignalNewVO.getSrCode()); + signal.setConfig(JsonUtils.writeValueAsString(configVO)); list.add(signal); - //SWITCH + } + } + //道岔 + for (MapSwitchVO mapSwitchVO : graphDataNew.getSwitchList()) { + if (StringUtils.hasText(mapSwitchVO.getSrCode())) { ProjectDevice aSwitch = new ProjectDevice(); - aSwitch.setProjectCode(projectCode); - aSwitch.setCode(prefix + "switch"); + aSwitch.setProjectCode(Project.SR_SANDBOX.name()); + aSwitch.setCode("sr-switch-" + mapSwitchVO.getCode()); aSwitch.setType(ProjectDeviceType.SWITCH.name()); aSwitch.setCreator(accountVO.getId()); aSwitch.setCreateTime(now); - aSwitch.setConfig(new SaySwitchConfigVO().toJson()); + SrSwitchConfigVO configVO = new SrSwitchConfigVO(mapSwitchVO.getCode(), + mapSwitchVO.getSrCode()); + aSwitch.setConfig(JsonUtils.writeValueAsString(configVO)); list.add(aSwitch); - //SECTION + } + } + //区段 + for (MapSectionNewVO mapSectionNewVO : graphDataNew.getSectionList()) { + if (StringUtils.hasText(mapSectionNewVO.getSrCode())) { ProjectDevice section = new ProjectDevice(); - section.setProjectCode(projectCode); - section.setCode(prefix + "section"); + section.setProjectCode(Project.SR_SANDBOX.name()); + section.setCode("sr-section-" + mapSectionNewVO.getCode()); section.setType(ProjectDeviceType.SECTION.name()); section.setCreator(accountVO.getId()); section.setCreateTime(now); - section.setConfig(new SaySectionConfigVO().toJson()); + SrSectionConfigVO configVO = new SrSectionConfigVO(mapSectionNewVO.getCode(), + mapSectionNewVO.getSrCode()); + srFillTime(configVO, mapSectionNewVO); + section.setConfig(JsonUtils.writeValueAsString(configVO)); list.add(section); - - return list; + } } - - private List buildHhcjProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(Project.RICHOR_HHCJ.name()); - plcGateway.setCode("hhcj-gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 304); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // IBP盘 - ProjectDevice ibp = new ProjectDevice(); - ibp.setProjectCode(Project.RICHOR_HHCJ.name()); - ibp.setCode("hhcj-ibp"); - ibp.setType(ProjectDeviceType.IBP.name()); - ibp.setCreator(accountVO.getId()); - ibp.setCreateTime(now); - HhcjIbpConfigVO ibpConfigVO = new HhcjIbpConfigVO(); - ibp.setConfig(ibpConfigVO.toJson()); - list.add(ibp); - // PSD - ProjectDevice psd = new ProjectDevice(); - psd.setProjectCode(Project.RICHOR_HHCJ.name()); - psd.setCode("hhcj-psd"); - psd.setType(ProjectDeviceType.PSD.name()); - psd.setCreator(accountVO.getId()); - psd.setCreateTime(now); - HhcjPsdConfigVO psdConfigVO = new HhcjPsdConfigVO(); - psd.setConfig(psdConfigVO.toJson()); - list.add(psd); - - return list; + //列车 + List trainList = graphDataNew.getTrainList(); + for (MapTrainVO mapTrainVO : trainList) { + ProjectDevice train = new ProjectDevice(); + train.setProjectCode(Project.SR_SANDBOX.name()); + train.setCode("sr-train-" + mapTrainVO.getGroupNumber()); + train.setType(ProjectDeviceType.TRAIN.name()); + train.setCreator(accountVO.getId()); + train.setCreateTime(now); + SrTrainConfigVO configVO = new SrTrainConfigVO(mapTrainVO.getGroupNumber(), + String.valueOf(Integer.parseInt(mapTrainVO.getGroupNumber()))); + train.setConfig(JsonUtils.writeValueAsString(configVO)); + list.add(train); } + return list; + } - private List buildSrProjectDevices(AccountVO accountVO, long mapId) { - LocalDateTime now = LocalDateTime.now(); - List 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("192.168.0.110", 44449); - 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.0.110", 44449); - 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()); - fillTime(configVO, mapSectionNewVO); - section.setConfig(JsonUtils.writeValueAsString(configVO)); - list.add(section); - } - } - //列车 - List trainList = graphDataNew.getTrainList(); - for (MapTrainVO mapTrainVO : trainList) { - ProjectDevice train = new ProjectDevice(); - train.setProjectCode(Project.SR_SANDBOX.name()); - train.setCode("sr-train-" + mapTrainVO.getGroupNumber()); - train.setType(ProjectDeviceType.TRAIN.name()); - train.setCreator(accountVO.getId()); - train.setCreateTime(now); - SrTrainConfigVO configVO = new SrTrainConfigVO(mapTrainVO.getGroupNumber(), String.valueOf(Integer.parseInt(mapTrainVO.getGroupNumber()))); - train.setConfig(JsonUtils.writeValueAsString(configVO)); - list.add(train); - } - return list; + /** + * 填充区段延时停车时间(上饶沙盘项目) + */ + private void srFillTime(SrSectionConfigVO configVO, MapSectionNewVO section) { + Float headDelayTime = null; + Float tailDelayTime = null; + switch (section.getCode()) { + //以车头到目标位置作为停车标志的区段 + case "T141": //49G + case "T142": + headDelayTime = 1.0f; + break; + case "T1": //1G + headDelayTime = 3.7f; + break; + case "T11": + headDelayTime = 3.7f; + break; + case "T73": + case "T75": + headDelayTime = 3.4f; + break; + //以车尾解除占用作为停车标志的区段 + case "T5": //1x + break; + case "T7": //2x + break; + case "T45": //3x + break; + case "T53": //4x + break; + case "T61": //5x + break; + case "T67": //6x + break; + case "T33": //1s + tailDelayTime = 2.0f; + break; + case "T35": //2s + tailDelayTime = 2.5f; + break; + case "T46": //3s + break; + case "T54": //4s + break; + case "T62": //5s + break; + case "T68": //6s + tailDelayTime = 2.0f; + break; } + configVO.setHeadDelayTime(headDelayTime); + configVO.setTailDelayTime(tailDelayTime); + } - /** - * 填充区段延时停车时间 - */ - private void fillTime(SrSectionConfigVO configVO, MapSectionNewVO section) { - Float headDelayTime = null; - Float tailDelayTime = null; - switch (section.getCode()) { - //以车头到目标位置作为停车标志的区段 - case "T141": //49G - case "T142": - headDelayTime = 1.0f; - break; - case "T1": //1G - headDelayTime = 3.7f; - break; - case "T11": - headDelayTime = 3.7f; - break; - case "T73": - case "T75": - headDelayTime = 3.4f; - break; - //以车尾解除占用作为停车标志的区段 - case "T5": //1x - break; - case "T7": //2x - break; - case "T45": //3x - break; - case "T53": //4x - break; - case "T61": //5x - break; - case "T67": //6x - break; - case "T33": //1s - tailDelayTime = 2.0f; - break; - case "T35": //2s - tailDelayTime = 2.5f; - break; - case "T46": //3s - break; - case "T54": //4s - break; - case "T62": //5s - break; - case "T68": //6s - tailDelayTime = 2.0f; - break; - } - configVO.setHeadDelayTime(headDelayTime); - configVO.setTailDelayTime(tailDelayTime); - } + private List buildZjdProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(Project.RICHOR_JOINT.name()); + plcGateway.setCode("zjd-gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 144); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // 屏蔽门 + ProjectDevice psd = new ProjectDevice(); + psd.setProjectCode(Project.RICHOR_JOINT.name()); + psd.setCode("zjd-psd"); + psd.setType(ProjectDeviceType.PSD.name()); + psd.setCreator(accountVO.getId()); + psd.setCreateTime(now); + ZjdPsdConfigVO psdConfigVO = new ZjdPsdConfigVO(); + psd.setConfig(psdConfigVO.toJson()); + list.add(psd); + // IBP盘 + ProjectDevice ibp = new ProjectDevice(); + ibp.setProjectCode(Project.RICHOR_JOINT.name()); + ibp.setCode("zjd-ibp"); + ibp.setType(ProjectDeviceType.IBP.name()); + ibp.setCreator(accountVO.getId()); + ibp.setCreateTime(now); + ZjdIbpConfigVO ibpConfigVO = new ZjdIbpConfigVO(); + ibp.setConfig(ibpConfigVO.toJson()); + list.add(ibp); + // PSL + ProjectDevice psl = new ProjectDevice(); + psl.setProjectCode(Project.RICHOR_JOINT.name()); + psl.setCode("zjd-psl"); + psl.setType(ProjectDeviceType.PSL.name()); + psl.setCreator(accountVO.getId()); + psl.setCreateTime(now); + ZjdPslConfigVO pslConfigVO = new ZjdPslConfigVO(); + psl.setConfig(pslConfigVO.toJson()); + list.add(psl); + return list; + } - private List buildZjdProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(Project.RICHOR_JOINT.name()); - plcGateway.setCode("zjd-gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 144); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // 屏蔽门 - ProjectDevice psd = new ProjectDevice(); - psd.setProjectCode(Project.RICHOR_JOINT.name()); - psd.setCode("zjd-psd"); - psd.setType(ProjectDeviceType.PSD.name()); - psd.setCreator(accountVO.getId()); - psd.setCreateTime(now); - ZjdPsdConfigVO psdConfigVO = new ZjdPsdConfigVO(); - psd.setConfig(psdConfigVO.toJson()); - list.add(psd); - // IBP盘 - ProjectDevice ibp = new ProjectDevice(); - ibp.setProjectCode(Project.RICHOR_JOINT.name()); - ibp.setCode("zjd-ibp"); - ibp.setType(ProjectDeviceType.IBP.name()); - ibp.setCreator(accountVO.getId()); - ibp.setCreateTime(now); - ZjdIbpConfigVO ibpConfigVO = new ZjdIbpConfigVO(); - ibp.setConfig(ibpConfigVO.toJson()); - list.add(ibp); - // PSL - ProjectDevice psl = new ProjectDevice(); - psl.setProjectCode(Project.RICHOR_JOINT.name()); - psl.setCode("zjd-psl"); - psl.setType(ProjectDeviceType.PSL.name()); - psl.setCreator(accountVO.getId()); - psl.setCreateTime(now); - ZjdPslConfigVO pslConfigVO = new ZjdPslConfigVO(); - psl.setConfig(pslConfigVO.toJson()); - list.add(psl); - return list; - } - - private List buildSdyProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); + private List buildSdyProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); // // 教员机 // list.add(buildIm(Project.SDY, userVO.getId())); - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(Project.SDY.name()); - plcGateway.setCode("sdy-gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 16); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // 屏蔽门 - ProjectDevice psd = new ProjectDevice(); - psd.setProjectCode(Project.SDY.name()); - psd.setCode("sdy-psd"); - psd.setType(ProjectDeviceType.PSD.name()); - psd.setCreator(accountVO.getId()); - psd.setCreateTime(now); - SdyPsdConfigVO psdConfigVO = new SdyPsdConfigVO(); - psd.setConfig(psdConfigVO.toJson()); - list.add(psd); - // PSL盘 - ProjectDevice psl = new ProjectDevice(); - psl.setProjectCode(Project.SDY.name()); - psl.setCode("sdy-psl"); - psl.setType(ProjectDeviceType.PSL.name()); - psl.setCreator(accountVO.getId()); - psl.setCreateTime(now); - SdyPslConfigVO pslConfigVO = new SdyPslConfigVO(); - psl.setConfig(pslConfigVO.toJson()); - list.add(psl); - return list; - } + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(Project.SDY.name()); + plcGateway.setCode("sdy-gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 16); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // 屏蔽门 + ProjectDevice psd = new ProjectDevice(); + psd.setProjectCode(Project.SDY.name()); + psd.setCode("sdy-psd"); + psd.setType(ProjectDeviceType.PSD.name()); + psd.setCreator(accountVO.getId()); + psd.setCreateTime(now); + SdyPsdConfigVO psdConfigVO = new SdyPsdConfigVO(); + psd.setConfig(psdConfigVO.toJson()); + list.add(psd); + // PSL盘 + ProjectDevice psl = new ProjectDevice(); + psl.setProjectCode(Project.SDY.name()); + psl.setCode("sdy-psl"); + psl.setType(ProjectDeviceType.PSL.name()); + psl.setCreator(accountVO.getId()); + psl.setCreateTime(now); + SdyPslConfigVO pslConfigVO = new SdyPslConfigVO(); + psl.setConfig(pslConfigVO.toJson()); + list.add(psl); + return list; + } - private ProjectDevice buildIm(ProjectVO projectVO, Long creatorId) { - ProjectDevice im = new ProjectDevice(); - im.setProjectCode(projectVO.name()); - im.setCode(projectVO.name().toLowerCase() + "-" + "im"); - im.setType(ProjectDeviceType.IM.name()); - im.setCreator(creatorId); - im.setCreateTime(LocalDateTime.now()); - return im; - } + private List buildGzbProjectDevices(AccountVO accountVO) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + // PLC网关 + ProjectDevice plcGateway = new ProjectDevice(); + plcGateway.setProjectCode(Project.GZB.name()); + plcGateway.setCode("gzb-gateway"); + plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); + plcGateway.setCreator(accountVO.getId()); + plcGateway.setCreateTime(now); + PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 16); + plcGateway.setConfig(plcGatewayConfigVO.toJson()); + list.add(plcGateway); + // 道岔 + ProjectDevice switchA = new ProjectDevice(); + switchA.setProjectCode(Project.GZB.name()); + switchA.setCode("gzb-switch"); + switchA.setType(ProjectDeviceType.SWITCH.name()); + switchA.setCreator(accountVO.getId()); + switchA.setCreateTime(now); + GzbSwitchConfigVO switchConfigVO = new GzbSwitchConfigVO(); + switchA.setConfig(switchConfigVO.toJson()); + list.add(switchA); + // 信号机 + ProjectDevice signal = new ProjectDevice(); + signal.setProjectCode(Project.GZB.name()); + signal.setCode("gzb-signal"); + signal.setType(ProjectDeviceType.SIGNAL.name()); + signal.setCreator(accountVO.getId()); + signal.setCreateTime(now); + GzbSignalConfigVO signalConfigVO = new GzbSignalConfigVO(); + signal.setConfig(signalConfigVO.toJson()); + list.add(signal); + return list; + } - private List buildGzbProjectDevices(AccountVO accountVO) { - LocalDateTime now = LocalDateTime.now(); - List list = new ArrayList<>(); - // PLC网关 - ProjectDevice plcGateway = new ProjectDevice(); - plcGateway.setProjectCode(Project.GZB.name()); - plcGateway.setCode("gzb-gateway"); - plcGateway.setType(ProjectDeviceType.PLC_GATEWAY.name()); - plcGateway.setCreator(accountVO.getId()); - plcGateway.setCreateTime(now); - PlcGatewayConfigVO plcGatewayConfigVO = new PlcGatewayConfigVO(0, 16); - plcGateway.setConfig(plcGatewayConfigVO.toJson()); - list.add(plcGateway); - // 道岔 - ProjectDevice switchA = new ProjectDevice(); - switchA.setProjectCode(Project.GZB.name()); - switchA.setCode("gzb-switch"); - switchA.setType(ProjectDeviceType.SWITCH.name()); - switchA.setCreator(accountVO.getId()); - switchA.setCreateTime(now); - GzbSwitchConfigVO switchConfigVO = new GzbSwitchConfigVO(); - switchA.setConfig(switchConfigVO.toJson()); - list.add(switchA); - // 信号机 + private List buildThailandProjectDevices(AccountVO accountVO, long mapId) { + LocalDateTime now = LocalDateTime.now(); + List list = new ArrayList<>(); + String projectCode = ProjectCode.THAILAND_SANDBOX; + //道岔和列车数据发送端口 + ProjectDevice switchTrainUdpLow = new ProjectDevice(); + switchTrainUdpLow.setProjectCode(projectCode); + switchTrainUdpLow.setCode("udp-sender-1"); + switchTrainUdpLow.setType(ProjectDeviceType.UDP_LOW.name()); + switchTrainUdpLow.setCreator(accountVO.getId()); + switchTrainUdpLow.setCreateTime(now); + switchTrainUdpLow.setConfig( + new UDPLowConfigVO(ThailandSwitchServiceImpl.NAME, "192.168.0.10", 44449).toJson()); + list.add(switchTrainUdpLow); + //信号机数据发送端口 + ProjectDevice signalUdpLow = new ProjectDevice(); + signalUdpLow.setProjectCode(projectCode); + signalUdpLow.setCode("udp-sender-2"); + signalUdpLow.setType(ProjectDeviceType.UDP_LOW.name()); + signalUdpLow.setCreator(accountVO.getId()); + signalUdpLow.setCreateTime(now); + signalUdpLow.setConfig( + new UDPLowConfigVO(ThailandSignalServiceImpl.NAME, "192.168.0.10", 44445).toJson()); + list.add(signalUdpLow); + //UDP数据接收 + ProjectDevice udpClient = new ProjectDevice(); + udpClient.setProjectCode(projectCode); + udpClient.setCode("udp-receiver"); + udpClient.setType(ProjectDeviceType.UDP_CLIENT.name()); + udpClient.setCreator(accountVO.getId()); + udpClient.setCreateTime(now); + UDPClientConfigVO udpClientConfigVO = new UDPClientConfigVO("192.168.0.10", 44449); + 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.GZB.name()); - signal.setCode("gzb-signal"); + signal.setProjectCode(projectCode); + signal.setCode("signal-" + mapSignalNewVO.getCode()); signal.setType(ProjectDeviceType.SIGNAL.name()); signal.setCreator(accountVO.getId()); signal.setCreateTime(now); - GzbSignalConfigVO signalConfigVO = new GzbSignalConfigVO(); - signal.setConfig(signalConfigVO.toJson()); + SrSignalConfigVO configVO = new SrSignalConfigVO(mapSignalNewVO.getCode(), + mapSignalNewVO.getSrCode()); + signal.setConfig(JsonUtils.writeValueAsString(configVO)); list.add(signal); - return list; + } } + //道岔 + for (MapSwitchVO mapSwitchVO : graphDataNew.getSwitchList()) { + if (StringUtils.hasText(mapSwitchVO.getSrCode())) { + ProjectDevice aSwitch = new ProjectDevice(); + aSwitch.setProjectCode(projectCode); + aSwitch.setCode("switch-" + mapSwitchVO.getCode()); + aSwitch.setType(ProjectDeviceType.SWITCH.name()); + aSwitch.setCreator(accountVO.getId()); + aSwitch.setCreateTime(now); + ThailandSwitchConfigVO configVO = new ThailandSwitchConfigVO(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(projectCode); + section.setCode("section-" + mapSectionNewVO.getCode()); + section.setType(ProjectDeviceType.SECTION.name()); + section.setCreator(accountVO.getId()); + section.setCreateTime(now); + ThailandSectionConfigVO configVO = new ThailandSectionConfigVO(mapSectionNewVO.getCode(), + mapSectionNewVO.getSrCode()); + thailandFillTime(configVO, mapSectionNewVO); + section.setConfig(JsonUtils.writeValueAsString(configVO)); + list.add(section); + } + } + //列车 + List trainList = graphDataNew.getTrainList(); + for (MapTrainVO mapTrainVO : trainList) { + ProjectDevice train = new ProjectDevice(); + train.setProjectCode(projectCode); + train.setCode("train-" + mapTrainVO.getGroupNumber()); + train.setType(ProjectDeviceType.TRAIN.name()); + train.setCreator(accountVO.getId()); + train.setCreateTime(now); + ThailandTrainConfigVO configVO = new ThailandTrainConfigVO(mapTrainVO.getGroupNumber(), + String.valueOf(Integer.parseInt(mapTrainVO.getGroupNumber()))); + train.setConfig(JsonUtils.writeValueAsString(configVO)); + list.add(train); + } + return list; + } + + private void thailandFillTime(ThailandSectionConfigVO configVO, MapSectionNewVO section) { + Float headDelayTime = null; + Float tailDelayTime = null; + if (section.isStandTrack()) { //站台轨默认为车尾出清立即停车 + headDelayTime = 5f; + } + switch (section.getCode()) { + case "T233": //X302G + headDelayTime = 7f; + break; + case "T232": //X303G + headDelayTime = 7f; + break; + case "T231": //X304G + headDelayTime = 5.5f; + break; + case "T175": //4站-IIG + headDelayTime = 5.5f; + break; + case "T121": //4站-IIG + headDelayTime = 5.2f; + break; + case "T77": //4站-IIG + headDelayTime = 6f; + break; + case "T145": //QX04 + tailDelayTime = 0f; + break; + case "T146": //QS04 + tailDelayTime = 0f; + break; + case "T104": //QX03 + tailDelayTime = 0f; + break; + case "T105": //QS03 + tailDelayTime = 0f; + break; + case "T62": //QX02 + tailDelayTime = 0f; + break; + case "T63": //QS02 + tailDelayTime = 0f; + break; + } + configVO.setHeadDelayTime(headDelayTime); + configVO.setTailDelayTime(tailDelayTime); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/device/CiSignalControlService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/device/CiSignalControlService.java index 9d8936010..a7eff5087 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/device/CiSignalControlService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/device/CiSignalControlService.java @@ -1,6 +1,5 @@ package club.joylink.rtss.simulation.cbtc.CI.device; -import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; import club.joylink.rtss.simulation.cbtc.data.map.Signal; @@ -62,9 +61,9 @@ public class CiSignalControlService { } else { this.virtualRealityDeviceService.control(simulation, vrSignal, SignalAspect.No); } - } else { // 后背模式,开放室外信号 + } else { // 后备模式,开放室外信号 if(signal.getSignalModel().getDefaultAspect().equals(aspect) || - (signal.getSignalModel().getGuideAspect().equals(aspect) && signal.isHigherThanGuideLevel()) || + (aspect.equals(signal.getSignalModel().getGuideAspect()) && signal.isHigherThanGuideLevel()) || (signal.isAtpLevel() || signal.isMainLevel())) { this.virtualRealityDeviceService.control(simulation, vrSignal, aspect); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationService.java index 00b6d7bf3..2382eb513 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationService.java @@ -7,21 +7,6 @@ import club.joylink.rtss.vo.project.ProjectVO; * 项目综合演练仿真服务 */ public interface ProjectJointSimulationService { - /** - * 实训室教员机登录创建仿真 - * - * @param loginUserInfo - * @return - */ - Simulation createSimulation(LoginUserInfoVO loginUserInfo); - - /** - * 获取实训室仿真 - * - * @param project - * @return - */ - Simulation getProjectSimulation(String project); /** * 通过项目设置的mapID与功能ID获取仿真 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationServiceImpl.java index a069f8185..f0db16ed8 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ProjectJointSimulationServiceImpl.java @@ -1,35 +1,21 @@ package club.joylink.rtss.simulation.cbtc; -import club.joylink.rtss.constants.MapPrdTypeEnum; -import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; -import club.joylink.rtss.services.IMapService; 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.device.real.modbustcp.SimulationRealDeviceThread; -import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDeviceConfig; -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.SimulationUser; -import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.client.project.ProjectDeviceVO; -import club.joylink.rtss.vo.map.MapVO; import club.joylink.rtss.vo.project.ProjectVO; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; @Slf4j @Service @@ -40,169 +26,17 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation @Autowired private ApplicationContext applicationContext; - @Autowired - private IMapService iMapService; - - @Autowired - private DeviceService deviceService; - @Autowired private GroupSimulationService groupSimulationService; - @Autowired - private MemberManager memberManager; - - @Autowired - private SimulationRealDeviceThread simulationRealDeviceThread; - - @Autowired - private UDPRealDeviceThread udpRealDeviceThread; - @Autowired private SimulationService simulationService; - @Override - public Simulation createSimulation(LoginUserInfoVO loginUserInfo) { - String project = loginUserInfo.getProject(); - Simulation oldSimulation = projectSimulationMap.get(project); - // 之前的仿真销毁 - if (Objects.nonNull(oldSimulation)) { - this.handleLogout(oldSimulation.getBuildParams().getLoginUserInfo()); - } - // 权限判断 - - AccountVO accountVO = loginUserInfo.getAccountVO(); - // 查询用户综合演练配置 - - // 查询项目地图,默认取第一个(暂时这样处理,后面考虑配置实训室-地图对应?) - List mapList = this.iMapService.findOnlineMapByProjectCode(project); - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertCollectionNotEmpty(mapList, - String.format("项目[%s]无地图", project)); - // 查询项目设备 - List projectDeviceList = this.deviceService - .queryDetailByTypes(ProjectDeviceType.PlcDeviceList(), project); - List realDeviceList = ProjectDeviceVO.convert2RealDeviceList(projectDeviceList); - log.info(String.format("load project device list: [%s]", - String.join(",", realDeviceList.stream().map(realDevice -> realDevice.toString()).collect(Collectors.toList())))); - // 构建仿真 - Long mapId = mapList.get(0).getId(); - Simulation simulation = this.groupSimulationService.create(loginUserInfo, mapId, - MapPrdTypeEnum.JOINT, Simulation.FunctionalType.SIMULATION); - this.loadRealDevices(simulation, realDeviceList); - projectSimulationMap.put(project, simulation); - return simulation; - } - - private void loadRealDevices(Simulation simulation, List realDeviceList) { - try { - simulation.setRealDeviceList(realDeviceList); - if (!CollectionUtils.isEmpty(realDeviceList)) { - simulationRealDeviceThread.addJobs(simulation); - udpRealDeviceThread.addJobs(simulation); - } - for (RealDeviceConfig realDevice : realDeviceList) { - if (ProjectDeviceType.PLC_GATEWAY.equals(realDevice.getDeviceType())) { - continue; - } - String deviceCode = this.queryDeviceCodeFromConfig(realDevice); - if (Objects.nonNull(deviceCode)) { - this.groupSimulationService.connectDevice(simulation.getId(), - deviceCode, realDevice.getProjectDevice().getId()); - } - } - } catch (Exception e) { - log.error("仿真加载真实设备异常", e); - // 清理仿真 - this.groupSimulationService.clearSimulation(simulation.getId(), simulation.getCreator()); - throw BusinessExceptionAssertEnum.TRAINING_ROOM_SIMULATION_LOAD_DEVICE_ERROR.exception(e); - } - } - - private String queryDeviceCodeFromConfig(RealDeviceConfig config) { - return config.findDeviceCode(); -// switch (config.getProject()) { -// case "HEB": { -// switch (config.getDeviceType()) { -// case IBP: -// return ((Heb1IbpConfig) config).getConfig().getStationCode(); -// case PSL: -// return ((Heb1PslConfig) config).getConfig().getPsdCode(); -// case PSC: -// return ((Heb1PscConfig) config).getConfig().getPsdCode(); -// } -// break; -// } -// case "XTY": { -// switch (config.getDeviceType()) { -// case PSD: -// return ((XtyPsdConfig) config).getConfig().getPsdCode(); -// } -// break; -// } -// case "RICHOR_JOINT": { -// switch (config.getDeviceType()) { -// case IBP: -// return ((ZjdIbpConfig) config).getConfigVO().getIbpCode(); -// case PSL: -// return ((ZjdPslConfig) config).getConfigVO().getPslCode(); -// } -// break; -// } -// 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(); -// case TRAIN: -// return ((SrTrainConfig) config).getConfigVO().getVrCode(); -// } -// break; -// } -// case "RICHOR_HHCJ": { -// switch (config.getDeviceType()) { -// case IBP: -// return ((HhcjIbpConfig) config).getConfigVO().getIbpCode(); -// case PSD: -// return ((HhcjPsdConfig) config).getConfigVO().getPsdCode(); -// } -// break; -// } -// case "SAY": { -// return config.findDeviceCode(); -// switch (config.getDeviceType()) { -// case IBP: -// return ((SayIbpConfig) config).getConfigVO().getIbpCode(); -// case PSD: -// return ((SayPsdConfig) config).getConfigVO().getPsdCode(); -// case SIGNAL: -// return ((SaySignalConfig) config).getConfigVO().getSignalCode(); -// case SWITCH: -// return ((SaySwitchConfig) config).getConfigVO().getSwitchCode(); -// case SECTION: -// return config.findDeviceCode(); -// } -// break; -// } -// } -// return null; - } - private Simulation queryProjectSimulation(String project) { Simulation simulation = projectSimulationMap.get(project); return simulation; } - @Override - public Simulation getProjectSimulation(String project) { - Simulation simulation = projectSimulationMap.get(project); - BusinessExceptionAssertEnum.TRAINING_ROOM_SIMULATION_NOT_EXIST - .assertNotNull(simulation, String.format("项目[%s]实训室仿真不存在", project)); - return simulation; - } - @Override public Simulation getSimulationByProject(ProjectVO project) { Simulation simulation = simulationService.querySimulation(project.getMapId(), project.getFunctionId()); @@ -219,52 +53,6 @@ public class ProjectJointSimulationServiceImpl implements ProjectJointSimulation simulation.addSimulationUser(simulationUser); SimulationUserEnterEvent userEnterEvent = new SimulationUserEnterEvent(this, simulation, simulationUser); this.applicationContext.publishEvent(userEnterEvent); -// switch (deviceVO.getType()) { -// case LW: { -// // 暂时默认先按配置的车站创建成员 -// LwConfigVO lwConfigVO = deviceVO.buildLwConfig(); -// Station station = simulation.getRepository().getByCode(lwConfigVO.getStationCode(), Station.class); -// SimulationMember member = simulation.getSimulationMember(station, SimulationMember.Type.STATION_SUPERVISOR); -// this.memberManager.playRole(simulation, loginUserInfo.getAccountVO().getId(), member.getId()); -// // 现地工作站 -// break; -// } -// case CW: { -// // 行调工作站 -// List dispatcherList = simulation.querySimulationMembersOfRole(SimulationMember.Type.DISPATCHER); -// SimulationMember dispatcher = null; -// for (SimulationMember member : dispatcherList) { -// if (member.isRobot()) { -// dispatcher = member; -// break; -// } -// } -// if (Objects.isNull(dispatcher)) { -// // 行调都被占用,添加新的行调 -// dispatcher = this.memberManager.addRole(simulation, SimulationMember.Type.DISPATCHER); -// } -// this.memberManager.playRole(simulation, loginUserInfo.getAccountVO().getId(), dispatcher.getId()); -// break; -// } -// case DEPOT: { -// List depoterList = simulation.querySimulationMembersOfRole(SimulationMember.Type.DEPOT_DISPATCHER); -// SimulationMember depoter = null; -// for (SimulationMember member : depoterList) { -// if (member.isRobot()) { -// depoter = member; -// break; -// } -// } -// if (Objects.isNull(depoter)) { -// depoter = this.memberManager.addRole(simulation, SimulationMember.Type.DEPOT_DISPATCHER); -// } -// this.memberManager.playRole(simulation, loginUserInfo.getAccountVO().getId(), depoter.getId()); -// break; -// } -// case SCHEDULING: { -// -// } -// } loginUserInfo.setGroup(simulation.getId()); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java index 5c8274e37..a0583a37c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java @@ -10,12 +10,17 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno; import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; import lombok.Getter; import lombok.Setter; import org.springframework.util.CollectionUtils; -import java.util.*; - /** * 区段 */ @@ -24,502 +29,513 @@ import java.util.*; @ExpConditionMaterialSrcAnno(name = "Section", deviceType = MapElement.DeviceType.SECTION) public class Section extends DelayUnlockDevice { - public Section(String code, String name) { - super(code, name, DeviceType.SECTION); - this.logicList = new ArrayList<>(); - this.standList = new ArrayList<>(); - this.shuntingTypeList = new ArrayList<>(); - } + public Section(String code, String name) { + super(code, name, DeviceType.SECTION); + this.logicList = new ArrayList<>(); + this.standList = new ArrayList<>(); + this.shuntingTypeList = new ArrayList<>(); + } - // ------------------固有属性/关联关系--------------------- + // ------------------固有属性/关联关系--------------------- - /** - * 所属设备集中站 - */ - private Station deviceStation; + /** + * 所属设备集中站 + */ + private Station deviceStation; - /** - * 如果是站台轨(正常上下行停车站台)/折返轨/转换轨,设置归属车站 - */ - private Station station; + /** + * 如果是站台轨(正常上下行停车站台)/折返轨/转换轨,设置归属车站 + */ + private Station station; - /** - * 左边区段 - */ - private Section leftSection; + /** + * 左边区段 + */ + private Section leftSection; - /** - * 右边区段 - */ - private Section rightSection; + /** + * 右边区段 + */ + private Section rightSection; - /** - * 区段路线类型 - */ - private SectionRoadType roadType; + /** + * 区段路线类型 + */ + private SectionRoadType roadType; - /** - * 是否物理区段(计轴区段或道岔区段是物理区段,逻辑区段和道岔计轴区段不是物理区段) - */ - private boolean physical; + /** + * 是否物理区段(计轴区段或道岔区段是物理区段,逻辑区段和道岔计轴区段不是物理区段) + */ + private boolean physical; - /** - * 是否岔心 - */ - private boolean cross; + /** + * 是否岔心 + */ + private boolean cross; - /** - * 是否计轴区段(区段两端有计轴器,道岔计轴区段和一般计轴区段) - */ - private boolean axleCounter; + /** + * 是否计轴区段(区段两端有计轴器,道岔计轴区段和一般计轴区段) + */ + private boolean axleCounter; - /** - * 虚拟真实计轴器 - */ - private VirtualRealitySectionAxleCounter virtualAxleCounter; + /** + * 虚拟真实计轴器 + */ + private VirtualRealitySectionAxleCounter virtualAxleCounter; - /** - * 长度(道岔计轴区段没有长度) - */ - private float len; + /** + * 长度(道岔计轴区段没有长度) + */ + private float len; - private float minOffset; + private float minOffset; - private float maxOffset; + private float maxOffset; - /** - * 关联的父区段 - */ - private Section parent; + /** + * 关联的父区段 + */ + private Section parent; - /** - * 岔心关联的物理区段;道岔计轴区段关联的道岔区段、岔心;物理区段关联的逻辑区段 - */ - private List
logicList; + /** + * 岔心关联的物理区段;道岔计轴区段关联的道岔区段、岔心;物理区段关联的逻辑区段 + */ + private List
logicList; - /** - * 关联的右向信号机 - */ - private Signal signalToRight; + /** + * 关联的右向信号机 + */ + private Signal signalToRight; - /** - * 关联的左向信号机 - */ - private Signal signalToLeft; + /** + * 关联的左向信号机 + */ + private Signal signalToLeft; - /** - * 是否道岔区段 - */ - private boolean switchTrack; + /** + * 是否道岔区段 + */ + private boolean switchTrack; - /** - * 关联道岔 - */ - private Switch relSwitch; + /** + * 关联道岔 + */ + private Switch relSwitch; - /** - * 是否站台轨 - */ - private boolean standTrack; + /** + * 是否站台轨 + */ + private boolean standTrack; - /** - * 关联站台 - */ - private List standList; + /** + * 关联站台 + */ + private List standList; - /** - * 是否折返轨 - */ - private boolean turnBackTrack; + /** + * 是否折返轨 + */ + private boolean turnBackTrack; - /** - * 是否优先折返 - */ - private boolean firstTurnBack; + /** + * 是否优先折返 + */ + private boolean firstTurnBack; - /** - * 是否转换轨 - */ - private boolean transferTrack; + /** + * 是否转换轨 + */ + private boolean transferTrack; - /** - * 是否停车轨 - */ - private boolean parkingTrack; + /** + * 是否停车轨 + */ + private boolean parkingTrack; - /** - * 目的地码 - */ - private String destinationCode; + /** + * 目的地码 + */ + private String destinationCode; - /** - * 左向停车点 - */ - private Float stopPointLeft; + /** + * 左向停车点 + */ + private Float stopPointLeft; - /** - * 右向停车点 - */ - private Float stopPointRight; + /** + * 右向停车点 + */ + private Float stopPointRight; - /** - * 所属zc - */ - private Set zcs = new HashSet<>(); + /** + * 所属zc + */ + private Set zcs = new HashSet<>(); - /** - * 有停稳计时? - */ - private boolean hasStopCountDown; + /** + * 有停稳计时? + */ + private boolean hasStopCountDown; - /** - * 公里标 最小(米) - */ - private Float kmMin; - /** - * 公里标 最大(米) - */ - private Float kmMax; + /** + * 公里标 最小(米) + */ + private Float kmMin; + /** + * 公里标 最大(米) + */ + private Float kmMax; - // ------------------状态属性--------------------- + // ------------------状态属性--------------------- - /** - * 是否封锁(封锁后,包含区段的进路不能排列) - */ - @ExpConditionMaterialAnno(name = "blockade", type = boolean.class, desc = "是否封锁") - private boolean blockade; + /** + * 是否封锁(封锁后,包含区段的进路不能排列) + */ + @ExpConditionMaterialAnno(name = "blockade", type = boolean.class, desc = "是否封锁") + private boolean blockade; - /** - * 是否进路锁闭 - */ - @ExpConditionMaterialAnno(name = "routeLock", type = boolean.class, desc = "是否进路锁闭") - private boolean routeLock; + /** + * 是否进路锁闭 + */ + @ExpConditionMaterialAnno(name = "routeLock", type = boolean.class, desc = "是否进路锁闭") + private boolean routeLock; - /** - * 锁闭该区段的进路 - */ - private Route route; + /** + * 锁闭该区段的进路 + */ + private Route route; - /** - * 锁闭方向 - */ - private boolean lockRight; + /** + * 锁闭方向 + */ + private boolean lockRight; - /** - * 进路延续保护锁闭 - */ - @ExpConditionMaterialAnno(name = "overlapLock", type = boolean.class, desc = "是否进路延续保护锁闭") - private boolean overlapLock; + /** + * 进路延续保护锁闭 + */ + @ExpConditionMaterialAnno(name = "overlapLock", type = boolean.class, desc = "是否进路延续保护锁闭") + private boolean overlapLock; - /** - * 通信车占用 - */ - @ExpConditionMaterialAnno(name = "ctOccupied", type = boolean.class, desc = "是否通信车占用") - private boolean ctOccupied; + /** + * 通信车占用 + */ + @ExpConditionMaterialAnno(name = "ctOccupied", type = boolean.class, desc = "是否通信车占用") + private boolean ctOccupied; - /** - * 计轴占用-非通信车占用 - */ - @ExpConditionMaterialAnno(name = "nctOccupied", type = boolean.class, desc = "是否非通信车占用") - private boolean nctOccupied; + /** + * 计轴占用-非通信车占用 + */ + @ExpConditionMaterialAnno(name = "nctOccupied", type = boolean.class, desc = "是否非通信车占用") + private boolean nctOccupied; - /** - * 占用列车方向 - */ - private boolean trainRight; + /** + * 占用列车方向 + */ + private boolean trainRight; - /** - * 是否切除 - */ - @ExpConditionMaterialAnno(name = "cutOff", type = boolean.class, desc = "是否切除") - private boolean cutOff; + /** + * 是否切除 + */ + @ExpConditionMaterialAnno(name = "cutOff", type = boolean.class, desc = "是否切除") + private boolean cutOff; - /** - * 计轴是否被报失效(ARB故障) - */ - @ExpConditionMaterialAnno(name = "invalid", type = boolean.class, desc = "是否ARB") - private boolean invalid; + /** + * 计轴是否被报失效(ARB故障) + */ + @ExpConditionMaterialAnno(name = "invalid", type = boolean.class, desc = "是否ARB") + private boolean invalid; - /** - * 故障锁闭 - */ - @ExpConditionMaterialAnno(name = "faultLock", type = boolean.class, desc = "是否故障锁闭") - private boolean faultLock; + /** + * 故障锁闭 + */ + @ExpConditionMaterialAnno(name = "faultLock", type = boolean.class, desc = "是否故障锁闭") + private boolean faultLock; - /** - * 最高限速(单位km/h) - */ - private int speedUpLimit = -1; + /** + * 最高限速(单位km/h) + */ + private int speedUpLimit = -1; - /** - * ATP故障前的限速 - */ - private Integer speedLimitBeforeFault; + /** + * ATP故障前的限速 + */ + private Integer speedLimitBeforeFault; - /** - * 延时解锁(延时解锁根据remain判定,该字段可以考虑删除) - */ - private boolean delayUnlock; + /** + * 延时解锁(延时解锁根据remain判定,该字段可以考虑删除) + */ + private boolean delayUnlock; - /** - * 关闭操作初始化(初始化后才能使用关闭操作) - */ - private boolean closeInit; + /** + * 关闭操作初始化(初始化后才能使用关闭操作) + */ + private boolean closeInit; - /** - * 开放操作初始化(初始化后才能使用开放操作) - */ - private boolean openInit; + /** + * 开放操作初始化(初始化后才能使用开放操作) + */ + private boolean openInit; - /** - * 关闭(关闭后列车不能进入该区段,已在该区段的紧急制动) - */ - private boolean closed; + /** + * 关闭(关闭后列车不能进入该区段,已在该区段的紧急制动) + */ + private boolean closed; - /** - * 分路不良状态 - */ - @ExpConditionMaterialAnno(name = "badShunt", type = boolean.class, desc = "分路不良状态") - private boolean badShunt; + /** + * 分路不良状态 + */ + @ExpConditionMaterialAnno(name = "badShunt", type = boolean.class, desc = "分路不良状态") + private boolean badShunt; - /** - * 分路不良类型 - */ - private List shuntingTypeList; + /** + * 分路不良类型 + */ + private List shuntingTypeList; - /** - * 停稳倒计时 - * 0 表示初始状态 - * -1 表示准备开始计时; - * 非负数表示当前计时; - */ - private int stopCountDown; + /** + * 停稳倒计时 0 表示初始状态 -1 表示准备开始计时; 非负数表示当前计时; + */ + private int stopCountDown; - @Override - public void reset() { - super.reset(); - this.blockade = false; - this.routeLock = false; - this.route = null; - this.lockRight = false; - this.overlapLock = false; - this.ctOccupied = false; - this.nctOccupied = false; - this.cutOff = false; - this.invalid = false; - this.faultLock = false; - this.speedUpLimit = -1; - this.speedLimitBeforeFault = null; - this.delayUnlock = false; - this.closeInit = false; - this.openInit = false; - this.closed = false; - this.badShunt = false; - this.shuntingTypeList = new ArrayList<>(); - this.stopCountDown = 0; - } + @Override + public void reset() { + super.reset(); + this.blockade = false; + this.routeLock = false; + this.route = null; + this.lockRight = false; + this.overlapLock = false; + this.ctOccupied = false; + this.nctOccupied = false; + this.cutOff = false; + this.invalid = false; + this.faultLock = false; + this.speedUpLimit = -1; + this.speedLimitBeforeFault = null; + this.delayUnlock = false; + this.closeInit = false; + this.openInit = false; + this.closed = false; + this.badShunt = false; + this.shuntingTypeList = new ArrayList<>(); + this.stopCountDown = 0; + } - /** - * 开始停稳倒计时 - */ - public void startStopCountDown() { - stopCountDown = 40 * 1000; - } + /** + * 开始停稳倒计时 + */ + public void startStopCountDown() { + stopCountDown = 40 * 1000; + } - /** - * 准备开始停稳倒计时 - */ - public void readyStartStopCountDown() { - stopCountDown = -1; - } + /** + * 准备开始停稳倒计时 + */ + public void readyStartStopCountDown() { + stopCountDown = -1; + } - public int getStopCountDownInSeconds() { - return stopCountDown / 1000; - } + public int getStopCountDownInSeconds() { + return stopCountDown / 1000; + } - /** - * 区段是否被列车占用 - */ - public boolean isOccupied() { - return this.nctOccupied || this.ctOccupied || this.isLogicOccupied(); - } + /** + * 区段是否被列车占用 + */ + public boolean isOccupied() { + return this.nctOccupied || this.ctOccupied || this.isLogicOccupied(); + } - private boolean isLogicOccupied() { - if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - if (logic.isOccupied()) { - return true; - } - } + private boolean isLogicOccupied() { + if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + if (logic.isOccupied()) { + return true; } - return false; + } } + return false; + } - /** - * 区段是否空闲 - * - * @return - */ - public boolean isFree() { - return !this.blockade && !this.routeLock && !this.overlapLock && !this.ctOccupied && !this.nctOccupied; - } + /** + * 区段是否空闲 + * + * @return + */ + public boolean isFree() { + return !this.blockade && !this.routeLock && !this.overlapLock && !this.ctOccupied + && !this.nctOccupied; + } - public void addLogicSection(Section logic) { - this.logicList.add(logic); - } + public void addLogicSection(Section logic) { + this.logicList.add(logic); + } - public void addRelStand(Stand stand) { - this.standList.add(stand); - } + public void addRelStand(Stand stand) { + this.standList.add(stand); + } - public boolean isNormalStandTrack() { - if (!CollectionUtils.isEmpty(this.standList)) { - for (Stand stand : this.standList) { - if (!stand.isSmall()) { - return true; - } - } + public boolean isNormalStandTrack() { + if (!CollectionUtils.isEmpty(this.standList)) { + for (Stand stand : this.standList) { + if (!stand.isSmall()) { + return true; } - return false; + } } + return false; + } - /** - * 是否显示逻辑区段 - * - * @return true 有逻辑区段;false 不显示逻辑区段 - */ - public boolean isShowLogic() { - return !CollectionUtils.isEmpty(this.logicList); + /** + * 是否显示逻辑区段 + * + * @return true 有逻辑区段;false 不显示逻辑区段 + */ + public boolean isShowLogic() { + return !CollectionUtils.isEmpty(this.logicList); + } + + public Signal getSignalOf(boolean right) { + return right ? this.getSignalToRight() : this.getSignalToLeft(); + } + + public Collection getSignals() { + List list = new ArrayList<>(2); + if (signalToLeft != null) { + list.add(signalToLeft); } - - public Signal getSignalOf(boolean right) { - return right ? this.getSignalToRight() : this.getSignalToLeft(); + if (signalToRight != null) { + list.add(signalToRight); } + return list; + } - public Collection getSignals() { - return Arrays.asList(getSignalToLeft(), getSignalToRight()); + public float getStopPointByDirection(boolean right) { + Float stopPoint = this.getStopPointOf(right); + if (Objects.isNull(stopPoint) || stopPoint == 0) { + return right ? this.getLen() - 10 : 10; } + return stopPoint; + } - public float getStopPointByDirection(boolean right) { - Float stopPoint = this.getStopPointOf(right); - if (Objects.isNull(stopPoint) || stopPoint == 0) { - return right ? this.getLen() - 10 : 10; + private Float getStopPointOf(boolean right) { + return right ? this.getStopPointRight() : this.getStopPointLeft(); + } + + /** + * 获取下一个运行到达区段(真实运行,考虑道岔区段的道岔方向) + * + * @param right + * @return + */ + public Section getNextRunningSectionOf(boolean right) { + if (right && Objects.nonNull(this.rightSection)) { + return this.rightSection; + } else if (!right && Objects.nonNull(this.leftSection)) { + return this.leftSection; + } else if (this.isSwitchTrack()) { + Switch relSwitch = this.getRelSwitch(); + Section a = relSwitch.getA(); + if (relSwitch.isA(this)) { + if ((right && a.getLeftSection() != null) || + (!right && a.getRightSection() != null)) { + if (relSwitch.isPosN()) { + return relSwitch.getB(); + } else if (relSwitch.isPosR()) { + return relSwitch.getC(); + } + } else { + return right ? this.rightSection : this.leftSection; } - return stopPoint; - } - - private Float getStopPointOf(boolean right) { - return right ? this.getStopPointRight() : this.getStopPointLeft(); - } - - /** - * 获取下一个运行到达区段(真实运行,考虑道岔区段的道岔方向) - * - * @param right - * @return - */ - public Section getNextRunningSectionOf(boolean right) { - if (right && Objects.nonNull(this.rightSection)) { - return this.rightSection; - } else if (!right && Objects.nonNull(this.leftSection)) { - return this.leftSection; - } else if (this.isSwitchTrack()) { - Switch relSwitch = this.getRelSwitch(); - Section a = relSwitch.getA(); - if (relSwitch.isA(this)) { - if ((right && a.getLeftSection() != null) || - (!right && a.getRightSection() != null)) { - if (relSwitch.isPosN()) { - return relSwitch.getB(); - } else if (relSwitch.isPosR()) { - return relSwitch.getC(); - } - } else { - return right ? this.rightSection : this.leftSection; - } - } else { // B或C - if (right && a.getLeftSection() != null) { - return this.rightSection; - } else if (!right && a.getRightSection() != null) { - return this.leftSection; - } else if ((relSwitch.isPosN() && relSwitch.isB(this)) || - (relSwitch.isPosR() && relSwitch.isC(this))) { - return a; - } - } + } else { // B或C + if (right && a.getLeftSection() != null) { + return this.rightSection; + } else if (!right && a.getRightSection() != null) { + return this.leftSection; + } else if ((relSwitch.isPosN() && relSwitch.isB(this)) || + (relSwitch.isPosR() && relSwitch.isC(this))) { + return a; + } + } // return this.getRelSwitch().getNextSectionOnBaseSection(this); - } - return null; } + return null; + } - /** - * 基于真实道岔找下一个可运行到的区段 - */ - public Section findNextRunningSectionBaseRealSwitch(boolean right) { - if (right && Objects.nonNull(this.rightSection)) { - return this.rightSection; - } else if (!right && Objects.nonNull(this.leftSection)) { - return this.leftSection; - } else if (this.isSwitchTrack()) { - return this.getRelSwitch().getNextSectionBaseRealSwitch(this); - } - return null; - } - public Section findBackRunningSectionBaseRealSwitch(boolean right) { - if (right && Objects.nonNull(this.leftSection)) { - return this.leftSection; - } else if (!right && Objects.nonNull(this.rightSection)) { - return this.rightSection; - } else if (this.isSwitchTrack()) { - return this.getRelSwitch().getNextSectionBaseRealSwitch(this); - } - return null; - } - /** - * 获取左/右向关联的区段 - * - * @param right - * @return - */ - public Section getSectionOf(boolean right) { - return right ? this.rightSection : this.leftSection; + /** + * 基于真实道岔找下一个可运行到的区段 + */ + public Section findNextRunningSectionBaseRealSwitch(boolean right) { + if (right && Objects.nonNull(this.rightSection)) { + return this.rightSection; + } else if (!right && Objects.nonNull(this.leftSection)) { + return this.leftSection; + } else if (this.isSwitchTrack()) { + return this.getRelSwitch().getNextSectionBaseRealSwitch(this); } + return null; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Section section = (Section) o; - return getCode().equals(section.getCode()); + public Section findBackRunningSectionBaseRealSwitch(boolean right) { + if (right && Objects.nonNull(this.leftSection)) { + return this.leftSection; + } else if (!right && Objects.nonNull(this.rightSection)) { + return this.rightSection; + } else if (this.isSwitchTrack()) { + return this.getRelSwitch().getNextSectionBaseRealSwitch(this); } + return null; + } - @Override - public int hashCode() { - return Objects.hash(getCode()); + /** + * 获取左/右向关联的区段 + * + * @param right + * @return + */ + public Section getSectionOf(boolean right) { + return right ? this.rightSection : this.leftSection; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public void setCtOccupied(boolean ctOccupied) { - if (AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault()) && !ctOccupied) { - if (!this.isNctOccupied()) { - return; - } else { - AxleFault.CBTC_OCCUPIED_FAULT.fix(this); - } - } - this.ctOccupied = ctOccupied; + if (o == null || getClass() != o.getClass()) { + return false; } + Section section = (Section) o; + return getCode().equals(section.getCode()); + } - /** - * 区段列车出清 - */ - public void clearOccupy() { - setCtOccupied(false); - setNctOccupied(false); - if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section section : this.logicList) { - section.clearOccupy(); - } - } + @Override + public int hashCode() { + return Objects.hash(getCode()); + } + + public void setCtOccupied(boolean ctOccupied) { + if (AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault()) && !ctOccupied) { + if (!this.isNctOccupied()) { + return; + } else { + AxleFault.CBTC_OCCUPIED_FAULT.fix(this); + } + } + this.ctOccupied = ctOccupied; + } + + /** + * 区段列车出清 + */ + public void clearOccupy() { + setCtOccupied(false); + setNctOccupied(false); + if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section section : this.logicList) { + section.clearOccupy(); + } + } // if (this.isAxleCounter()) { // // 是计轴区段 // if (this.getVirtualAxleCounter().isOccupy()) { @@ -538,977 +554,995 @@ public class Section extends DelayUnlockDevice { // logic.setNctOccupied(false); // }); // } - } + } - /** - * 计轴区段占用 - * - * @param right - */ - public void axleCounterOccupy(boolean right) { - this.trainRight = right; - this.setNctOccupied(true); + /** + * 计轴区段占用 + * + * @param right + */ + public void axleCounterOccupy(boolean right) { + this.trainRight = right; + this.setNctOccupied(true); // if (isSwitchAxleCounterSection()) { // nctOccupiedBySwitchPosition(); // } - } + } - /** - * 计轴占用出清 - */ - public void axleCounterClear() { - if (AxleFault.FAULT.equals(this.getFault()) || AxleFault.ARB.equals(this.getFault())) { - this.setFault(null); + /** + * 计轴占用出清 + */ + public void axleCounterClear() { + if (AxleFault.FAULT.equals(this.getFault()) || AxleFault.ARB.equals(this.getFault())) { + this.setFault(null); + } + if (this.isInvalid()) { + this.judgeAsValid(); + } + this.nctOccupied = false; + if (!CollectionUtils.isEmpty(logicList)) { + logicList.forEach(Section::axleCounterClear); + } + } + + /** + * 仅道岔计轴区段使用 + */ + public List getRelSwitchList() { + if (this.isSwitchAxleCounterSection()) { + List switchList = new ArrayList<>(); + this.logicList.forEach(section -> { + Switch relSwitch = section.getRelSwitch(); + if (Objects.nonNull(relSwitch) && !switchList.contains(relSwitch)) { + switchList.add(relSwitch); } - if (this.isInvalid()) { - this.judgeAsValid(); + }); + return switchList; + } + return null; + } + + /** + * 逻辑区段 + * + * @return + */ + public boolean isLogicSection() { + return !this.physical && !this.axleCounter && !this.isCross() && Objects.nonNull(this.parent); + } + + /** + * 是否道岔计轴区段 + * + * @return + */ + public boolean isSwitchAxleCounterSection() { + return this.isAxleCounter() && + !CollectionUtils.isEmpty(this.logicList) && + this.logicList.get(0).isSwitchTrack(); + } + + /** + * 一般计轴区段 + * + * @return + */ + public boolean isAxleCounterSection() { + return this.physical && this.axleCounter; + } + + /** + * 一般计轴区段 + * + * @return + */ + public boolean isSectionOfCross() { + return this.physical && this.axleCounter && Objects.nonNull(parent) && parent.isCross(); + } + + /** + * 是否通信车占用 + * + * @return + */ + public boolean isCbtcOccupy() { + return this.ctOccupied; + } + + /** + * 是否有非通信车占用 + * + * @return + */ + public boolean hasNctOccupy() { + boolean nct = this.nctOccupied && !this.ctOccupied; + if (!CollectionUtils.isEmpty(this.logicList)) { + nct = false; + for (Section logic : this.logicList) { + if (!logic.isCtOccupied() && logic.isNctOccupied()) { + nct = true; + break; } - this.nctOccupied = false; - if (!CollectionUtils.isEmpty(logicList)) { - logicList.forEach(Section::axleCounterClear); + } + } + return nct; + } + + public boolean isOnlyCtcOccupy() { + boolean ctOccupied = this.ctOccupied; + if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + if (logic.isCtOccupied()) { + ctOccupied = true; + break; } + } } + return ctOccupied; + } - /** - * 仅道岔计轴区段使用 - */ - public List getRelSwitchList() { - if (this.isSwitchAxleCounterSection()) { - List switchList = new ArrayList<>(); - this.logicList.forEach(section -> { - Switch relSwitch = section.getRelSwitch(); - if (Objects.nonNull(relSwitch) && !switchList.contains(relSwitch)) { - switchList.add(relSwitch); - } - }); - return switchList; + public List
getAtpSectionListBy(float offset1, float offset2) { + if (this.isSwitchTrack() || this.isSwitchAxleCounterSection()) { + throw new SimulationException(SimulationExceptionType.System_Fault); + } + // 正常物理计轴区段 + List
atpOccupyList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(this.logicList)) { // 有逻辑区段 + float min = Math.min(offset1, offset2); + float max = Math.max(offset1, offset2); + this.logicList.forEach(logic -> { + if (!(logic.getMinOffset() > max || logic.getMaxOffset() < min)) { + atpOccupyList.add(logic); } - return null; + }); + } else { + atpOccupyList.add(this); } + return atpOccupyList; + } - /** - * 逻辑区段 - * - * @return - */ - public boolean isLogicSection() { - return !this.physical && !this.axleCounter && !this.isCross() && Objects.nonNull(this.parent); - } - - /** - * 是否道岔计轴区段 - * - * @return - */ - public boolean isSwitchAxleCounterSection() { - return this.isAxleCounter() && - !CollectionUtils.isEmpty(this.logicList) && - this.logicList.get(0).isSwitchTrack(); - } - - /** - * 一般计轴区段 - * - * @return - */ - public boolean isAxleCounterSection() { - return this.physical && this.axleCounter; - } - - /** - * 一般计轴区段 - * - * @return - */ - public boolean isSectionOfCross() { - return this.physical && this.axleCounter && Objects.nonNull(parent) && parent.isCross(); - } - - /** - * 是否通信车占用 - * - * @return - */ - public boolean isCbtcOccupy() { - return this.ctOccupied; - } - - /** - * 是否有非通信车占用 - * - * @return - */ - public boolean hasNctOccupy() { - boolean nct = this.nctOccupied && !this.ctOccupied; - if (!CollectionUtils.isEmpty(this.logicList)) { - nct = false; - for (Section logic : this.logicList) { - if (!logic.isCtOccupied() && logic.isNctOccupied()) { - nct = true; - break; - } - } + public List
getAtpSections() { + List
atpSectionList = new ArrayList<>(); + if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 + List relSwitchList = this.getRelSwitchList(); + relSwitchList.forEach(aSwitch -> { + atpSectionList.add(aSwitch.getA()); + if (aSwitch.isPosN()) { + atpSectionList.add(aSwitch.getB()); + } else if (aSwitch.isPosR()) { + atpSectionList.add(aSwitch.getC()); } - return nct; + }); + } else if (!CollectionUtils.isEmpty(this.logicList)) { // 有逻辑区段 + atpSectionList.addAll(this.logicList); + } else { + atpSectionList.add(this); } + return atpSectionList; + } - public boolean isOnlyCtcOccupy() { - boolean ctOccupied = this.ctOccupied; - if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - if (logic.isCtOccupied()) { - ctOccupied = true; - break; - } - } - } - return ctOccupied; + /** + * 进路锁闭(连同逻辑区段) + */ + public void routeLocking(Route route, boolean right) { + //岔心锁闭 + if (this.parent != null && this.parent.isCross()) { + this.parent.setRoute(route); + this.parent.setRouteLock(true); + this.parent.setLockRight(right); } - - public List
getAtpSectionListBy(float offset1, float offset2) { - if (this.isSwitchTrack() || this.isSwitchAxleCounterSection()) { - throw new SimulationException(SimulationExceptionType.System_Fault); - } - // 正常物理计轴区段 - List
atpOccupyList = new ArrayList<>(); - if (!CollectionUtils.isEmpty(this.logicList)) { // 有逻辑区段 - float min = Math.min(offset1, offset2); - float max = Math.max(offset1, offset2); - this.logicList.forEach(logic -> { - if (!(logic.getMinOffset() > max || logic.getMaxOffset() < min)) { - atpOccupyList.add(logic); - } - }); - } else { - atpOccupyList.add(this); - } - return atpOccupyList; + this.route = route; + this.routeLock = true; + this.lockRight = right; + if (!CollectionUtils.isEmpty(this.logicList)) { + this.logicList.forEach(logic -> logic.routeLocking(route, right)); } + } - public List
getAtpSections() { - List
atpSectionList = new ArrayList<>(); - if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 - List relSwitchList = this.getRelSwitchList(); - relSwitchList.forEach(aSwitch -> { - atpSectionList.add(aSwitch.getA()); - if (aSwitch.isPosN()) { - atpSectionList.add(aSwitch.getB()); - } else if (aSwitch.isPosR()) { - atpSectionList.add(aSwitch.getC()); - } - }); - } else if (!CollectionUtils.isEmpty(this.logicList)) { // 有逻辑区段 - atpSectionList.addAll(this.logicList); - } else { - atpSectionList.add(this); - } - return atpSectionList; + /** + * 进路解锁(连同逻辑区段) + * + * @param route + */ + public void routeUnlocking(Route route) { + if (this.isRouteLockBy(route)) { + //岔心解锁 + if (this.parent != null && this.parent.isCross()) { + this.parent.setRouteLock(false); + this.parent.setRoute(null); + } + //自身解锁 + this.routeLock = false; + this.route = null; + if (!CollectionUtils.isEmpty(this.logicList)) { + this.logicList.forEach(logic -> logic.routeUnlocking(route)); + } } + } - /** - * 进路锁闭(连同逻辑区段) - */ - public void routeLocking(Route route, boolean right) { - //岔心锁闭 - if (this.parent != null && this.parent.isCross()) { - this.parent.setRoute(route); - this.parent.setRouteLock(true); - this.parent.setLockRight(right); - } - this.route = route; - this.routeLock = true; - this.lockRight = right; - if (!CollectionUtils.isEmpty(this.logicList)) { - this.logicList.forEach(logic -> logic.routeLocking(route, right)); - } + private boolean isRouteLockBy(Route route) { + return this.routeLock && this.route.equals(route); + } + + public void forceUnlocking() { + this.routeLock = false; + this.route = null; + this.overlapLock = false; + if (!isCross() && !CollectionUtils.isEmpty(this.logicList)) { + this.logicList.forEach(logic -> logic.forceUnlocking()); } + } - /** - * 进路解锁(连同逻辑区段) - * - * @param route - */ - public void routeUnlocking(Route route) { - if (this.isRouteLockBy(route)) { - //岔心解锁 - if (this.parent != null && this.parent.isCross()) { - this.parent.setRouteLock(false); - this.parent.setRoute(null); - } - //自身解锁 - this.routeLock = false; - this.route = null; - if (!CollectionUtils.isEmpty(this.logicList)) { - this.logicList.forEach(logic -> logic.routeUnlocking(route)); - } - } + /** + * 进路延续保护(连同逻辑区段) + */ + public void overlapLocking(boolean lockRight) { + //封锁岔心 + if (this.parent != null && this.parent.isCross()) { + this.parent.setOverlapLock(true); + this.parent.setLockRight(lockRight); } - - private boolean isRouteLockBy(Route route) { - return this.routeLock && this.route.equals(route); + this.overlapLock = true; + this.lockRight = lockRight; + if (!CollectionUtils.isEmpty(this.logicList)) { + this.logicList.forEach(logic -> logic.overlapLocking(lockRight)); } + } - public void forceUnlocking() { - this.routeLock = false; - this.route = null; - this.overlapLock = false; - if (!isCross() && !CollectionUtils.isEmpty(this.logicList)) { - this.logicList.forEach(logic -> logic.forceUnlocking()); - } - } - - /** - * 进路延续保护(连同逻辑区段) - */ - public void overlapLocking(boolean lockRight) { - //封锁岔心 - if (this.parent != null && this.parent.isCross()) { - this.parent.setOverlapLock(true); - this.parent.setLockRight(lockRight); - } - this.overlapLock = true; - this.lockRight = lockRight; - if (!CollectionUtils.isEmpty(this.logicList)) { - this.logicList.forEach(logic -> logic.overlapLocking(lockRight)); - } - } - - /** - * 进路延续保护解锁(连同逻辑区段) - */ - public void overlapUnlocking() { - this.overlapLock = false; + /** + * 进路延续保护解锁(连同逻辑区段) + */ + public void overlapUnlocking() { + this.overlapLock = false; // if (!CollectionUtils.isEmpty(this.logicList)) { // this.logicList.forEach(logic -> logic.overlapUnlocking()); // } - } + } - public boolean isSamePhysical(String sectionCode) { - if (Objects.equals(this.getCode(), sectionCode)) { - return true; - } else if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : logicList) { - if (Objects.equals(logic.getCode(), sectionCode)) { - return true; - } - } - } else if (!this.isSwitchTrack() && Objects.nonNull(this.getParent()) - && Objects.equals(this.getParent().getCode(), sectionCode)) { + public boolean isSamePhysical(String sectionCode) { + if (Objects.equals(this.getCode(), sectionCode)) { + return true; + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : logicList) { + if (Objects.equals(logic.getCode(), sectionCode)) { + return true; + } + } + } else if (!this.isSwitchTrack() && Objects.nonNull(this.getParent()) + && Objects.equals(this.getParent().getCode(), sectionCode)) { + return true; + } + return false; + } + + public boolean isSameAxle(String sectionCode) { + if (this.getCode().equals(sectionCode)) { + return true; + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + if (logic.getCode().equals(sectionCode)) { + return true; + } + } + } else if (!this.isCross() && Objects.nonNull(this.parent)) { + if (this.parent.getCode().equals(sectionCode)) { + return true; + } else { + for (Section logic : this.parent.getLogicList()) { + if (logic.getCode().equals(sectionCode)) { return true; + } } - return false; + } } + return false; + } - public boolean isSameAxle(String sectionCode) { - if (this.getCode().equals(sectionCode)) { - return true; - } else if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - if (logic.getCode().equals(sectionCode)) { - return true; - } - } - } else if (!this.isCross() && Objects.nonNull(this.parent)) { - if (this.parent.getCode().equals(sectionCode)) { - return true; - } else { - for (Section logic : this.parent.getLogicList()) { - if (logic.getCode().equals(sectionCode)) { - return true; - } - } - } - } - return false; + public boolean isLocked() { + return this.routeLock || this.overlapLock || this.faultLock; + } + + /** + * 获取道岔区段向外连接的区段 + * + * @return + */ + public Section getSwitchSectionConnectedSection() { + if (Objects.nonNull(this.leftSection)) { + return this.leftSection; + } else { + return this.rightSection; } + } - public boolean isLocked() { - return this.routeLock || this.overlapLock || this.faultLock; + public void communicateTrainOccupy(boolean right) { + this.trainRight = right; + setCtOccupied(true); + } + + public void setNctOccupied(boolean nctOccupied) { + if (nctOccupied) { + this.invalid = false; } + this.nctOccupied = nctOccupied; + } - /** - * 获取道岔区段向外连接的区段 - * - * @return - */ - public Section getSwitchSectionConnectedSection() { - if (Objects.nonNull(this.leftSection)) { - return this.leftSection; - } else { - return this.rightSection; - } + public void nonCommunicateTrainOccupy(boolean right) { + VirtualRealitySectionAxleCounter axle = findAxle(); + if (axle != null && axle.isOccupy()) { + this.trainRight = right; + this.setNctOccupied(true); } + } - public void communicateTrainOccupy(boolean right) { - this.trainRight = right; - setCtOccupied(true); + public VirtualRealitySectionAxleCounter findAxle() { + VirtualRealitySectionAxleCounter axle = this.virtualAxleCounter; + if (axle == null && this.parent != null) { + return this.parent.findAxle(); } + return axle; + } - public void setNctOccupied(boolean nctOccupied) { - if (nctOccupied) { - this.invalid = false; - } - this.nctOccupied = nctOccupied; + public boolean isOccupiedOn(boolean right) { + return this.isOccupied() && Objects.equals(this.trainRight, right); + } + + public List
getSingleSwitchSectionsBySwitchPosition() { + if (!this.isSwitchTrack()) { + throw new SimulationException(SimulationExceptionType.System_Fault); } + Switch relSwitch = this.getRelSwitch(); + return relSwitch.getSectionsByPosition(); + } - public void nonCommunicateTrainOccupy(boolean right) { - VirtualRealitySectionAxleCounter axle = findAxle(); - if (axle != null && axle.isOccupy()) { - this.trainRight = right; - this.setNctOccupied(true); - } + public List
getSwitchAxleSectionsBySwitchPosition() { + List
atpSectionList = new ArrayList<>(); + Section parent = this.getParent(); + List relSwitchList = parent.getRelSwitchList(); + relSwitchList.forEach(relSwitch -> atpSectionList.addAll(relSwitch.getSectionsByPosition())); + return atpSectionList; + } + + /** + * 判定为非通信车占用 + * + * @param simulation + */ + public void judgeAsNctOccupied(Simulation simulation) { + if (!this.isAxleCounter()) { + return; } - - public VirtualRealitySectionAxleCounter findAxle() { - VirtualRealitySectionAxleCounter axle = this.virtualAxleCounter; - if (axle == null && this.parent != null) { - return this.parent.findAxle(); - } - return axle; + this.setNctOccupied(true); + if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 + nctOccupiedBySwitchPosition(simulation); + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + logic.setNctOccupied(true); + } } + } - public boolean isOccupiedOn(boolean right) { - return this.isOccupied() && Objects.equals(this.trainRight, right); - } - - public List
getSingleSwitchSectionsBySwitchPosition() { - if (!this.isSwitchTrack()) { - throw new SimulationException(SimulationExceptionType.System_Fault); - } - Switch relSwitch = this.getRelSwitch(); - return relSwitch.getSectionsByPosition(); - } - - public List
getSwitchAxleSectionsBySwitchPosition() { - List
atpSectionList = new ArrayList<>(); - Section parent = this.getParent(); - List relSwitchList = parent.getRelSwitchList(); - relSwitchList.forEach(relSwitch -> atpSectionList.addAll(relSwitch.getSectionsByPosition())); - return atpSectionList; - } - - /** - * 判定为非通信车占用 - * - * @param simulation - */ - public void judgeAsNctOccupied(Simulation simulation) { - if (!this.isAxleCounter()) { - return; - } - this.setNctOccupied(true); - if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 - nctOccupiedBySwitchPosition(simulation); - } else if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - logic.setNctOccupied(true); - } - } - } - - /** - * 根据道岔位置设置非通信车占用 - * - * @param simulation - */ - private void nctOccupiedBySwitchPosition(Simulation simulation) { - List relSwitchList = this.getRelSwitchList(); - if (relSwitchList.size() == 2 && simulation.getRepository().getConfig().isSwitchSingleHandle()) { - // 道岔计轴区段两个道岔有一个反位 - if (!relSwitchList.stream().allMatch(Switch::isPosN)) { - for (Switch aSwitch : relSwitchList) { - if (aSwitch.isPosN()) { - continue; - } - setSwitchNctOccupied(aSwitch); - } - Section cross = queryCross(); - if (cross != null) { - cross.crossJudgeOccupied(); - } - return; - } - } + /** + * 根据道岔位置设置非通信车占用 + * + * @param simulation + */ + private void nctOccupiedBySwitchPosition(Simulation simulation) { + List relSwitchList = this.getRelSwitchList(); + if (relSwitchList.size() == 2 && simulation.getRepository().getConfig() + .isSwitchSingleHandle()) { + // 道岔计轴区段两个道岔有一个反位 + if (!relSwitchList.stream().allMatch(Switch::isPosN)) { for (Switch aSwitch : relSwitchList) { - setSwitchNctOccupied(aSwitch); + if (aSwitch.isPosN()) { + continue; + } + setSwitchNctOccupied(aSwitch); } - } - - private void setSwitchNctOccupied(Switch aSwitch) { - aSwitch.getA().setNctOccupied(true); - if (aSwitch.isPosN()) { - aSwitch.getB().setNctOccupied(true); - aSwitch.getC().setNctOccupied(false); - } else if (aSwitch.isPosR()) { - aSwitch.getC().setNctOccupied(true); - aSwitch.getB().setNctOccupied(false); - } else { - aSwitch.getB().setNctOccupied(true); - aSwitch.getC().setNctOccupied(true); + Section cross = queryCross(); + if (cross != null) { + cross.crossJudgeOccupied(); } + return; + } } - - /** - * 岔心判断占用 - */ - private void crossJudgeOccupied() { - if (!this.cross) - return; - this.logicList.forEach(logic -> { - Section leftSection = logic.getLeftSection(); - boolean leftSectionNctOccupied = leftSection.isNctOccupied() && leftSection.getParent().equals(this.parent); - Section rightSection = logic.getRightSection(); - boolean rightSectionNctOccupied = rightSection.isNctOccupied() && rightSection.getParent().equals(this.parent); - if (leftSectionNctOccupied || rightSectionNctOccupied) { - logic.setNctOccupied(true); - setNctOccupied(true); - } - }); + for (Switch aSwitch : relSwitchList) { + setSwitchNctOccupied(aSwitch); } + } - /** - * 判定为有效 - */ - public void judgeAsValid() { - if (!this.isAxleCounter()) { - throw new SimulationException(SimulationExceptionType.System_Fault); - } - this.setInvalid(false); - if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 - List relSwitchList = this.getRelSwitchList(); - for (Switch aSwitch : relSwitchList) { - aSwitch.getA().setInvalid(false); - aSwitch.getB().setInvalid(false); - aSwitch.getC().setInvalid(false); - } - } else if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - logic.setInvalid(false); - } - } + private void setSwitchNctOccupied(Switch aSwitch) { + aSwitch.getA().setNctOccupied(true); + if (aSwitch.isPosN()) { + aSwitch.getB().setNctOccupied(true); + aSwitch.getC().setNctOccupied(false); + } else if (aSwitch.isPosR()) { + aSwitch.getC().setNctOccupied(true); + aSwitch.getB().setNctOccupied(false); + } else { + aSwitch.getB().setNctOccupied(true); + aSwitch.getC().setNctOccupied(true); } + } - /** - * 查询道岔计轴区段关联的岔心 - */ - private Section queryCross() { - return this.logicList.stream().filter(Section::isCross).findAny().orElse(null); + /** + * 岔心判断占用 + */ + private void crossJudgeOccupied() { + if (!this.cross) { + return; } + this.logicList.forEach(logic -> { + Section leftSection = logic.getLeftSection(); + boolean leftSectionNctOccupied = + leftSection.isNctOccupied() && leftSection.getParent().equals(this.parent); + Section rightSection = logic.getRightSection(); + boolean rightSectionNctOccupied = + rightSection.isNctOccupied() && rightSection.getParent().equals(this.parent); + if (leftSectionNctOccupied || rightSectionNctOccupied) { + logic.setNctOccupied(true); + setNctOccupied(true); + } + }); + } - /** - * 确认计轴有效 - */ - public void confirmValid() { - if (!this.isAxleCounter()) { - throw new SimulationException(SimulationExceptionType.System_Fault); - } - this.setInvalid(false); - if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - logic.setInvalid(false); - } - } + /** + * 判定为有效 + */ + public void judgeAsValid() { + if (!this.isAxleCounter()) { + throw new SimulationException(SimulationExceptionType.System_Fault); } - - public void delayUnlock(int delayTime) { - setDelayUnlock(true); + this.setInvalid(false); + if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 + List relSwitchList = this.getRelSwitchList(); + for (Switch aSwitch : relSwitchList) { + aSwitch.getA().setInvalid(false); + aSwitch.getB().setInvalid(false); + aSwitch.getC().setInvalid(false); + } + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + logic.setInvalid(false); + } } + } - public void faultUnlock() { - this.faultLock = false; - this.routeLock = false; - this.route = null; - this.overlapLock = false; - this.delayUnlock = false; - this.shuntingTypeList = new ArrayList<>(); + /** + * 查询道岔计轴区段关联的岔心 + */ + private Section queryCross() { + return this.logicList.stream().filter(Section::isCross).findAny().orElse(null); + } + + /** + * 确认计轴有效 + */ + public void confirmValid() { + if (!this.isAxleCounter()) { + throw new SimulationException(SimulationExceptionType.System_Fault); } - - public boolean isLockedOn(boolean right) { - return Objects.equals(this.lockRight, right) && - (this.routeLock || this.overlapLock); + this.setInvalid(false); + if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + logic.setInvalid(false); + } } + } - public boolean isRouteLockOn(boolean right) { - return this.routeLock && Objects.equals(this.lockRight, right); + public void delayUnlock(int delayTime) { + setDelayUnlock(true); + } + + public void faultUnlock() { + this.faultLock = false; + this.routeLock = false; + this.route = null; + this.overlapLock = false; + this.delayUnlock = false; + this.shuntingTypeList = new ArrayList<>(); + } + + public boolean isLockedOn(boolean right) { + return Objects.equals(this.lockRight, right) && + (this.routeLock || this.overlapLock); + } + + public boolean isRouteLockOn(boolean right) { + return this.routeLock && Objects.equals(this.lockRight, right); + } + + public boolean isOverlapLockOn(boolean right) { + return this.overlapLock && this.lockRight == right; + } + + /** + * 获取道岔计轴区段关联的道岔区段中,道岔区段对应方向有连接区段(且此连接区段不是此道岔计轴区段的一员)的道岔区段 + * + * @param right + * @return + */ + public Section getSectionHasConnectedTo(boolean right) { + for (Section section : this.logicList) { + Section next = section.getSectionOf(right); + if (Objects.nonNull(next) && !this.logicList.contains(next)) { + return section; + } } + return null; + } - public boolean isOverlapLockOn(boolean right) { - return this.overlapLock && this.lockRight == right; + public Section getSectionHasDirectionSignal(boolean right) { + for (Section section : this.logicList) { + Signal signal = section.getSignalOf(right); + if (Objects.nonNull(signal)) { + return section; + } } + return null; + } - /** - * 获取道岔计轴区段关联的道岔区段中,道岔区段对应方向有连接区段(且此连接区段不是此道岔计轴区段的一员)的道岔区段 - * - * @param right - * @return - */ - public Section getSectionHasConnectedTo(boolean right) { - for (Section section : this.logicList) { - Section next = section.getSectionOf(right); - if (Objects.nonNull(next) && !this.logicList.contains(next)) { - return section; - } - } - return null; + public boolean isLeftLine() { + return Objects.equals(this.roadType, SectionRoadType.LEFT); + } + + public boolean isRightLine() { + return Objects.equals(this.roadType, SectionRoadType.RIGHT); + } + + public Float getNeedLimitSpeed() { + if (this.getSpeedUpLimit() >= 0) { + return this.getSpeedUpLimit() / 3.6f; + } else if (this.isSwitchTrack() && this.getRelSwitch().isPosR()) { + return 30 / 3.6f; + } else if (this.isStandTrack() || isLogicStandTrack()) { //站台逻辑区段默认限速 + return 45 / 3.6f; } + return null; + } - public Section getSectionHasDirectionSignal(boolean right) { - for (Section section : this.logicList) { - Signal signal = section.getSignalOf(right); - if (Objects.nonNull(signal)) { - return section; - } - } - return null; + private boolean isLogicStandTrack() { + Section parent = this.getParent(); + if (parent == null || !parent.isStandTrack()) { + return false; } + float left = parent.getStopPointByDirection(false); + float right = parent.getStopPointByDirection(true); + return this.minOffset <= right && this.maxOffset >= left; + } - public boolean isLeftLine() { - return Objects.equals(this.roadType, SectionRoadType.LEFT); + /** + * 根据方向获取终点偏移量 + */ + public float getEndOffsetByDirection(boolean right) { + if (right) { + return maxOffset; + } else { + return minOffset; } + } - public boolean isRightLine() { - return Objects.equals(this.roadType, SectionRoadType.RIGHT); + public Signal querySwitchSectionRelatedSignalByDirection(boolean right) { + if (!this.isSwitchTrack()) { + throw new SimulationException(SimulationExceptionType.System_Fault); } - - public Float getNeedLimitSpeed() { - if (this.getSpeedUpLimit() >= 0) { - return this.getSpeedUpLimit() / 3.6f; - } else if (this.isSwitchTrack() && this.getRelSwitch().isPosR()) { - return 30 / 3.6f; - } else if (this.isStandTrack() || isLogicStandTrack()) { //站台逻辑区段默认限速 - return 45 / 3.6f; - } - return null; + Signal signal = this.getSignalOf(right); + if (Objects.nonNull(signal)) { + return signal; } - - private boolean isLogicStandTrack() { - Section parent = this.getParent(); - if (parent == null || !parent.isStandTrack()) - return false; - float left = parent.getStopPointByDirection(false); - float right = parent.getStopPointByDirection(true); - return this.minOffset <= right && this.maxOffset >= left; + Switch relSwitch = this.getRelSwitch(); + if (relSwitch.isA(this)) { + return relSwitch.getB().getSignalOf(right); + } else if (relSwitch.isB(this)) { + return relSwitch.getA().getSignalOf(right); } + return null; + } - /** - * 根据方向获取终点偏移量 - */ - public float getEndOffsetByDirection(boolean right) { - if (right) { - return maxOffset; - } else { - return minOffset; - } + public Signal queryTurnBackTrackSignalOf(boolean right) { + if (this.isSwitchTrack()) { + return this.querySwitchSectionRelatedSignalByDirection(right); + } else { + return this.getSignalOf(right); } + } - public Signal querySwitchSectionRelatedSignalByDirection(boolean right) { - if (!this.isSwitchTrack()) { - throw new SimulationException(SimulationExceptionType.System_Fault); - } - Signal signal = this.getSignalOf(right); - if (Objects.nonNull(signal)) { - return signal; - } - Switch relSwitch = this.getRelSwitch(); - if (relSwitch.isA(this)) { - return relSwitch.getB().getSignalOf(right); - } else if (relSwitch.isB(this)) { - return relSwitch.getA().getSignalOf(right); - } - return null; + public SectionPosition buildStopPointPosition(boolean right) { + if (this.isStandTrack() || this.isTurnBackTrack() || this.isTransferTrack()) { + return new SectionPosition(this, this.getStopPointOf(right)); + } else { + throw new SimulationException(SimulationExceptionType.System_Fault); } + } - public Signal queryTurnBackTrackSignalOf(boolean right) { - if (this.isSwitchTrack()) { - return this.querySwitchSectionRelatedSignalByDirection(right); - } else { - return this.getSignalOf(right); - } + public String debugStr() { + return String.format("%s(%s)", this.getName(), this.getCode()); + } + + public boolean isFunctionTrack() { + return this.isStandTrack() || this.isTurnBackTrack() || this.isTransferTrack(); + } + + public boolean isSpecialSection() { + return this.standTrack || this.turnBackTrack || this.transferTrack; + } + + /** + * 是否预复位 + */ + public boolean isPreReset() { + if (switchTrack) { + return false; } - - public SectionPosition buildStopPointPosition(boolean right) { - if (this.isStandTrack() || this.isTurnBackTrack() || this.isTransferTrack()) { - return new SectionPosition(this, this.getStopPointOf(right)); - } else { - throw new SimulationException(SimulationExceptionType.System_Fault); - } + Section axleCounterSection = findAxleCounterSection(); + if (axleCounterSection != null) { + return axleCounterSection.getVirtualAxleCounter().isPreReset(); + } else { + return false; } + } - public String debugStr() { - return String.format("%s(%s)", this.getName(), this.getCode()); + /** + * 查找计轴区段 + * + * @return + */ + public Section findAxleCounterSection() { + if (this.isAxleCounter()) { + return this; + } else if (parent != null) { + return parent.findAxleCounterSection(); + } else { + return null; } + } - public boolean isFunctionTrack() { - return this.isStandTrack() || this.isTurnBackTrack() || this.isTransferTrack(); + public Section getAxleCounterSection() { + Section axleSection = findAxleCounterSection(); + BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(axleSection, + this.debugStr() + "无归属计轴区段"); + return axleSection; + } + + public boolean isAheadOf(SimulationDataRepository repository, Section other, boolean right) { + List routePaths = repository.queryRoutePathsByEndAndContainsSection(this, other); + if (CollectionUtils.isEmpty(routePaths)) { + return false; } - - public boolean isSpecialSection() { - return this.standTrack || this.turnBackTrack || this.transferTrack; + for (RoutePath routePath : routePaths) { + if (routePath.isRight() == right) { + return true; + } } + return false; + } - /** - * 是否预复位 - */ - public boolean isPreReset() { - if (switchTrack) { - return false; - } - Section axleCounterSection = findAxleCounterSection(); - if (axleCounterSection != null) { - return axleCounterSection.getVirtualAxleCounter().isPreReset(); - } else { - return false; - } + public void addZc(ZC zc) { + this.zcs.add(zc); + } + + /** + * 任意一个zc正常工作 + */ + public boolean anyZcWorking() { + Section axleCounterSection = this.findAxleCounterSection(); + if (axleCounterSection != null && !CollectionUtils.isEmpty(axleCounterSection.getZcs())) { + return axleCounterSection.getZcs().stream().anyMatch(zc -> !zc.isFault()); } - - /** - * 查找计轴区段 - * - * @return - */ - public Section findAxleCounterSection() { - if (this.isAxleCounter()) { - return this; - } else if (parent != null) { - return parent.findAxleCounterSection(); - } else { - return null; - } - } - - public Section getAxleCounterSection() { - Section axleSection = findAxleCounterSection(); - BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(axleSection, - this.debugStr() + "无归属计轴区段"); - return axleSection; - } - - public boolean isAheadOf(SimulationDataRepository repository, Section other, boolean right) { - List routePaths = repository.queryRoutePathsByEndAndContainsSection(this, other); - if (CollectionUtils.isEmpty(routePaths)) - return false; - for (RoutePath routePath : routePaths) { - if (routePath.isRight() == right) - return true; - } - return false; - } - - public void addZc(ZC zc) { - this.zcs.add(zc); - } - - /** - * 任意一个zc正常工作 - */ - public boolean anyZcWorking() { - Section axleCounterSection = this.findAxleCounterSection(); - if (axleCounterSection != null && !CollectionUtils.isEmpty(axleCounterSection.getZcs())) { - return axleCounterSection.getZcs().stream().anyMatch(zc -> !zc.isFault()); - } - return false; + return false; // if (!CollectionUtils.isEmpty(zcs)) { // return zcs.stream().anyMatch(zc -> !zc.isFault()); // } // return false; - } + } - public void setInvalid(boolean invalid) { - if (invalid) { - this.setNctOccupied(false); - } - this.invalid = invalid; + public void setInvalid(boolean invalid) { + if (invalid) { + this.setNctOccupied(false); } + this.invalid = invalid; + } - public void judgeAsARB() { - if (!this.isAxleCounter()) { - return; - } - this.setInvalid(true); - if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 - List relSwitchList = this.getRelSwitchList(); - for (Switch aSwitch : relSwitchList) { - aSwitch.getA().setInvalid(true); - if (aSwitch.isPosN()) { - aSwitch.getB().setInvalid(true); - aSwitch.getC().setInvalid(false); - } else if (aSwitch.isPosR()) { - aSwitch.getC().setInvalid(true); - aSwitch.getB().setInvalid(false); - } else { - aSwitch.getB().setInvalid(true); - aSwitch.getC().setInvalid(true); - } - } - } else if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section logic : this.logicList) { - logic.setInvalid(true); - } - } + public void judgeAsARB() { + if (!this.isAxleCounter()) { + return; } + this.setInvalid(true); + if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 + List relSwitchList = this.getRelSwitchList(); + for (Switch aSwitch : relSwitchList) { + aSwitch.getA().setInvalid(true); + if (aSwitch.isPosN()) { + aSwitch.getB().setInvalid(true); + aSwitch.getC().setInvalid(false); + } else if (aSwitch.isPosR()) { + aSwitch.getC().setInvalid(true); + aSwitch.getB().setInvalid(false); + } else { + aSwitch.getB().setInvalid(true); + aSwitch.getC().setInvalid(true); + } + } + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + logic.setInvalid(true); + } + } + } - public boolean isJustTurnBackTrack() { - return !this.isNormalStandTrack() && !this.isTransferTrack() && this.isTurnBackTrack(); - } + public boolean isJustTurnBackTrack() { + return !this.isNormalStandTrack() && !this.isTransferTrack() && this.isTurnBackTrack(); + } - public boolean isLogicOverlapLock() { - if (!CollectionUtils.isEmpty(this.logicList)) { - for (Section section : this.logicList) { - if (section.isOverlapLock()) { - return true; - } - } + public boolean isLogicOverlapLock() { + if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section section : this.logicList) { + if (section.isOverlapLock()) { + return true; } - return false; + } } + return false; + } - public boolean isFaultOccupied() { - if (this.isOccupied() && - this.getVirtualAxleCounter() != null && - this.getFault() != null && - (AxleFault.FAULT.equals(this.getFault()) || AxleFault.CBTC_OCCUPIED_FAULT.equals(this.getFault()))) { - return true; - } else if (this.getParent() != null) { - return this.getParent().isFaultOccupied(); - } - return false; + public boolean isFaultOccupied() { + if (this.isOccupied() && + this.getVirtualAxleCounter() != null && + this.getFault() != null && + (AxleFault.FAULT.equals(this.getFault()) || AxleFault.CBTC_OCCUPIED_FAULT.equals( + this.getFault()))) { + return true; + } else if (this.getParent() != null) { + return this.getParent().isFaultOccupied(); } + return false; + } - public boolean isStandHoldTrain() { - List standList = this.getStandList(); - if (standList != null) { - for (Stand stand : standList) { - if (stand.isHoldTrain()) { - return true; - } - } + public boolean isStandHoldTrain() { + List standList = this.getStandList(); + if (standList != null) { + for (Stand stand : standList) { + if (stand.isHoldTrain()) { + return true; } - return false; + } } + return false; + } + + /** + * 获取道岔计轴区段被道岔连接起来的区段 + */ + public List
findConnectedSections() { + if (!isSwitchAxleCounterSection()) { + return Collections.emptyList(); + } + Switch relSwitch = getLogicList().get(0).getRelSwitch(); + List
sections = new ArrayList<>(); + sections.add(relSwitch.getA()); + if (relSwitch.isPosN()) { + sections.add(relSwitch.getB()); + } else if (relSwitch.isPosR()) { + sections.add(relSwitch.getC()); + } + return sections; + } + + public Section findPhysicalSection() { + if (this.isPhysical()) { + return this; + } + if (this.parent != null) { + return this.parent.findPhysicalSection(); + } + return null; + } + + @Override + public void loseStatus() { + setNoStatus(true); + if (!CollectionUtils.isEmpty(this.getLogicList())) { + for (Section section : this.getLogicList()) { + section.loseStatus(); + } + } + } + + @Override + public void restoreStatus() { + setNoStatus(false); + if (!CollectionUtils.isEmpty(this.getLogicList())) { + for (Section section : this.getLogicList()) { + section.restoreStatus(); + } + } + } + + /** + * 递归地设置故障锁闭 + */ + public void recursivelySetFaultLock(boolean faultLock) { + this.setFaultLock(faultLock); + if (!CollectionUtils.isEmpty(this.logicList)) { + logicList.forEach(section -> section.recursivelySetFaultLock(faultLock)); + } + } + + /** + * 获取下一个区段 + */ + public Section getNextSection(boolean right) { + return right ? rightSection : leftSection; + } + + @Override + public String toString() { + return String.format("Section[code:\"%s\", name:\"%s\"]", getCode(), getName()); + } + + public enum SectionRoadType { + /** + * 左行线 + */ + LEFT, + /** + * 右行线 + */ + RIGHT, + /** + * 渡线 + */ + CROSS, + /** + * 联段线 + */ + DEPOT, + /** + * 库线 + */ + PARKING + } + + public enum AxleFault implements DeviceFault { + /** + * 计轴故障 + */ + FAULT { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (Objects.equals(this, axleSection.getFault())) { + return false; + } + VirtualRealitySectionAxleCounter virtualAxleCounter = axleSection.getVirtualAxleCounter(); + VirtualRealitySectionAxleCounter.Fault.FAULT.apply(virtualAxleCounter); + axleSection.setFault(this); + return true; + } + + @Override + public void fix(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (this.equals(axleSection.getFault())) { + axleSection.setFault(null); + VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); + } + } + }, /** - * 获取道岔计轴区段被道岔连接起来的区段 + * 无法从真实设备采集状态(哈尔滨灰显) */ - public List
findConnectedSections() { - if (!isSwitchAxleCounterSection()) - return Collections.emptyList(); - Switch relSwitch = getLogicList().get(0).getRelSwitch(); - List
sections = new ArrayList<>(); - sections.add(relSwitch.getA()); - if (relSwitch.isPosN()) { - sections.add(relSwitch.getB()); - } else if (relSwitch.isPosR()) { - sections.add(relSwitch.getC()); + UNABLE_COLLECT_STATUS { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (this.equals(axleSection.getFault())) { + return false; } - return sections; - } + axleSection.setFault(this); + axleSection.loseStatus(); + return true; + } - public Section findPhysicalSection() { - if (this.isPhysical()) - return this; - if (this.parent != null) - return this.parent.findPhysicalSection(); - return null; - } - - @Override - public void loseStatus() { - setNoStatus(true); - if (!CollectionUtils.isEmpty(this.getLogicList())) { - for (Section section : this.getLogicList()) { - section.loseStatus(); - } + @Override + public void fix(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (this.equals(axleSection.getFault())) { + axleSection.setFault(null); + axleSection.restoreStatus(); } - } + } + }, - @Override - public void restoreStatus() { - setNoStatus(false); - if (!CollectionUtils.isEmpty(this.getLogicList())) { - for (Section section : this.getLogicList()) { - section.restoreStatus(); - } + CBTC_OCCUPIED_FAULT { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Section section = (Section) device; + if (!CollectionUtils.isEmpty(section.getLogicList())) { + return false; } - } - - /** - * 递归地设置故障锁闭 - */ - public void recursivelySetFaultLock(boolean faultLock) { - this.setFaultLock(faultLock); - if (!CollectionUtils.isEmpty(this.logicList)) { - logicList.forEach(section -> section.recursivelySetFaultLock(faultLock)); + if (this.equals(section.getFault())) { + return false; } - } + Section axleSection = section.getAxleCounterSection(); + section.setFault(this); + VirtualRealitySectionAxleCounter.Fault.FAULT.apply(axleSection.getVirtualAxleCounter()); + section.setCtOccupied(true); + return true; + } - /** - * 获取下一个区段 - */ - public Section getNextSection(boolean right) { - return right ? rightSection : leftSection; - } - - @Override - public String toString() { - return String.format("Section[code:\"%s\", name:\"%s\"]", getCode(), getName()); - } - - public enum SectionRoadType { - /** - * 左行线 - */ - LEFT, - /** - * 右行线 - */ - RIGHT, - /** - * 渡线 - */ - CROSS, - /** - * 联段线 - */ - DEPOT, - /** - * 库线 - */ - PARKING - } - - public enum AxleFault implements DeviceFault { - /** - * 计轴故障 - */ - FAULT { - @Override - public boolean apply(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (Objects.equals(this, axleSection.getFault())) - return false; - VirtualRealitySectionAxleCounter virtualAxleCounter = axleSection.getVirtualAxleCounter(); - VirtualRealitySectionAxleCounter.Fault.FAULT.apply(virtualAxleCounter); - axleSection.setFault(this); - return true; - } - - @Override - public void fix(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (this.equals(axleSection.getFault())) { - axleSection.setFault(null); - VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); - } - } - }, - - /** - * 无法从真实设备采集状态(哈尔滨灰显) - */ - UNABLE_COLLECT_STATUS { - @Override - public boolean apply(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (this.equals(axleSection.getFault())) - return false; - axleSection.setFault(this); - axleSection.loseStatus(); - return true; - } - - @Override - public void fix(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (this.equals(axleSection.getFault())) { - axleSection.setFault(null); - axleSection.restoreStatus(); - } - } - }, - - CBTC_OCCUPIED_FAULT { - @Override - public boolean apply(MayOutOfOrderDevice device) { - Section section = (Section) device; - if (!CollectionUtils.isEmpty(section.getLogicList())) - return false; - if (this.equals(section.getFault())) - return false; - Section axleSection = section.getAxleCounterSection(); - section.setFault(this); - VirtualRealitySectionAxleCounter.Fault.FAULT.apply(axleSection.getVirtualAxleCounter()); - section.setCtOccupied(true); - return true; - } - - @Override - public void fix(MayOutOfOrderDevice device) { - if (this.equals(device.getFault())) { - Section section = (Section) device; - section.setFault(null); - section.setCtOccupied(false); - if (section.isSwitchTrack()) { - section.getRelSwitch().getAllSections().forEach(section1 -> section1.setCtOccupied(false)); - } - Section axleSection = section.getAxleCounterSection(); - VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); - } - } - }, - - ARB { - @Override - public boolean apply(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (this.equals(axleSection.getFault())) - return false; - VirtualRealitySectionAxleCounter.Fault.FAULT.apply(axleSection.getVirtualAxleCounter()); - axleSection.setFault(this); - return true; - } - - @Override - public void fix(MayOutOfOrderDevice device) { - Section axleSection = ((Section) device).getAxleCounterSection(); - if (this.equals(axleSection.getFault())) { - VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); - axleSection.setFault(null); - } - } - }, - - FAULT_LOCK { - @Override - public boolean apply(MayOutOfOrderDevice device) { - Section section = (Section) device; - if (this.equals(section.getFault())) - return false; - section.setFault(this); - section.setFaultLock(true); - return true; - } - - @Override - public void fix(MayOutOfOrderDevice device) { - Section section = (Section) device; - if (this.equals(section.getFault())) { - section.setFault(null); - section.setFaultLock(false); - } - } + @Override + public void fix(MayOutOfOrderDevice device) { + if (this.equals(device.getFault())) { + Section section = (Section) device; + section.setFault(null); + section.setCtOccupied(false); + if (section.isSwitchTrack()) { + section.getRelSwitch().getAllSections() + .forEach(section1 -> section1.setCtOccupied(false)); + } + Section axleSection = section.getAxleCounterSection(); + VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); } + } + }, + + ARB { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (this.equals(axleSection.getFault())) { + return false; + } + VirtualRealitySectionAxleCounter.Fault.FAULT.apply(axleSection.getVirtualAxleCounter()); + axleSection.setFault(this); + return true; + } + + @Override + public void fix(MayOutOfOrderDevice device) { + Section axleSection = ((Section) device).getAxleCounterSection(); + if (this.equals(axleSection.getFault())) { + VirtualRealitySectionAxleCounter.Fault.FAULT.fix(axleSection.getVirtualAxleCounter()); + axleSection.setFault(null); + } + } + }, + + FAULT_LOCK { + @Override + public boolean apply(MayOutOfOrderDevice device) { + Section section = (Section) device; + if (this.equals(section.getFault())) { + return false; + } + section.setFault(this); + section.setFaultLock(true); + return true; + } + + @Override + public void fix(MayOutOfOrderDevice device) { + Section section = (Section) device; + if (this.equals(section.getFault())) { + section.setFault(null); + section.setFaultLock(false); + } + } } + } - /** - * 分路不良枚举类型 - */ - public enum ShuntingType { - SECTION_SHUNTING, // 区段分路不良 + /** + * 分路不良枚举类型 + */ + public enum ShuntingType { + SECTION_SHUNTING, // 区段分路不良 - SWITCH_FRONT_SHUNTING, // 岔前分路不良 + SWITCH_FRONT_SHUNTING, // 岔前分路不良 - FIXED_POSITION_SHUNTING,// 定位分路不良 + FIXED_POSITION_SHUNTING,// 定位分路不良 - REVERSE_POSITION_SHUNTING,// 反位分路不良 - } + REVERSE_POSITION_SHUNTING,// 反位分路不良 + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java index 9b5b7a3a4..84322b803 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java @@ -6,7 +6,11 @@ import club.joylink.rtss.simulation.cbtc.constant.RunLevel; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.TrainTBControl; import club.joylink.rtss.simulation.cbtc.data.CalculateService; -import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.map.MapElement; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +import club.joylink.rtss.simulation.cbtc.data.map.Signal; +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.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; @@ -14,15 +18,14 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.vo.client.operation.DriveParamVO; import club.joylink.rtss.vo.ws.TrainPosition; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.CollectionUtils; - import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.CollectionUtils; /** * 虚拟真实列车 @@ -1188,6 +1191,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice { return robotDriveParam.needStop(); } + public boolean isRobotStopControl() { + return robotDriveParam.isStopControl(); + } + @Getter @Setter public static class Door extends ControllableVrDevice { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainControlParam.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainControlParam.java similarity index 81% rename from src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainControlParam.java rename to src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainControlParam.java index 5d489484a..433aa1ba1 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainControlParam.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainControlParam.java @@ -1,16 +1,15 @@ -package club.joylink.rtss.simulation.cbtc.device.real.udp.sr; +package club.joylink.rtss.simulation.cbtc.device.real.udp; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - @Getter @Setter @NoArgsConstructor -public class SrTrainControlParam { +public class SandTableTrainControlParam { @NotBlank(message = "车组号不能为空") private String groupNumber; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainController.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainController.java new file mode 100644 index 000000000..728655169 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/SandTableTrainController.java @@ -0,0 +1,70 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp; + +import club.joylink.rtss.constants.ProjectCode; +import club.joylink.rtss.dao.MapDataDAO; +import club.joylink.rtss.entity.MapDataExample; +import club.joylink.rtss.entity.MapDataWithBLOBs; +import club.joylink.rtss.simulation.cbtc.GroupSimulationService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.service.SrTrainServiceImpl; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service.ThailandTrainServiceImpl; +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.map.MapLogicDataNewVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/sandTable") +public class SandTableTrainController { + + @Autowired + private GroupSimulationService groupSimulationService; + @Autowired + private ThailandTrainServiceImpl thailandTrainService; + @Autowired + private SrTrainServiceImpl srTrainService; + + @PutMapping("/{simulationId}/control") + public void control(@PathVariable String simulationId, String groupNumber, boolean right, + int speed) { + Simulation simulation = groupSimulationService.getSimulationByGroup(simulationId); + switch (simulation.getProject()) { + case ProjectCode.THAILAND_SANDBOX: + thailandTrainService.controlTrain(simulationId, groupNumber, right, speed); + break; + case ProjectCode.SR_SANDBOX: + srTrainService.controlTrain(simulationId, groupNumber, right, speed); + break; + default: + } + } + + @Autowired + private MapDataDAO mapDataDAO; + + @PutMapping("/handle") + public void handle() { + MapDataExample example = new MapDataExample(); + example.setOrderByClause("id desc"); + example.setLimit(1); + MapDataWithBLOBs data = mapDataDAO.selectByExampleWithBLOBs(example).get(0); + MapLogicDataNewVO logicDataNewVO = JsonUtils.read(data.getLogicData(), MapLogicDataNewVO.class); + logicDataNewVO.getRouteList().stream() + .filter(route -> route.getStartSignalCode().equals("X542") || route.getStartSignalCode() + .equals("X11357") + || route.getStartSignalCode().equals("X47820") || route.getStartSignalCode() + .equals("X4371") + || route.getStartSignalCode().equals("X21134") || route.getStartSignalCode() + .equals("X99402") + || route.getStartSignalCode().equals("X2670") || route.getStartSignalCode() + .equals("X49087")) + .forEach(route -> { + route.setSignalAspect(3); + }); + data.setLogicData(JsonUtils.writeValueAsString(logicDataNewVO)); + mapDataDAO.updateByPrimaryKeyWithBLOBs(data); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPClient.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPClient.java index c1bbc8620..3fcc613f6 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPClient.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPClient.java @@ -10,6 +10,9 @@ 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 java.net.InetSocketAddress; +import java.time.LocalDateTime; +import java.util.concurrent.ConcurrentLinkedQueue; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -18,73 +21,74 @@ import org.springframework.boot.ApplicationRunner; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.concurrent.ConcurrentLinkedQueue; - @Component @Slf4j public class UDPClient implements ApplicationRunner { - @Autowired - private UDPConfig udpConfig; - private Channel channel; + @Autowired + private UDPConfig udpConfig; - private final ConcurrentLinkedQueue msgQueue = new ConcurrentLinkedQueue<>(); + private Channel channel; - @Override - public void run(ApplicationArguments args) throws Exception { - this.start(); + private final ConcurrentLinkedQueue msgQueue = new ConcurrentLinkedQueue<>(); + + @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() { + @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 start() throws InterruptedException { - Bootstrap bootstrap = new Bootstrap(); - NioEventLoopGroup group = new NioEventLoopGroup(); - bootstrap.group(group) - .channel(NioDatagramChannel.class) - .handler(new ChannelInitializer() { - @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(InetSocketAddress addr, byte[] msg) { + if (msg != null) { + msgQueue.add(new Msg(addr, msg)); + System.out.println(LocalDateTime.now()); } + } - public void write(InetSocketAddress addr, byte[] msg) { - msgQueue.add(new Msg(addr, msg)); + @Scheduled(fixedRate = 10) + public void send() { + Msg msg = msgQueue.poll(); + if (msg == null) { + return; + } + InetSocketAddress addr = msg.getAddr(); + byte[] data = msg.getData(); + if (channel != null && channel.isWritable() && addr != null && data != null) { + ByteBuf byteBuf = Unpooled.copiedBuffer(data); + DatagramPacket datagramPacket = new DatagramPacket(byteBuf, addr); + channel.writeAndFlush(datagramPacket); } + } - @Scheduled(fixedRate = 10) - public void send() { - Msg msg = msgQueue.poll(); - if (msg == null) - return; - InetSocketAddress addr = msg.getAddr(); - byte[] data = msg.getData(); - if (channel != null && channel.isWritable() && addr != null && data != null) { - ByteBuf byteBuf = Unpooled.copiedBuffer(data); - DatagramPacket datagramPacket = new DatagramPacket(byteBuf, addr); - channel.writeAndFlush(datagramPacket); - } - } - - @Getter - class Msg { - private InetSocketAddress addr; - - private byte[] data; - - public Msg(InetSocketAddress addr, byte[] data) { - this.addr = addr; - this.data = data; - } + @Getter + class Msg { + + private InetSocketAddress addr; + + private byte[] data; + + public Msg(InetSocketAddress addr, byte[] data) { + this.addr = addr; + this.data = data; } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPLowConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPLowConfig.java index 83af48211..f2ab7541d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPLowConfig.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPLowConfig.java @@ -5,12 +5,11 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDevice 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; +import lombok.Getter; +import org.springframework.util.StringUtils; public class UDPLowConfig extends RealDeviceConfig { @Getter @@ -53,4 +52,8 @@ public class UDPLowConfig extends RealDeviceConfig { public String findDeviceCode() { return null; } + + public String getName() { + return configVO == null ? null : configVO.getName(); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceService.java index ff7bf45b9..2753782cc 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceService.java @@ -5,6 +5,10 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.device.RealDevice import io.netty.buffer.ByteBuf; public interface UDPRealDeviceService { + default boolean isMatch(UDPLowConfig udpLowConfig) { + return true; + } + boolean isMatch(RealDeviceConfig realDevice); void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceThread.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceThread.java index c1457be01..3f8afecdb 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceThread.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/UDPRealDeviceThread.java @@ -3,93 +3,104 @@ 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 java.util.List; 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; + /** + * 真是设备逻辑执行频率。 + *

+ * 因沙盘对延迟要求较高,所以将频率提高 + */ + public static final int RATE = 100; - @EventListener - public void simulationReset(SimulationResetEvent event) { - Simulation simulation = event.getSimulation(); - List 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); - } - } - } + @Autowired + private UDPRealDeviceServiceManager udpRealDeviceServiceManager; + + @Autowired + private GroupSimulationService groupSimulationService; + + @EventListener + public void simulationReset(SimulationResetEvent event) { + Simulation simulation = event.getSimulation(); + List realDeviceList = simulation.getRealDeviceList(); + if (CollectionUtils.isEmpty(realDeviceList)) { + return; } - - public void run(Simulation simulation) { - List realDeviceList = simulation.getRealDeviceList(); - if (CollectionUtils.isEmpty(realDeviceList)) - return; - List 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; - } + 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); } - for (RealDeviceConfig config : realDeviceList) { + } + } + } + + public void run(Simulation simulation) { + List realDeviceList = simulation.getRealDeviceList(); + if (CollectionUtils.isEmpty(realDeviceList)) { + return; + } + List serviceList = udpRealDeviceServiceManager.getServiceList(); + if (CollectionUtils.isEmpty(serviceList)) { + return; + } + realDeviceList.stream() + .filter( + realDeviceConfig -> ProjectDeviceType.UDP_LOW.equals(realDeviceConfig.getDeviceType())) + .map(realDeviceConfig -> (UDPLowConfig) realDeviceConfig) + .forEach(udpLowConfig -> { + for (RealDeviceConfig config : realDeviceList) { for (UDPRealDeviceService service : serviceList) { - if (service.isMatch(config) && config.getMapElement() != null) { - service.run(simulation, udpLowConfig, config); - } + if (service.isMatch(udpLowConfig) && service.isMatch(config) + && config.getMapElement() != null) { + service.run(simulation, udpLowConfig, config); + } } - } - } + } + }); + } - public void handleData(String ip, int port, ByteBuf data) { - List simulations = groupSimulationService.querySimulations(); - for (Simulation simulation : simulations) { - List 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); - } - } - } + public void handleData(String ip, int port, ByteBuf data) { + List simulations = groupSimulationService.querySimulations(); + for (Simulation simulation : simulations) { + List 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); + } } + } } + } - public void addJobs(Simulation simulation) { - simulation.addFixedRateJob(Simulation.JobName.udpRealDevice, - () -> this.run(simulation), SimulationConstants.VRD_LOOP_RATE); - } + public void addJobs(Simulation simulation) { + simulation.addFixedRateJob(Simulation.JobName.udpRealDevice, () -> this.run(simulation), RATE); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainController.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainController.java deleted file mode 100644 index 67ba43e6f..000000000 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/SrTrainController.java +++ /dev/null @@ -1,22 +0,0 @@ -package club.joylink.rtss.simulation.cbtc.device.real.udp.sr; - -import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.service.SrTrainServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping("/api/sr") -public class SrTrainController { - @Autowired - private SrTrainServiceImpl srTrainService; - -// @PutMapping("/{simulationId}/control") -// public void control(@PathVariable String simulationId, @RequestBody @Validated SrTrainControlParam controlParam) { -// srTrainService.control(simulationId, controlParam.getGroupNumber(), controlParam.getRight(), controlParam.getSpeed()); -// } - - @PutMapping("/{simulationId}/control") - public void control(@PathVariable String simulationId, String groupNumber, boolean right, int speed) { - srTrainService.controlTrain(simulationId, groupNumber, right, speed); - } -} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/service/SrSectionServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/service/SrSectionServiceImpl.java index 002e7a5a6..73a52d106 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/service/SrSectionServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/sr/service/SrSectionServiceImpl.java @@ -15,10 +15,6 @@ import club.joylink.rtss.simulation.cbtc.device.real.udp.UDPRealDeviceService; import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrSectionConfig; import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrTrainConfig; import io.netty.buffer.ByteBuf; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - import java.time.LocalDateTime; import java.util.Collections; import java.util.List; @@ -26,167 +22,187 @@ import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; @Slf4j @Service public class SrSectionServiceImpl implements UDPRealDeviceService { - @Autowired - private SrTrainServiceImpl srTrainService; - @Autowired - private MaService maService; + public static final String PROJECT_CODE = "SR_SANDBOX"; - @Override - public boolean isMatch(RealDeviceConfig realDevice) { - return realDevice instanceof UDPClientConfig; + @Autowired + private MaService maService; + + @Override + public boolean isMatch(RealDeviceConfig realDevice) { + return realDevice instanceof UDPClientConfig && PROJECT_CODE + .equals(realDevice.getProject()); + } + + @Override + public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + + } + + @Override + public void init(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + } + + @Override + public void handle(Simulation simulation, ByteBuf msg) { + //检查数据 + byte[] data = new byte[msg.readableBytes()]; + if (data.length < 4) { + return; } - - @Override - public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { - + msg.readBytes(data); + if (Byte.toUnsignedInt(data[1]) != 137) { + return; } - - @Override - public void init(Simulation simulation, UDPLowConfig udpLowConfig, 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 configMap = simulation.queryAllRealDevice( + ProjectDeviceType.SECTION).stream() + .map(config -> (SrSectionConfig) config) + .collect( + Collectors.toMap(config -> config.getConfigVO().getSandboxCode(), Function.identity())); + for (int i = 3, dataLength = data.length; i < dataLength; i += 2) { + int code = Byte.toUnsignedInt(data[i - 1]); + String key = String.valueOf(code); + SrSectionConfig config = configMap.get(key); + if (config == null) { + continue; + } + VirtualRealitySectionAxleCounter axle = (VirtualRealitySectionAxleCounter) config.getMapElement(); + if (axle != null) { + int n = Byte.toUnsignedInt(data[i]); + if (n == 170) { + updateTrainPosition(simulation, axle); + config.setTimesOfRelease(0); + axle.setOccupy(true); + } else if (n == 85) { + config.setTimesOfRelease(config.getTimesOfRelease() + 1); + if (config.getTimesOfRelease() > 3) { //连续4次该计轴都是无占用状态,才视为确实无占用 + config.setTimesOfRelease(0); + axle.clear(); + } } - //处理数据 - Map configMap = simulation.queryAllRealDevice(ProjectDeviceType.SECTION).stream() - .map(config -> (SrSectionConfig) config) - .collect(Collectors.toMap(config -> config.getConfigVO().getSandboxCode(), Function.identity())); - for (int i = 3, dataLength = data.length; i < dataLength; i += 2) { - int code = Byte.toUnsignedInt(data[i - 1]); - String key = String.valueOf(code); - SrSectionConfig config = configMap.get(key); - if (config == null) - continue; - VirtualRealitySectionAxleCounter axle = (VirtualRealitySectionAxleCounter) config.getMapElement(); - if (axle != null) { - int n = Byte.toUnsignedInt(data[i]); - if (n == 170) { - updateTrainPosition(simulation, axle); - config.setTimesOfRelease(0); - axle.setOccupy(true); - } else if (n == 85) { - config.setTimesOfRelease(config.getTimesOfRelease() + 1); - if (config.getTimesOfRelease() > 3) { //连续4次该计轴都是无占用状态,才视为确实无占用 - config.setTimesOfRelease(0); - axle.clear(); - } - } - } - } - //设置停车信息 - stop(simulation); + } } + //设置停车信息 + stop(simulation); + } - /** - * 列车到达特殊轨道,设置延迟停车时间 - */ - private void stop(Simulation simulation) { - for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) { - Section headSection = train.getHeadPosition().getSection(); + /** + * 列车到达特殊轨道,设置延迟停车时间 + */ + private void stop(Simulation simulation) { + for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) { + Section headSection = train.getHeadPosition().getSection(); + SrTrainConfig config = (SrTrainConfig) train.getRealDevice(); + if (!Objects.equals(headSection, config.getHeadSection())) //列车无需在该站台停车 + { + continue; + } + if (config.getTimeOfStop() != null) //已经设置过停车时间 + { + continue; + } + if (!headSection.isFunctionTrack()) { + continue; + } + VirtualRealitySectionAxleCounter headAxle = headSection.findAxle(); + if (headAxle == null) { + continue; + } + SrSectionConfig sectionConfig = (SrSectionConfig) headAxle.getRealDevice(); + //设置延时停车时间 + long m = 1000000000; + long nanos; + if (sectionConfig.getConfigVO().getHeadDelayTime() != null) { + nanos = (long) (sectionConfig.getConfigVO().getHeadDelayTime() * m); + config.setTimeOfStop(LocalDateTime.now().plusNanos(nanos)); + continue; + } + //以前一个区段无占用作为停车标志的区段 + boolean right = train.isRight(); + Section behindSection = headSection.getNextRunningSectionOf(!right); + if (behindSection == null) { + continue; + } + VirtualRealitySectionAxleCounter behindAxle = behindSection.findAxle(); + if (behindAxle == null) { + continue; + } + if (!behindAxle.isOccupy()) { //车头后方区段所属计轴无占用状态 + nanos = 0; + if (sectionConfig.getConfigVO().getTailDelayTime() != null) { + nanos = (long) (sectionConfig.getConfigVO().getTailDelayTime() * m); + } + if (nanos == 0) { + train.setHeadPosition(headSection.buildStopPointPosition(right)); + } else { + config.setTimeOfStop(LocalDateTime.now().plusNanos(nanos)); + } + } + } + } + + private void updateTrainPosition(Simulation simulation, VirtualRealitySectionAxleCounter axle) { + for (Section section : simulation.getRepository().getAxleSectionList()) { + if (section.getVirtualAxleCounter().equals(axle)) { + List

pSection; + if (section.isPhysical()) { + pSection = Collections.singletonList(section); + } else if (section.isSwitchAxleCounterSection()) { + pSection = section.findConnectedSections(); + } else { + pSection = Collections.emptyList(); + } + for (Section sec : pSection) { + check4UpdateHeadPosition(simulation, sec, false); + check4UpdateHeadPosition(simulation, sec, true); + } + } + } + } + + /** + * 检查是否有right向的列车可以更新车头位置 + */ + private void check4UpdateHeadPosition(Simulation simulation, Section occupiedSection, + boolean right) { + Section section = occupiedSection.getNextRunningSectionOf(!right); //找反向的区段 + if (section != null) { + for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) { + Section headSection = train.getHeadPosition().getSection(); + boolean trainRight = train.isRight(); + if (trainRight == right && section.equals(headSection)) { //列车到达occupiedSection + //判断更新ITC ma + if (headSection.getSignalOf(trainRight) != null) { + maService.calculateAndUpdateItcMa(simulation, train); + } + //更新位置 + SectionPosition headPosition; + SectionPosition stopPointPosition; + if (occupiedSection.isFunctionTrack()) { + stopPointPosition = occupiedSection.buildStopPointPosition(right); + headPosition = CalculateService.calculateNextPositionByStartAndLen(stopPointPosition, + !right, 1, true); + } else { + stopPointPosition = new SectionPosition(occupiedSection, + occupiedSection.getEndOffsetByDirection(right)); + headPosition = CalculateService.calculateNextPositionByStartAndLen(stopPointPosition, + !right, 3, true); + } + train.setHeadPosition(headPosition); //更新位置 + if (occupiedSection.isFunctionTrack()) { //功能轨可能需要停车 SrTrainConfig config = (SrTrainConfig) train.getRealDevice(); - if (!Objects.equals(headSection, config.getHeadSection())) //列车无需在该站台停车 - continue; - if (config.getTimeOfStop() != null) //已经设置过停车时间 - continue; - if (!headSection.isFunctionTrack()) - continue; - VirtualRealitySectionAxleCounter headAxle = headSection.findAxle(); - if (headAxle == null) - continue; - SrSectionConfig sectionConfig = (SrSectionConfig) headAxle.getRealDevice(); - //设置延时停车时间 - long m = 1000000000; - long nanos; - if (sectionConfig.getConfigVO().getHeadDelayTime() != null) { - nanos = (long) (sectionConfig.getConfigVO().getHeadDelayTime() * m); - config.setTimeOfStop(LocalDateTime.now().plusNanos(nanos)); - continue; - } - //以前一个区段无占用作为停车标志的区段 - boolean right = train.isRight(); - Section behindSection = headSection.getNextRunningSectionOf(!right); - if (behindSection == null) - continue; - VirtualRealitySectionAxleCounter behindAxle = behindSection.findAxle(); - if (behindAxle == null) - continue; - if (!behindAxle.isOccupy()) { //车头后方区段所属计轴无占用状态 - nanos = 0; - if (sectionConfig.getConfigVO().getTailDelayTime() != null) { - nanos = (long) (sectionConfig.getConfigVO().getTailDelayTime() * m); - } - if (nanos == 0) { - train.setHeadPosition(headSection.buildStopPointPosition(right)); - } else { - config.setTimeOfStop(LocalDateTime.now().plusNanos(nanos)); - } - } - } - } - - private void updateTrainPosition(Simulation simulation, VirtualRealitySectionAxleCounter axle) { - for (Section section : simulation.getRepository().getAxleSectionList()) { - if (section.getVirtualAxleCounter().equals(axle)) { - List
pSection; - if (section.isPhysical()) { - pSection = Collections.singletonList(section); - } else if (section.isSwitchAxleCounterSection()) { - pSection = section.findConnectedSections(); - } else { - pSection = Collections.emptyList(); - } - for (Section sec : pSection) { - check4UpdateHeadPosition(simulation, sec, false); - check4UpdateHeadPosition(simulation, sec, true); - } - } - } - } - - /** - * 检查是否有right向的列车可以更新车头位置 - */ - private void check4UpdateHeadPosition(Simulation simulation, Section occupiedSection, boolean right) { - Section section = occupiedSection.getNextRunningSectionOf(!right); //找反向的区段 - if (section != null) { - for (VirtualRealityTrain train : simulation.getRepository().getOnlineTrainList()) { - Section headSection = train.getHeadPosition().getSection(); - boolean trainRight = train.isRight(); - if (trainRight == right && section.equals(headSection)) { //列车到达occupiedSection - //判断更新ITC ma - if (headSection.getSignalOf(trainRight) != null) { - maService.calculateAndUpdateItcMa(simulation, train); - } - //更新位置 - SectionPosition headPosition; - SectionPosition stopPointPosition; - if (occupiedSection.isFunctionTrack()) { - stopPointPosition = occupiedSection.buildStopPointPosition(right); - headPosition = CalculateService.calculateNextPositionByStartAndLen(stopPointPosition, !right, 1, true); - } else { - stopPointPosition = new SectionPosition(occupiedSection, occupiedSection.getEndOffsetByDirection(right)); - headPosition = CalculateService.calculateNextPositionByStartAndLen(stopPointPosition, !right, 3, true); - } - train.setHeadPosition(headPosition); //更新位置 - if (occupiedSection.isFunctionTrack()) { //功能轨可能需要停车 - SrTrainConfig config = (SrTrainConfig) train.getRealDevice(); - config.updateHeadSection(occupiedSection); - } - } - } + config.updateHeadSection(occupiedSection); + } } + } } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSectionConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSectionConfig.java new file mode 100644 index 000000000..42a202406 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSectionConfig.java @@ -0,0 +1,32 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config; + +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.thailand.ThailandSectionConfigVO; +import java.util.Objects; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class ThailandSectionConfig extends RealDeviceConfig { + private ThailandSectionConfigVO configVO; + + /** + * 连续无占用次数 + */ + @Setter + private int timesOfRelease; + + public ThailandSectionConfig(ProjectDeviceVO projectDevice) { + super(projectDevice); + if (Objects.nonNull(projectDevice.getConfig())) { + this.configVO = JsonUtils.read(projectDevice.getConfig(), ThailandSectionConfigVO.class); + } + } + + @Override + public String findDeviceCode() { + return configVO.findDeviceCode(); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSignalConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSignalConfig.java new file mode 100644 index 000000000..5b909afa2 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSignalConfig.java @@ -0,0 +1,30 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config; + +import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; +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.thailand.ThailandSignalConfigVO; +import java.util.Objects; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class ThailandSignalConfig extends RealDeviceConfig { + private ThailandSignalConfigVO configVO; + + @Setter + private SignalAspect aspect; + + public ThailandSignalConfig(ProjectDeviceVO projectDevice) { + super(projectDevice); + if (Objects.nonNull(projectDevice.getConfig())) { + this.configVO = JsonUtils.read(projectDevice.getConfig(), ThailandSignalConfigVO.class); + } + } + + @Override + public String findDeviceCode() { + return configVO.findDeviceCode(); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSwitchConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSwitchConfig.java new file mode 100644 index 000000000..61054d818 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandSwitchConfig.java @@ -0,0 +1,29 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config; + +import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication; +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.thailand.ThailandSwitchConfigVO; +import java.util.Objects; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class ThailandSwitchConfig extends RealDeviceConfig { + private ThailandSwitchConfigVO configVO; + + @Setter + private SwitchIndication p; + public ThailandSwitchConfig(ProjectDeviceVO projectDevice) { + super(projectDevice); + if (Objects.nonNull(projectDevice.getConfig())) { + this.configVO = JsonUtils.read(projectDevice.getConfig(), ThailandSwitchConfigVO.class); + } + } + + @Override + public String findDeviceCode() { + return configVO.findDeviceCode(); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandTrainConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandTrainConfig.java new file mode 100644 index 000000000..d9c282aea --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/config/ThailandTrainConfig.java @@ -0,0 +1,58 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config; + +import club.joylink.rtss.simulation.cbtc.data.map.Section; +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.thailand.ThailandTrainConfigVO; +import java.time.LocalDateTime; +import java.util.Objects; +import lombok.Getter; +import lombok.Setter; + +@Getter +public class ThailandTrainConfig extends RealDeviceConfig { + + private ThailandTrainConfigVO configVO; + + @Setter + private Integer gear; + + /** + * 列车需要在这个轨道停车 + */ + private Section headSection; + + /** + * 列车抵达停车点的时间。 + *

+ * 当走到这个时间时,需要将列车的车头位置更新至当前区段的停车点。 + *

+ * 上述停车点指代一切可能需要停车的位置,比如站台轨的停车点、信号机2m前、轨道尽头10m前。 + */ + @Setter + private LocalDateTime timeOfArriveStopPoint; + + /** + * 人为驾驶的档位 + */ + @Setter + private Integer manualGear; + + public void updateHeadSection(Section headSection) { + this.headSection = headSection; + this.timeOfArriveStopPoint = null; + } + + public ThailandTrainConfig(ProjectDeviceVO projectDevice) { + super(projectDevice); + if (Objects.nonNull(projectDevice.getConfig())) { + this.configVO = JsonUtils.read(projectDevice.getConfig(), ThailandTrainConfigVO.class); + } + } + + @Override + public String findDeviceCode() { + return configVO.findDeviceCode(); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSectionServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSectionServiceImpl.java new file mode 100644 index 000000000..c4942a10a --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSectionServiceImpl.java @@ -0,0 +1,85 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service; + +import club.joylink.rtss.constants.ProjectCode; +import club.joylink.rtss.constants.ProjectDeviceType; +import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService; +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 club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSectionConfig; +import io.netty.buffer.ByteBuf; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class ThailandSectionServiceImpl implements UDPRealDeviceService { + + @Autowired + private MaService maService; + + @Override + public boolean isMatch(RealDeviceConfig realDevice) { + return realDevice instanceof UDPClientConfig && ProjectCode.THAILAND_SANDBOX + .equals(realDevice.getProject()); + } + + @Override + public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + + } + + @Override + public void init(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + //沙盘不需要停太长时间 + simulation.getRepository().getStandList().forEach(stand -> stand.setParkingTime(15)); + } + + @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 configMap = simulation.queryAllRealDevice( + ProjectDeviceType.SECTION).stream() + .map(config -> (ThailandSectionConfig) config) + .collect( + Collectors.toMap(config -> config.getConfigVO().getSandboxCode(), Function.identity())); + for (int i = 3, dataLength = data.length; i < dataLength; i += 2) { + int code = Byte.toUnsignedInt(data[i - 1]); + String key = String.valueOf(code); + ThailandSectionConfig config = configMap.get(key); + if (config == null) { + continue; + } + VirtualRealitySectionAxleCounter axle = (VirtualRealitySectionAxleCounter) config.getMapElement(); + if (axle != null) { + int n = Byte.toUnsignedInt(data[i]); + if (n == 170) { + config.setTimesOfRelease(0); + axle.setOccupy(true); + } else if (n == 85) { + config.setTimesOfRelease(config.getTimesOfRelease() + 1); + if (config.getTimesOfRelease() > 2) { //连续3次该计轴都是无占用状态,才视为确实无占用 + config.setTimesOfRelease(0); + axle.clear(); + } + } + } + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSignalServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSignalServiceImpl.java new file mode 100644 index 000000000..574bed898 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSignalServiceImpl.java @@ -0,0 +1,136 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service; + +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 club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSignalConfig; +import io.netty.buffer.ByteBuf; +import java.util.Objects; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ThailandSignalServiceImpl implements UDPRealDeviceService { + public static final String NAME = "SIGNAL"; + + @Autowired + private UDPClient udpClient; + + @Override + public boolean isMatch(UDPLowConfig udpLowConfig) { + return NAME.equals(udpLowConfig.getName()); + } + + @Override + public boolean isMatch(RealDeviceConfig realDevice) { + return realDevice instanceof ThailandSignalConfig; + } + + @Override + public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + ThailandSignalConfig config = (ThailandSignalConfig) realDevice; + //控制vr设备 + VirtualRealitySignal vrSignal = (VirtualRealitySignal) realDevice.getMapElement(); + SignalAspect aspect = vrSignal.getAspect(); + SignalAspect command = vrSignal.getCommand(); + if (Objects.equals(aspect, command)) { + return; + } + if (vrSignal.isTurning()) { + vrSignal.turning(SimulationConstants.VRD_LOOP_RATE); + } + //控制沙盘设备 + aspect = vrSignal.getAspect(); + if (aspect == null || udpLowConfig == null || Objects.equals(aspect, config.getAspect())) { + return; + } + byte[] data = buildData(aspect, config); + if (data == null) + return; + udpClient.write(udpLowConfig.getAddr(), data); + } + + @Override + public void init(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + + } + + @Override + public void handle(Simulation simulation, ByteBuf msg) { + + } + + private byte[] buildData(SignalAspect aspect, ThailandSignalConfig config) { + if (aspect == null) + return null; + config.setAspect(aspect); + 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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSwitchServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSwitchServiceImpl.java new file mode 100644 index 000000000..810cf64e6 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandSwitchServiceImpl.java @@ -0,0 +1,85 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service; + +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 club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSwitchConfig; +import io.netty.buffer.ByteBuf; +import java.util.Objects; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ThailandSwitchServiceImpl implements UDPRealDeviceService { + public static final String NAME = "SWITCH-TRAIN"; + + @Autowired + private UDPClient udpClient; + + @Override + public boolean isMatch(UDPLowConfig udpLowConfig) { + return NAME.equals(udpLowConfig.getName()); + } + + @Override + public boolean isMatch(RealDeviceConfig realDevice) { + return realDevice instanceof ThailandSwitchConfig; + } + + @Override + public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + ThailandSwitchConfig config = (ThailandSwitchConfig) realDevice; + //控制vr设备 + VirtualRealitySwitch vrSwitch = (VirtualRealitySwitch) realDevice.getMapElement(); + if (vrSwitch.isTurning()) { + vrSwitch.turning(SimulationConstants.VRD_LOOP_RATE); + } + //控制沙盘设备 + SwitchIndication p = vrSwitch.getP(); + if (p == null || udpLowConfig == null || Objects.equals(p, config.getP())) { + return; + } + byte[] data = buildData(p, config); + if (data == null) + return; + udpClient.write(udpLowConfig.getAddr(), data); + } + + @Override + public void init(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + + } + + @Override + public void handle(Simulation simulation, ByteBuf msg) { + + } + + private byte[] buildData(SwitchIndication p, ThailandSwitchConfig config) { + if (p == null) + return null; + config.setP(p); + 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; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandTrainServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandTrainServiceImpl.java new file mode 100644 index 000000000..d6465f28e --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/device/real/udp/thailand/service/ThailandTrainServiceImpl.java @@ -0,0 +1,303 @@ +package club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.service; + +import club.joylink.rtss.constants.ProjectDeviceType; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService; +import club.joylink.rtss.simulation.cbtc.GroupSimulationService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; +import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; +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 club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSectionConfig; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandTrainConfig; +import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; +import club.joylink.rtss.vo.client.project.thailand.ThailandSectionConfigVO; +import club.joylink.rtss.vo.map.graph.MapSectionNewVO; +import io.netty.buffer.ByteBuf; +import java.time.LocalDateTime; +import java.util.Objects; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class ThailandTrainServiceImpl implements UDPRealDeviceService { + + public static final String NAME = ThailandSwitchServiceImpl.NAME; + + @Autowired + private UDPClient udpClient; + @Autowired + private ATPService atpService; + @Autowired + private GroupSimulationService groupSimulationService; + @Autowired + private AtsTrainLoadService atsTrainLoadService; + + @Override + public boolean isMatch(UDPLowConfig udpLowConfig) { + return NAME.equals(udpLowConfig.getName()); + } + + @Override + public boolean isMatch(RealDeviceConfig realDevice) { + return realDevice instanceof ThailandTrainConfig; + } + + @Override + public void run(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + ThailandTrainConfig config = (ThailandTrainConfig) realDevice; + //控制vr设备 + VirtualRealityTrain train = (VirtualRealityTrain) config.getMapElement(); + SimulationDataRepository repository = simulation.getRepository(); + String groupNumber = train.getGroupNumber(); + if (repository.isVrTrainOnline(groupNumber)) { + removeVrTrainIfNotSupervised(repository, groupNumber); + if (!train.isRobotStopControl() && config.getManualGear() != null) { + config.setManualGear(null); + config.setGear(null); + } + updateTrainPosition(simulation, train, config); + updateTrainSpeed(simulation, train, config); + //减少关门后的延迟发车时间 + if (train.getDelayTime() > 3000) { + train.setDelayTime(3000); + } + //控制沙盘设备 + byte[] data = buildData(train, config); + udpClient.write(udpLowConfig.getAddr(), data); + } else { + addVrTrainIfSupervised(simulation, repository, groupNumber); + } + } + + /** + * 更新列车位置。 + *

+ * 1.如果列车占压新的区段,则先将列车车头位置更新至该区段的停车点之前(保证列车可以继续运行)。 2.根据区段的配置信息,决定列车何时将车头位置更新至停车点 + * 3.根据上一步设置的停车时间,判断执行更新车头位置至停车点逻辑(触发列车停车逻辑) + */ + private void updateTrainPosition(Simulation simulation, VirtualRealityTrain train, + ThailandTrainConfig config) { + //判断列车是否到达新区段 + boolean right = train.isRight(); //车头方向 + Section headSection = train.getHeadPosition().getSection(); //车头区段 + Section previousSection = null; //车头方向的上一个区段 + Section nextSection = headSection.getNextRunningSectionOf(right); //车头方向的下一个区段 + ThailandSectionConfig sectionConfig = (ThailandSectionConfig) headSection.findAxle() + .getRealDevice(); //车头区段的配置 + if (nextSection != null) { + VirtualRealitySectionAxleCounter nextAxle = nextSection.findAxle(); + if (nextAxle.isOccupy()) { + train.setHeadPosition( + new SectionPosition(nextSection, right ? 0 : nextSection.getMaxOffset())); + config.setTimeOfArriveStopPoint(null); + sectionConfig = (ThailandSectionConfig) nextAxle.getRealDevice(); + //更新变量 + previousSection = headSection; + headSection = train.getHeadPosition().getSection(); + nextSection = null; + } + } + //根据区段的配置信息,设置车头位置更新至停车点的时间 +// fill(headSection, sectionConfig.getConfigVO()); 仅用于调试 + LocalDateTime now = LocalDateTime.now(); + if (config.getTimeOfArriveStopPoint() == null) { + int rate = 1000000000; //秒到纳秒的换算比例 + Long delayOfNano = null; //延迟时间的纳秒表示 + if (sectionConfig.getConfigVO().getHeadDelayTime() != null) { //车头占压延时停车 + delayOfNano = (long) (sectionConfig.getConfigVO().getHeadDelayTime() * rate); + } else if (sectionConfig.getConfigVO().getTailDelayTime() != null) { //车尾出清延时停车 + if (previousSection == null) { + previousSection = headSection.getNextRunningSectionOf(!right); + } + if (previousSection != null && !previousSection.isOccupied()) { + delayOfNano = (long) (sectionConfig.getConfigVO().getTailDelayTime() * rate); + } + } else { //未设置则认为车头占压即刻停车 + delayOfNano = 0L; + } + if (delayOfNano != null) { + config.setTimeOfArriveStopPoint(now.plusNanos(delayOfNano)); + } + } + //根据当前时间,判断更新车头位置至停车点 + LocalDateTime timeOfArriveStopPoint = config.getTimeOfArriveStopPoint(); + if (timeOfArriveStopPoint != null && !now.isBefore(timeOfArriveStopPoint)) { + SectionPosition stopPosition = train.getRobotDriveParam().getStopPosition(); + if (stopPosition != null && stopPosition.getSection().equals(headSection)) { + train.setHeadPosition(stopPosition); + } else if (stopPosition == null || !stopPosition.getSection().equals(headSection)) { + float offset = right ? headSection.getMaxOffset() : 0; + train.setHeadPosition(new SectionPosition(headSection, offset)); + } + } + } + + /** + * 如果有监控,添加一个vrTrain + */ + private void addVrTrainIfSupervised(Simulation simulation, SimulationDataRepository repository, + String groupNumber) { + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); + if (trainInfo != null) { + Section section = repository.getByCode(trainInfo.getSection(), Section.class); + if (section.isSwitchAxleCounterSection()) { + section = section.getLogicList().get(0).getRelSwitch().getA(); + } + atsTrainLoadService.loadSpareTrain(simulation, groupNumber, section.getCode(), false); + } + } + + /** + * 移除vrTrain,如果没有被监控 + */ + private void removeVrTrainIfNotSupervised(SimulationDataRepository repository, + String groupNumber) { + TrainInfo trainInfo = repository.findSupervisedTrainByGroup(groupNumber); + if (trainInfo == null) { + repository.deleteOnlineTrain(groupNumber); + } + } + + @Override + public void init(Simulation simulation, UDPLowConfig udpLowConfig, RealDeviceConfig realDevice) { + ThailandTrainConfig config = (ThailandTrainConfig) realDevice; + //控制vr设备 + VirtualRealityTrain train = (VirtualRealityTrain) config.getMapElement(); + //控制沙盘设备 + byte[] data = buildData(train, config); + udpClient.write(udpLowConfig.getAddr(), data); + //清除状态 + config.updateHeadSection(null); + } + + @Override + public void handle(Simulation simulation, ByteBuf msg) { + + } + + private void updateTrainSpeed(Simulation simulation, VirtualRealityTrain train, + ThailandTrainConfig config) { + //更新速度 + if (config.getManualGear() != null) { + return; + } + if (train.getFk() > train.getFb()) { + train.setSpeed(10 / 3.6f); + } else if (train.getFb() > train.getFk()) { + train.setSpeed(0); + } + } + + private byte[] buildData(VirtualRealityTrain train, ThailandTrainConfig config) { + int gear; + if (train.isStop()) { + gear = 0; + } else { + float speedKmPh = train.getSpeedKmPh(); + if (train.isStop()) { + gear = 0; + } else { + gear = (int) Math.ceil(speedKmPh / 10); + gear = Math.max(1, gear); + } + if (train.isRight()) { //档位1-5是正向,6-10是反向 + gear += 5; + } + } + if (Objects.equals(config.getGear(), gear)) { + return null; + } + config.setGear(gear); + byte[] data = new byte[4]; + data[1] = (byte) 1; + data[2] = (byte) Integer.parseInt(config.getConfigVO().getSandboxCode()); + data[3] = (byte) gear; + return data; + } + + /** + * 此方法用于调试,调试完成后方法内的数据请保存到项目设备配置{@link club.joylink.rtss.services.project.DeviceServiceImpl#thailandFillTime(ThailandSectionConfigVO, MapSectionNewVO)} + */ + public void fill(Section section, ThailandSectionConfigVO configVO) { + Float headDelayTime = null; + Float tailDelayTime = null; + if (section.isStandTrack()) { //站台轨默认为车尾出清立即停车 + headDelayTime = 5f; + } + switch (section.getCode()) { + case "T233": //X302G + headDelayTime = 7f; + break; + case "T232": //X303G + headDelayTime = 7f; + break; + case "T231": //X304G + headDelayTime = 5.5f; + break; + case "T175": //4站-IIG + headDelayTime = 5.5f; + break; + case "T121": //4站-IIG + headDelayTime = 5.2f; + break; + case "T77": //4站-IIG + headDelayTime = 6f; + break; + case "T145": //QX04 + tailDelayTime = 0f; + break; + case "T146": //QS04 + tailDelayTime = 0f; + break; + case "T104": //QX03 + tailDelayTime = 0f; + break; + case "T105": //QS03 + tailDelayTime = 0f; + break; + case "T62": //QX02 + tailDelayTime = 0f; + break; + case "T63": //QS02 + tailDelayTime = 0f; + break; + } + configVO.setHeadDelayTime(headDelayTime); + configVO.setTailDelayTime(tailDelayTime); + } + + public void controlTrain(String simulationId, String groupNumber, boolean right, int speed) { + Simulation simulation = groupSimulationService.getSimulationByGroup(simulationId); + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + ThailandTrainConfig config = (ThailandTrainConfig) train.getRealDevice(); + if (right != train.isRight()) { //调头 + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertTrue(train.getSpeed() == 0, "换端需先停车"); + atpService.turnDirectionImmediately(train); + } + train.setRobotTargetPosition(null); //终止机器人司机驾驶 + //加减速 + if (train.isEB()) { + return; + } + atpService.changeGear(train, VirtualRealityTrain.Handwheel.MANUAL); + int manualGear = speed / 10; + config.setManualGear(manualGear); + train.setSpeed(speed / 3.6f); + train.getRobotDriveParam().stopControl(); + byte[] data = buildData(train, config); + UDPLowConfig udpLowConfig = (UDPLowConfig) simulation.queryOneRealDevice( + ProjectDeviceType.UDP_LOW); + udpClient.write(udpLowConfig.getAddr(), data); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java index e2c8294d1..22e48b247 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATO/SpeedCurve.java @@ -9,14 +9,18 @@ import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; -import java.util.*; - /** * 目标速度-距离曲线 */ @@ -315,75 +319,6 @@ public class SpeedCurve { return speedCurve; } -// public static SpeedCurve buildTargetSpeedCurve(SectionPosition headPosition, -// SectionPosition tailPosition, boolean right, -// float totalLen, float v0, float recommendedSpeedMax) { -// if (totalLen <= 0) { -// return SpeedCurve.ZERO; -// } -// Section base = tailPosition.getSection(); -// Section headSection = headPosition.getSection(); -// float limitSpeed = recommendedSpeedMax; -// boolean limit = false; -// if (Objects.nonNull(tailPosition.getSection().getNeedLimitSpeed())) { -// limitSpeed = Math.min(limitSpeed, tailPosition.getSection().getNeedLimitSpeed() * 0.9f); -// limit = true; -// } else if (Objects.nonNull(headPosition.getSection().getNeedLimitSpeed())) { -// limitSpeed = Math.min(limitSpeed, headPosition.getSection().getNeedLimitSpeed() * 0.9f); -// limit = true; -// } -// SectionPosition endPosition = null; -// boolean ahead = false; -// float vt = 0; -// int count = 0; -// if (!limit) { -// // 无限速,找前方限速 -// while (Objects.nonNull(base) && count < 20) { -// ++count; -// Float limitSpeed1 = base.getNeedLimitSpeed(); -// if (limitSpeed1 == null && !CollectionUtils.isEmpty(base.getLogicList())) { //兼容逻辑区段设置限速 -// float distanceBetweenLogicAndPhysical = 0; //逻辑区段距物理区段端点的距离(同向端点) -// for (Section section : base.getLogicList()) { -// limitSpeed1 = section.getNeedLimitSpeed(); -// if (limitSpeed1 != null) { -// float offsetOfLogicSectionOnPhysicalSection = distanceBetweenLogicAndPhysical + (right ? section.getLen() : 0); //逻辑区段的端点在物理区段上的偏移量 -// SectionPosition logicSectionPosition = new SectionPosition(base, offsetOfLogicSectionOnPhysicalSection); -// if (logicSectionPosition.isAheadOf(tailPosition, right)) { -// break; -// } -// } -// distanceBetweenLogicAndPhysical += section.getLen(); -// } -// } -// if (Objects.nonNull(limitSpeed1)) { -// if (ahead) { -// // 车头前方 -// vt = Math.min(limitSpeed, limitSpeed1 * 0.9f); -// endPosition = new SectionPosition(base, right ? 0 : base.getLen()); -// break; -// } else { -// limitSpeed = Math.min(limitSpeed, limitSpeed1 * 0.9f); -// } -// } -// if (Objects.equals(base, headSection)) { -// ahead = true; -// } -// base = base.getNextRunningSectionOf(right); -// } -// } -// SpeedCurve normalSpeedCurve = buildTargetSpeedCurve(totalLen, v0, 0, limitSpeed); -// if (endPosition != null) { -// Float distance = CalculateService.calculateDistance(headPosition, endPosition, right); -// if (distance != null && distance < totalLen) { -// SpeedCurve limitSpeedCurve = buildTargetSpeedCurve(distance, v0, vt, limitSpeed); -// float normalStartSpeed = normalSpeedCurve.getSpeedOf(normalSpeedCurve.getTotalDistance()); -// float limitStartSpeed = limitSpeedCurve.getSpeedOf(limitSpeedCurve.getTotalDistance()); -// return normalStartSpeed < limitStartSpeed ? normalSpeedCurve : limitSpeedCurve; -// } -// } -// return normalSpeedCurve; -// } - /** * 构建目标速度曲线 * diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/SimulationRobotService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/SimulationRobotService.java index d15a066b0..eb75a9ec9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/robot/SimulationRobotService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/robot/SimulationRobotService.java @@ -1,5 +1,7 @@ package club.joylink.rtss.simulation.cbtc.robot; +import static club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage.Confirm_Release_Speed; + import club.joylink.rtss.services.psl.IVirtualRealityPslService; import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService; import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher; @@ -15,579 +17,637 @@ import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; -import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.map.PSD; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +import club.joylink.rtss.simulation.cbtc.data.map.Signal; +import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.data.map.Station; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vo.ControlTransferReplyVO; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; -import club.joylink.rtss.simulation.cbtc.data.vr.*; +import club.joylink.rtss.simulation.cbtc.data.vr.StandParkedTrainActivity; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve; import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.training2.Training2; import club.joylink.rtss.vo.client.operation.DriveParamVO; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.util.*; -import java.util.stream.Collectors; - -import static club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage.Confirm_Release_Speed; - /** * 仿真机器人逻辑循环 */ @Component public class SimulationRobotService { - @Autowired - private AtsStationService atsStationService; - @Autowired - private DriverOperateHandler driverOperateHandler; + @Autowired + private AtsStationService atsStationService; - @Autowired - private ATOService atoService; + @Autowired + private DriverOperateHandler driverOperateHandler; - @Autowired - private ATPService atpService; + @Autowired + private ATOService atoService; - @Autowired - private IVirtualRealityPslService iVirtualRealityPslService; + @Autowired + private ATPService atpService; - @Autowired - private AtsOperationDispatcher atsOperationDispatcher; + @Autowired + private IVirtualRealityPslService iVirtualRealityPslService; - /** - * 根据目标位置运行 - */ - public void run(Simulation simulation) { - try { - robotDriverLogicLoop(simulation); - } catch (RuntimeException e) { - e.printStackTrace(); - } - robotReplyControlTransferApplicationLogicLoop(simulation); - robotStationControlAutoTransfer(simulation); - robotStationOperationModel(simulation); + @Autowired + private AtsOperationDispatcher atsOperationDispatcher; + + /** + * 根据目标位置运行 + */ + public void run(Simulation simulation) { + try { + robotDriverLogicLoop(simulation); + } catch (RuntimeException e) { + e.printStackTrace(); } + robotReplyControlTransferApplicationLogicLoop(simulation); + robotStationControlAutoTransfer(simulation); + robotStationOperationModel(simulation); + } - /** - * 机器人准备发车 - */ - private void robotReadyForDeparture(Simulation simulation, VirtualRealityTrain train) { - StandParkedTrainActivity activity = train.getStandParkedTrainActivity(); - if (activity != null) { - switch (activity) { - case OPEN_DOOR: - if (!train.isAutoOpenDoor()) { - atoService.syncOpenDoor(simulation, train); - usePsl2ControlPsd(simulation, train, true); - } - break; - case CLOSE_DOOR: - if (!train.isAutoCloseDoor()) { - atoService.syncCloseDoor(simulation, train); - usePsl2ControlPsd(simulation, train, false); - } - break; - case START: - if (train.isAtoCanOpen()) { - atpService.openATO(train); - } - break; - } - } - if (train.isStop() && train.isITC() && train.isAtoOn()) { - Signal signal = train.getHeadPosition().getSection().getSignalOf(train.isRight()); - if (signal != null && signal.isMainAspect()) { - atpService.confirmMessage(train, Confirm_Release_Speed); - } - } + /** + * 机器人准备发车 + */ + private void robotReadyForDeparture(Simulation simulation, VirtualRealityTrain train) { + StandParkedTrainActivity activity = train.getStandParkedTrainActivity(); + if (activity != null) { + switch (activity) { + case OPEN_DOOR: + if (!train.isAutoOpenDoor()) { + atoService.syncOpenDoor(simulation, train); + usePsl2ControlPsd(simulation, train, true); + } + break; + case CLOSE_DOOR: + if (!train.isAutoCloseDoor()) { + atoService.syncCloseDoor(simulation, train); + usePsl2ControlPsd(simulation, train, false); + } + break; + case START: + if (train.isAtoCanOpen()) { + atpService.openATO(train); + } + break; + } } - - /** - * 使用psl控制屏蔽门 - */ - public void usePsl2ControlPsd(Simulation simulation, VirtualRealityTrain train, boolean open) { - SectionPosition headPosition = train.getHeadPosition(); - Section section = headPosition.getSection(); - List standList = section.getStandList(); - if (!CollectionUtils.isEmpty(standList)) { - for (Stand stand : standList) { - PSD psd = stand.getPsd(); - if (psd == null) - continue; - VirtualRealityScreenDoor vrPsd = psd.getVirtualScreenDoor(); - if (open) { - if (!vrPsd.isClose() || vrPsd.isSettingOpen()) { - continue; - } - } else { - if (vrPsd.isLockAndClose() || vrPsd.isSettingClose()) { - continue; - } - } - VirtualRealityPsl vrPsl = stand.getVrPsl(); - if (!vrPsl.isAllowOperate()) { //确保此时允许操作 - iVirtualRealityPslService.pressTheButton(simulation, - stand.getCode(), VirtualRealityPsl.Button.YXJZ); - } - if (open) { - iVirtualRealityPslService.pressTheButton(simulation, - stand.getCode(), VirtualRealityPsl.Button.KM); - } else { - iVirtualRealityPslService.pressTheButton(simulation, - stand.getCode(), VirtualRealityPsl.Button.GM); - } - if (vrPsl.isAllowOperate()) { //将允许禁止钥匙打到禁止位 - iVirtualRealityPslService.pressTheButton(simulation, - stand.getCode(), VirtualRealityPsl.Button.YXJZ); - } - } - } + if (train.isStop() && train.isITC() && train.isAtoOn()) { + Signal signal = train.getHeadPosition().getSection().getSignalOf(train.isRight()); + if (signal != null && signal.isMainAspect()) { + atpService.confirmMessage(train, Confirm_Release_Speed); + } } + } - /** - * 机器人司机逻辑循环 - */ - private void robotDriverLogicLoop(Simulation simulation) { - List drivers = simulation.querySimulationMembersOfRole(SimulationMember.Type.DRIVER); - for (SimulationMember driver : drivers) { + /** + * 使用psl控制屏蔽门 + */ + public void usePsl2ControlPsd(Simulation simulation, VirtualRealityTrain train, boolean open) { + SectionPosition headPosition = train.getHeadPosition(); + Section section = headPosition.getSection(); + List standList = section.getStandList(); + if (!CollectionUtils.isEmpty(standList)) { + for (Stand stand : standList) { + PSD psd = stand.getPsd(); + if (psd == null) { + continue; + } + VirtualRealityScreenDoor vrPsd = psd.getVirtualScreenDoor(); + if (open) { + if (!vrPsd.isClose() || vrPsd.isSettingOpen()) { + continue; + } + } else { + if (vrPsd.isLockAndClose() || vrPsd.isSettingClose()) { + continue; + } + } + VirtualRealityPsl vrPsl = stand.getVrPsl(); + if (!vrPsl.isAllowOperate()) { //确保此时允许操作 + iVirtualRealityPslService.pressTheButton(simulation, + stand.getCode(), VirtualRealityPsl.Button.YXJZ); + } + if (open) { + iVirtualRealityPslService.pressTheButton(simulation, + stand.getCode(), VirtualRealityPsl.Button.KM); + } else { + iVirtualRealityPslService.pressTheButton(simulation, + stand.getCode(), VirtualRealityPsl.Button.GM); + } + if (vrPsl.isAllowOperate()) { //将允许禁止钥匙打到禁止位 + iVirtualRealityPslService.pressTheButton(simulation, + stand.getCode(), VirtualRealityPsl.Button.YXJZ); + } + } + } + } + + /** + * 机器人司机逻辑循环 + */ + private void robotDriverLogicLoop(Simulation simulation) { + List drivers = simulation.querySimulationMembersOfRole( + SimulationMember.Type.DRIVER); + for (SimulationMember driver : drivers) { // if (!driver.isRobot()) // continue; - SimulationDataRepository repository = simulation.getRepository(); - VirtualRealityTrain train = (VirtualRealityTrain) driver.getDevice(); - if (train.isTakeOver() || !repository.isVrTrainOnline(train.getGroupNumber())) { //如果列车被接管或不在线 - continue; - } - //准备发车 - robotReadyForDeparture(simulation, train); - //机器人驾驶 - if (train.isRobotNeedStop()) { - if (train.isStop()) { - train.getRobotDriveParam().setStop(false); - } else { - if (!train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位 - CommandBO.Step step = CommandBO.buildGearChangeStep(train.getGroupNumber(), VirtualRealityTrain.Handwheel.MANUAL); - atsOperationDispatcher.execute(simulation, driver, step.getOperationType().name(), step.getOperationParams()); - } - doBreakMax(simulation, train); - } - } else if (train.isRobotNeedRun() && (train.isRMMode() || train.isNRMMode())) { //CM应当根据推荐速度驾驶,待实现 - Optional targetPositionOptional = calculateTargetPosition(simulation, train); - targetPositionOptional.ifPresent(tp -> robotDrive(simulation, driver, train, tp)); - } - } - } - - /** - * 计算目标位置 - */ - private Optional calculateTargetPosition(Simulation simulation, VirtualRealityTrain train) { - DriveParamVO robotDriveParam = train.getRobotDriveParam(); - if (train.isEB()) { - if (!robotDriveParam.isReleaseEB()) { //列车EB了且没有要求解除EB - return Optional.empty(); - } + SimulationDataRepository repository = simulation.getRepository(); + VirtualRealityTrain train = (VirtualRealityTrain) driver.getDevice(); + if (train.isTakeOver() || !repository.isVrTrainOnline(train.getGroupNumber())) { //如果列车被接管或不在线 + continue; + } + //准备发车 + robotReadyForDeparture(simulation, train); + //机器人驾驶 + if (train.isRobotNeedStop()) { + if (train.isStop()) { + train.getRobotDriveParam().setStop(false); } else { - robotDriveParam.setReleaseEB(false); + if (!train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位 + CommandBO.Step step = CommandBO.buildGearChangeStep(train.getGroupNumber(), + VirtualRealityTrain.Handwheel.MANUAL); + atsOperationDispatcher.execute(simulation, driver, step.getOperationType().name(), + step.getOperationParams()); + } + doBreakMax(simulation, train); } + } else if (train.isRobotNeedRun() && (train.isRMMode() + || train.isNRMMode())) { //CM应当根据推荐速度驾驶,待实现 + Optional targetPositionOptional = calculateTargetPosition(simulation, + train); + targetPositionOptional.ifPresent(tp -> robotDrive(simulation, driver, train, tp)); + } + } + } - Set

plannedParkingSections = new HashSet<>(); //计划中的停车位置。当此字段不为空时,则计划外的站台轨不停车 - SimulationDataRepository repository = simulation.getRepository(); - SectionPosition headPosition = train.getHeadPosition(); - boolean right = train.isRight(); - if (repository.getConfig().isRailway()) { //如果是大铁线路,计划根据运行日志确定要停车的区段 - TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber()); - CtcRepository ctcRepository = simulation.getCtcRepository(); - Collection runPlans = ctcRepository.findRunPlans(trainInfo.getTripNumber()); - if (!CollectionUtils.isEmpty(runPlans)) { - for (CtcStationRunPlanLog runPlan : runPlans) { - CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); - if (arriveRunPlan != null) { - Section trackSection = arriveRunPlan.getTrackSection(); - if (!Objects.equals(trackSection, train.getParkSection())) { - plannedParkingSections.add(trackSection); - } - } - CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan(); - if (departRunPlan != null) { - Section trackSection = departRunPlan.getTrackSection(); - if (!Objects.equals(trackSection, train.getParkSection())) { - plannedParkingSections.add(trackSection); - } - } - } - } - } - - Signal throughSignal = robotDriveParam.getThroughSignal(); - SignalAspect throughAspect = robotDriveParam.getThroughSignalAspect(); - Section section = headPosition.getSection(); - if (throughSignal != null && !Objects.equals(section, throughSignal.getSection())) { //当车头与要越过的信号机不在同一区段 - throughSignal = null; - throughAspect = null; - robotDriveParam.setThrough(DriveParamVO.NO); - } - SectionPosition selectedPosition = robotDriveParam.getTargetPosition(); //用户选择的位置 - SectionPosition targetPosition = null; - for (int i = 0; i < 10; i++) { - if (section.isNormalStandTrack() && !section.equals(train.getParkSection())) { //正常站台轨且未在此处停过车 - if (CollectionUtils.isEmpty(plannedParkingSections) || plannedParkingSections.contains(section)) { - SectionPosition stopPosition = section.buildStopPointPosition(right); - if (targetPosition == null || stopPosition.isAheadOf(targetPosition, right)) { - if (headPosition.getOffset() < (section.getStopPointByDirection(right) + SimulationConstants.PARK_POINT_MAX_OFFSET)) { //防止意外开过站后无法发车 - targetPosition = stopPosition; - } - } - } - } - // 取禁止信号前停车位置与当前目标停车位置中更近的一个 - Signal signal = section.getSignalOf(right); - if (signal != null && !signal.isShunting()) { - VirtualRealitySignal vrSignal = signal.getVirtualSignal(); - SectionPosition signalPosition = signal.getPosition(); - if (vrSignal != null && (i != 0 || signalPosition.isAheadOf(headPosition, right))) { //有实体信号机且列车未越过信号机 - if (Objects.equals(vrSignal.getAspect(), signal.getDefaultAspect()) //禁止信号 - || Objects.equals(vrSignal.getAspect(), signal.getGuideAspect())) { //引导信号 - if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(), throughAspect)) { - SectionPosition noPassPosition = CalculateService - .calculateNextPositionByStartAndLen(signalPosition, !right, 2, true); - if (targetPosition == null || noPassPosition.isAheadOf(targetPosition, right)) { - targetPosition = noPassPosition; - } - } - } - } - } - - if (targetPosition == null) { - if (selectedPosition != null && section.equals(selectedPosition.getSection())) { //不会有比选定位置更靠前的停车点了 - targetPosition = selectedPosition; - } else { - Section tempSection = section.findNextRunningSectionBaseRealSwitch(right); - if (tempSection == null) { //到了轨道尽头,目标位置为尽头向内10m - targetPosition = new SectionPosition(section, right ? section.getLen() - 10 : 10); - } else { - section = tempSection; - } - } - } else { - if (selectedPosition != null && selectedPosition.isAheadOf(targetPosition, right)) { - targetPosition = selectedPosition; - } - } - if (targetPosition != null) { - break; - } - } - if (targetPosition == null) { //上方的区段遍历完后,即没有找到目标区段,也没有找到轨道尽头 - targetPosition = new SectionPosition(section, right ? 0 : section.getMaxOffset()); - } - return Optional.ofNullable(targetPosition); + /** + * 计算目标位置 + */ + private Optional calculateTargetPosition(Simulation simulation, + VirtualRealityTrain train) { + DriveParamVO robotDriveParam = train.getRobotDriveParam(); + if (train.isEB()) { + if (!robotDriveParam.isReleaseEB()) { //列车EB了且没有要求解除EB + return Optional.empty(); + } + } else { + robotDriveParam.setReleaseEB(false); } - private void releaseEB(Simulation simulation, SimulationMember driver, VirtualRealityTrain train) { - Operation.Type operationType = null; - Map param = null; - if (train.isSignalEB()) { - CommandBO.Step step = CommandBO.getStep4ReleaseEB(train); - if (step != null) { - operationType = step.getOperationType(); - param = step.getOperationParams(); + Set
plannedParkingSections = new HashSet<>(); //计划中的停车位置。当此字段不为空时,则计划外的站台轨不停车 + SimulationDataRepository repository = simulation.getRepository(); + SectionPosition headPosition = train.getHeadPosition(); + boolean right = train.isRight(); + if (repository.getConfig().isRailway()) { //如果是大铁线路,计划根据运行日志确定要停车的区段 + TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber()); + CtcRepository ctcRepository = simulation.getCtcRepository(); + Collection runPlans = ctcRepository.findRunPlans( + trainInfo.getTripNumber()); + if (!CollectionUtils.isEmpty(runPlans)) { + for (CtcStationRunPlanLog runPlan : runPlans) { + CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); + if (arriveRunPlan != null) { + Section trackSection = arriveRunPlan.getTrackSection(); + if (!Objects.equals(trackSection, train.getParkSection())) { + plannedParkingSections.add(trackSection); } + } + CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan(); + if (departRunPlan != null) { + Section trackSection = departRunPlan.getTrackSection(); + if (!Objects.equals(trackSection, train.getParkSection())) { + plannedParkingSections.add(trackSection); + } + } } - if (train.isCircuitEB()) { - operationType = Operation.Type.Driver_EB; - param = new HashMap<>(); - param.put("groupNumber", train.getGroupNumber()); - } - if (operationType != null) { - atsOperationDispatcher.execute(simulation, driver, operationType.name(), param); - } + } } - /** - * 机器人驾驶 - */ - private void robotDrive(Simulation simulation, SimulationMember driver, VirtualRealityTrain train, SectionPosition targetPosition) { - if (!train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位 - return; + Signal throughSignal = robotDriveParam.getThroughSignal(); + SignalAspect throughAspect = robotDriveParam.getThroughSignalAspect(); + Section section = headPosition.getSection(); + if (throughSignal != null && !Objects.equals(section, + throughSignal.getSection())) { //当车头与要越过的信号机不在同一区段 + throughSignal = null; + throughAspect = null; + robotDriveParam.setThrough(DriveParamVO.NO); + } + SectionPosition selectedPosition = robotDriveParam.getTargetPosition(); //用户选择的位置 + SectionPosition targetPosition = null; + for (int i = 0; i < 10; i++) { + if (section.isNormalStandTrack() && !section.equals(train.getParkSection())) { //正常站台轨且未在此处停过车 + if (CollectionUtils.isEmpty(plannedParkingSections) || plannedParkingSections.contains( + section)) { + SectionPosition stopPosition = section.buildStopPointPosition(right); + if (targetPosition == null || stopPosition.isAheadOf(targetPosition, right)) { + if (headPosition.getOffset() < (section.getStopPointByDirection(right) + + SimulationConstants.PARK_POINT_MAX_OFFSET)) { //防止意外开过站后无法发车 + targetPosition = stopPosition; + } + } + } + } + // 取禁止信号前停车位置与当前目标停车位置中更近的一个 + Signal signal = section.getSignalOf(right); + if (signal != null && !signal.isShunting()) { + VirtualRealitySignal vrSignal = signal.getVirtualSignal(); + SectionPosition signalPosition = signal.getPosition(); + if (vrSignal != null && (i != 0 || signalPosition.isAheadOf(headPosition, + right))) { //有实体信号机且列车未越过信号机 + if (Objects.equals(vrSignal.getAspect(), signal.getDefaultAspect()) //禁止信号 + || Objects.equals(vrSignal.getAspect(), signal.getGuideAspect())) { //引导信号 + if (!Objects.equals(signal, throughSignal) || !Objects.equals(vrSignal.getAspect(), + throughAspect)) { + SectionPosition noPassPosition = CalculateService + .calculateNextPositionByStartAndLen(signalPosition, !right, 2, true); + if (targetPosition == null || noPassPosition.isAheadOf(targetPosition, right)) { + targetPosition = noPassPosition; + } + } + } + } + } + + if (targetPosition == null) { + if (selectedPosition != null && section.equals( + selectedPosition.getSection())) { //不会有比选定位置更靠前的停车点了 + targetPosition = selectedPosition; + } else { + Section tempSection = section.findNextRunningSectionBaseRealSwitch(right); + if (tempSection == null) { //到了轨道尽头,目标位置为尽头向内10m + targetPosition = new SectionPosition(section, right ? section.getLen() - 10 : 10); + } else { + section = tempSection; + } + } + } else { + if (selectedPosition != null && selectedPosition.isAheadOf(targetPosition, right)) { + targetPosition = selectedPosition; + } + } + if (targetPosition != null) { + break; + } + } + if (targetPosition == null) { //上方的区段遍历完后,即没有找到目标区段,也没有找到轨道尽头 + targetPosition = new SectionPosition(section, right ? 0 : section.getMaxOffset()); + } + return Optional.ofNullable(targetPosition); + } + + private void releaseEB(Simulation simulation, SimulationMember driver, + VirtualRealityTrain train) { + Operation.Type operationType = null; + Map param = null; + if (train.isSignalEB()) { + CommandBO.Step step = CommandBO.getStep4ReleaseEB(train); + if (step != null) { + operationType = step.getOperationType(); + param = step.getOperationParams(); + } + } + if (train.isCircuitEB()) { + operationType = Operation.Type.Driver_EB; + param = new HashMap<>(); + param.put("groupNumber", train.getGroupNumber()); + } + if (operationType != null) { + atsOperationDispatcher.execute(simulation, driver, operationType.name(), param); + } + } + + /** + * 机器人驾驶 + */ + private void robotDrive(Simulation simulation, SimulationMember driver, VirtualRealityTrain train, + SectionPosition targetPosition) { + train.getRobotDriveParam().setStopPosition(targetPosition); + if (!train.isInTheGear(VirtualRealityTrain.Handwheel.MANUAL)) { //确保当前在手动档位 + return; // CommandBO.Step step = CommandBO.buildGearChangeStep(train.getGroupNumber(), VirtualRealityTrain.Handwheel.MANUAL); // atsOperationDispatcher.execute(simulation, driver, step.getOperationType().name(), step.getOperationParams()); - } - if (train.isEB()) { - if (train.getRobotDriveParam().isReleaseEB()) { - releaseEB(simulation, driver, train); - } else { - return; - } - } + } + if (train.isEB()) { + if (train.getRobotDriveParam().isReleaseEB()) { + releaseEB(simulation, driver, train); + } else { + return; + } + } - SimulationDataRepository repository = simulation.getRepository(); - SectionPosition headPosition = train.getHeadPosition(); - boolean right = train.isRight(); - float speed = train.getSpeed(); - if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock()) { //如果车门没关 - return; - } - /* - * 添加车辆停靠车站时,车门关闭后向前行驶一点的问题,因为车头偏移与目标偏移大于 @see SimulationConstants.PARK_POINT_MAX_OFFSET位置,故修正逻辑如下 - * 判断车辆是否停靠车站,没有开发的信号,没有新车命令,如果有其中一项的条件那么车辆可以启动 - * begin 2022-08-15 - */ - boolean trainPackingForStand = train.isParkingAt(); + SimulationDataRepository repository = simulation.getRepository(); + SectionPosition headPosition = train.getHeadPosition(); + boolean right = train.isRight(); + float speed = train.getSpeed(); + if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock()) { //如果车门没关 + return; + } + /* + * 添加车辆停靠车站时,车门关闭后向前行驶一点的问题,因为车头偏移与目标偏移大于 @see SimulationConstants.PARK_POINT_MAX_OFFSET位置,故修正逻辑如下 + * 判断车辆是否停靠车站,没有开发的信号,没有新车命令,如果有其中一项的条件那么车辆可以启动 + * begin 2022-08-15 + */ + boolean trainPackingForStand = train.isParkingAt(); // headPosition.getSection().getStandList().stream().anyMatch(d->d.isTrainParking()); - Signal targetSignal = headPosition.getSection().getSignalOf(right); - boolean closeSignal = false; - if(Objects.nonNull(targetSignal)){ - closeSignal = targetSignal.getAspect() == targetSignal.getSignalModel().getDefaultAspect(); - } - boolean noCommond = Objects.isNull(train.getRobotDriveParam().getThroughSignal()); - if(trainPackingForStand && closeSignal && noCommond){ - return; - } - /* - * end 2022-08-15 - */ - Float distance = CalculateService.calculateDistance(headPosition, targetPosition, right, true); - if (distance == null || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置 - atoService.doBreakMax(train); - return; - } - - SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), true); - SpeedCurve speedCurve = null; - switch (train.getDriveMode()) { - case AM: //AM模式下不需要司机驾驶 - return; - case CM: - MaService.Ma ma = train.getMa2(); - if (ma != null) { - speedCurve = ma.getAtoStopCurve(); - } - break; - case RM: - speedCurve = SpeedCurve.buildTargetSpeedCurve(headPosition, tailPosition, right, - distance, speed, Math.min(repository.getConfig().getRmAtpSpeed(), train.getSpeedLimitInMs()) * 0.9f); - break; - case NRM: - speedCurve = SpeedCurve.buildTargetSpeedCurve(headPosition, tailPosition, right, - distance, speed, Math.min(repository.getConfig().getUrmAtpSpeed(), train.getSpeedLimitInMs()) * 0.9f); - break; - default: - return; - } - train.setTargetDistance(distance); - if (speedCurve != null) { - float atoSpeed = speedCurve.getSpeedOf(speedCurve.getTotalDistance()); - atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), atoSpeed); - } + Signal targetSignal = headPosition.getSection().getSignalOf(right); + boolean closeSignal = false; + if (Objects.nonNull(targetSignal)) { + closeSignal = targetSignal.getAspect() == targetSignal.getSignalModel().getDefaultAspect(); } - - /** - * 机器人回复控制权转换申请逻辑循环 + boolean noCommond = Objects.isNull(train.getRobotDriveParam().getThroughSignal()); + if (trainPackingForStand && closeSignal && noCommond) { + return; + } + /* + * end 2022-08-15 */ - private void robotReplyControlTransferApplicationLogicLoop(Simulation simulation) { - if (simulation.getScript() != null && simulation.getScript().isBgSet()) { - return; - } - // 实训场景模式,已设置背景处于编制状态的实训,不做自动转换处理 - Training2 training2 = simulation.getTraining2(); - if (training2 != null && training2.isScene() && StringUtils.hasText(training2.getBgSceneJson()) && !training2.isRunning()) { - return; - } - Map> collect = simulation.getRepository().getStationList().stream() - .filter(station -> station.getApplicant() != null).collect(Collectors.groupingBy(Station::getApplicant)); - - for (Map.Entry> entry : collect.entrySet()) { - if (entry.getValue().get(0).getValidDuration() > SimulationConstants.CONTROL_TRANSFER_VALID_DURATION - 2 * 1000) { //延时通过申请 - continue; - } - if (SimulationMember.Type.DISPATCHER.equals(entry.getKey().getType())) { //如果申请者是行调 - for (Station station : entry.getValue()) { - List supervisors = simulation.getSimulationMembersByDevice(station); - if (supervisors.stream().allMatch(SimulationMember::isRobot)) { - List replyVOList = Collections.singletonList(new ControlTransferReplyVO(station.getCode(), true)); - this.robotReplyControlTransferApplication(simulation, replyVOList, station.getApply2TheControlMode()); - } - } - } - if (SimulationMember.Type.STATION_SUPERVISOR.equals(entry.getKey().getType())) { //如果申请者是行值 - List dispatchers = simulation.getMemberListByType(SimulationMember.Type.DISPATCHER); - if (dispatchers.stream().anyMatch(dispatcher -> !dispatcher.isRobot())) { //有任何一个行调不是机器人 - continue; - } - List replyVOList = entry.getValue() - .stream().map(station -> new ControlTransferReplyVO(station.getCode(), true)).collect(Collectors.toList()); - this.robotReplyControlTransferApplication(simulation, replyVOList, entry.getValue().get(0).getApply2TheControlMode()); - } - } + Float distance = CalculateService.calculateDistance(headPosition, targetPosition, right, true); + if (distance == null + || distance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //如果列车已经抵达或越过目标位置 + atoService.doBreakMax(train); + return; } - /** - * 机器人自动执行车站控制权限转移 - */ - private void robotStationControlAutoTransfer(Simulation simulation) { - if (simulation.getScript() != null && simulation.getScript().isBgSet()) { - return; + SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, + !right, train.getLen(), true); + SpeedCurve speedCurve = null; + switch (train.getDriveMode()) { + case AM: //AM模式下不需要司机驾驶 + return; + case CM: + MaService.Ma ma = train.getMa2(); + if (ma != null) { + speedCurve = ma.getAtoStopCurve(); } - Map> robotControlStations = simulation.getRepository().getStationList().stream() - .filter(station -> Objects.nonNull(station.getController()) && station.getController().isRobot() && Objects.nonNull(station.getControlApplicant())) - .collect(Collectors.groupingBy(Station::getController)); - robotControlStations.forEach((controler, stations) -> { - atsStationService.transferControl(simulation, stations.stream().map(Station::getCode).collect(Collectors.toList()), true, controler); - }); + break; + case RM: + speedCurve = SpeedCurve.buildTargetSpeedCurve(headPosition, tailPosition, right, + distance, speed, + Math.min(repository.getConfig().getRmAtpSpeed(), train.getSpeedLimitInMs()) * 0.9f); + break; + case NRM: + speedCurve = SpeedCurve.buildTargetSpeedCurve(headPosition, tailPosition, right, + distance, speed, + Math.min(repository.getConfig().getUrmAtpSpeed(), train.getSpeedLimitInMs()) * 0.9f); + break; + default: + return; } + train.setTargetDistance(distance); + if (speedCurve != null) { + float atoSpeed = speedCurve.getSpeedOf(speedCurve.getTotalDistance()); + atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), atoSpeed); + } + } - /** - * 机器人回复控制权转换申请 - * - * @param controlMode 申请转到该控制模式 - */ - private void robotReplyControlTransferApplication(Simulation simulation, List replyVOList, Station.ControlMode controlMode) { - switch (controlMode) { - case Center: - atsStationService.replyForCenterControl(simulation, replyVOList); - break; - case Local: - atsStationService.replyForStationControl(simulation, replyVOList); - break; - default: + /** + * 机器人回复控制权转换申请逻辑循环 + */ + private void robotReplyControlTransferApplicationLogicLoop(Simulation simulation) { + if (simulation.getScript() != null && simulation.getScript().isBgSet()) { + return; + } + // 实训场景模式,已设置背景处于编制状态的实训,不做自动转换处理 + Training2 training2 = simulation.getTraining2(); + if (training2 != null && training2.isScene() && StringUtils.hasText(training2.getBgSceneJson()) + && !training2.isRunning()) { + return; + } + Map> collect = simulation.getRepository().getStationList() + .stream() + .filter(station -> station.getApplicant() != null) + .collect(Collectors.groupingBy(Station::getApplicant)); + + for (Map.Entry> entry : collect.entrySet()) { + if (entry.getValue().get(0).getValidDuration() + > SimulationConstants.CONTROL_TRANSFER_VALID_DURATION - 2 * 1000) { //延时通过申请 + continue; + } + if (SimulationMember.Type.DISPATCHER.equals(entry.getKey().getType())) { //如果申请者是行调 + for (Station station : entry.getValue()) { + List supervisors = simulation.getSimulationMembersByDevice(station); + if (supervisors.stream().allMatch(SimulationMember::isRobot)) { + List replyVOList = Collections.singletonList( + new ControlTransferReplyVO(station.getCode(), true)); + this.robotReplyControlTransferApplication(simulation, replyVOList, + station.getApply2TheControlMode()); + } } - } - - /** - * 机器人执行车站分散自律模式操作方式转换 - */ - private void robotStationOperationModel(Simulation simulation) { - if (simulation.getScript() != null && simulation.getScript().isBgSet()) { - return; + } + if (SimulationMember.Type.STATION_SUPERVISOR.equals(entry.getKey().getType())) { //如果申请者是行值 + List dispatchers = simulation.getMemberListByType( + SimulationMember.Type.DISPATCHER); + if (dispatchers.stream().anyMatch(dispatcher -> !dispatcher.isRobot())) { //有任何一个行调不是机器人 + continue; } - // 实训场景模式,已设置背景处于编制状态的实训,不做自动转换处理 - Training2 training2 = simulation.getTraining2(); - if (training2 != null && training2.isScene() && StringUtils.hasText(training2.getBgSceneJson()) && !training2.isRunning()) { - return; - } - // 非单岗位一直等待角色同意 - if (!simulation.getBuildParams().getWorkParamVO().getDomConfig().isSingleMember()) { - return; - } - simulation.getRepository().getStationList().stream() - // 申请不为空、审批人全部为机器人 - .filter(station -> station.getOperationModeApplication() != null && station.getOperationModeApplication().isRobotApproval()) - .forEach(station -> atsStationService.doOperationModeSwitch(station)); + List replyVOList = entry.getValue() + .stream().map(station -> new ControlTransferReplyVO(station.getCode(), true)) + .collect(Collectors.toList()); + this.robotReplyControlTransferApplication(simulation, replyVOList, + entry.getValue().get(0).getApply2TheControlMode()); + } } + } - private void doControlBySpeedCurve(Simulation simulation, VirtualRealityTrain train, SpeedCurve speedCurve, float remainDistance) { - if (speedCurve.equals(SpeedCurve.ZERO)) { - this.doBreakMax(simulation, train); - return; - } - SpeedCurve.SpeedCalculator calculator = speedCurve.getCalculatorOf(remainDistance); - if (calculator.getVt() == 0 && remainDistance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //末速度为0且当前距终点距离在停车误差内 - this.doBreakMax(simulation, train); - return; - } - float speed = train.getSpeed(); - if (speed == 0) { - this.doStart(simulation, train); - return; - } - float atoSpeed = train.getAtoSpeed(); - float acceleration = calculator.getAcceleration(); - float diff = speed - atoSpeed; - if (acceleration == 0) { //匀速段 - if (diff <= -0.1) { //当前速度远小于目标速度 - this.doAccelerateMax(simulation, train); - } else if (diff < 0) { //当前速度略小于目标速度 - this.doAccelerate(simulation, train, 0.1f); - } else if (0 == diff) { - this.doIdle(simulation, train); - } else if (diff < 0.1) { //当前速度略大于目标速度 - this.doBreak(simulation, train, -0.1f); - } else { - this.doBreakMax(simulation, train); //当前速度远大于目标速度 - } - } else { //减速段 - if (diff <= -0.1) { //当前速度远小于目标速度 - this.doAccelerateMax(simulation, train); - } else if (diff < 0) { //当前速度略小于目标速度 - this.doBreak(simulation, train, Math.abs(acceleration) - 0.1f); - } else if (0 == diff) { - this.doBreak(simulation, train, Math.abs(acceleration)); - } else if (diff < 0.1) { //当前速度略大于目标速度 - this.doBreak(simulation, train, Math.abs(acceleration) + 0.1f); - } else { - this.doBreakMax(simulation, train); //当前速度远大于目标速度 - } - } + /** + * 机器人自动执行车站控制权限转移 + */ + private void robotStationControlAutoTransfer(Simulation simulation) { + if (simulation.getScript() != null && simulation.getScript().isBgSet()) { + return; } + Map> robotControlStations = simulation.getRepository() + .getStationList().stream() + .filter( + station -> Objects.nonNull(station.getController()) && station.getController().isRobot() + && Objects.nonNull(station.getControlApplicant())) + .collect(Collectors.groupingBy(Station::getController)); + robotControlStations.forEach((controler, stations) -> { + atsStationService.transferControl(simulation, + stations.stream().map(Station::getCode).collect(Collectors.toList()), true, controler); + }); + } - /** - * 列车启动 - * - * @param simulation - * @param train - */ - private void doStart(Simulation simulation, VirtualRealityTrain train) { - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), 1f); + /** + * 机器人回复控制权转换申请 + * + * @param controlMode 申请转到该控制模式 + */ + private void robotReplyControlTransferApplication(Simulation simulation, + List replyVOList, Station.ControlMode controlMode) { + switch (controlMode) { + case Center: + atsStationService.replyForCenterControl(simulation, replyVOList); + break; + case Local: + atsStationService.replyForStationControl(simulation, replyVOList); + break; + default: } + } - /** - * 惰行(不牵引,不制动) - * - * @param simulation - * @param train - */ - private void doIdle(Simulation simulation, VirtualRealityTrain train) { - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), 0f); + /** + * 机器人执行车站分散自律模式操作方式转换 + */ + private void robotStationOperationModel(Simulation simulation) { + if (simulation.getScript() != null && simulation.getScript().isBgSet()) { + return; } + // 实训场景模式,已设置背景处于编制状态的实训,不做自动转换处理 + Training2 training2 = simulation.getTraining2(); + if (training2 != null && training2.isScene() && StringUtils.hasText(training2.getBgSceneJson()) + && !training2.isRunning()) { + return; + } + // 非单岗位一直等待角色同意 + if (!simulation.getBuildParams().getWorkParamVO().getDomConfig().isSingleMember()) { + return; + } + simulation.getRepository().getStationList().stream() + // 申请不为空、审批人全部为机器人 + .filter(station -> station.getOperationModeApplication() != null + && station.getOperationModeApplication().isRobotApproval()) + .forEach(station -> atsStationService.doOperationModeSwitch(station)); + } - private void doAccelerateMax(Simulation simulation, VirtualRealityTrain train) { - this.doAccelerate(simulation, train, VirtualRealityTrain.Stable_Acceleration); + private void doControlBySpeedCurve(Simulation simulation, VirtualRealityTrain train, + SpeedCurve speedCurve, float remainDistance) { + if (speedCurve.equals(SpeedCurve.ZERO)) { + this.doBreakMax(simulation, train); + return; } + SpeedCurve.SpeedCalculator calculator = speedCurve.getCalculatorOf(remainDistance); + if (calculator.getVt() == 0 + && remainDistance <= SimulationConstants.PARK_POINT_MAX_OFFSET) { //末速度为0且当前距终点距离在停车误差内 + this.doBreakMax(simulation, train); + return; + } + float speed = train.getSpeed(); + if (speed == 0) { + this.doStart(simulation, train); + return; + } + float atoSpeed = train.getAtoSpeed(); + float acceleration = calculator.getAcceleration(); + float diff = speed - atoSpeed; + if (acceleration == 0) { //匀速段 + if (diff <= -0.1) { //当前速度远小于目标速度 + this.doAccelerateMax(simulation, train); + } else if (diff < 0) { //当前速度略小于目标速度 + this.doAccelerate(simulation, train, 0.1f); + } else if (0 == diff) { + this.doIdle(simulation, train); + } else if (diff < 0.1) { //当前速度略大于目标速度 + this.doBreak(simulation, train, -0.1f); + } else { + this.doBreakMax(simulation, train); //当前速度远大于目标速度 + } + } else { //减速段 + if (diff <= -0.1) { //当前速度远小于目标速度 + this.doAccelerateMax(simulation, train); + } else if (diff < 0) { //当前速度略小于目标速度 + this.doBreak(simulation, train, Math.abs(acceleration) - 0.1f); + } else if (0 == diff) { + this.doBreak(simulation, train, Math.abs(acceleration)); + } else if (diff < 0.1) { //当前速度略大于目标速度 + this.doBreak(simulation, train, Math.abs(acceleration) + 0.1f); + } else { + this.doBreakMax(simulation, train); //当前速度远大于目标速度 + } + } + } - /** - * 列车加速 - */ - private void doAccelerate(Simulation simulation, VirtualRealityTrain train, float a) { - float fk = a * train.getMass(); - float fkMax = train.getCurrentFkMax(); - fk = Math.min(fk, fkMax); - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), Math.min(fk / fkMax, 1)); - } + /** + * 列车启动 + * + * @param simulation + * @param train + */ + private void doStart(Simulation simulation, VirtualRealityTrain train) { + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), 1f); + } - private void doBreakMax(Simulation simulation, VirtualRealityTrain train) { - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), -1f); - } + /** + * 惰行(不牵引,不制动) + * + * @param simulation + * @param train + */ + private void doIdle(Simulation simulation, VirtualRealityTrain train) { + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), 0f); + } - /** - * 列车制动 - */ - private void doBreak(Simulation simulation, VirtualRealityTrain train, float a) { - a = -Math.abs(a); - float fb = train.getMass() * a; - float fbMax = train.getCurrentFbMax(); - driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), Math.max(fb / fbMax, -1)); - } + private void doAccelerateMax(Simulation simulation, VirtualRealityTrain train) { + this.doAccelerate(simulation, train, VirtualRealityTrain.Stable_Acceleration); + } - public void addJobs(Simulation simulation) { - simulation.addJob(SimulationModule.ROBOT.name(), () -> this.run(simulation), SimulationConstants.ROBOT_LOGIC_LOOP_RATE); - } + /** + * 列车加速 + */ + private void doAccelerate(Simulation simulation, VirtualRealityTrain train, float a) { + float fk = a * train.getMass(); + float fkMax = train.getCurrentFkMax(); + fk = Math.min(fk, fkMax); + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), + Math.min(fk / fkMax, 1)); + } - public void stopTrain(Simulation simulation, SimulationMember simulationMember, String groupNumber, Boolean eb) { - SimulationDataRepository repository = simulation.getRepository(); - VirtualRealityTrain train = repository.getOnlineTrainBy(groupNumber); - if (Objects.equals(true, eb)) { - Map param = new HashMap<>(); - param.put("groupNumber", train.getGroupNumber()); - atsOperationDispatcher.execute(simulation, simulationMember, Operation.Type.Driver_EB.name(), param); - } else { - train.getRobotDriveParam().setStop(true); - } - train.getRobotDriveParam().setRun(false); + private void doBreakMax(Simulation simulation, VirtualRealityTrain train) { + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), -1f); + } + + /** + * 列车制动 + */ + private void doBreak(Simulation simulation, VirtualRealityTrain train, float a) { + a = -Math.abs(a); + float fb = train.getMass() * a; + float fbMax = train.getCurrentFbMax(); + driverOperateHandler.changeTrainForce(simulation, train.getGroupNumber(), + Math.max(fb / fbMax, -1)); + } + + public void addJobs(Simulation simulation) { + simulation.addJob(SimulationModule.ROBOT.name(), () -> this.run(simulation), + SimulationConstants.ROBOT_LOGIC_LOOP_RATE); + } + + public void stopTrain(Simulation simulation, SimulationMember simulationMember, + String groupNumber, Boolean eb) { + SimulationDataRepository repository = simulation.getRepository(); + VirtualRealityTrain train = repository.getOnlineTrainBy(groupNumber); + if (Objects.equals(true, eb)) { + Map param = new HashMap<>(); + param.put("groupNumber", train.getGroupNumber()); + atsOperationDispatcher.execute(simulation, simulationMember, Operation.Type.Driver_EB.name(), + param); + } else { + train.getRobotDriveParam().setStop(true); } + train.getRobotDriveParam().setRun(false); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/work/MetroSimulationWorkServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/work/MetroSimulationWorkServiceImpl.java index d38d75951..445ca2a5c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/work/MetroSimulationWorkServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/work/MetroSimulationWorkServiceImpl.java @@ -1,9 +1,12 @@ package club.joylink.rtss.simulation.cbtc.work; -import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.entity.Ibp; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; -import club.joylink.rtss.services.*; +import club.joylink.rtss.services.ICommandService; +import club.joylink.rtss.services.ILoadPlanService; +import club.joylink.rtss.services.IMapService; +import club.joylink.rtss.services.IRunPlanTemplateService; +import club.joylink.rtss.services.IVirtualRealityIbpService; import club.joylink.rtss.services.iscs.IscsDeviceService; import club.joylink.rtss.services.iscs.IscsSystemResourcesService; import club.joylink.rtss.services.project.DeviceService; @@ -15,12 +18,16 @@ import club.joylink.rtss.services.simulation.SchedulingService; import club.joylink.rtss.services.training.ITrainingV1Service; import club.joylink.rtss.simulation.cbtc.ATS.ATSLogicLoop; import club.joylink.rtss.simulation.cbtc.ATS.ATSMessageCollectAndDispatcher; -import club.joylink.rtss.simulation.cbtc.ATS.service.alarm.NccAlarmService; import club.joylink.rtss.simulation.cbtc.ATS.ATSTrainMessageDiagram; +import club.joylink.rtss.simulation.cbtc.ATS.service.alarm.NccAlarmService; import club.joylink.rtss.simulation.cbtc.CI.CiLogic; -import club.joylink.rtss.simulation.cbtc.*; +import club.joylink.rtss.simulation.cbtc.DeviceStatusService; +import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.ISCS.IscsLogicLoop; import club.joylink.rtss.simulation.cbtc.ISCS.IscsMessageCollectAndDispatcher; +import club.joylink.rtss.simulation.cbtc.PowerSupplyService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService; import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams; import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder; import club.joylink.rtss.simulation.cbtc.build.UserConfigDataBuilder; @@ -28,7 +35,6 @@ import club.joylink.rtss.simulation.cbtc.communication.Joylink3DMessageService; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.depot.DepotService; 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.udp.UDPRealDeviceThread; import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop; import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService; @@ -48,7 +54,6 @@ import club.joylink.rtss.vo.client.CommandDefinitionVO; import club.joylink.rtss.vo.client.iscs.device.IscsDeviceVO; import club.joylink.rtss.vo.client.iscs.systemRes.IscsSystemResourcesQueryVO; import club.joylink.rtss.vo.client.iscs.systemRes.IscsSystemResourcesVO; -import club.joylink.rtss.vo.client.project.ProjectDeviceVO; import club.joylink.rtss.vo.client.runplan.RunPlanLoadVO; import club.joylink.rtss.vo.client.runplan.RunPlanVO; import club.joylink.rtss.vo.client.runplan.user.RunPlanParkingTimeVO; @@ -56,18 +61,16 @@ import club.joylink.rtss.vo.client.runplan.user.RunPlanRunlevelVO; import club.joylink.rtss.vo.client.schedulingNew.SchedulingPlanNewVO; import club.joylink.rtss.vo.client.simulationv1.RunAsPlanParam; import club.joylink.rtss.vo.map.MapVO; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; @Slf4j @Service @@ -190,12 +193,7 @@ public class MetroSimulationWorkServiceImpl implements SimulationWorkService { simulationWorkServiceManager.buildMember(simulation); // 添加项目设备 if (buildParams.getWorkParamVO().containsRealDeviceItem()) { - List projectDeviceList = this.deviceService - .queryDetailByTypes(ProjectDeviceType.PlcDeviceList(), buildParams.getMap().getProjectCode()); - List realDeviceList = ProjectDeviceVO.convert2RealDeviceList(projectDeviceList); - log.info(String.format("load project device list: [%s]", - realDeviceList.stream().map(Object::toString).collect(Collectors.joining(",")))); - this.loadRealDevices(simulation, realDeviceList); + simulationWorkServiceManager.loadRealDevices(simulation); } } @@ -491,29 +489,4 @@ public class MetroSimulationWorkServiceImpl implements SimulationWorkService { } }); } - - private void loadRealDevices(Simulation simulation, List realDeviceList) { - try { - simulation.setRealDeviceList(realDeviceList); - if (!CollectionUtils.isEmpty(realDeviceList)) { - simulationRealDeviceThread.addJobs(simulation); - udpRealDeviceThread.addJobs(simulation); - } - for (RealDeviceConfig realDevice : realDeviceList) { - if (ProjectDeviceType.PLC_GATEWAY.equals(realDevice.getDeviceType())) { - continue; - } - String deviceCode = realDevice.findDeviceCode(); - if (Objects.nonNull(deviceCode)) { - this.groupSimulationService.connectDevice(simulation.getId(), - deviceCode, realDevice.getProjectDevice().getId()); - } - } - } catch (Exception e) { - log.error("仿真加载真实设备异常", e); - // 清理仿真 - this.groupSimulationService.clearSimulation(simulation.getId(), simulation.getCreator()); - throw BusinessExceptionAssertEnum.TRAINING_ROOM_SIMULATION_LOAD_DEVICE_ERROR.exception(e); - } - } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/work/RailwaySimulationWorkServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/work/RailwaySimulationWorkServiceImpl.java index a05456705..7e07743ed 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/work/RailwaySimulationWorkServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/work/RailwaySimulationWorkServiceImpl.java @@ -33,17 +33,16 @@ import club.joylink.rtss.vo.map.MapGraphDataNewVO; import club.joylink.rtss.vo.map.MapLogicDataNewVO; import club.joylink.rtss.vo.map.MapVO; import club.joylink.rtss.websocket.StompMessageService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - import java.time.LocalDateTime; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; @Slf4j @Service @@ -101,16 +100,20 @@ public class RailwaySimulationWorkServiceImpl implements SimulationWorkService { @Override public void loadData(Simulation simulation) { - SimulationBuildParams params = simulation.getBuildParams(); + SimulationBuildParams buildParams = simulation.getBuildParams(); // 加载地图数据 loadMapData(simulation); // // 车辆段 // depotService.loadDepotTrain(simulation); // 添加仿真用户 - SimulationUser creator = SimulationUser.buildCreator(simulation, params.getLoginUserInfo()); + SimulationUser creator = SimulationUser.buildCreator(simulation, buildParams.getLoginUserInfo()); simulation.addSimulationUser(creator); // 添加仿真成员 simulationWorkServiceManager.buildMember(simulation); + // 添加项目设备 + if (buildParams.getWorkParamVO().containsRealDeviceItem()) { + simulationWorkServiceManager.loadRealDevices(simulation); + } } @Override diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/work/SimulationWorkServiceManager.java b/src/main/java/club/joylink/rtss/simulation/cbtc/work/SimulationWorkServiceManager.java index d6c296c36..ace5169f9 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/work/SimulationWorkServiceManager.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/work/SimulationWorkServiceManager.java @@ -1,13 +1,26 @@ package club.joylink.rtss.simulation.cbtc.work; +import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.services.project.DeviceService; +import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; +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.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.SimulationUser; +import club.joylink.rtss.vo.client.project.ProjectDeviceVO; import club.joylink.rtss.vo.map.graph.MapMemberVO; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; @@ -18,11 +31,11 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - +/** + * 仿真工作服务管理。 + * 1.管理仿真工作服务的实现类 + * 2.各种仿真的公共方法 + */ @Slf4j @Component public class SimulationWorkServiceManager implements ApplicationContextAware { @@ -30,6 +43,14 @@ public class SimulationWorkServiceManager implements ApplicationContextAware { private MemberManager memberManager; @Autowired private ApplicationContext applicationContext; + @Autowired + private DeviceService deviceService; + @Autowired + private GroupSimulationService groupSimulationService; + @Autowired + private SimulationRealDeviceThread simulationRealDeviceThread; + @Autowired + private UDPRealDeviceThread udpRealDeviceThread; private Map map; @@ -95,4 +116,39 @@ public class SimulationWorkServiceManager implements ApplicationContextAware { SimulationUserEnterEvent userEnterEvent = new SimulationUserEnterEvent(this, simulation, simulationUser); this.applicationContext.publishEvent(userEnterEvent); } + + public void loadRealDevices(Simulation simulation) { + SimulationBuildParams buildParams = simulation.getBuildParams(); + List projectDeviceList = this.deviceService + .queryDetailByTypes(ProjectDeviceType.PlcDeviceList(), buildParams.getMap().getProjectCode()); + List realDeviceList = ProjectDeviceVO.convert2RealDeviceList(projectDeviceList); + log.info(String.format("load project device list: [%s]", + realDeviceList.stream().map(Object::toString).collect(Collectors.joining(",")))); + this.loadRealDevices(simulation, realDeviceList); + } + + private void loadRealDevices(Simulation simulation, List realDeviceList) { + try { + simulation.setRealDeviceList(realDeviceList); + if (!CollectionUtils.isEmpty(realDeviceList)) { + simulationRealDeviceThread.addJobs(simulation); + udpRealDeviceThread.addJobs(simulation); + } + for (RealDeviceConfig realDevice : realDeviceList) { + if (ProjectDeviceType.PLC_GATEWAY.equals(realDevice.getDeviceType())) { + continue; + } + String deviceCode = realDevice.findDeviceCode(); + if (Objects.nonNull(deviceCode)) { + this.groupSimulationService.connectDevice(simulation.getId(), + deviceCode, realDevice.getProjectDevice().getId()); + } + } + } catch (Exception e) { + log.error("仿真加载真实设备异常", e); + // 清理仿真 + this.groupSimulationService.clearSimulation(simulation.getId(), simulation.getCreator()); + throw BusinessExceptionAssertEnum.TRAINING_ROOM_SIMULATION_LOAD_DEVICE_ERROR.exception(e); + } + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/operation/DriveParamVO.java b/src/main/java/club/joylink/rtss/vo/client/operation/DriveParamVO.java index 849a934e4..b9d5e610b 100644 --- a/src/main/java/club/joylink/rtss/vo/client/operation/DriveParamVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/operation/DriveParamVO.java @@ -16,107 +16,127 @@ import lombok.Setter; @Setter @NoArgsConstructor public class DriveParamVO { - /** - * 限速值(km/h) - */ - private Float speedLimit; - /** - * 限速值(m/s) - */ - @JsonIgnore - @Setter(value = AccessLevel.NONE) - private float speedLimitInMs = Float.MAX_VALUE; + /** + * 限速值(km/h) + */ + private Float speedLimit; - /** - * 下令停车(优先级比运行高) - */ - @JsonIgnore - private boolean stop; + /** + * 限速值(m/s) + */ + @JsonIgnore + @Setter(value = AccessLevel.NONE) + private float speedLimitInMs = Float.MAX_VALUE; - /** - * 下令驾驶 - */ - @JsonIgnore - private boolean run = true; + /** + * 下令停车(优先级比运行高) + */ + @JsonIgnore + private boolean stop; - /** - * 目标设备code(用于确定目标位置) - */ - private String targetDeviceCode; + /** + * 下令驾驶 + */ + @JsonIgnore + private boolean run = true; - /** - * 根据目标设备code计算出的目标位置 - */ - @JsonIgnore - private SectionPosition targetPosition; + /** + * 目标设备code(用于确定目标位置) + */ + private String targetDeviceCode; - /** - * 越过信号机 - */ - private int through; + /** + * 根据目标设备code计算出的目标位置 + */ + @JsonIgnore + private SectionPosition targetPosition; - public static final int NO = 0; - public static final int RED_SIGNAL = 1; - public static final int GUIDE_SIGNAL = 2; - public static final int DRIVER_NEXT_STAND = 3; - public static final int DRIVER_ROUTE_BLOCK = 4; + /** + * 越过信号机 + */ + private int through; - /** - * 要越过的信号机 - */ - @JsonIgnore - private Signal throughSignal; + /** + * 这个停车位置是机器人驾驶逻辑计算出来的,这个字段仅供泰国沙盘的列车逻辑使用。 + */ + @JsonIgnore + private SectionPosition stopPosition; - /** - * 要越过的信号 - */ - @JsonIgnore - private SignalAspect throughSignalAspect; - /** - * 解除EB(目的是在且仅在每次进行驾驶操作后自动缓解当时存在的EB) - */ - @JsonIgnore - private boolean releaseEB = true; + public static final int NO = 0; + public static final int RED_SIGNAL = 1; + public static final int GUIDE_SIGNAL = 2; + public static final int DRIVER_NEXT_STAND = 3; + public static final int DRIVER_ROUTE_BLOCK = 4; - public void setSpeedLimit(Float speedLimit) { - this.speedLimit = speedLimit; - this.speedLimitInMs = speedLimit == null ? Float.MAX_VALUE : speedLimit / 3.6f; + /** + * 要越过的信号机 + */ + @JsonIgnore + private Signal throughSignal; + + /** + * 要越过的信号 + */ + @JsonIgnore + private SignalAspect throughSignalAspect; + /** + * 解除EB(目的是在且仅在每次进行驾驶操作后自动缓解当时存在的EB) + */ + @JsonIgnore + private boolean releaseEB = true; + + public void setSpeedLimit(Float speedLimit) { + this.speedLimit = speedLimit; + this.speedLimitInMs = speedLimit == null ? Float.MAX_VALUE : speedLimit / 3.6f; + } + + /** + * 让机器人驾驶逻辑停止控制该列车 + */ + public void stopControl() { + stop = false; + run = false; + } + + @JsonIgnore + public boolean isStopControl() { + return !stop && !run; + } + + public boolean needStop() { + return stop; + } + + public boolean needRun() { + return !stop && run; + } + + public void setThrough(int v) { + this.through = v; + if (through == NO) { + throughSignal = null; + throughSignalAspect = null; } + } - public boolean needStop() { - return stop; - } + @JsonIgnore + public boolean isThroughRedSignal() { + return RED_SIGNAL == through; + } - public boolean needRun() { - return !stop && run; - } + @JsonIgnore + public boolean isThroughGuideSignal() { + return GUIDE_SIGNAL == through; + } - public void setThrough(int v) { - this.through = v; - if (through == NO) { - throughSignal = null; - throughSignalAspect = null; - } - } + @JsonIgnore + public boolean isDriverNextStand() { + return DRIVER_NEXT_STAND == through; + } - @JsonIgnore - public boolean isThroughRedSignal() { - return RED_SIGNAL == through; - } - - @JsonIgnore - public boolean isThroughGuideSignal() { - return GUIDE_SIGNAL == through; - } - - @JsonIgnore - public boolean isDriverNextStand() { - return DRIVER_NEXT_STAND == through; - } - - @JsonIgnore - public boolean isRouteBlockDriver() { - return DRIVER_ROUTE_BLOCK == through; - } + @JsonIgnore + public boolean isRouteBlockDriver() { + return DRIVER_ROUTE_BLOCK == through; + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/project/ProjectDeviceVO.java b/src/main/java/club/joylink/rtss/vo/client/project/ProjectDeviceVO.java index a9278d27d..f5c779178 100644 --- a/src/main/java/club/joylink/rtss/vo/client/project/ProjectDeviceVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/project/ProjectDeviceVO.java @@ -1,5 +1,6 @@ package club.joylink.rtss.vo.client.project; +import club.joylink.rtss.constants.ProjectCode; import club.joylink.rtss.constants.ProjectDeviceType; import club.joylink.rtss.entity.ProjectDevice; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; @@ -9,10 +10,18 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.gxsd.GxsdSignalCo import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.gxsd.GxsdSwitchConfig; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.gzb.GzbSignalConfig; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.gzb.GzbSwitchConfig; -import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.*; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1IbpConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1PscConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1PslConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1SignalConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.heb.device.Heb1SwitchConfig; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.hhcj.HhcjIbpConfig; import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.hhcj.HhcjPsdConfig; -import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.*; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.SayIbpConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.SayPsdConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.SaySectionConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.SaySignalConfig; +import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.say.SaySwitchConfig; 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; @@ -25,8 +34,17 @@ import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrSectionConf import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrSignalConfig; import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrSwitchConfig; import club.joylink.rtss.simulation.cbtc.device.real.udp.sr.config.SrTrainConfig; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSectionConfig; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSignalConfig; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandSwitchConfig; +import club.joylink.rtss.simulation.cbtc.device.real.udp.thailand.config.ThailandTrainConfig; import club.joylink.rtss.util.JsonUtils; import com.fasterxml.jackson.annotation.JsonIgnore; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.validation.constraints.NotBlank; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -34,12 +52,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import javax.validation.constraints.NotBlank; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - /** * 项目设备对象 */ @@ -104,8 +116,7 @@ public class ProjectDeviceVO { List list = new ArrayList<>(); if (!CollectionUtils.isEmpty(voList)) { String project = voList.get(0).getProject(); - String projectCode = StringUtils.hasText(project) ? project.toUpperCase() : ""; - switch (projectCode) { + switch (project) { case "XTY": { return xtyDeviceConfigConvert(voList); } @@ -121,7 +132,7 @@ public class ProjectDeviceVO { case "RICHOR_JOINT": { return zjdDeviceConfigConvert(voList); } - case "SR_SANDBOX": { + case ProjectCode.SR_SANDBOX: { return srSandboxDeviceConfigConvert(voList); } case "RICHOR_HHCJ": { @@ -130,6 +141,9 @@ public class ProjectDeviceVO { case "SAY": { return sayDeviceConfigConvert(voList); } + case ProjectCode.THAILAND_SANDBOX: { + return thailandSandboxDeviceConfigConvert(voList); + } case "GXSD": { return gxsdDeviceConfigConvert(voList); } @@ -139,6 +153,34 @@ public class ProjectDeviceVO { return list; } + private static List thailandSandboxDeviceConfigConvert( + List voList) { + List 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 ThailandSignalConfig(deviceVO)); + break; + case SECTION: + list.add(new ThailandSectionConfig(deviceVO)); + break; + case SWITCH: + list.add(new ThailandSwitchConfig(deviceVO)); + break; + case TRAIN: + list.add(new ThailandTrainConfig(deviceVO)); + break; + } + } + return list; + } + private static List gxsdDeviceConfigConvert(List voList) { List list = new ArrayList<>(); for (ProjectDeviceVO deviceVO : voList) { diff --git a/src/main/java/club/joylink/rtss/vo/client/project/UDPLowConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/project/UDPLowConfigVO.java index 812db1317..3d19d6532 100644 --- a/src/main/java/club/joylink/rtss/vo/client/project/UDPLowConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/project/UDPLowConfigVO.java @@ -12,6 +12,12 @@ import lombok.Setter; @Setter @NoArgsConstructor public class UDPLowConfigVO { + /** + * 名称。 + * 泰国沙盘下位机有两个接收数据的端口,一个用于接收信号机控制指令;一个用于接收道岔和区段控制指令。 + */ + private String name; + private String ip; private Integer port; @@ -21,6 +27,11 @@ public class UDPLowConfigVO { this.port = port; } + public UDPLowConfigVO(String name, String ip, Integer port) { + this(ip, port); + this.name = name; + } + public String toJson() { return JsonUtils.writeValueAsString(this); } diff --git a/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSectionConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSectionConfigVO.java new file mode 100644 index 000000000..a90bcd489 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSectionConfigVO.java @@ -0,0 +1,38 @@ +package club.joylink.rtss.vo.client.project.thailand; + +import club.joylink.rtss.vo.client.project.RealConfigVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ThailandSectionConfigVO extends RealConfigVO { + private String vrCode; + + private String sandboxCode; + + /** + * 车头到达区段延迟停车时间/s + */ + private Float headDelayTime; + + /** + * 车尾解除占用延迟停车时间/s + */ + private Float tailDelayTime; + + public ThailandSectionConfigVO() { + super(null, null); + } + + public ThailandSectionConfigVO(String vrCode, String sandboxCode) { + this(); + this.vrCode = vrCode; + this.sandboxCode = sandboxCode; + } + + @Override + public String findDeviceCode() { + return vrCode; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSignalConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSignalConfigVO.java new file mode 100644 index 000000000..b85f5aca7 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSignalConfigVO.java @@ -0,0 +1,28 @@ +package club.joylink.rtss.vo.client.project.thailand; + +import club.joylink.rtss.vo.client.project.RealConfigVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ThailandSignalConfigVO extends RealConfigVO { + private String vrCode; + + private String sandboxCode; + + public ThailandSignalConfigVO() { + super(null, null); + } + + public ThailandSignalConfigVO(String vrCode, String sandboxCode) { + this(); + this.vrCode = vrCode; + this.sandboxCode = sandboxCode; + } + + @Override + public String findDeviceCode() { + return vrCode; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSwitchConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSwitchConfigVO.java new file mode 100644 index 000000000..834e608cd --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandSwitchConfigVO.java @@ -0,0 +1,28 @@ +package club.joylink.rtss.vo.client.project.thailand; + +import club.joylink.rtss.vo.client.project.RealConfigVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ThailandSwitchConfigVO extends RealConfigVO { + private String vrCode; + + private String sandboxCode; + + public ThailandSwitchConfigVO() { + super(null, null); + } + + public ThailandSwitchConfigVO(String vrCode, String sandboxCode) { + this(); + this.vrCode = vrCode; + this.sandboxCode = sandboxCode; + } + + @Override + public String findDeviceCode() { + return vrCode; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandTrainConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandTrainConfigVO.java new file mode 100644 index 000000000..a8c2580d8 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/client/project/thailand/ThailandTrainConfigVO.java @@ -0,0 +1,28 @@ +package club.joylink.rtss.vo.client.project.thailand; + +import club.joylink.rtss.vo.client.project.RealConfigVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ThailandTrainConfigVO extends RealConfigVO { + private String vrCode; + + private String sandboxCode; + + public ThailandTrainConfigVO() { + super(null, null); + } + + public ThailandTrainConfigVO(String vrCode, String sandboxCode) { + this(); + this.vrCode = vrCode; + this.sandboxCode = sandboxCode; + } + + @Override + public String findDeviceCode() { + return vrCode; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ff552fb77..868709f4f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -215,7 +215,7 @@ common: spring: profiles: local datasource: - url: jdbc:mysql://192.168.1.254:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true + url: jdbc:mysql://192.168.53.12:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: localdb