diff --git a/pom.xml b/pom.xml index 6b5cdcd81..a169bd5c5 100644 --- a/pom.xml +++ b/pom.xml @@ -107,8 +107,27 @@ wechatpay-apache-httpclient 0.2.1 + + com.huawei.sis + huaweicloud-java-sdk-sis + 1.3.0 + + + + sis-repo + Sis Release Repository + https://mirrors.huaweicloud.com/repository/maven/huaweicloudsdk + + true + + + false + + + + diff --git a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java index 94f9f3651..3d20f84d3 100644 --- a/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java +++ b/src/main/java/club/joylink/rtss/controller/simulation/SimulationV1Controller.java @@ -296,7 +296,7 @@ public class SimulationV1Controller { @ApiOperation("仿真客流数据切换") @PutMapping(path = "/{group}/passengerFlow/{passengerFlowId}") - public void AlarmConfirm(@PathVariable String group,@PathVariable Long passengerFlowId) { + public void AlarmConfirm(@PathVariable String group, @PathVariable Long passengerFlowId) { groupSimulationService.changePassengerFlow(group, passengerFlowId); } @@ -306,9 +306,22 @@ public class SimulationV1Controller { return groupSimulationService.getLog(group, queryVO); } - @ApiOperation("查询区段路径") + /* ----------------------- 泰雷兹操作辅助接口 ----------------------- */ + @ApiOperation("查询进路路径") @GetMapping("/{group}/querySectionPaths") public List> querySectionPaths(@PathVariable String group, String groupNumber, String standCode, String signalCode) { return simulationSupportService.queryRoutePaths(group, groupNumber, standCode, signalCode); } + + @ApiOperation("查询列车或运行线经过的站台") + @GetMapping("/{group}/queryStands/trainOrDestination") + public List queryStandsThatTrainGoingThrough(@PathVariable String group, String groupNumber, String destinationCode) { + return simulationSupportService.queryStandsThatTrainGoingThrough(group, groupNumber, destinationCode); + } + + @ApiOperation("查询为该列车已建立的进路") + @GetMapping("/{group}/queryEstablishedRoutes/{groupNumber}") + public List queryEstablishedRoutes(@PathVariable String group, @PathVariable String groupNumber) { + return simulationSupportService.queryEstablishedRoutes(group, groupNumber); + } } diff --git a/src/main/java/club/joylink/rtss/services/IVoiceService.java b/src/main/java/club/joylink/rtss/services/IVoiceService.java index 2c6f27cd4..878853b21 100644 --- a/src/main/java/club/joylink/rtss/services/IVoiceService.java +++ b/src/main/java/club/joylink/rtss/services/IVoiceService.java @@ -80,7 +80,7 @@ public interface IVoiceService { os.close(); } if (saveFile != null) { - saveFile.delete(); +// saveFile.delete(); } } } @@ -106,6 +106,11 @@ public interface IVoiceService { */ String synthesis(String message, String per); + /** + * 华为语音识别 + */ + VoiceRecognitionResult huaweiVoiceRecognition(MultipartFile file, String lang); + @Getter @Setter @NoArgsConstructor diff --git a/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java b/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java index 2c37a5dfc..d19544513 100644 --- a/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java +++ b/src/main/java/club/joylink/rtss/services/VirtualRealityIbpService.java @@ -82,13 +82,13 @@ public class VirtualRealityIbpService implements IVirtualRealityIbpService { upStands.forEach(stand -> ciApiService.standHoldTrainCancel(simulation, stand.getCode(), false)); break; case JJTC: - upStands.forEach(stand -> ciApiService.standEB(simulation, stand)); - downStands.forEach(stand -> ciApiService.standEB(simulation, stand)); + upStands.forEach(stand -> ciApiService.standEC(simulation, stand)); + downStands.forEach(stand -> ciApiService.standEC(simulation, stand)); ibp.setJjtcBuzzer(true); break; case QXJJTC: - upStands.forEach(stand -> ciApiService.cancelStandEB(simulation, stand)); - downStands.forEach(stand -> ciApiService.cancelStandEB(simulation, stand)); + upStands.forEach(stand -> ciApiService.cancelStandEC(simulation, stand)); + downStands.forEach(stand -> ciApiService.cancelStandEC(simulation, stand)); break; case BJQC: ibp.setJjtcBuzzer(false); diff --git a/src/main/java/club/joylink/rtss/services/org/OrgScoringRuleService.java b/src/main/java/club/joylink/rtss/services/org/OrgScoringRuleService.java index b0c3202a8..ba9e0a7c6 100644 --- a/src/main/java/club/joylink/rtss/services/org/OrgScoringRuleService.java +++ b/src/main/java/club/joylink/rtss/services/org/OrgScoringRuleService.java @@ -193,7 +193,6 @@ public class OrgScoringRuleService implements IOrgScoringRuleService { return score(ruleVO, orgId); } - // TODO: 2021/3/24 组织id改成long @Override public void applyOrgScoringRule(Long ruleId, List orgIds) { //校验 @@ -290,7 +289,6 @@ public class OrgScoringRuleService implements IOrgScoringRuleService { && orgScoringRuleVO.getOrgIds().contains(clsId), String.format("评价规则[%s]可应用的班级不包含[%s]", orgScoringRuleVO.getId(), clsId)); } - // TODO: 2021/3/24 评价结果保存、确认流程 List students; if (clsId == null) { students = iOrgUserService.findEntitiesByOrgIds(orgScoringRuleVO.getOrgIds(), BusinessConsts.OrgRole.Student); diff --git a/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java index 7f0689a3b..27f6ac9da 100644 --- a/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java +++ b/src/main/java/club/joylink/rtss/services/simulation/SimulationSupportService.java @@ -4,21 +4,24 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.GroupSimulationService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.CalculateService; -import club.joylink.rtss.simulation.cbtc.data.map.MapElement; -import club.joylink.rtss.simulation.cbtc.data.map.Section; -import club.joylink.rtss.simulation.cbtc.data.map.Signal; -import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.plan.StationPlan; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; +import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; +import java.util.stream.Stream; /** - * 仿真运行支持 + * 仿真操作支持 */ @Service public class SimulationSupportService { @@ -46,4 +49,44 @@ public class SimulationSupportService { .stream().map(MapElement::getCode).collect(Collectors.toList())) .collect(Collectors.toList()); } + + public List queryStandsThatTrainGoingThrough(String group, String groupNumber, String destinationCode) { + List standCodes = new ArrayList<>(); + Simulation simulation = groupSimulationService.getSimulationByGroup(group); + if (StringUtils.hasText(groupNumber)) { + TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); + if (trainInfo.isPlanTrain()) { + standCodes = simulation.getRepository().getTripPlanList(trainInfo.getServiceNumber()).stream() + .flatMap(tripPlan -> tripPlan.getPlanList().stream()) + .flatMap(stationPlan -> stationPlan.getSection().getStandList().stream()) + .map(MapElement::getCode) + .collect(Collectors.toList()); + } else if (trainInfo.isHeadCodeTrain()) { + DestinationCodeDefinition dest = simulation.getRepository().findDestinationCodeDefinition(trainInfo.getDestinationCode()); + if (dest != null) { + standCodes = dest.getRunPath().stream().flatMap(section -> section.getStandList().stream()) + .map(MapElement::getCode).collect(Collectors.toList()); + } + } + } else { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(destinationCode, "列车和运行线必须选一个"); + DestinationCodeDefinition dest = simulation.getRepository().findDestinationCodeDefinition(destinationCode); + if (dest != null) { + standCodes = dest.getRunPath().stream().flatMap(section -> section.getStandList().stream()) + .map(MapElement::getCode).collect(Collectors.toList()); + } + } + return standCodes; + } + + /** + * 查询为该列车已建立的进路 + */ + public List queryEstablishedRoutes(String group, String groupNumber) { + Simulation simulation = groupSimulationService.getSimulationByGroup(group); + return simulation.getRepository().getSettingRoutes().stream() + .filter(route -> route.getTrain() != null && Objects.equals(route.getTrain().getGroupNumber(), groupNumber)) + .map(MapElement::getCode) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/club/joylink/rtss/services/student/DepartUserStaticServiceImpl.java b/src/main/java/club/joylink/rtss/services/student/DepartUserStaticServiceImpl.java index 587d71506..75b8fe5a8 100644 --- a/src/main/java/club/joylink/rtss/services/student/DepartUserStaticServiceImpl.java +++ b/src/main/java/club/joylink/rtss/services/student/DepartUserStaticServiceImpl.java @@ -85,7 +85,6 @@ public class DepartUserStaticServiceImpl implements IDepartUserStatisticService @Autowired private OrgUserDAO departmentUserDAO; - //TODO 迁移学生权限分发 @Override @Transactional public void importStudentInfos(String projectCode, ImportStudentInfo importStudentInfo, UserVO creator) { diff --git a/src/main/java/club/joylink/rtss/services/voice/baidu/VoiceServiceImpl.java b/src/main/java/club/joylink/rtss/services/voice/baidu/VoiceServiceImpl.java index ff6f30577..540cad9d8 100644 --- a/src/main/java/club/joylink/rtss/services/voice/baidu/VoiceServiceImpl.java +++ b/src/main/java/club/joylink/rtss/services/voice/baidu/VoiceServiceImpl.java @@ -3,6 +3,12 @@ package club.joylink.rtss.services.voice.baidu; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.services.IVoiceService; import club.joylink.rtss.vo.client.VoiceRecognitionResult; +import com.huawei.sis.bean.AuthInfo; +import com.huawei.sis.bean.SisConfig; +import com.huawei.sis.bean.request.AsrCustomShortRequest; +import com.huawei.sis.bean.response.AsrCustomShortResponse; +import com.huawei.sis.client.AsrCustomizationClient; +import com.huawei.sis.exception.SisException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -12,11 +18,20 @@ import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Base64; @Slf4j @Service("baiDuVoiceService") public class VoiceServiceImpl implements IVoiceService { + /** + * 华为语音识别配置 + */ + private final String ak = "YDUXTXRYGAHGPHAIXZCU"; + private final String sk = "Kcbm3sTDCYEou8kGeAhKxfBkgWybIn6IjJyGBX3p"; + private final String region = "cn-north-4"; + private final String projectId = "0aada8176180f28c2f34c0196f5394e8"; + @Autowired private AsrService asrService; @@ -50,4 +65,30 @@ public class VoiceServiceImpl implements IVoiceService { } } + @Override + public VoiceRecognitionResult huaweiVoiceRecognition(MultipartFile file, String lang) { + String filePath; + try { + filePath = IVoiceService.handleAndSaveFile(file); + } catch (IOException e) { + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音文件上传失败", e); + } + AuthInfo authInfo = new AuthInfo(ak, sk, region, projectId); + SisConfig sisConfig = new SisConfig(); + AsrCustomizationClient client = new AsrCustomizationClient(authInfo, sisConfig); + String data; + try { + data = Base64.getEncoder().encodeToString(file.getBytes()); + } catch (IOException e) { + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音文件编码失败", e); + } + try { + AsrCustomShortRequest request = new AsrCustomShortRequest(data, "pcm16k16bit", "chinese_16k_common"); + AsrCustomShortResponse response = client.getAsrShortResponse(request); + return new VoiceRecognitionResult(filePath, response.getResult().getText()); + } catch (SisException e) { + throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音识别失败", e); + } + } + } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java index d4b4ad74d..8793f18b2 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java @@ -105,7 +105,7 @@ public class ZCLogicLoop { SectionPosition headPosition = train.getHeadPosition(); SectionPosition tailPosition = train.calculateTailPosition(); Section tailSection = tailPosition.getSection(); - MovementAuthority.End openPsdEnd = checkPsdOpen(tailSection); + MovementAuthority.End openPsdEnd = checkPsdOpenOrClose(tailSection); List endList = new ArrayList<>(); if (openPsdEnd != null) endList.add(openPsdEnd); @@ -143,7 +143,7 @@ public class ZCLogicLoop { // } // } // 站台屏蔽门 - MovementAuthority.End psdEnd = checkPsdOpen(section); + MovementAuthority.End psdEnd = checkPsdOpenOrClose(section); if (psdEnd != null) endList.add(psdEnd); // 紧急关闭的站台 @@ -463,13 +463,16 @@ public class ZCLogicLoop { /** * 检查是否站台屏蔽门开门 */ - private MovementAuthority.End checkPsdOpen(Section section) { + private MovementAuthority.End checkPsdOpenOrClose(Section section) { if (section.isStandTrack()) { List standList = section.getStandList(); for (Stand stand : standList) { if (!stand.isInterlockRelease() && stand.isPsdOpen()) { return new MovementAuthority.End(stand, MovementAuthority.EndType.OPENED_PSD); } + if (stand.isClosed()) { + return new MovementAuthority.End(stand, MovementAuthority.EndType.CLOSED_STAND); + } } } return null; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java index 403716c99..99496a788 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java @@ -2,17 +2,23 @@ package club.joylink.rtss.simulation.cbtc.ATS; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsPlanService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; +import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainService; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Stand; import club.joylink.rtss.simulation.cbtc.data.map.Station; +import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; +import club.joylink.rtss.simulation.cbtc.data.support.DeviationInfo; import club.joylink.rtss.simulation.cbtc.data.support.TrainStopMessage; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import java.util.List; import java.util.Objects; @@ -33,6 +39,9 @@ public class AtsApiServiceImpl implements AtsApiService { @Autowired private ATSMessageCollectAndDispatcher atsMessageCollectAndDispatcher; + @Autowired + private AtsTrainService atsTrainService; + @Override public void handleDeviceStatus(Simulation simulation, List deviceList) { this.atsMessageCollectAndDispatcher.collectDeviceStatusAndSend(simulation, deviceList); @@ -53,7 +62,31 @@ public class AtsApiServiceImpl implements AtsApiService { return; } this.atsPlanService.handleArriveStation(simulation, train, station, section); - +// //处理列车偏离【泰雷兹】 2021-04-08 16:21:26 对运行线设置偏离理解不了,暂时不做 +// List standList = section.getStandList(); +// if (CollectionUtils.isEmpty(standList)) +// return; +// Stand stand = standList.get(0); +// DeviationInfo deviationInfo = simulation.getRepository().findDeviationInfo(stand.getCode()); +// if (deviationInfo != null) { +// if (Objects.equals(stand, deviationInfo.getStartStand())) { //如果列车车头区段的站台是偏离起始站台 +// if (StringUtils.hasText(deviationInfo.getDeviate2DestinationCode())) { +// atsTrainService.setHeadTrain(simulation, train.getGroupNumber(), train.getServiceNumber(), +// train.getTripNumber(), deviationInfo.getDeviate2DestinationCode()); +// } else if (deviationInfo.getDeviate2TripPlan() != null) { +// TripPlan tripPlan = deviationInfo.getDeviate2TripPlan(); +// atsTrainService.setPlanTrain(simulation, train.getGroupNumber(), tripPlan.getServiceNumber(), tripPlan.getTripNumber()); +// } +// } else if (Objects.equals(stand, deviationInfo.getEndStand())) { //如果列车车头区段的站台是偏离结束站台 +// if (StringUtils.hasText(deviationInfo.getBack2DestinationCode())) { +// atsTrainService.setHeadTrain(simulation, train.getGroupNumber(), train.getServiceNumber(), +// train.getTripNumber(), deviationInfo.getBack2DestinationCode()); +// } else if (deviationInfo.getBack2TripPlan() != null) { +// TripPlan tripPlan = deviationInfo.getBack2TripPlan(); +// atsTrainService.setPlanTrain(simulation, train.getGroupNumber(), tripPlan.getServiceNumber(), tripPlan.getTripNumber()); +// } +// } +// } } @Override diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java index df52e3f48..9c683f655 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java @@ -215,6 +215,10 @@ public class Operation { Stand_Sys_Hold_Train(), /** 取消系统扣车 */ Stand_Cancel_Sys_Hold_Train(), + /** 站台开放 */ + Stand_Open, + /** 站台关闭 */ + Stand_Close, //--------------------------- 控制模式 --------------------------- /** 请求站控 */ @@ -352,14 +356,30 @@ public class Operation { Train_Trust, /** 连挂 */ Train_Link, - /** 排列进路到 */ + /** 排列进路到【泰雷兹】 */ Train_Set_Route, - /** 设置运行类型 */ + /** 设置运行类型【泰雷兹】 */ Train_Set_Run_Type, /** 下令停车 */ Train_Order_Stop, /** 取消停车命令 */ Train_Cancel_Order_Stop, + /** 跳停【泰雷兹】 */ + Train_Skip_Stop, + /** 取消跳停【泰雷兹】 */ + Train_Cancel_Skip_Stop, + /** 列车发车【泰雷兹】*/ + Train_Departure, + /** 分配【泰雷兹】 */ + Train_Distribute, + /** 更新偏差【泰雷兹】 */ + Train_Update_Plan_Time, + /** 取消CBTC进路【泰雷兹】 */ + Train_Cancel_CBTC_Route, + /** 设置偏离【泰雷兹】 */ + Train_Set_Deviation, + /** 取消偏离【泰雷兹】 */ + Train_Cancel_Deviation, //--------------------------- 司机 --------------------------- /** 改变列车的牵引/制动力 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SectionOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SectionOperateHandler.java index 6a643e4c5..7c34fd51e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SectionOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/SectionOperateHandler.java @@ -97,7 +97,6 @@ public class SectionOperateHandler { } /**区段计轴预复位*/ - //TODO @OperateHandlerMapping(type =Operation.Type.Section_Axis_Pre_Reset) public void axisPreReset(Simulation simulation, String sectionCode) { ciApiService.axlePreReset(simulation, sectionCode); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java index 6d46c0ace..11843b4a4 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/StandOperateHandler.java @@ -8,6 +8,7 @@ import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.status.StandStatus; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import club.joylink.rtss.simulation.operation.SimulationOperationMapping; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -211,4 +212,14 @@ public class StandOperateHandler { public void cancelSetting(Simulation simulation, String standCode) { atsStandService.cancelSetting(simulation, standCode); } + + @OperateHandlerMapping(type = Operation.Type.Stand_Open) + public void open(Simulation simulation, List standCodes) { + atsStandService.open(simulation, standCodes); + } + + @OperateHandlerMapping(type = Operation.Type.Stand_Close) + public void close(Simulation simulation, List standCodes) { + atsStandService.close(simulation, standCodes); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java index 8edd6be1b..fbd5f1628 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/TrainOperateHandler.java @@ -16,6 +16,7 @@ import club.joylink.rtss.simulation.cbtc.data.support.TrainLoadParam2; 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 org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Autowired; import java.util.Arrays; @@ -321,8 +322,8 @@ public class TrainOperateHandler { * 排列进路到(站台/信号机)【泰雷兹】 */ @OperateHandlerMapping(type = Operation.Type.Train_Set_Route) - public void setRouteTo(Simulation simulation, List routes) { - atsTrainService.setRouteTo(simulation, routes); + public void setRouteTo(Simulation simulation, String groupNumber, List routeCodes) { + atsTrainService.setRouteTo(simulation, groupNumber, routeCodes); } /** @@ -342,4 +343,34 @@ public class TrainOperateHandler { public void cancelOrderStop(Simulation simulation, String groupNumber) { atsTrainService.cancelOrderStop(simulation, groupNumber); } + + @OperateHandlerMapping(type = Operation.Type.Train_Departure) + public void departure(Simulation simulation, String groupNumber) { + atsTrainService.departure(simulation, groupNumber); + } + + @OperateHandlerMapping(type = Operation.Type.Train_Skip_Stop) + public void skipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { + atsTrainService.skipStop(simulation, groupNumber, destinationCode, standCodes); + } + + @OperateHandlerMapping(type = Operation.Type.Train_Cancel_Skip_Stop) + public void cancelSkipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { + atsTrainService.cancelSkipStop(simulation, groupNumber, destinationCode, standCodes); + } + + @OperateHandlerMapping(type = Operation.Type.Train_Distribute) + public void distribute(Simulation simulation, String groupNumber, String serviceNumber) { + atsTrainService.distribute(simulation, groupNumber, serviceNumber); + } + + @OperateHandlerMapping(type = Operation.Type.Train_Update_Plan_Time) + public void updatePlanTime(Simulation simulation, String groupNumber, boolean all) { + // TODO: 2021/4/7 先不做 + } + + @OperateHandlerMapping(type = Operation.Type.Train_Cancel_CBTC_Route) + public void cancelCBTCRoute(Simulation simulation, List routeCodes) { + atsTrainService.cancelCBTCRoute(simulation, routeCodes); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsSectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsSectionService.java index 1baced6cd..96f6f4f03 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsSectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsSectionService.java @@ -63,9 +63,9 @@ public class AtsSectionService { * 开放区段 */ public void open(Simulation simulation, Section section) { - if (simulation.getRepository().getConfig().isSomeCommandNeedInit()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(section.isOpenInit(), section.debugStr() + "没有初始化开放操作"); - } +// if (simulation.getRepository().getConfig().isSomeCommandNeedInit()) { +// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(section.isOpenInit(), section.debugStr() + "没有初始化开放操作"); +// } section.setOpenInit(false); section.setClosed(false); } @@ -81,9 +81,9 @@ public class AtsSectionService { * 关闭区段 */ public void close(Simulation simulation, Section section) { - if (simulation.getRepository().getConfig().isSomeCommandNeedInit()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(section.isCloseInit(), section.debugStr() + "没有初始化开放操作"); - } +// if (simulation.getRepository().getConfig().isSomeCommandNeedInit()) { +// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(section.isCloseInit(), section.debugStr() + "没有初始化开放操作"); +// } section.setCloseInit(false); section.setClosed(true); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java index 78d1e3c54..12a9dc672 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsStandService.java @@ -313,7 +313,7 @@ public class AtsStandService { public void checkAndCancelGivenTrainJump(Simulation simulation, Section section, String groupNumber) { List standList = section.getStandList(); standList.forEach(stand -> { - if (stand.isGivenTrainSkip(groupNumber)) { + if (stand.isGivenTrainSkip(groupNumber) && !stand.isSkipAlwaysValid()) { stand.removeSkipTrain(groupNumber); } }); @@ -389,9 +389,14 @@ public class AtsStandService { // 先默认CBTC模式,取消扣车发送给列车 List superviseTrainList = simulation.getRepository().getSuperviseTrainList(); for (TrainInfo trainInfo : superviseTrainList) { - if (trainInfo.isParkingStand(stand) || - Objects.equals(stand.getSection().getCode(), trainInfo.getEstimatedArriveStandTrack())) { - this.onboardAtpApiService.standCancelHoldTrain(simulation, trainInfo.getGroupNumber()); + if (trainInfo.isParking()) { + if (trainInfo.isParkingStand(stand)) { + this.onboardAtpApiService.standCancelHoldTrain(simulation, trainInfo.getGroupNumber()); + } + } else { + if (Objects.equals(stand.getSection().getCode(), trainInfo.getEstimatedArriveStandTrack())) { + this.onboardAtpApiService.standCancelHoldTrain(simulation, trainInfo.getGroupNumber()); + } } } } @@ -400,10 +405,15 @@ public class AtsStandService { public void cancelHoldTrain(Simulation simulation, String standCode) { Stand stand = simulation.getRepository().getByCode(standCode, Stand.class); Station station = stand.getStation(); - if (station.underCenterControl()) { // 中控 + if (simulation.getRepository().getConfig().isHoldCommandIgnoreControlMode()) { this.ciApiService.standHoldTrainCancel(simulation, standCode, true); - } else { this.ciApiService.standHoldTrainCancel(simulation, standCode, false); + } else { + if (station.underCenterControl()) { // 中控 + this.ciApiService.standHoldTrainCancel(simulation, standCode, true); + } else { + this.ciApiService.standHoldTrainCancel(simulation, standCode, false); + } } this.checkAndCancelTrainHold(simulation, stand); } @@ -464,4 +474,16 @@ public class AtsStandService { cancelJumpStop(simulation, standCode, null); } } + + public void open(Simulation simulation, List standCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台不能为空"); + SimulationDataRepository repository = simulation.getRepository(); + standCodes.forEach(code->repository.getByCode(code, Stand.class).open()); + } + + public void close(Simulation simulation, List standCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台不能为空"); + SimulationDataRepository repository = simulation.getRepository(); + standCodes.forEach(code->repository.getByCode(code, Stand.class).close()); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java index db2fc40fb..22298f771 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/AtsTrainService.java @@ -17,16 +17,20 @@ import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; 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 club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService; import club.joylink.rtss.simulation.cbtc.onboard.ATP.OnboardAtpApiService; import club.joylink.rtss.vo.client.map.newmap.MapStationRunLevelVO; import lombok.extern.slf4j.Slf4j; +import org.aspectj.apache.bcel.classfile.Code; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import java.time.LocalTime; import java.time.temporal.ChronoUnit; import java.util.*; +import java.util.stream.Collectors; /** * ATS列车服务 @@ -44,6 +48,12 @@ public class AtsTrainService { @Autowired private OnboardAtpApiService onboardAtpApiService; + @Autowired + private ATPService atpService; + + @Autowired + private AtsRouteService atsRouteService; + /** * 添加列车追踪 * @@ -85,11 +95,6 @@ public class AtsTrainService { /** * 设置计划车 - * - * @param simulation - * @param groupNumber - * @param serviceNumber - * @param tripNumber */ public void setPlanTrain(Simulation simulation, String groupNumber, String serviceNumber, String tripNumber) { Objects.requireNonNull(groupNumber); @@ -893,8 +898,15 @@ public class AtsTrainService { /** * 排列进路到(站台/信号机) */ - public void setRouteTo(Simulation simulation, List routes) { - routes.forEach(code -> ciApiService.settingRoute(simulation, code)); + public void setRouteTo(Simulation simulation, String groupNumber, List routeCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeCodes, "所选进路不能为空"); + SimulationDataRepository repository = simulation.getRepository(); + TrainInfo trainInfo = repository.getSupervisedTrainByGroup(groupNumber); + routeCodes.forEach(code -> { + ciApiService.settingRoute(simulation, code); + Route route = repository.getByCode(code, Route.class); + route.setTrain(trainInfo); + }); } /** @@ -916,7 +928,7 @@ public class AtsTrainService { } /** - * 取消权限列车扣车 + * 取消全线列车扣车 */ public void cancelAllHold(Simulation simulation) { simulation.getRepository().getOnlineTrainList().forEach(train -> { @@ -942,4 +954,81 @@ public class AtsTrainService { VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); train.setOrderStop(false); } + + /** + * 列车发车【泰雷兹】 + */ + public void departure(Simulation simulation, String groupNumber) { + TrainInfo trainInfo = simulation.getRepository().getSupervisedTrainByGroup(groupNumber); + if (trainInfo.isParking() || trainInfo.isHold()) { + onboardAtpApiService.departure(simulation, groupNumber); + VirtualRealityTrain train = simulation.getRepository().getOnlineTrainBy(groupNumber); + train.setNeedDepartureCommand(false); + } + } + + /** + * 列车跳停 + */ + public void skipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { + // TODO: 2021/4/6 目前计划车没有运行线,所以运行线的跳停在计划车上不生效。并且<查询列车经过的站台>接口,计划车的站台是根据车次计划而不是运行线筛选的。 + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台列表不能为空"); + //2021-04-09 16:26:21 为了简化逻辑,对运行线的跳停先改为对站台设置所有列车跳停。所以可以直接调用站台的跳停方法 + standCodes.forEach(code -> atsStandService.setJumpStop(simulation, code, groupNumber)); + +// SimulationDataRepository repository = simulation.getRepository(); +// if (StringUtils.hasText(groupNumber)) { +// standCodes.forEach(code -> { +// Stand stand = repository.getByCode(code, Stand.class); +// atsStandService.setJumpStop(simulation, code, groupNumber); +// stand.setSkipAlwaysValid(false); +// }); +// } else if (StringUtils.hasText(destinationCode)) { +// Set trains = repository.getOnlineTrainList().stream() +// .filter(train -> Objects.equals(train.getDestinationCode(), destinationCode)).collect(Collectors.toSet()); +// standCodes.forEach(standCode -> { +// Stand stand = repository.getByCode(standCode, Stand.class); +// stand.setSkipAlwaysValid(true); +// trains.forEach(train -> atsStandService.setJumpStop(simulation, standCode, train.getGroupNumber())); +// }); +// } + } + + public void distribute(Simulation simulation, String groupNumber, String serviceNumber) { + // TODO: 2021/4/7 如果给某列车分配一个已经有列车在跑的班次,该列车在停车点会分配上班次,该班次原来那辆车会被分配一条和班次相关的运行线。(就类似脱离班次操作) + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(simulation.getRepository().isVrTrainOnline(groupNumber)); + LocalTime now = LocalTime.now(); + Optional tripPlanOptional = simulation.getRepository().getTripPlanList(serviceNumber).stream() + .filter(tripPlan -> tripPlan.getStartTime().isBefore(now) && tripPlan.getEndTime().isAfter(now)) + .findAny(); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(tripPlanOptional.isPresent(), + String.format("当前时间不能分配该服务号[%s]", serviceNumber)); + setPlanTrain(simulation, groupNumber, serviceNumber, tripPlanOptional.get().getTripNumber()); + } + + /** + * 取消CBTC进路【泰雷兹】 + */ + public void cancelCBTCRoute(Simulation simulation, List routeCodes) { + SimulationDataRepository repository = simulation.getRepository(); + Map settingRouteMap = repository.getSettingRouteMap(); + List collect = routeCodes.stream().map(settingRouteMap::get).filter(Objects::nonNull).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(collect)) { + TrainInfo trainInfo = collect.get(0).getTrain(); + if (trainInfo != null) { + VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); + atpService.triggerSignalEB(train); + train.setNeedDepartureCommand(true); + } + collect.forEach(route -> atsRouteService.cancelRoute(simulation, route.getStart().getCode())); + } + } + + /** + * 取消跳停【泰雷兹】 + */ + public void cancelSkipStop(Simulation simulation, String groupNumber, String destinationCode, List standCodes) { + BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(standCodes, "所选站台列表不能为空"); + standCodes.forEach(code->atsStandService.cancelJumpStop(simulation, code, groupNumber)); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java index 9f730cc69..c3a59987b 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiService.java @@ -315,12 +315,12 @@ public interface CiApiService { /** * 站台紧急停车 */ - void standEB(Simulation simulation, Stand stand); + void standEC(Simulation simulation, Stand stand); /** * 取消站台紧急停车 */ - void cancelStandEB(Simulation simulation, Stand stand); + void cancelStandEC(Simulation simulation, Stand stand); /** * 强扳道岔 @@ -364,5 +364,8 @@ public interface CiApiService { */ void cancelGuideInitialization(Simulation simulation, String signalCode); + /** + * 计轴复位 + */ void axleReset(Simulation simulation, String sectionCode); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java index 42d91c523..8e5233e6d 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/CiApiServiceImpl.java @@ -163,9 +163,9 @@ public class CiApiServiceImpl implements CiApiService { return; } } - if (config.isSomeCommandNeedInit()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(aSwitch.isInit(), aSwitch.debugStr() + "未初始化"); - } +// if (config.isSomeCommandNeedInit()) { +// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(aSwitch.isInit(), aSwitch.debugStr() + "未初始化"); +// } this.switchService.blockade(aSwitch); } @@ -431,9 +431,9 @@ public class CiApiServiceImpl implements CiApiService { BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(signal.getLockedRoute(), String.format("信号机[%s]无已办理进路", signal.getCode())); } } - if (config.isSomeCommandNeedInit()) { - BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isInit(), signal.debugStr() + "未初始化"); - } +// if (config.isSomeCommandNeedInit()) { +// BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isInit(), signal.debugStr() + "未初始化"); +// } BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertTrue(signal.isClose(), String.format("信号机[%s]需处于关闭状态", signal.getCode())); boolean signalApproachOccupied = signal.getApproachPathList() .stream().anyMatch(sectionPath -> sectionPath.getSectionList().stream().anyMatch(Section::isOccupied)); @@ -531,14 +531,14 @@ public class CiApiServiceImpl implements CiApiService { } @Override - public void standEB(Simulation simulation, Stand stand) { + public void standEC(Simulation simulation, Stand stand) { if (stand.getEsp() == null) return; stand.getEsp().update(true); } @Override - public void cancelStandEB(Simulation simulation, Stand stand) { + public void cancelStandEC(Simulation simulation, Stand stand) { if (stand.getEsp() == null) return; stand.getEsp().update(false); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java index d60505d06..7b8ab1a92 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java @@ -975,10 +975,6 @@ public class GroupSimulationServiceImpl implements GroupSimulationService { if (Project.CGY.name().equals(mapDetail.getProjectCode())) { //成都工业所有资源免费 return true; } - if (userVO.getCompanyId() != null) { - String mapProject = mapDetail.getProjectCode(); - return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject)); - } List ups = iUserPermissionService.getSimulationUserPermission(userVO, mapId, prdType); if (!CollectionUtils.isEmpty(ups)) { if (!MapPrdTypeEnum.JOINT.getCode().equals(prdType)) { @@ -989,6 +985,10 @@ public class GroupSimulationServiceImpl implements GroupSimulationService { return true; } } + if (userVO.getCompanyId() != null) { + String mapProject = mapDetail.getProjectCode(); + return userVO.getProjectCodes().stream().anyMatch(orgProject -> Objects.equals(mapProject, orgProject)); + } return false; } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java index 153c5d34a..472e0d610 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/conversation/ConversationManagerService.java @@ -255,7 +255,7 @@ public class ConversationManagerService { Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group); Conversation conversation = simulation.getSimulationConversationById(conversationId); SimulationMember member = simulation.getSimulationMemberByUserId(userVO.getId()); - VoiceRecognitionResult recognitionResult = this.iVoiceService.voiceRecognition(file, ""); + VoiceRecognitionResult recognitionResult = this.iVoiceService.huaweiVoiceRecognition(file, ""); String upperCaseResult = recognitionResult.getResult().toUpperCase(); String handledContent = this.simulationVoiceHandler.handle(upperCaseResult); this.chat(simulation, conversation, member, handledContent, recognitionResult.getFilePath()); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java index 63f3840b9..eb1cbe819 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.data; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.ATS.data.AtsTrainInfo; import club.joylink.rtss.simulation.cbtc.communication.vo.TrainHmiDisplay; import club.joylink.rtss.simulation.cbtc.data.map.*; @@ -7,6 +8,7 @@ import club.joylink.rtss.simulation.cbtc.data.plan.*; import club.joylink.rtss.simulation.cbtc.data.status.DeviceStatus; import club.joylink.rtss.simulation.cbtc.data.status.IbpStatus; import club.joylink.rtss.simulation.cbtc.data.status.TrainStatus; +import club.joylink.rtss.simulation.cbtc.data.support.DeviationInfo; import club.joylink.rtss.simulation.cbtc.data.support.RoutePath; import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition; import club.joylink.rtss.simulation.cbtc.data.vo.TdtStatusVO; @@ -182,9 +184,23 @@ public class SimulationDataRepository { */ private final Map> catenaryMap = new ConcurrentHashMap<>(); - private Map> sectionRespondersMap = new HashMap<>(); + /** + * ats用户设置的列车偏离操作信息 + * key-偏离起始站台或偏离结束站台code + */ + private final Map deviationInfoMap = new ConcurrentHashMap<>(); + + public void addDeviationInfo(DeviationInfo deviationInfo) { + deviationInfoMap.put(deviationInfo.getStartStand().getCode(), deviationInfo); + deviationInfoMap.put(deviationInfo.getEndStand().getCode(), deviationInfo); + } + + public DeviationInfo findDeviationInfo(String standCode) { + return deviationInfoMap.get(standCode); + } + public Set findCatenaries(String sectionCode) { return this.catenaryMap.get(sectionCode); } @@ -969,6 +985,12 @@ public class SimulationDataRepository { return null; } + public DestinationCodeDefinition getDestinationCodeDefinition(String code) { + DestinationCodeDefinition destinationCodeDefinition = destinationMap.get(code); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(destinationCodeDefinition, String.format("目的地码[%s]不存在", code)); + return destinationCodeDefinition; + } + public DestinationCodeDefinition findDestinationCodeDefinition(String code) { return destinationMap.get(code); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java index e913d4690..3ecf5d029 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java @@ -191,10 +191,10 @@ public class MapConfig { */ private boolean blockadeCommandOnlyValidInStandbyMode; - /** - * 一些命令需要初始化【泰雷兹】(道岔封锁、信号机开放引导) - */ - private boolean someCommandNeedInit; +// /** +// * 一些命令需要初始化【泰雷兹】(道岔封锁、信号机开放引导) +// */ +// private boolean someCommandNeedInit; /** * 计轴预复位前需要车站预复位 @@ -206,6 +206,11 @@ public class MapConfig { */ private boolean switchTurnOperationCanRecoverSplitFault; + /** + * 扣车命令不区分控制模式 + */ + private boolean holdCommandIgnoreControlMode; + private Set needConfirmConnectMembers = Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet()); @@ -245,9 +250,10 @@ public class MapConfig { setNeedApproachLockBeforeSetGuide(configVO.isNeedApproachLockBeforeSetGuide()); // setStandSkipSetTrainOnlyOnce(configVO.isStandSkipSetTrainOnlyOnce()); setBlockadeCommandOnlyValidInStandbyMode(configVO.isBlockadeCommandOnlyValidInStandbyMode()); - setSomeCommandNeedInit(configVO.isSwitchBlockadeCommandNeedInit()); +// setSomeCommandNeedInit(configVO.isSwitchBlockadeCommandNeedInit()); setStationPreResetBeforeAxlePreReset(configVO.isStationPreResetBeforeAxlePreReset()); setSwitchTurnOperationCanRecoverSplitFault(configVO.isSwitchTurnOperationCanRecoverSplitFault()); + setHoldCommandIgnoreControlMode(configVO.isHoldCommandIgnoreControlMode()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java index 27bfceb3e..9862814aa 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Stand.java @@ -101,6 +101,11 @@ public class Stand extends MayOutOfOrderDevice { */ private Set skipSet = Collections.synchronizedSet(new HashSet()); + /** + * 跳停一直有效? + */ + private boolean skipAlwaysValid; + /*运行等级(时间)相关*/ /** * 区间运行时间(自动为 0) @@ -140,6 +145,8 @@ public class Stand extends MayOutOfOrderDevice { */ private boolean noStatus; + private boolean closed; + /** * 折返路径策略 */ @@ -160,12 +167,14 @@ public class Stand extends MayOutOfOrderDevice { this.autoHoldTrain = false; this.allSkip = false; this.skipSet = Collections.synchronizedSet(new HashSet<>()); + this.skipAlwaysValid = false; this.runLevelTime = 0; this.runLevelTimeForever = false; this.parkingTime = -1; this.parkingAlwaysValid = false; this.typeStrategy = TurnBackType.DEFAULT; this.noStatus = false; + this.closed = false; } public boolean isEmergencyClosed() { @@ -296,6 +305,14 @@ public class Stand extends MayOutOfOrderDevice { this.isRight() ? "上行" : "下行"); } + public void open() { + this.closed = false; + } + + public void close() { + this.closed = true; + } + /** * 站台折返类型策略 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java index 49c3edf96..bff904146 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java @@ -107,7 +107,7 @@ public class Switch extends MayOutOfOrderDevice { /** * 自动 */ - private boolean auto; + private boolean auto = true; /** * 中央调度员预留 @@ -148,7 +148,7 @@ public class Switch extends MayOutOfOrderDevice { this.delayTime = 0; this.noStatus = false; this.preReset = false; - this.auto = false; + this.auto = true; this.dispatcherReserve = false; this.interlockReserve = false; this.blockadeInvalid = false; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SectionStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SectionStatus.java index 103b178c6..494362507 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SectionStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SectionStatus.java @@ -90,6 +90,9 @@ public class SectionStatus extends DeviceStatus { @JsonSerialize(using = Boolean2NumSerializer.class) private boolean delayUnlock; + @JsonSerialize(using = Boolean2NumSerializer.class) + private boolean closed; + private String fault; public SectionStatus(Section section) { @@ -107,6 +110,7 @@ public class SectionStatus extends DeviceStatus { this.noStatus = section.isNoStatus(); this.preReset = section.isPreReset(); this.delayUnlock = section.isDelayUnlock(); + this.closed = section.isClosed(); this.fault = section.getFault() == null ? null : section.getFault().toString(); } @@ -180,6 +184,11 @@ public class SectionStatus extends DeviceStatus { status.setDelayUnlock(this.delayUnlock); change = true; } + if (!Objects.equals(this.closed, section.isClosed())) { + this.closed = section.isClosed(); + status.setClosed(this.closed); + change = true; + } return change; } @@ -198,6 +207,7 @@ public class SectionStatus extends DeviceStatus { statusVO.setNoStatus(noStatus); statusVO.setPreReset(preReset); statusVO.setDelayUnlock(delayUnlock); + statusVO.setClosed(closed); return statusVO; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java index a3f87bf75..1dbd16e51 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/StandStatus.java @@ -80,6 +80,9 @@ public class StandStatus extends DeviceStatus { @JsonSerialize(using = Boolean2NumSerializer.class) private boolean noStatus; + @JsonSerialize(using = Boolean2NumSerializer.class) + private boolean closed; + /**故障*/ private String fault; @@ -109,6 +112,7 @@ public class StandStatus extends DeviceStatus { this.parkingTime = stand.getParkingTime(); this.parkingAlwaysValid = stand.isParkingAlwaysValid(); this.noStatus = stand.isNoStatus(); + this.closed = stand.isClosed(); this.fault = Objects.nonNull(stand.getFault())?((Stand.Fault)stand.getFault()).name():null; } @@ -204,6 +208,11 @@ public class StandStatus extends DeviceStatus { status.setNoStatus(noStatus); change = true; } + if (!Objects.equals(this.closed, stand.isClosed())) { + this.closed = stand.isClosed(); + status.setClosed(this.closed); + change = true; + } MayOutOfOrderDevice.DeviceFault fault = stand.getFault(); if (!Objects.equals(this.fault, Objects.nonNull(fault)?((Stand.Fault)fault).name():null)) { if(Objects.isNull(fault)) { @@ -236,6 +245,7 @@ public class StandStatus extends DeviceStatus { statusVO.setTrainParking(trainParking); statusVO.setRemainTime(remainTime); statusVO.setNoStatus(noStatus); + statusVO.setClosed(closed); statusVO.setFault(fault); return statusVO; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/DeviationInfo.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/DeviationInfo.java new file mode 100644 index 000000000..739156f71 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/DeviationInfo.java @@ -0,0 +1,54 @@ +package club.joylink.rtss.simulation.cbtc.data.support; + +import club.joylink.rtss.simulation.cbtc.data.map.Stand; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 列车偏离信息【泰雷兹】 + */ +@Getter +@AllArgsConstructor +public class DeviationInfo { + /** + * 要执行偏离的列车 + */ + private VirtualRealityTrain train; + + /** + * 要执行偏离的运行线(列车和运行线只会有一个) + */ + private String destinationCode; + + /** + * 从这个站台开始偏离 + */ + private Stand startStand; + + /** + * 到这个站台结束偏离 + */ + private Stand endStand; + + /** + * 要偏离到的运行线 + */ + private String deviate2DestinationCode; + + /** + * 要偏离到的运行计划(运行线和运行计划只会有一个) + */ + private TripPlan deviate2TripPlan; + + /** + * 偏离结束后要回到的运行线 + */ + private String back2DestinationCode; + + /** + * 偏离结束后要回到的运行计划(运行线和运行计划只会有一个) + */ + private TripPlan back2TripPlan; +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java index 332fe73df..8d911dd1c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/MovementAuthority.java @@ -93,7 +93,8 @@ public class MovementAuthority { private SectionPosition computeEndPosition(boolean right) { switch (this.type) { - case OPENED_PSD: { + case OPENED_PSD: + case CLOSED_STAND:{ Section section = ((Stand) device).getSection(); SectionPosition stopPosition = new SectionPosition(section, section.getStopPointByDirection(right)); return CalculateService.calculateNextPositionByStartAndLen(stopPosition, !right, 300); @@ -220,6 +221,10 @@ public class MovementAuthority { * 关闭的区段 */ CLOSED_SECTION, + /** + * 关闭的站台 + */ + CLOSED_STAND, } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SectionStatusVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SectionStatusVO.java index 3ec3ce965..4843f8a98 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SectionStatusVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SectionStatusVO.java @@ -61,6 +61,9 @@ public class SectionStatusVO extends DeviceStatusVO { @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean delayUnlock; + @JsonSerialize(using = Boolean2NumSerializer.class) + private Boolean closed; + private String fault; public SectionStatusVO(Section section) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java index 9226b842f..d01b4ca30 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/StandStatusVO.java @@ -77,6 +77,9 @@ public class StandStatusVO extends DeviceStatusVO { @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean noStatus; + @JsonSerialize(using = Boolean2NumSerializer.class) + private Boolean closed; + /**故障*/ @JsonInclude(JsonInclude.Include.ALWAYS) private String fault; 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 9b6e6cbec..d04aaab72 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 @@ -383,16 +383,21 @@ public class VirtualRealityTrain extends VirtualRealityDevice { */ private boolean orderStop; + /** + * 需要发车命令才能列车才能移动 + */ + private boolean needDepartureCommand; + public void setRunType(RunType runType) { this.runType = runType; switch (runType) { case ENERGY_CONSERVATION: this.atoSpeedMax = this.atpSpeedMax * 0.2f * 0.9f; break; - case MIDDLE_ONE: + case MIDDLE_TWO: this.atoSpeedMax = this.atpSpeedMax * 0.4f * 0.9f; break; - case MIDDLE_TWO: + case MIDDLE_ONE: this.atoSpeedMax = this.atpSpeedMax * 0.6f * 0.9f; break; case NORMAL: @@ -478,6 +483,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice { this.lastTwoPassedResponders = new FixedQueue<>(Responders_Record); this.runType = null; this.orderStop = false; + this.needDepartureCommand = false; this.fault = null; } @@ -591,6 +597,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice { if (Fault.DRIVE_FAULT.equals(fault) && fk > 0) { return; } + if (isNeedDepartureCommand()) { + return; + } enforceUpdateTBForce(fk, fb); } @@ -1106,10 +1115,10 @@ public class VirtualRealityTrain extends VirtualRealityDevice { public enum RunType{ /** 节能 */ ENERGY_CONSERVATION, - /** 中间的1 */ - MIDDLE_ONE, /** 中间的2 */ MIDDLE_TWO, + /** 中间的1 */ + MIDDLE_ONE, /** 正常 */ NORMAL, /** 加速 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java index 79e9f7182..4587d4b83 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java @@ -219,12 +219,12 @@ public class ATPLogicLoop { if (train.isJump()) { // 列车跳停,跳过开门 train.earlyDeparture(); // if (simulation.getRepository().getConfig().isStandSkipSetTrainOnlyOnce()) { - List standList = train.getHeadPosition().getSection().getStandList(); - if (!CollectionUtils.isEmpty(standList)) { - standList.stream().filter(stand -> stand.isGivenTrainSkip(train.getGroupNumber())).forEach(stand -> { - atsApiService.cancelStandSkipSetOfTrain(simulation,train.getGroupNumber(), stand.getCode()); - }); - } + List standList = train.getHeadPosition().getSection().getStandList(); + if (!CollectionUtils.isEmpty(standList)) { + standList.stream().filter(stand -> stand.isGivenTrainSkip(train.getGroupNumber())).forEach(stand -> { + atsApiService.cancelStandSkipSetOfTrain(simulation, train.getGroupNumber(), stand.getCode()); + }); + } // } } else { this.atoService.syncOpenDoor(simulation, train); @@ -236,28 +236,30 @@ public class ATPLogicLoop { case BOARD: // 乘客乘降 if (simulation.getRepository().getConfig().isAdjustOperationAutomatically()) { if (parkRemainTime < 10000) { // 小于10秒,关门 - train.nextParkedTrainActivity(); + if (!train.isHold()) { + train.nextParkedTrainActivity(); + } } } else { if (parkRemainTime <= 0) { - train.nextParkedTrainActivity(); + if (!train.isHold()) { + train.nextParkedTrainActivity(); + } } } break; case CLOSE_DOOR: // 关门 // Signal signal = train.getHeadPosition().getSection().getSignalOf(train.isRight()); - if (!train.isHold() || simulation.getRepository().getConfig().isAllowEarlyDepartureWhenHoldTrain()) { // 列车未扣车或允许在扣车状态下提前发车 // if (Objects.nonNull(signal) && !signal.isNormalOpen()) { // if (!train.isRMMode() && !train.isNRMMode()) { // // 信号机未正常开放 // break; // } // } - // 可以关门 - this.atoService.syncCloseDoor(simulation, train); - if (this.isAllDoorClose(simulation, train)) { - train.nextParkedTrainActivity(); - } + // 可以关门 + this.atoService.syncCloseDoor(simulation, train); + if (this.isAllDoorClose(simulation, train)) { + train.nextParkedTrainActivity(); } break; case START: // 准备出发 diff --git a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java index 06872fd3b..e7793a37f 100644 --- a/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/map/RealLineConfigVO.java @@ -130,10 +130,10 @@ public class RealLineConfigVO { */ private boolean blockadeCommandOnlyValidInStandbyMode; - /** - * 道岔封锁命令需要初始化 - */ - private boolean switchBlockadeCommandNeedInit; +// /** +// * 道岔封锁命令需要初始化 +// */ +// private boolean switchBlockadeCommandNeedInit; /** * 计轴预复位前需要车站预复位 @@ -145,6 +145,11 @@ public class RealLineConfigVO { */ private boolean switchTurnOperationCanRecoverSplitFault; + /** + * 扣车命令不区分控制模式 + */ + private boolean holdCommandIgnoreControlMode; + public static RealLineConfigVO parseJsonStr(String configData) { if (StringUtils.hasText(configData)) { return JsonUtils.read(configData, RealLineConfigVO.class);