diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserConnectEvent.java b/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserConnectEvent.java new file mode 100644 index 000000000..575d7dd72 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserConnectEvent.java @@ -0,0 +1,21 @@ +package club.joylink.rtss.simulation.cbtc.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * 仿真进入事件 + */ +@Getter +public class PassengerUserConnectEvent extends ApplicationEvent { + + private String group; + + private Long userId; + + public PassengerUserConnectEvent(Long userId, String group, Object source) { + super(source); + this.group = group; + this.userId = userId; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserDisconnectEvent.java b/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserDisconnectEvent.java new file mode 100644 index 000000000..4c39bc67d --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/event/PassengerUserDisconnectEvent.java @@ -0,0 +1,21 @@ +package club.joylink.rtss.simulation.cbtc.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * 仿真进入事件 + */ +@Getter +public class PassengerUserDisconnectEvent extends ApplicationEvent { + + private String group; + + private Long userId; + + public PassengerUserDisconnectEvent(Long userId, String group, Object source) { + super(source); + this.group = group; + this.userId = userId; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeManager.java b/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeManager.java index 257c886ca..e5317ff5c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeManager.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeManager.java @@ -95,6 +95,14 @@ public class SimulationSubscribeManager { } break; } + case PassengerFlow:{ + if (sub) { + this.applicationContext.publishEvent(new PassengerUserConnectEvent(user.getUser().getId(), subscribeTopic.getId(destination), this)); + } else { + this.applicationContext.publishEvent(new PassengerUserDisconnectEvent(user.getUser().getId(), subscribeTopic.getId(destination), this)); + } + break; + } } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeTopic.java b/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeTopic.java index 506270c2f..2932a21ca 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeTopic.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/message/websocket/SimulationSubscribeTopic.java @@ -1,16 +1,19 @@ package club.joylink.rtss.simulation.cbtc.message.websocket; +import lombok.Getter; import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.StringUtils; import java.util.Objects; import java.util.Properties; +@Getter public enum SimulationSubscribeTopic { Main("/queue/simulation/{id}"), SandBox("/queue/simulation/jl3d/{id}"), Drive("/queue/simulation/drive/{id}"), + PassengerFlow("/queue/simulation/passenger/{id}"), WeChatMini("/topic/simulation/assistant/{id}"), ; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java index 3ff2e349f..717b1f7ab 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/PassengerFlowSimulateService.java @@ -12,7 +12,7 @@ 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.vo.TrainInfo; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain; -import club.joylink.rtss.simulation.cbtc.event.SandboxUserConnectEvent; +import club.joylink.rtss.simulation.cbtc.event.PassengerUserConnectEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationDestroyEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationResetEvent; import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent; @@ -199,7 +199,7 @@ public class PassengerFlowSimulateService { } @EventListener - public void handleSandboxConnectEvent(SandboxUserConnectEvent event) { + public void handleSandboxConnectEvent(PassengerUserConnectEvent event) { Simulation simulation = this.groupSimulationCache.findSimulationByGroup(event.getGroup()); if (Objects.isNull(simulation)) { return; @@ -306,7 +306,7 @@ public class PassengerFlowSimulateService { add = flowData.getNum(); } } - log.debug(String.format("站台[%s]增加乘客: %s", stand.debugStr(), add)); +// log.debug(String.format("站台[%s]增加乘客: %s", stand.debugStr(), add)); int total = standPassengerFlow.plus(add); sendData.put("standCode", stand.getCode()); sendData.put("num", total); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java index a3a54aa6b..c13144875 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/Config.java @@ -2,7 +2,7 @@ package club.joylink.rtss.simulation.cbtc.passenger.strategy; public final class Config { /** 策略计算推荐间隔,单位 - 分钟 */ - public static final int CAL_INTERVAL = 5; + public static final int CAL_INTERVAL = 3; /** 策略向后推算的时间,单位 - 分钟 */ public static final int STRATEGY_CAL_TIME = 30; /** 站台大客流判断基准值 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java index ad5f0186d..57d307630 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/LargePassengerFlowStrategyService.java @@ -6,6 +6,7 @@ import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.passenger.PassengerFlowSimulateService; import club.joylink.rtss.simulation.cbtc.passenger.data.PassengerFlowSimulationData; import club.joylink.rtss.simulation.cbtc.passenger.data.StandPassengerFlow; +import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.LpfStrategyRecommend; import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.Strategy; import club.joylink.rtss.simulation.cbtc.passenger.strategy.data.StrategyCalculateData; import club.joylink.rtss.util.JsonUtils; @@ -64,13 +65,14 @@ public class LargePassengerFlowStrategyService { log.info(String.format("[%s]出现大客流,开始生成策略计算", lpfList.get(0).getStand().debugStr())); // 发现大客流,计算策略 StrategyCalculateData strategyCalculateData = this.buildStrategyCalculateData(passengerFlowSimulationData); - List recommendList = this.strategyCalculateAndRecommendService.calculateAndRecommend(strategyCalculateData); + List recommendList = this.strategyCalculateAndRecommendService.calculateAndRecommend(strategyCalculateData.clone()); if (!CollectionUtils.isEmpty(recommendList)) { if (simulation == null) { return; } Set users = simulation.getSimulationUserIds(); - String body = JsonUtils.writeValueAsString(recommendList); + LpfStrategyRecommend recommend = new LpfStrategyRecommend(strategyCalculateData, recommendList); + String body = JsonUtils.writeValueAsString(recommend); SocketMessageVO message = SocketMessageFactory .build(WebSocketMessageType.LPF_STRATEGY_RECOMMEND, simulation.getGroup(), body); this.stompMessageService.sendToUser(users, message); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/LpfStrategyRecommend.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/LpfStrategyRecommend.java new file mode 100644 index 000000000..c4801e004 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/LpfStrategyRecommend.java @@ -0,0 +1,18 @@ +package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class LpfStrategyRecommend { + + List lpfList; + + List recommendList; + + public LpfStrategyRecommend(StrategyCalculateData data, List recommendList) { + this.lpfList = data.getLpfStandList(); + this.recommendList = recommendList; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java index 001ad9b9c..a200479df 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/data/StandPassenger.java @@ -3,11 +3,13 @@ package club.joylink.rtss.simulation.cbtc.passenger.strategy.data; import club.joylink.rtss.simulation.cbtc.data.map.Stand; import club.joylink.rtss.simulation.cbtc.passenger.data.StandPassengerFlow; import club.joylink.rtss.simulation.cbtc.passenger.strategy.Config; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; @Getter public class StandPassenger { + @JsonIgnore Stand stand; /** 是否大客流站 */ @@ -29,6 +31,10 @@ public class StandPassenger { } } + public String getStandCode() { + return this.stand.getCode(); + } + public StandPassenger clone() { StandPassenger obj = new StandPassenger(); obj.stand = this.stand; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/service/JumpStrategyServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/service/JumpStrategyServiceImpl.java index 99584ccc6..ecfd0a433 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/service/JumpStrategyServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/passenger/strategy/service/JumpStrategyServiceImpl.java @@ -68,16 +68,45 @@ public class JumpStrategyServiceImpl implements StrategyService { continue; } // 该站是否被前列车跳过 -// boolean jump = this.isJustJumped(data, s); + RealRun jumpRun = this.isJustJumped(data, s); + if (jumpRun != null) { + log.debug(String.format("站台[%s]刚被跳停,不生成", s.debugStr())); + continue; + } + // 前一站是否刚跳停 + if (i - 1 > 0) { + Stand pre = jumpableStandList.get(i - 1); + jumpRun = this.isJustJumped(data, pre); + if (jumpRun != null) { + boolean jump = false; + List realRuns = data.queryRealRuns(jumpRun.getGroupNumber()); + int i1 = realRuns.indexOf(jumpRun); + for (int j = i1; j < realRuns.size(); j++) { + RealRun realRun = realRuns.get(j); + if (Objects.equals(realRun.getSectionCode(), s.getSection().getCode())) { + if (!realRun.isArrive()) { + jump = true; + } + break; + } + } + if (jump) { + log.debug(String.format("站台[%s]的前一站台[%s]刚被跳停,不生成", s.debugStr(), pre.debugStr())); + continue; + } + } + } list.add(new JumpStrategy(s)); } log.debug(String.format("生成跳停策略[%s]个", list.size())); return list; } - private boolean isJustJumped(StrategyCalculateData data, Stand stand) { + private RealRun isJustJumped(StrategyCalculateData data, Stand stand) { List trainPassengerList = data.getTrainPassengerList(); - List list = new ArrayList<>(); + StationPlan plan = null; + boolean jump = false; + RealRun standLastRun = null; for (TrainPassenger trainPassenger : trainPassengerList) { String groupNumber = trainPassenger.getGroupNumber(); TripPlan tripPlan = data.queryTripPlan(trainPassenger.getServiceNumber(), trainPassenger.getTripNumber()); @@ -96,42 +125,42 @@ public class JumpStrategyServiceImpl implements StrategyService { RealRun last = realRunList.get(realRunList.size() - 1); int lastRunIndex = tripPlan.getPlanIndex(last.getSectionCode()); if (lastRunIndex < index) { // 列车实际运行未过站台 + StationPlan stationPlan = tripPlan.getPlanList().get(index); + if (plan == null || plan.getArriveTime().isAfter(stationPlan.getArriveTime())) { + plan = stationPlan; + } continue; } - RealRun jumpRun = this.isTrainJumpStand(trainPassenger, realRunList, stand); - if (jumpRun != null) { - list.add(jumpRun); - } - } - } - return false; - } - - private RealRun isTrainJumpStand(TrainPassenger trainPassenger, List realRunList, Stand stand) { - RealRun jumpRun = null; - boolean jump = true; - for (int i = realRunList.size() - 1; i >= 0; i--) { - RealRun realRun = realRunList.get(i); - if (!Objects.equals(realRun.getServiceNumber(), trainPassenger.getServiceNumber()) || - !Objects.equals(realRun.getTripNumber(), trainPassenger.getTripNumber())) { - break; - } - if (Objects.equals(realRun.getSectionCode(), stand.getSection().getCode())) { - if (!realRun.isArrive() && i > 0) { - RealRun pre = realRunList.get(i - 1); - if (Objects.equals(pre.getServiceNumber(), trainPassenger.getServiceNumber()) && - Objects.equals(pre.getTripNumber(), trainPassenger.getTripNumber()) && - Objects.equals(pre.getSectionCode(), stand.getSection().getCode())) { - jump = false; + for (int i = realRunList.size() - 1; i >= 0; i--) { + RealRun realRun = realRunList.get(i); + if (!Objects.equals(realRun.getServiceNumber(), trainPassenger.getServiceNumber()) || + !Objects.equals(realRun.getTripNumber(), trainPassenger.getTripNumber())) { + break; + } + if (Objects.equals(realRun.getSectionCode(), stand.getSection().getCode())) { + if (!realRun.isArrive() && i > 0) { + RealRun pre = realRunList.get(i - 1); + if (pre.isArrive() && + Objects.equals(pre.getSectionCode(), stand.getSection().getCode())) { + if (standLastRun == null || standLastRun.getTime().isAfter(pre.getTime())) { + jump = false; + standLastRun = pre; + } + } else { + if (standLastRun == null || standLastRun.getTime().isAfter(realRun.getTime())) { + jump = true; + standLastRun = realRun; + } + } + } } } - if (jump) { - jumpRun = realRun; - } - break; } } - return jumpRun; + if (jump) { + return standLastRun; + } + return null; } @Override diff --git a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java index 01f62d9bb..0e435c02d 100644 --- a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java +++ b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java @@ -9,6 +9,7 @@ import club.joylink.rtss.simulation.cbtc.data.status.IbpStatus; import club.joylink.rtss.simulation.cbtc.data.vo.*; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationUser; +import club.joylink.rtss.simulation.cbtc.message.websocket.SimulationSubscribeTopic; import club.joylink.rtss.vo.client.SocketMessageVO; import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.passenger.PassengerFlowMessage2TD; @@ -90,8 +91,6 @@ public class SocketMessageFactory { case Simulation_Quest_Finish: case Simulation_PlayBack_Finish: case Competition_Practical: - case STATION_PFI_NUM: - case LPF_STRATEGY_RECOMMEND: case Simulation_Alarm: { topicList.add(String.format(WebSocketSubscribeTopic.Simulation, group)); break; @@ -120,10 +119,6 @@ public class SocketMessageFactory { topicList.add(String.format(WebSocketSubscribeTopic.Sandbox3D, group)); break; } - case TrainRun_3D: - case Device_Fault_Set_3D: - case Device_Fault_Over_3D: - case VR_Sync_3D: case STAND_PFI_NUM: case STAND_PFI_TO: case STAND_PFI: @@ -131,6 +126,15 @@ public class SocketMessageFactory { case TRAIN_PFI_BL: case TRAIN_PIS: case PFV: + case STATION_PFI_NUM: + case LPF_STRATEGY_RECOMMEND:{ + topicList.add(SimulationSubscribeTopic.PassengerFlow.buildDestination(group)); + break; + } + case TrainRun_3D: + case Device_Fault_Set_3D: + case Device_Fault_Over_3D: + case VR_Sync_3D: case SJL3D_TrainStatus: { topicList.add(String.format(WebSocketSubscribeTopic.Sandbox3D, group)); break; @@ -158,6 +162,7 @@ public class SocketMessageFactory { case Simulation_Reset: { topicList.add(String.format(WebSocketSubscribeTopic.Simulation, group)); topicList.add(String.format(WebSocketSubscribeTopic.AssistantSimulation, group)); + topicList.add(SimulationSubscribeTopic.PassengerFlow.buildDestination(group)); topicList.add(String.format(WebSocketSubscribeTopic.Sandbox3D, group)); topicList.add(String.format(WebSocketSubscribeTopic.TrainDrive3D, group)); topicList.add(String.format(WebSocketSubscribeTopic.WeiAngU3dSimulation, group)); @@ -166,6 +171,7 @@ public class SocketMessageFactory { case Simulation_Over: { topicList.add(String.format(WebSocketSubscribeTopic.Simulation, group)); topicList.add(String.format(WebSocketSubscribeTopic.Sandbox3D, group)); + topicList.add(SimulationSubscribeTopic.PassengerFlow.buildDestination(group)); topicList.add(String.format(WebSocketSubscribeTopic.TrainDrive3D, group)); topicList.add(String.format(WebSocketSubscribeTopic.AssistantSimulation, group)); }