武汉8号线列车位置显示功能
This commit is contained in:
parent
753c314292
commit
41fe8bba1c
@ -0,0 +1,133 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsRouteSelectService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiLogic;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
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.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.TrainLoadParam2;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop;
|
||||
import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService;
|
||||
import club.joylink.rtss.simulation.cbtc.event.SimulationRunAsPlanEvent;
|
||||
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.tool.DeviceStatusModifyTool;
|
||||
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class NewAtsTrainLoadService extends AtsTrainLoadService {
|
||||
|
||||
@Resource
|
||||
private VRTrainRunningService vrTrainRunningService;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void loadTripNumberTrain(Simulation simulation, TrainPosition tp,Section section) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
String tripNumber = tp.getTrainTripNum();
|
||||
TrainInfo trainInfo = repository.getTrainInfoMap().values().stream().filter(train -> tripNumber.equals(train.getTripNumber())).findFirst().orElse(null);
|
||||
|
||||
// List<VirtualRealityTrain> allVrTrain = repository.getAllVrTrain();
|
||||
|
||||
if(Objects.nonNull(trainInfo)){
|
||||
//存在列车需要更新位置
|
||||
Optional<VirtualRealityTrain> virtualRealityTrainOptional = repository.getAllVrTrain().stream().filter(d->Objects.equals(d.getTripNumber(),tripNumber)).findFirst();
|
||||
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
|
||||
trainOnline(simulation, section, tp, virtualRealityTrain);
|
||||
// virtualRealityTrain.initManualTrain(headPosition, tp.isRight());
|
||||
}else{
|
||||
|
||||
Optional<VirtualRealityTrain> virtualRealityTrainOptional = repository.getAllVrTrain().stream()
|
||||
.filter(vrTrain -> !repository.isVrTrainOnline(vrTrain.getGroupNumber()))
|
||||
.findFirst();
|
||||
VirtualRealityTrain virtualRealityTrain = virtualRealityTrainOptional.get();
|
||||
// 设置列车车次
|
||||
virtualRealityTrain.setTripNumber(tripNumber);
|
||||
trainOnline(simulation, section, tp, virtualRealityTrain);
|
||||
// SectionPosition headPosition = new SectionPosition(section, tp.getLocation() - section.getKmMin());
|
||||
// virtualRealityTrain.initManualTrain(headPosition, tp.isRight());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 列车上线并构建ATS监控列车信息
|
||||
* @param simulation
|
||||
* @param section
|
||||
* @param tp
|
||||
* @param train
|
||||
*/
|
||||
private void trainOnline(Simulation simulation, Section section, TrainPosition tp, VirtualRealityTrain train) {
|
||||
boolean right = tp.isRight();
|
||||
if (!section.isPhysical()) {
|
||||
section = section.getParent();
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(section.isPhysical(), "列车需加载到物理区段上");
|
||||
//重叠检测
|
||||
SectionPosition headPosition = new SectionPosition(section, tp.getLocation() - section.getKmMin());
|
||||
// SectionPosition headPosition = new SectionPosition(section, section.getStopPointByDirection(right));
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, train.getLen(), false);
|
||||
boolean willOverlap = vrTrainRunningService.willOverlap(simulation, headPosition, tailPosition);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(willOverlap, "列车重叠");
|
||||
// 列车上线并构建ATS监控列车信息
|
||||
manualTrainOnlineAndSupervise(simulation, train, headPosition, right);
|
||||
}
|
||||
|
||||
/**
|
||||
* 人工车上线并监控
|
||||
*/
|
||||
private void manualTrainOnlineAndSupervise(Simulation simulation, VirtualRealityTrain train, SectionPosition headPosition, boolean right) {
|
||||
train.initManualTrain(headPosition, right);
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
//设置列车预选模式、驾驶模式、运行级别
|
||||
if (!headPosition.getSection().anyZcWorking()) {
|
||||
train.initAsRM();
|
||||
} else {
|
||||
MapConfig config = repository.getConfig();
|
||||
if (RunLevel.ITC.equals(config.getRunMode())) {
|
||||
train.initAsAM_I();
|
||||
} else if (RunLevel.IL.equals(config.getRunMode())) {
|
||||
train.initAsRM();
|
||||
}
|
||||
}
|
||||
if (!repository.getConfig().isHandleDepot()) {
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
repository.addOnlineTrain(train);
|
||||
repository.addTrainInfo(trainInfo);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,71 +6,110 @@ import club.joylink.rtss.simulation.SimulationManager;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class TrainPositionService {
|
||||
@Resource
|
||||
AtsTrainLoadService atsTrainLoadService;
|
||||
private NewAtsTrainLoadService newAtsTrainLoadService;
|
||||
@Resource
|
||||
SimulationManager simulationManager;
|
||||
private final static Cache<Section.SectionRoadType,List<Section>> ROAD_TYPE_CACHE = CacheBuilder.newBuilder().build();
|
||||
|
||||
public void initTrainOrUpdate(String mapName,TrainPosition tp){
|
||||
private SimulationManager simulationManager;
|
||||
/**
|
||||
* 数据过期时间
|
||||
*/
|
||||
private final static long EXPIRE_SECTION_TIME_MIN = 10;
|
||||
/**
|
||||
* 区段的缓存
|
||||
* key 对应的方向类型
|
||||
* EXPIRE_SECTION_TIME_MIN 数据过期时间
|
||||
*/
|
||||
private final static Cache<Section.SectionRoadType,List<Section>> ROAD_TYPE_CACHE = CacheBuilder.newBuilder().expireAfterWrite(EXPIRE_SECTION_TIME_MIN, TimeUnit.MINUTES).build();
|
||||
|
||||
/**
|
||||
* 初始化或更新列车的位置
|
||||
* @param mapName
|
||||
* @param json
|
||||
*/
|
||||
public void initTrainOrUpdate(String mapName,String json){
|
||||
TrainPosition tp = JsonUtils.read(json, TrainPosition.class);
|
||||
List<Simulation> simulationList = this.findSimulationList(mapName);
|
||||
if(Objects.equals(true, CollectionUtils.isEmpty(simulationList))){
|
||||
log.error("");
|
||||
log.error("未找到对应的类型的仿真,无法渲染列车位置 param:{}",json);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Section> sectionList = findDirectionAllSection(simulationList.get(0),tp.getRoadType());
|
||||
Section section = this.findSecion(sectionList,tp);
|
||||
if(Objects.isNull(section)){
|
||||
log.error("未找到对应的区段 param:{}",json);
|
||||
return;
|
||||
}
|
||||
for (Simulation sim : simulationList) {
|
||||
|
||||
this.newAtsTrainLoadService.loadTripNumberTrain(sim,tp,section);
|
||||
}
|
||||
}
|
||||
|
||||
private void findSecion(List<Section> sectionList,TrainPosition tp){
|
||||
/**
|
||||
* 根据传入的参数 定位对应的所在的区段
|
||||
* @param sectionList
|
||||
* @param tp
|
||||
* @return
|
||||
*/
|
||||
private Section findSecion(List<Section> sectionList,TrainPosition tp){
|
||||
int i = 0;
|
||||
Section findSection;
|
||||
// Section findSection;
|
||||
for (Section section : sectionList) {
|
||||
if(tp.isRight()){
|
||||
if(tp.getLocation() <= section.getKmMax()){
|
||||
findSection = section;
|
||||
break;
|
||||
return section;
|
||||
}
|
||||
}else{
|
||||
|
||||
if(tp.getLocation() <= section.getKmMax() && tp.getLocation() >= section.getKmMin()){
|
||||
return section;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据车辆方向获取对应的区段并升序排序
|
||||
* @param sim
|
||||
* @param roadType
|
||||
* @return
|
||||
*/
|
||||
private static synchronized List<Section> findDirectionAllSection(Simulation sim,Section.SectionRoadType roadType){
|
||||
List<Section> list = ROAD_TYPE_CACHE.getIfPresent(roadType);
|
||||
if(Objects.equals(true,CollectionUtils.isEmpty(list))){
|
||||
list = sim.getRepository().getSectionList();
|
||||
list = list.stream().filter(d->d.getRoadType() == roadType)
|
||||
.sorted(Comparator.comparing(Section::getKmMin)/*.reversed()*/).collect(Collectors.toList());
|
||||
.sorted(Comparator.comparing(Section::getKmMin)).collect(Collectors.toList());
|
||||
ROAD_TYPE_CACHE.put(roadType,list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应线路的仿真,并且地图类型为 MapPrdTypeEnum.BIG_SCREEN_TRAIN_POSITION
|
||||
* @param mapName
|
||||
* @return
|
||||
*/
|
||||
private List<Simulation> findSimulationList(String mapName){
|
||||
return this.simulationManager.getSimulationList().stream().filter(d->{
|
||||
if(d instanceof Simulation){
|
||||
|
@ -1,15 +1,20 @@
|
||||
package club.joylink.rtss.websocket;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.TrainPositionService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.client.SocketMessageVO;
|
||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||
import club.joylink.rtss.vo.ws.TrainPosition;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.handler.annotation.DestinationVariable;
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.security.Principal;
|
||||
|
||||
@Controller
|
||||
@ -21,7 +26,8 @@ public class WebSocketController {
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationCache groupSimulationCache;
|
||||
|
||||
@Resource
|
||||
private TrainPositionService trainPositionService;
|
||||
@MessageMapping("/simulation/{group}/vr")
|
||||
public void routingData(Principal user, String json, @DestinationVariable String group) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
@ -29,11 +35,8 @@ public class WebSocketController {
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
|
||||
@MessageMapping("/{mapId}/trainPosition")
|
||||
public void mlbs( String json,@DestinationVariable String mapId) {
|
||||
// Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
// SocketMessageVO<String> message = SocketMessageFactory.buildVrMessage(group, json);
|
||||
// stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
System.out.println("aaaaaaaaaaaaa");
|
||||
@MessageMapping("/{mapName}/trainPosition")
|
||||
public void mlbs( String json,@DestinationVariable String mapName) {
|
||||
this.trainPositionService.initTrainOrUpdate(mapName,json);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
public class StompClientManager {
|
||||
@ -26,14 +27,50 @@ public class StompClientManager {
|
||||
.connect("ws://127.0.0.1:9000/joylink-tbi-websocket",handler, "null");
|
||||
StompSession stompSession = future.get();
|
||||
|
||||
runToLeft(stompSession,"train001");
|
||||
// runToRight(stompSession,"train002");
|
||||
|
||||
}
|
||||
|
||||
public static void runToLeft(StompSession stompSession,String tripNum){
|
||||
int step = 80;
|
||||
int location = 40000;
|
||||
while(true){
|
||||
location -= step;
|
||||
Map<String,Object> dataMap = new HashMap<>();
|
||||
dataMap.put("trainTripNum","train001");
|
||||
dataMap.put("direction",1);
|
||||
dataMap.put("location",19.99);
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
dataMap.put("trainTripNum",tripNum);
|
||||
// dataMap.put("direction",1);
|
||||
dataMap.put("direction",0);
|
||||
dataMap.put("location",location);
|
||||
String val = JsonUtils.writeValueNullableFieldAsString(dataMap);
|
||||
System.out.println(val);
|
||||
stompSession.send("/app/测试中文/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
||||
stompSession.send("/app/武汉8号线/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void runToRight(StompSession stompSession,String tripNum){
|
||||
int step = 20;
|
||||
int location = 0;
|
||||
while(true){
|
||||
location += step;
|
||||
Map<String,Object> dataMap = new HashMap<>();
|
||||
dataMap.put("trainTripNum",tripNum);
|
||||
dataMap.put("direction",1);
|
||||
// dataMap.put("direction",0);
|
||||
dataMap.put("location",location);
|
||||
String val = JsonUtils.writeValueNullableFieldAsString(dataMap);
|
||||
System.out.println(val);
|
||||
stompSession.send("/app/武汉8号线/trainPosition",val.getBytes(StandardCharsets.UTF_8));
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user