客流消息添加单独订阅路径

客流订阅事件处理
客流计算逻辑调整-跳停考虑跳站规则
策略消息推送对象修改
This commit is contained in:
walker-sheng 2021-02-04 18:02:11 +08:00
parent 54c5ec595c
commit 5695af9fac
11 changed files with 159 additions and 45 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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}"),
;

View File

@ -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);

View File

@ -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;
/** 站台大客流判断基准值 */

View File

@ -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<Strategy> recommendList = this.strategyCalculateAndRecommendService.calculateAndRecommend(strategyCalculateData);
List<Strategy> recommendList = this.strategyCalculateAndRecommendService.calculateAndRecommend(strategyCalculateData.clone());
if (!CollectionUtils.isEmpty(recommendList)) {
if (simulation == null) {
return;
}
Set<String> users = simulation.getSimulationUserIds();
String body = JsonUtils.writeValueAsString(recommendList);
LpfStrategyRecommend recommend = new LpfStrategyRecommend(strategyCalculateData, recommendList);
String body = JsonUtils.writeValueAsString(recommend);
SocketMessageVO<String> message = SocketMessageFactory
.build(WebSocketMessageType.LPF_STRATEGY_RECOMMEND, simulation.getGroup(), body);
this.stompMessageService.sendToUser(users, message);

View File

@ -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<StandPassenger> lpfList;
List<Strategy> recommendList;
public LpfStrategyRecommend(StrategyCalculateData data, List<Strategy> recommendList) {
this.lpfList = data.getLpfStandList();
this.recommendList = recommendList;
}
}

View File

@ -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;

View File

@ -68,16 +68,45 @@ public class JumpStrategyServiceImpl implements StrategyService<JumpStrategy> {
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<RealRun> 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<TrainPassenger> trainPassengerList = data.getTrainPassengerList();
List<RealRun> 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<JumpStrategy> {
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<RealRun> 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

View File

@ -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));
}