Merge remote-tracking branch 'origin/test' into dev
This commit is contained in:
commit
f25f8f5972
@ -60,6 +60,7 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
whiteList.add("/api/cgy/**");
|
||||
//项目域名查询
|
||||
whiteList.add("/api/projectServer/project/{project}");
|
||||
whiteList.add("/test/simulation/**");
|
||||
registry.addInterceptor(authenticateInterceptor).excludePathPatterns(whiteList);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package club.joylink.rtss.controller.draft;
|
||||
|
||||
import club.joylink.rtss.services.draftData.DraftMapSignalApproachSectionService;
|
||||
import club.joylink.rtss.services.draftData.SignalApproachSectionGenerator;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSASQueryVO;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSignalApproachSectionVO;
|
||||
@ -18,6 +19,11 @@ public class DraftMapSignalApproachSectionController {
|
||||
@Autowired
|
||||
private DraftMapSignalApproachSectionService draftMapSignalApproachSectionService;
|
||||
|
||||
@PostMapping("/generate")
|
||||
public List<MapSignalApproachSectionVO> generate(@PathVariable Long id, @RequestBody SignalApproachSectionGenerator.Config config) {
|
||||
return this.draftMapSignalApproachSectionService.generate(id, config);
|
||||
}
|
||||
|
||||
@GetMapping("/paging")
|
||||
public PageVO<MapSignalApproachSectionVO> pagingQuery(@PathVariable Long id, MapSASQueryVO queryVO) {
|
||||
return this.draftMapSignalApproachSectionService.pagingQuery(id, queryVO);
|
||||
|
@ -42,4 +42,6 @@ public interface DraftMapService {
|
||||
void cleanAndSaveParkTime(Long mapId, List<MapStationParkingTimeVO> parkTimeList);
|
||||
|
||||
List<MapStationParkingTimeVO> queryParkTimes(Long mapId);
|
||||
|
||||
void cleanAndSaveSignalApproachSection(Long mapId, List<MapSignalApproachSectionVO> approachVOList);
|
||||
}
|
||||
|
@ -120,6 +120,12 @@ public class DraftMapServiceImpl implements DraftMapService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanAndSaveSignalApproachSection(Long mapId, List<MapSignalApproachSectionVO> approachVOList) {
|
||||
this.cleanMapApproachSection(mapId);
|
||||
this.saveMapApproachSection(mapId, approachVOList);
|
||||
}
|
||||
|
||||
private void saveMapCycle(Long mapId, List<MapAutoReentryVO> autoReentryVOList) {
|
||||
if (!CollectionUtils.isEmpty(autoReentryVOList)) {
|
||||
for (MapAutoReentryVO autoReentryVO : autoReentryVOList) {
|
||||
|
@ -7,10 +7,11 @@ import club.joylink.rtss.vo.client.map.newmap.MapSignalApproachSectionVO;
|
||||
import java.util.List;
|
||||
|
||||
public interface DraftMapSignalApproachSectionService {
|
||||
List<MapSignalApproachSectionVO> generate(Long id, SignalApproachSectionGenerator.Config config);
|
||||
|
||||
PageVO<MapSignalApproachSectionVO> pagingQuery(Long id, MapSASQueryVO queryVO);
|
||||
|
||||
List<MapSignalApproachSectionVO> queryAll(Long id);
|
||||
|
||||
void update(Long id, String signalCode, MapSignalApproachSectionVO vo);
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ import club.joylink.rtss.dao.DraftMapSignalApproachSectionDAO;
|
||||
import club.joylink.rtss.entity.DraftMapSignalApproachSection;
|
||||
import club.joylink.rtss.entity.DraftMapSignalApproachSectionExample;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepository;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepositoryBuilder;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.client.map.MapVO;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSASQueryVO;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSignalApproachSectionVO;
|
||||
import com.github.pagehelper.Page;
|
||||
@ -20,6 +23,19 @@ import java.util.stream.Collectors;
|
||||
public class DraftMapSignalApproachSectionServiceImpl implements DraftMapSignalApproachSectionService {
|
||||
@Autowired
|
||||
private DraftMapSignalApproachSectionDAO draftMapSignalApproachSectionDAO;
|
||||
@Autowired
|
||||
private DraftMapService draftMapService;
|
||||
@Autowired
|
||||
private SignalApproachSectionGenerator signalApproachSectionGenerator;
|
||||
|
||||
@Override
|
||||
public List<MapSignalApproachSectionVO> generate(Long id, SignalApproachSectionGenerator.Config config) {
|
||||
MapVO mapVO = draftMapService.getDraftMapData(id);
|
||||
CommonRepository commonRepository = CommonRepositoryBuilder.buildFrom(mapVO.getGraphDataNew());
|
||||
List<MapSignalApproachSectionVO> voList = this.signalApproachSectionGenerator.generateAll(commonRepository, config);
|
||||
this.draftMapService.cleanAndSaveSignalApproachSection(id, voList);
|
||||
return voList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageVO<MapSignalApproachSectionVO> pagingQuery(Long id, MapSASQueryVO queryVO) {
|
||||
|
@ -0,0 +1,105 @@
|
||||
package club.joylink.rtss.services.draftData;
|
||||
|
||||
import club.joylink.rtss.simulation.rt.repo.*;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSectionPathVO;
|
||||
import club.joylink.rtss.vo.client.map.newmap.MapSignalApproachSectionVO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class SignalApproachSectionGenerator {
|
||||
|
||||
public List<MapSignalApproachSectionVO> generateAll(CommonRepository commonRepository, Config config) {
|
||||
List<MapSignalApproachSectionVO> voList = new ArrayList<>();
|
||||
for (CommonSignal signal : commonRepository.getSignalMap().values()) {
|
||||
MapSignalApproachSectionVO vo = this.generate(signal, config);
|
||||
voList.add(vo);
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
|
||||
public MapSignalApproachSectionVO generate(CommonSignal signal, Config config) {
|
||||
CommonSection section = signal.getSection();
|
||||
boolean right = signal.isRight();
|
||||
int offset = signal.getOffset();
|
||||
CommonSection startSection = section;
|
||||
if (right) {
|
||||
if (offset < (section.getLen() - offset)) {
|
||||
startSection = section.getLeftSection();
|
||||
}
|
||||
} else {
|
||||
if ((section.getLen() - offset) < offset) {
|
||||
startSection = section.getRightSection();
|
||||
}
|
||||
}
|
||||
List<TrackPath> list = new ArrayList<>();
|
||||
this.queryPath(startSection, new TrackPath(!right), list, config);
|
||||
MapSignalApproachSectionVO vo = this.buildVO(signal, list);
|
||||
return vo;
|
||||
}
|
||||
|
||||
private MapSignalApproachSectionVO buildVO(CommonSignal signal, List<TrackPath> list) {
|
||||
MapSignalApproachSectionVO vo = new MapSignalApproachSectionVO();
|
||||
vo.setSignalCode(signal.getId());
|
||||
vo.setReleaseTime(180);
|
||||
vo.setSectionPathList(MapSectionPathVO.convertTrackPath2VOList(list));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private void queryPath(CommonSection section, TrackPath trackPath, List<TrackPath> list, Config config) {
|
||||
if (section == null) {
|
||||
list.add(trackPath);
|
||||
return;
|
||||
}
|
||||
if ((trackPath.calTotalLen()/1000) >= config.len) {
|
||||
list.add(trackPath);
|
||||
return;
|
||||
}
|
||||
boolean right = trackPath.isRight();
|
||||
List<CommonSignal> signals = section.getSignalOf(!right);
|
||||
if (!signals.isEmpty()) {
|
||||
trackPath.addSection(section);
|
||||
list.add(trackPath);
|
||||
return;
|
||||
}
|
||||
trackPath.addSection(section);
|
||||
if (section.isSwitchSection()) {
|
||||
CommonSwitch belongSwitch = section.getBelongSwitch();
|
||||
if (belongSwitch.isA(section)) {
|
||||
TrackPath clone = trackPath.clone();
|
||||
clone.addSection(belongSwitch.getB());
|
||||
clone.addSwitchPosition(belongSwitch, true);
|
||||
CommonSection bNext = belongSwitch.getB().queryNextBy(right);
|
||||
this.queryPath(bNext, clone, list, config);
|
||||
trackPath.addSection(belongSwitch.getC());
|
||||
trackPath.addSwitchPosition(belongSwitch, false);
|
||||
CommonSection cNext = belongSwitch.getC().queryNextBy(right);
|
||||
this.queryPath(cNext, trackPath, list, config);
|
||||
} else if (belongSwitch.isB(section)) {
|
||||
trackPath.addSection(belongSwitch.getA());
|
||||
CommonSection next = belongSwitch.getA().queryNextBy(right);
|
||||
trackPath.addSwitchPosition(belongSwitch, true);
|
||||
this.queryPath(next, trackPath, list, config);
|
||||
} else {
|
||||
trackPath.addSection(belongSwitch.getA());
|
||||
trackPath.addSwitchPosition(belongSwitch, false);
|
||||
CommonSection next = belongSwitch.getA().queryNextBy(right);
|
||||
this.queryPath(next, trackPath, list, config);
|
||||
}
|
||||
} else {
|
||||
CommonSection next = section.queryNextBy(right);
|
||||
this.queryPath(next, trackPath, list, config);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class Config {
|
||||
float len;
|
||||
boolean beyondAheadSignal;
|
||||
}
|
||||
}
|
@ -453,17 +453,17 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
this.checkPublisherExist();
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(this.messagePublisherMap.containsKey(messagePublisher.name));
|
||||
this.messagePublisherMap.put(messagePublisher.name, messagePublisher);
|
||||
if (!messagePublisher.isScheduled()) {
|
||||
return;
|
||||
}
|
||||
if (messagePublisher.isFixed()) {
|
||||
this.addFixedRateJob(messagePublisher.name, () -> {
|
||||
messagePublisher.buildAndPublish(this.messageSender);
|
||||
}, messagePublisher.rate);
|
||||
} else {
|
||||
this.addJob(messagePublisher.getName(), () -> {
|
||||
messagePublisher.buildAndPublish(this.messageSender);
|
||||
}, messagePublisher.rate);
|
||||
if ((messagePublisher instanceof SimulationScheduleMessagePublisher)) {
|
||||
SimulationScheduleMessagePublisher publisher = (SimulationScheduleMessagePublisher) messagePublisher;
|
||||
if (publisher.isFixed()) {
|
||||
this.addFixedRateJob(publisher.name, () -> {
|
||||
publisher.buildAndPublish(this.messageSender);
|
||||
}, publisher.rate);
|
||||
} else {
|
||||
this.addJob(publisher.getName(), () -> {
|
||||
publisher.buildAndPublish(this.messageSender);
|
||||
}, publisher.rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import club.joylink.rtss.simulation.vo.SimulationInfoVO;
|
||||
import club.joylink.rtss.simulation.vo.SimulationMemberVO;
|
||||
import club.joylink.rtss.simulation.vo.SimulationUserVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
@ -64,9 +65,10 @@ public class SimulationCommonController {
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/members")
|
||||
public List<SimulationMemberVO> getSimulationMembers(@PathVariable String id) {
|
||||
public List<SimulationMemberVO> getSimulationMembers(@PathVariable String id, @RequestParam(required = false) String role) {
|
||||
return this.simulationManager.getSimulationMembers(id).stream()
|
||||
.map(SimulationMember::convertToVO)
|
||||
.filter(member -> StringUtils.hasText(role) ? member.getRole().toString().equals(role) : true)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
@ -1,85 +1,82 @@
|
||||
package club.joylink.rtss.simulation;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import lombok.Getter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Getter
|
||||
public abstract class SimulationMessagePublisher {
|
||||
String name;
|
||||
boolean scheduled; // 是否定时推送
|
||||
int rate; // 消息发送频率,单位ms
|
||||
boolean fixed; // 是否固定频率
|
||||
String destinationPatten; // 订阅路径patten
|
||||
Set<String> subscribeDestinationList = new ConcurrentSkipListSet<>();
|
||||
List<String> destinationPattenList; // 订阅路径patten
|
||||
Map<String, List<String>> destinationParamsMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 消息推送线程池
|
||||
*/
|
||||
private static final ExecutorService Message_Executor = Executors.newSingleThreadExecutor();
|
||||
private static ExecutorService Message_Executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
public SimulationMessagePublisher(String name, String destinationPatten) {
|
||||
this(name, false, 0, false, destinationPatten);
|
||||
}
|
||||
|
||||
public SimulationMessagePublisher(String name, int rate, String destinationPatten) {
|
||||
this(name, true, rate, true, destinationPatten);
|
||||
}
|
||||
|
||||
public SimulationMessagePublisher(String name, int rate, boolean fixed, String destinationPatten) {
|
||||
this(name, true, rate, fixed, destinationPatten);
|
||||
}
|
||||
|
||||
public SimulationMessagePublisher(String name, boolean scheduled, int rate, boolean fixed, String destinationPatten) {
|
||||
public SimulationMessagePublisher(String name, List<String> destinationPattenList) {
|
||||
this.name = name;
|
||||
this.scheduled = scheduled;
|
||||
this.rate = rate;
|
||||
this.fixed = fixed;
|
||||
this.destinationPatten = destinationPatten;
|
||||
this.destinationPattenList = destinationPattenList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收并处理订阅路径,如果匹配上,返回true,否则返回false
|
||||
* @param destination
|
||||
* @return
|
||||
*/
|
||||
public boolean acceptedSubscribePath(String destination) {
|
||||
if (this.isMatch(destination)) {
|
||||
this.subscribeDestinationList.add(destination);
|
||||
List<String> params = this.match(destination);
|
||||
if (!params.isEmpty()) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(this.isValidParams(params));
|
||||
this.destinationParamsMap.putIfAbsent(destination, params);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ExecutorService getMessage_Executor() {
|
||||
return Message_Executor;
|
||||
}
|
||||
|
||||
public boolean isValidParams(List<String> params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void unsubscribe(String destination) {
|
||||
this.subscribeDestinationList.remove(destination);
|
||||
this.destinationParamsMap.remove(destination);
|
||||
}
|
||||
|
||||
public boolean isMatch(String destination) {
|
||||
String destPattern = this.destinationPatten;
|
||||
String[] patterns = StringUtils.tokenizeToStringArray(destPattern, "/");
|
||||
String[] dests = StringUtils.tokenizeToStringArray(destination, "/");
|
||||
if (patterns.length == dests.length) {
|
||||
for (int i = 0; i < patterns.length; i++) {
|
||||
String p = patterns[i];
|
||||
if (p.startsWith("{")) {
|
||||
continue;
|
||||
}
|
||||
if (!Objects.equals(p, dests[i])) {
|
||||
return false;
|
||||
public List<String> match(String destination) {
|
||||
List<String> params = new ArrayList<>();
|
||||
for (String destPattern : this.destinationPattenList) {
|
||||
String[] patterns = StringUtils.tokenizeToStringArray(destPattern, "/");
|
||||
String[] dests = StringUtils.tokenizeToStringArray(destination, "/");
|
||||
if (patterns.length == dests.length) {
|
||||
for (int i = 0; i < patterns.length; i++) {
|
||||
String p = patterns[i];
|
||||
if (p.startsWith("{")) {
|
||||
params.add(dests[i]);
|
||||
continue;
|
||||
}
|
||||
if (!Objects.equals(p, dests[i])) {
|
||||
params.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void buildAndPublish(SimulationMessageSender sender) {
|
||||
for (String destination : this.subscribeDestinationList) {
|
||||
Object message = this.getNextSendMessage(destination);
|
||||
if (message != null) {
|
||||
Message_Executor.execute(() -> sender.publishMessage(destination, message));
|
||||
if (!params.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public void buildAndPublishMessageOfSubscribe(SimulationMessageSender sender, String destination) {
|
||||
@ -89,7 +86,5 @@ public abstract class SimulationMessagePublisher {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Object getNextSendMessage(String destination);
|
||||
|
||||
public abstract Object buildMessageOfSubscribe(String destination);
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package club.joylink.rtss.simulation;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public abstract class SimulationScheduleMessagePublisher extends SimulationMessagePublisher {
|
||||
int rate; // 消息发送频率,单位ms
|
||||
boolean fixed; // 是否固定频率
|
||||
|
||||
public SimulationScheduleMessagePublisher(String name, int rate, boolean fixed, List<String> destinationPattenList) {
|
||||
super(name, destinationPattenList);
|
||||
this.rate = rate;
|
||||
this.fixed = fixed;
|
||||
}
|
||||
|
||||
public void buildAndPublish(SimulationMessageSender sender) {
|
||||
for (String destination : this.destinationParamsMap.keySet()) {
|
||||
Object message = this.buildNextSendMessage(destination);
|
||||
if (message != null) {
|
||||
getMessage_Executor().execute(() -> sender.publishMessage(destination, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Object buildNextSendMessage(String destination);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package club.joylink.rtss.simulation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SimulationTriggerMessagePublisher extends SimulationMessagePublisher implements Watcher {
|
||||
|
||||
public SimulationTriggerMessagePublisher(String name, List<String> destinationPattenList) {
|
||||
super(name, destinationPattenList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要此监控对象消息的订阅路径
|
||||
* @param watchable
|
||||
* @return
|
||||
*/
|
||||
public abstract List<String> getNeedBuildDestination(Watchable watchable);
|
||||
|
||||
/**
|
||||
* 构建监控对象消息
|
||||
* @param watchable
|
||||
* @return
|
||||
*/
|
||||
public abstract Object buildMessage(Watchable watchable);
|
||||
|
||||
@Override
|
||||
public void handleStateChange(Simulation simulation, Watchable watchable) {
|
||||
List<String> destinationList = this.getNeedBuildDestination(watchable);
|
||||
if (!destinationList.isEmpty()) {
|
||||
Object message = this.buildMessage(watchable);
|
||||
if (message != null) {
|
||||
for (String destination : destinationList) {
|
||||
getMessage_Executor().execute(() -> simulation.getMessageSender().publishMessage(destination, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +1,30 @@
|
||||
package club.joylink.rtss.simulation;
|
||||
|
||||
public class StateMessagePublisher extends SimulationMessagePublisher implements Watcher<Simulation> {
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class StateMessagePublisher extends SimulationTriggerMessagePublisher {
|
||||
public static final String Name = "state-sync";
|
||||
public static final String Destination = String.format("%s/%s", Simulation.MESSAGE_SUB_PREFIX, "state");
|
||||
Simulation simulation;
|
||||
public StateMessagePublisher(Simulation simulation) {
|
||||
super(Name, String.format("%s/%s", Simulation.MESSAGE_SUB_PREFIX, "state"));
|
||||
super(Name, Arrays.asList(Destination));
|
||||
this.simulation = simulation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextSendMessage(String destination) {
|
||||
public List<String> getNeedBuildDestination(Watchable watchable) {
|
||||
return new ArrayList<>(this.destinationParamsMap.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessage(Watchable watchable) {
|
||||
return this.simulation.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessageOfSubscribe(String destination) {
|
||||
return this.getNextSendMessage(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStateChange(Simulation simulation, Simulation watchable) {
|
||||
this.buildAndPublish(watchable.getMessageSender());
|
||||
return this.buildMessage(this.simulation);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,22 @@
|
||||
package club.joylink.rtss.simulation;
|
||||
|
||||
public class SysTimeMessagePublisher extends SimulationMessagePublisher {
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SysTimeMessagePublisher extends SimulationScheduleMessagePublisher {
|
||||
Simulation simulation;
|
||||
public static final String Destination = String.format("%s/%s", Simulation.MESSAGE_SUB_PREFIX, "sysTime");
|
||||
public SysTimeMessagePublisher(Simulation simulation) {
|
||||
super("sys-time-sync", 1000, String.format("%s/%s", Simulation.MESSAGE_SUB_PREFIX, "sysTime"));
|
||||
super("sys-time-sync", 1000, false, Arrays.asList(Destination));
|
||||
this.simulation = simulation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextSendMessage(String destination) {
|
||||
public Object buildNextSendMessage(String destination) {
|
||||
return this.simulation.getSystemTime().toLocalTime().toSecondOfDay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessageOfSubscribe(String destination) {
|
||||
return this.getNextSendMessage(destination);
|
||||
return this.buildNextSendMessage(destination);
|
||||
}
|
||||
}
|
||||
|
@ -493,6 +493,14 @@ public class Signal extends MayOutOfOrderDevice {
|
||||
* 调车信号机
|
||||
*/
|
||||
SHUNTING,
|
||||
/**
|
||||
* 进站信号机
|
||||
*/
|
||||
ARRIVAL,
|
||||
/**
|
||||
* 出站信号机
|
||||
*/
|
||||
EXIT,
|
||||
}
|
||||
|
||||
public enum SignalFault implements DeviceFault {
|
||||
|
@ -1,17 +1,14 @@
|
||||
package club.joylink.rtss.simulation.rt.ATS;
|
||||
|
||||
import club.joylink.rtss.simulation.Simulation;
|
||||
import club.joylink.rtss.simulation.SimulationMessagePublisher;
|
||||
import club.joylink.rtss.simulation.SimulationScheduleMessagePublisher;
|
||||
import club.joylink.rtss.simulation.rt.ATS.bo.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AtsMessagePublisher extends SimulationMessagePublisher {
|
||||
public class AtsMessagePublisher extends SimulationScheduleMessagePublisher {
|
||||
public static final String NAME = "AtsMP";
|
||||
public static final int RATE = 1000;
|
||||
public static final String DESTINATION = String.format("%s%s", Simulation.MESSAGE_SUB_PREFIX, "/ats");
|
||||
@ -23,7 +20,7 @@ public class AtsMessagePublisher extends SimulationMessagePublisher {
|
||||
Map<String, List<Object>> routeMap = new ConcurrentHashMap<>();
|
||||
|
||||
public AtsMessagePublisher(AtsRepository atsRepository) {
|
||||
super(NAME, RATE, DESTINATION);
|
||||
super(NAME, RATE, true, Arrays.asList(DESTINATION));
|
||||
this.atsRepository = atsRepository;
|
||||
this.buildMessage(atsRepository);
|
||||
}
|
||||
@ -67,7 +64,7 @@ public class AtsMessagePublisher extends SimulationMessagePublisher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextSendMessage(String destination) {
|
||||
public Object buildNextSendMessage(String destination) {
|
||||
HashMap<Object, Object> message = new HashMap<>();
|
||||
if (!this.switchMap.isEmpty()) {
|
||||
message.put("switch", new ArrayList<>(this.switchMap.values()));
|
||||
|
@ -125,6 +125,7 @@ public class CilLogicService {
|
||||
}
|
||||
|
||||
private void mainLogic(RtSimulation rtSimulation, CilRepository cilRepository) {
|
||||
this.cilRouteLogicService.ciTriggerRoute(rtSimulation, cilRepository);
|
||||
this.cilRouteLogicService.routeLogic(rtSimulation, cilRepository);
|
||||
this.cilSectionLogicService.mainLogic(rtSimulation, cilRepository);
|
||||
}
|
||||
|
@ -3,12 +3,16 @@ package club.joylink.rtss.simulation.rt.CIL;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.rt.CIL.bo.*;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrTrain;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrdRepository;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.TrackPosition;
|
||||
import club.joylink.rtss.simulation.rt.repo.*;
|
||||
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.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@ -22,6 +26,32 @@ public class CilRouteLogicService {
|
||||
@Autowired
|
||||
private CilSignalLogicService cilSignalLogicService;
|
||||
|
||||
public void ciTriggerRoute(RtSimulation rtSimulation, CilRepository cilRepository) {
|
||||
SrdRepository srdRepository = SrdRepository.getInstanceFrom(rtSimulation);
|
||||
for (SrTrain srTrain : srdRepository.getTrainList()) {
|
||||
TrackPosition position = srTrain.getHeadPosition();
|
||||
if (position == null) {
|
||||
continue;
|
||||
}
|
||||
boolean right = srTrain.isRight();
|
||||
// 获取区段接近信号机列表
|
||||
List<CommonSignal> approachSignalList = cilRepository.getApproachSignalOf(position.getTrack().getId());
|
||||
for (CommonSignal commonSignal : approachSignalList) {
|
||||
if (!Objects.equals(commonSignal.isRight(), right) || commonSignal.isShunting()) {
|
||||
continue;
|
||||
} else {
|
||||
CommonRoute route = commonSignal.getRouteList().stream()
|
||||
.sorted(Comparator.comparing(commonRoute -> commonRoute.getPathElement().getReverseSwitchCount()))
|
||||
.findFirst().get();
|
||||
if (!cilRepository.isSupervised(route.getId())) {
|
||||
this.setRoute(rtSimulation, route.getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void routeLogic(RtSimulation rtSimulation, CilRepository cilRepository) {
|
||||
List<CilRoute> supervisedRouteList = cilRepository.getSupervisedRouteList();
|
||||
for (CilRoute cilRoute : supervisedRouteList) {
|
||||
|
@ -51,10 +51,10 @@ public class CilSignalLogicService {
|
||||
CommonRepository commonRepository = simulation.getRepository(CommonRepository.NAME, CommonRepository.class);
|
||||
CilRepository cilRepository = simulation.getRepository(CilRepository.NAME, CilRepository.class);
|
||||
CommonSignal commonSignal = commonRepository.getSignalById(signalId);
|
||||
List<TrackWay> approachList = commonSignal.getApproachList();
|
||||
List<TrackPath> approachList = commonSignal.getApproachList();
|
||||
if (!CollectionUtils.isEmpty(approachList)) {
|
||||
for (TrackWay trackWay : approachList) {
|
||||
List<CommonSection> sectionList = trackWay.getAllSectionList();
|
||||
for (TrackPath trackPath : approachList) {
|
||||
List<CommonSection> sectionList = trackPath.getSectionList();
|
||||
if (!CollectionUtils.isEmpty(sectionList)) {
|
||||
for (CommonSection commonSection : sectionList) {
|
||||
if (cilRepository.getSectionById(commonSection.getId()).isAxcOccupy()) {
|
||||
|
@ -2,8 +2,10 @@ package club.joylink.rtss.simulation.rt.CIL.bo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.SimulationRepository;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepository;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSection;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSignal;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSwitch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -190,4 +192,12 @@ public class CilRepository extends SimulationRepository {
|
||||
}
|
||||
|
||||
|
||||
public List<CommonSignal> getApproachSignalOf(String sectionId) {
|
||||
CommonRepository commonRepository = CommonRepository.getInstanceFrom((RtSimulation) this.getSimulation());
|
||||
List<CommonSignal> signals = commonRepository.getApproachSignalMap().get(sectionId);
|
||||
if (signals != null) {
|
||||
return signals;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package club.joylink.rtss.simulation.rt;
|
||||
|
||||
import club.joylink.rtss.constants.MapPrdTypeEnum;
|
||||
import club.joylink.rtss.constants.Project;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.MapService;
|
||||
import club.joylink.rtss.simulation.SimulationManager;
|
||||
@ -10,6 +11,7 @@ import club.joylink.rtss.simulation.rt.SRD.SrdLogicService;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrTrain;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrdRepository;
|
||||
import club.joylink.rtss.simulation.rt.TL.TlLogicService;
|
||||
import club.joylink.rtss.simulation.rt.operation.SrTrainOperationHandler;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepoService;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepository;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonStation;
|
||||
@ -38,6 +40,9 @@ public class RtSimulationService {
|
||||
@Autowired
|
||||
private TlLogicService tlLogicService;
|
||||
|
||||
@Autowired
|
||||
private SrTrainOperationHandler srTrainOperationHandler;
|
||||
|
||||
public RtSimulation create(UserVO userVO, Long mapId, MapPrdTypeEnum prdTypeEnum) {
|
||||
Objects.requireNonNull(mapId);
|
||||
MapVO mapVO = this.mapService.getMapDetail(mapId);
|
||||
@ -48,21 +53,37 @@ public class RtSimulationService {
|
||||
rtSimulation.mapVO = mapVO;
|
||||
this.loading(rtSimulation, mapVO);
|
||||
this.initSimulationMember(rtSimulation);
|
||||
this.initCreatorPlayMember(rtSimulation);
|
||||
this.initCreatorPlayMember(rtSimulation, mapVO);
|
||||
} catch (Exception e) {
|
||||
this.simulationManager.destroy(rtSimulation.getId());
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(String.format("仿真初始化失败"), e);
|
||||
}
|
||||
rtSimulation.init();
|
||||
// 郑州共赢驾驶默认加载一辆列车
|
||||
if (Objects.equals(Project.ZZWW.name(), mapVO.getProjectCode()) &&
|
||||
Objects.equals(MapPrdTypeEnum.DRIVER, prdTypeEnum)) {
|
||||
this.srTrainOperationHandler.loadTrain(rtSimulation, "001", true, "T21");
|
||||
}
|
||||
simulationManager.start(rtSimulation.getId());
|
||||
return rtSimulation;
|
||||
}
|
||||
|
||||
private void initCreatorPlayMember(RtSimulation rtSimulation) {
|
||||
private void initCreatorPlayMember(RtSimulation rtSimulation, MapVO mapVO) {
|
||||
// RtSimulationMember simulationMember = rtSimulation.querySimulationMemberById("2");
|
||||
// List<RtSimulationMember> memberList = rtSimulation.querySimulationMembersOfRole(RtSimulationMember.Role.LOWS);
|
||||
// 大铁暂时默认新绛站值班员
|
||||
this.simulationManager.memberPlayedByUser(rtSimulation.getId(), "2", rtSimulation.getCreator().getId());
|
||||
// 大铁微机联锁项目默认新绛站值班员
|
||||
if (Objects.equals(Project.WJLS.name(), mapVO.getProjectCode())) {
|
||||
this.simulationManager.memberPlayedByUser(rtSimulation.getId(), "2", rtSimulation.getCreator().getId());
|
||||
} else {
|
||||
String memberId = "1";
|
||||
for (RtSimulationMember rtSimulationMember : rtSimulation.getSimulationMembers()) {
|
||||
if (Objects.equals("001", rtSimulationMember.deviceId)) {
|
||||
memberId = rtSimulationMember.getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.simulationManager.memberPlayedByUser(rtSimulation.getId(), memberId, rtSimulation.getCreator().getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void initSimulationMember(RtSimulation rtSimulation) {
|
||||
|
@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.rt.SRD;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||
import club.joylink.rtss.simulation.rt.TL.bo.TlRepository;
|
||||
import club.joylink.rtss.simulation.rt.TL.bo.TlTrain;
|
||||
import club.joylink.rtss.vo.client.map.MapVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -26,20 +28,30 @@ public class SrdLogicService {
|
||||
// 加载数据
|
||||
SrdRepository srdRepository = SrdRepositoryBuilder.buildFrom(mapVO);
|
||||
rtSimulation.addRepository(srdRepository);
|
||||
SrdStateMessagePublisher srdStateMessagePublisher = new SrdStateMessagePublisher(rtSimulation);
|
||||
rtSimulation.addMessagePublisher(srdStateMessagePublisher);
|
||||
// 监控对象
|
||||
for (SrSwitch srSwitch : srdRepository.getSwitchList()) {
|
||||
rtSimulation.watch(srSwitch);
|
||||
rtSimulation.watch(srSwitch, srdStateMessagePublisher);
|
||||
}
|
||||
for (SrSignal srSignal : srdRepository.getSignalList()) {
|
||||
rtSimulation.watch(srSignal);
|
||||
rtSimulation.watch(srSignal, srdStateMessagePublisher);
|
||||
}
|
||||
for (SrAXC srAXC : srdRepository.getAxcList()) {
|
||||
rtSimulation.watch(srAXC);
|
||||
rtSimulation.watch(srAXC, srdStateMessagePublisher);
|
||||
}
|
||||
for (SrPSD srPSD : srdRepository.getPsdList()) {
|
||||
rtSimulation.watch(srPSD);
|
||||
rtSimulation.watch(srPSD, srdStateMessagePublisher);
|
||||
}
|
||||
SrdTrainMessagePublisher publisher = new SrdTrainMessagePublisher(srdRepository);
|
||||
rtSimulation.addMessagePublisher(publisher);
|
||||
// 加载任务
|
||||
this.addJobs(rtSimulation);
|
||||
|
||||
return srdRepository;
|
||||
}
|
||||
|
||||
@ -93,8 +105,9 @@ public class SrdLogicService {
|
||||
if (position == null) {
|
||||
continue;
|
||||
}
|
||||
this.tryUpdateDirection(srTrain, repository);
|
||||
boolean right = srTrain.isRight();
|
||||
float cv = this.calculateSpeed(srTrain);
|
||||
float cv = this.calculateSpeed(srTrain, repository);
|
||||
int s = this.calculateLen(srTrain, cv, TRAIN_RUN_RATE);
|
||||
// if (s == 0) {
|
||||
// continue;
|
||||
@ -120,6 +133,11 @@ public class SrdLogicService {
|
||||
}
|
||||
}
|
||||
|
||||
private void tryUpdateDirection(SrTrain srTrain, SrdRepository repository) {
|
||||
TlTrain tlTrain = TlRepository.getInstanceFrom((RtSimulation) repository.getSimulation()).getTrainById(srTrain.getId());
|
||||
srTrain.updateDirection(tlTrain.calGear());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param srTrain
|
||||
@ -135,31 +153,14 @@ public class SrdLogicService {
|
||||
} else {
|
||||
s = (int) l;
|
||||
}
|
||||
if (!srTrain.isNeutralGear()) {
|
||||
return s * srTrain.getGear();
|
||||
}
|
||||
return s;
|
||||
return s * srTrain.getDirection();
|
||||
}
|
||||
|
||||
private float calculateSpeed(SrTrain srTrain) {
|
||||
private float calculateSpeed(SrTrain srTrain, SrdRepository repository) {
|
||||
float speed = srTrain.getSpeed();
|
||||
// 暂时不考虑在前进挡中直接切到倒挡的情况
|
||||
float maxSpeed = srTrain.getP() * srTrain.getSpeedMax() / 100;
|
||||
float f = 0;
|
||||
if (speed > maxSpeed) {
|
||||
f -= srTrain.getFbDef();
|
||||
} else if (speed < maxSpeed) {
|
||||
f += srTrain.getFkMax() / srTrain.getSpeedMax() * (maxSpeed - speed);
|
||||
float fkMin = (float) (0.3 * srTrain.getMass());
|
||||
if (f < fkMin) {
|
||||
f = fkMin;
|
||||
}
|
||||
}
|
||||
if (srTrain.isEb()) {
|
||||
f -= srTrain.getFbMax();
|
||||
} else {
|
||||
f -= srTrain.getBp() * srTrain.getFbMax() / 100 * 0.6f;
|
||||
}
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom((RtSimulation) repository.getSimulation());
|
||||
TlTrain tlTrain = tlRepository.getTrainById(srTrain.getId());
|
||||
float f = tlTrain.calculateF();
|
||||
float a = f / (srTrain.getMass() + srTrain.getLoadMass());
|
||||
float cv = (speed + a * TRAIN_RUN_RATE / 1000); // 当前速度
|
||||
if (cv < 0) {
|
||||
@ -168,6 +169,15 @@ public class SrdLogicService {
|
||||
return cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算列车摩擦阻力
|
||||
* @param srTrain
|
||||
* @return
|
||||
*/
|
||||
private float calculateFriction(SrTrain srTrain) {
|
||||
return (float) (0.05*(srTrain.getMass() +srTrain.getLoadMass()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param position 起始位置
|
||||
@ -180,6 +190,10 @@ public class SrdLogicService {
|
||||
if (s == 0) {
|
||||
return position;
|
||||
}
|
||||
if (s < 0) {
|
||||
right = !right;
|
||||
s = Math.abs(s);
|
||||
}
|
||||
SrTrack track = position.getTrack();
|
||||
int offset = position.getOffset();
|
||||
if (right) {
|
||||
|
@ -0,0 +1,149 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD;
|
||||
|
||||
import club.joylink.rtss.simulation.Simulation;
|
||||
import club.joylink.rtss.simulation.SimulationTriggerMessagePublisher;
|
||||
import club.joylink.rtss.simulation.Watchable;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SrdStateMessagePublisher extends SimulationTriggerMessagePublisher {
|
||||
public static final String Name = "SrdStateMP";
|
||||
public static final String SrDeviceStatePath = "/srDeviceState";
|
||||
private static final String AllDevicePatten = String.format("%s%s", Simulation.MESSAGE_SUB_PREFIX, SrDeviceStatePath);
|
||||
public static final String SrSignalPath = "/srSignal";
|
||||
private static final String SignalPatten = String.format("%s%s%s", Simulation.MESSAGE_SUB_PREFIX, SrSignalPath, "/{signalId}");
|
||||
public static final String SrSwitchPath = "/srSwitch";
|
||||
private static final String SwitchPatten = String.format("%s%s%s", Simulation.MESSAGE_SUB_PREFIX, SrSwitchPath, "/{switchId}");
|
||||
public static final String SrAxcPath = "/srAxc";
|
||||
private static final String AxcPatten = String.format("%s%s%s", Simulation.MESSAGE_SUB_PREFIX, SrAxcPath, "/{axcId}");
|
||||
public static final String SrPsdPath = "/srPsd";
|
||||
private static final String PsdPatten = String.format("%s%s%s", Simulation.MESSAGE_SUB_PREFIX, SrPsdPath, "/{psdId}");
|
||||
|
||||
RtSimulation simulation;
|
||||
public SrdStateMessagePublisher(RtSimulation simulation) {
|
||||
super(Name, Arrays.asList(AllDevicePatten, SignalPatten, SwitchPatten, AxcPatten, PsdPatten));
|
||||
this.simulation = simulation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessageOfSubscribe(String destination) {
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
if (destination.contains(SrDeviceStatePath)) {
|
||||
return this.buildAllSrDeviceMessage();
|
||||
} else if(destination.contains(SrSignalPath)) {
|
||||
return this.buildSignalMessage(SrdRepository.getInstanceFrom(simulation).getSignalById(this.getDestinationParamsMap().get(destination).get(1)));
|
||||
} else if(destination.contains(SrSwitchPath)) {
|
||||
return this.buildSwitchMessage(SrdRepository.getInstanceFrom(simulation).getSwitchById(this.getDestinationParamsMap().get(destination).get(1)));
|
||||
} else if(destination.contains(SrAxcPath)) {
|
||||
return this.buildAxcMessage(SrdRepository.getInstanceFrom(simulation).getAxcById(this.getDestinationParamsMap().get(destination).get(1)));
|
||||
} else if(destination.contains(SrPsdPath)) {
|
||||
return this.buildPsdMessage(SrdRepository.getInstanceFrom(simulation).getPsdById(this.getDestinationParamsMap().get(destination).get(1)));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Object buildAllSrDeviceMessage() {
|
||||
Map<String, List<List<Object>>> map = new HashMap<>();
|
||||
SrdRepository srdRepository = SrdRepository.getInstanceFrom(this.simulation);
|
||||
List<List<Object>> signalMsgList = new ArrayList<>();
|
||||
for (SrSignal srSignal : srdRepository.getSignalList()) {
|
||||
signalMsgList.add(srSignal.getStateList());
|
||||
}
|
||||
map.put("srSignalList", signalMsgList);
|
||||
List<List<Object>> switchMsgList = new ArrayList<>();
|
||||
for (SrSwitch srSwitch : srdRepository.getSwitchList()) {
|
||||
switchMsgList.add(srSwitch.getStateList());
|
||||
}
|
||||
map.put("srSwitchList", switchMsgList);
|
||||
List<List<Object>> axcMsgList = new ArrayList<>();
|
||||
for (SrAXC srAXC : srdRepository.getAxcList()) {
|
||||
axcMsgList.add(srAXC.getStateList());
|
||||
}
|
||||
map.put("srAxcList", axcMsgList);
|
||||
List<List<Object>> psdMsgList = new ArrayList<>();
|
||||
for (SrPSD srPSD : srdRepository.getPsdList()) {
|
||||
psdMsgList.add(srPSD.getStateList());
|
||||
}
|
||||
map.put("srPsdList", psdMsgList);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNeedBuildDestination(Watchable watchable) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (String destination : this.getDestinationParamsMap().keySet()) {
|
||||
if (destination.contains(SrDeviceStatePath)) {
|
||||
list.add(destination);
|
||||
} else {
|
||||
List<String> params = this.getDestinationParamsMap().get(destination);
|
||||
if (destination.contains(SrSignalPath)) {
|
||||
if (watchable instanceof SrSignal) {
|
||||
if (((SrSignal) watchable).getId().equals(params.get(1))) {
|
||||
list.add(destination);
|
||||
}
|
||||
}
|
||||
} else if (destination.contains(SrSwitchPath)) {
|
||||
if (watchable instanceof SrSwitch) {
|
||||
if (((SrSwitch) watchable).getId().equals(params.get(1))) {
|
||||
list.add(destination);
|
||||
}
|
||||
}
|
||||
} else if (destination.contains(SrAxcPath)) {
|
||||
if (watchable instanceof SrAXC) {
|
||||
if (((SrAXC) watchable).getId().equals(params.get(1))) {
|
||||
list.add(destination);
|
||||
}
|
||||
}
|
||||
} else if (destination.contains(SrPsdPath)) {
|
||||
if (watchable instanceof SrPSD) {
|
||||
if (((SrPSD) watchable).getId().equals(params.get(1))) {
|
||||
list.add(destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessage(Watchable watchable) {
|
||||
if (watchable instanceof SrSignal) {
|
||||
return this.buildSignalMessage((SrSignal) watchable);
|
||||
} else if (watchable instanceof SrSwitch) {
|
||||
return this.buildSwitchMessage((SrSwitch) watchable);
|
||||
} else if (watchable instanceof SrAXC) {
|
||||
return this.buildAxcMessage((SrAXC) watchable);
|
||||
} else if (watchable instanceof SrPSD) {
|
||||
return this.buildPsdMessage((SrPSD) watchable);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Object buildSignalMessage(SrSignal srSignal) {
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
map.put("srSignal", srSignal.getStateList());
|
||||
return map;
|
||||
}
|
||||
|
||||
private Object buildSwitchMessage(SrSwitch srSwitch) {
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
map.put("srSwitch", srSwitch.getStateList());
|
||||
return map;
|
||||
}
|
||||
|
||||
private Object buildAxcMessage(SrAXC srAXC) {
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
map.put("srAxc", srAXC.getStateList());
|
||||
return map;
|
||||
}
|
||||
|
||||
private Object buildPsdMessage(SrPSD srPSD) {
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
map.put("srPsd", srPSD.getStateList());
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,14 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD;
|
||||
|
||||
import club.joylink.rtss.simulation.Simulation;
|
||||
import club.joylink.rtss.simulation.SimulationMessagePublisher;
|
||||
import club.joylink.rtss.simulation.SimulationScheduleMessagePublisher;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrTrain;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrdRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SrdTrainMessagePublisher extends SimulationMessagePublisher {
|
||||
public class SrdTrainMessagePublisher extends SimulationScheduleMessagePublisher {
|
||||
public static final String NAME = "SrTrainMP";
|
||||
public static final int RATE = 20;
|
||||
public static final String DESTINATION = String.format("%s%s", Simulation.MESSAGE_SUB_PREFIX, "/trainPosition");
|
||||
@ -19,7 +16,7 @@ public class SrdTrainMessagePublisher extends SimulationMessagePublisher {
|
||||
Map<String, List<Object>> trainPositionMap = new ConcurrentHashMap<>();
|
||||
|
||||
public SrdTrainMessagePublisher(SrdRepository srdRepository) {
|
||||
super(NAME, RATE, DESTINATION);
|
||||
super(NAME, RATE, true, Arrays.asList(DESTINATION));
|
||||
List<SrTrain> trainList = srdRepository.getTrainList();
|
||||
for (SrTrain train : trainList) {
|
||||
this.trainPositionMap.put(train.getId(), train.getStateList());
|
||||
@ -27,7 +24,7 @@ public class SrdTrainMessagePublisher extends SimulationMessagePublisher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextSendMessage(String destination) {
|
||||
public Object buildNextSendMessage(String destination) {
|
||||
Map<String, List<List<Object>>> map = new HashMap<>();
|
||||
List<List<Object>> trainList = new ArrayList<>();
|
||||
map.put("trainPosList", trainList);
|
||||
@ -44,6 +41,6 @@ public class SrdTrainMessagePublisher extends SimulationMessagePublisher {
|
||||
|
||||
@Override
|
||||
public Object buildMessageOfSubscribe(String destination) {
|
||||
return this.getNextSendMessage(destination);
|
||||
return this.buildNextSendMessage(destination);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
|
||||
public enum DeviceType {
|
||||
/** 计轴器 */
|
||||
AXC,
|
||||
/** 道岔 */
|
||||
TURNOUT,
|
||||
/** 信号机 */
|
||||
SIGNAL,
|
||||
/** 站台屏蔽门 */
|
||||
PSD,
|
||||
TRAIN,
|
||||
/** 轨道 */
|
||||
TRACK
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -11,16 +12,18 @@ public class SrAXC extends SrDevice {
|
||||
int state = OFF;
|
||||
public static final int OFF = 0;//出清
|
||||
public static final int ON = 1;//占用
|
||||
boolean right; // 占用方向
|
||||
|
||||
Fault fault;
|
||||
|
||||
public SrAXC(String id) {
|
||||
super(id, DeviceType.AXC);
|
||||
super(id);
|
||||
}
|
||||
|
||||
private boolean updateState(int state) {
|
||||
if (this.state != state) {
|
||||
this.state = state;
|
||||
this.stateList.set(1, this.state);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -44,7 +47,7 @@ public class SrAXC extends SrDevice {
|
||||
|
||||
@Override
|
||||
public void initState() {
|
||||
this.state = OFF;
|
||||
this.updateState(OFF);
|
||||
this.fault = null;
|
||||
this.fireWatcher();
|
||||
}
|
||||
@ -56,7 +59,7 @@ public class SrAXC extends SrDevice {
|
||||
|
||||
@Override
|
||||
List<Object> buildMessage() {
|
||||
return null;
|
||||
return Arrays.asList(this.id, this.state);
|
||||
}
|
||||
|
||||
public void setFault(Fault fault) {
|
||||
|
@ -13,7 +13,6 @@ import java.util.Objects;
|
||||
@Getter
|
||||
public abstract class SrDevice extends Watchable implements Debug {
|
||||
String id;
|
||||
DeviceType deviceType;
|
||||
List<Object> stateList;
|
||||
|
||||
/**
|
||||
@ -23,9 +22,8 @@ public abstract class SrDevice extends Watchable implements Debug {
|
||||
|
||||
public SrDevice() {}
|
||||
|
||||
public SrDevice(String id, DeviceType deviceType) {
|
||||
public SrDevice(String id) {
|
||||
this.id = id;
|
||||
this.deviceType = deviceType;
|
||||
this.stateList = this.buildMessage();
|
||||
}
|
||||
|
||||
@ -35,7 +33,7 @@ public abstract class SrDevice extends Watchable implements Debug {
|
||||
|
||||
@Override
|
||||
public String debugStr() {
|
||||
return String.format("%s:%s", this.deviceType, this.id);
|
||||
return String.format("%s:%s", getClass().getSimpleName(), this.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,10 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 虚拟真实屏蔽门(Platform screen door)
|
||||
@ -17,15 +18,15 @@ public class SrPSD extends SrDevice {
|
||||
public static final int TURNING = 3;//转换中
|
||||
public static final int OPEN_FINISH = 4;//打开到位
|
||||
|
||||
AtomicInteger command = new AtomicInteger(NONE);
|
||||
public static final int NONE = 0;//无动作
|
||||
int command;
|
||||
public static final int NONE = -1;//无动作
|
||||
/**
|
||||
* 转换完成时间
|
||||
*/
|
||||
LocalDateTime finishTime;
|
||||
|
||||
public SrPSD(String id) {
|
||||
super(id, DeviceType.PSD);
|
||||
super(id);
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
@ -33,7 +34,36 @@ public class SrPSD extends SrDevice {
|
||||
}
|
||||
|
||||
public boolean isTurning() {
|
||||
return NONE != this.command.get();
|
||||
return NONE != this.command;
|
||||
}
|
||||
|
||||
private boolean updateState(int state) {
|
||||
if (this.state != state) {
|
||||
this.state = state;
|
||||
this.stateList.set(1, this.state);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean updateCommand(int command) {
|
||||
if (this.command != command) {
|
||||
this.command = (command);
|
||||
this.stateList.set(2, this.command);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean updateFinishTime(LocalDateTime finishTime) {
|
||||
if (!Objects.equals(this.finishTime, finishTime)) {
|
||||
this.finishTime = finishTime;
|
||||
// this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void open(LocalDateTime systemTime) {
|
||||
@ -45,9 +75,9 @@ public class SrPSD extends SrDevice {
|
||||
}
|
||||
|
||||
private void startTurn(LocalDateTime systemTime, int command) {
|
||||
this.finishTime = systemTime.plusNanos(TimeUnit.MILLISECONDS.toNanos(turnTime));
|
||||
this.command.set(command);
|
||||
this.state = TURNING;
|
||||
this.updateFinishTime(systemTime.plusNanos(TimeUnit.MILLISECONDS.toNanos(turnTime)));
|
||||
this.updateCommand(command);
|
||||
this.updateState(TURNING);
|
||||
}
|
||||
|
||||
public void tryFinishTurning(LocalDateTime systemTime) {
|
||||
@ -57,16 +87,16 @@ public class SrPSD extends SrDevice {
|
||||
}
|
||||
|
||||
public void turnFinish() {
|
||||
this.state = this.command.get();
|
||||
this.command.set(NONE);
|
||||
this.finishTime = null;
|
||||
this.updateState(this.command);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initState() {
|
||||
this.state = CLOSE_LOCK;
|
||||
this.command.set(NONE);
|
||||
this.finishTime = null;
|
||||
this.updateState(CLOSE_LOCK);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,6 +110,6 @@ public class SrPSD extends SrDevice {
|
||||
|
||||
@Override
|
||||
List<Object> buildMessage() {
|
||||
return null;
|
||||
return Arrays.asList(this.id, this.state, this.command);
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 虚拟真实信号机
|
||||
@ -32,7 +32,7 @@ public class SrSignal extends SrDevice {
|
||||
public static final int B = 11; // 白
|
||||
public static final int HS = 12; // 红闪
|
||||
|
||||
AtomicInteger command = new AtomicInteger(NONE);
|
||||
int command;
|
||||
public static final int NONE = -1;
|
||||
/**
|
||||
* 转换完成时间
|
||||
@ -40,12 +40,13 @@ public class SrSignal extends SrDevice {
|
||||
LocalDateTime finishTime;
|
||||
|
||||
public SrSignal(String id) {
|
||||
super(id, DeviceType.SIGNAL);
|
||||
super(id);
|
||||
}
|
||||
|
||||
private boolean updateState(int state) {
|
||||
public boolean updateState(int state) {
|
||||
if (this.state != state) {
|
||||
this.state = state;
|
||||
this.stateList.set(1, this.state);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -53,8 +54,8 @@ public class SrSignal extends SrDevice {
|
||||
}
|
||||
|
||||
private boolean updateCommand(int command) {
|
||||
if (this.command.get() != command) {
|
||||
this.command.set(command);
|
||||
if (this.command != command) {
|
||||
this.command = (command);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -64,7 +65,7 @@ public class SrSignal extends SrDevice {
|
||||
private boolean updateFinishTime(LocalDateTime finishTime) {
|
||||
if (!Objects.equals(this.finishTime, finishTime)) {
|
||||
this.finishTime = finishTime;
|
||||
this.fireWatcher();
|
||||
// this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -75,7 +76,7 @@ public class SrSignal extends SrDevice {
|
||||
}
|
||||
|
||||
public boolean isTurning() {
|
||||
return NONE != this.command.get();
|
||||
return NONE != this.command;
|
||||
}
|
||||
|
||||
public void close(LocalDateTime systemTime) {
|
||||
@ -110,7 +111,7 @@ public class SrSignal extends SrDevice {
|
||||
}
|
||||
|
||||
public void turnFinish() {
|
||||
this.updateState(this.command.get());
|
||||
this.updateState(this.command);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
@ -121,9 +122,9 @@ public class SrSignal extends SrDevice {
|
||||
if (this.shunting) {
|
||||
state = A;
|
||||
}
|
||||
this.state = state;
|
||||
this.command.set(NONE);
|
||||
this.finishTime = null;
|
||||
this.updateState(state);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -137,7 +138,7 @@ public class SrSignal extends SrDevice {
|
||||
|
||||
@Override
|
||||
List<Object> buildMessage() {
|
||||
return null;
|
||||
return Arrays.asList(this.id, this.state);
|
||||
}
|
||||
|
||||
public void open(LocalDateTime systemTime, int aspect) {
|
||||
|
@ -3,10 +3,10 @@ package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 虚拟真实道岔
|
||||
@ -21,7 +21,7 @@ public class SrSwitch extends SrDevice {
|
||||
public static final int REVERSE = 2; // 反位
|
||||
public static final int SQUEEZING = 4; // 挤叉
|
||||
|
||||
AtomicInteger command = new AtomicInteger(NONE);
|
||||
int command;
|
||||
public static final int NONE = -1;
|
||||
/**
|
||||
* 转换完成时间
|
||||
@ -29,12 +29,13 @@ public class SrSwitch extends SrDevice {
|
||||
LocalDateTime finishTime;
|
||||
|
||||
public SrSwitch(String id) {
|
||||
super(id, DeviceType.TURNOUT);
|
||||
super(id);
|
||||
}
|
||||
|
||||
private boolean updateState(int state) {
|
||||
if (this.state != state) {
|
||||
this.state = state;
|
||||
this.stateList.set(1, this.state);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -42,8 +43,9 @@ public class SrSwitch extends SrDevice {
|
||||
}
|
||||
|
||||
private boolean updateCommand(int command) {
|
||||
if (this.command.get() != command) {
|
||||
this.command.set(command);
|
||||
if (this.command != command) {
|
||||
this.command = (command);
|
||||
this.stateList.set(2, this.command);
|
||||
this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
@ -53,7 +55,7 @@ public class SrSwitch extends SrDevice {
|
||||
private boolean updateFinishTime(LocalDateTime finishTime) {
|
||||
if (!Objects.equals(this.finishTime, finishTime)) {
|
||||
this.finishTime = finishTime;
|
||||
this.fireWatcher();
|
||||
// this.fireWatcher();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -72,19 +74,19 @@ public class SrSwitch extends SrDevice {
|
||||
}
|
||||
|
||||
public boolean isTurning() {
|
||||
return NONE != this.command.get();
|
||||
return NONE != this.command;
|
||||
}
|
||||
|
||||
public boolean isTurningToNormal() {
|
||||
return NORMAL == this.command.get();
|
||||
return NORMAL == this.command;
|
||||
}
|
||||
|
||||
public boolean isTurningToReverse() {
|
||||
return REVERSE == this.command.get();
|
||||
return REVERSE == this.command;
|
||||
}
|
||||
|
||||
public boolean turnToNormal(LocalDateTime systemTime) {
|
||||
if (this.isNormalPosition() || this.command.get() == NORMAL) {
|
||||
if (this.isNormalPosition() || this.command == NORMAL) {
|
||||
return false;
|
||||
}
|
||||
this.startTurn(systemTime, NORMAL);
|
||||
@ -92,7 +94,7 @@ public class SrSwitch extends SrDevice {
|
||||
}
|
||||
|
||||
public boolean turnToReverse(LocalDateTime systemTime) {
|
||||
if (this.isReversePosition() || this.command.get() == REVERSE) {
|
||||
if (this.isReversePosition() || this.command == REVERSE) {
|
||||
return false;
|
||||
}
|
||||
this.startTurn(systemTime, REVERSE);
|
||||
@ -112,16 +114,16 @@ public class SrSwitch extends SrDevice {
|
||||
}
|
||||
|
||||
public void turnFinish() {
|
||||
this.updateState(this.command.get());
|
||||
this.updateState(this.command);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initState() {
|
||||
this.state = NORMAL;
|
||||
this.command.set(NONE);
|
||||
this.finishTime = null;
|
||||
this.updateState(NORMAL);
|
||||
this.updateCommand(NONE);
|
||||
this.updateFinishTime(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -135,6 +137,6 @@ public class SrSwitch extends SrDevice {
|
||||
|
||||
@Override
|
||||
List<Object> buildMessage() {
|
||||
return null;
|
||||
return Arrays.asList(this.id, this.state, this.command);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class SrTrack extends SrDevice implements Debug {
|
||||
SrSwitch srSwitch;
|
||||
|
||||
public SrTrack(String id) {
|
||||
super(id, DeviceType.TRACK);
|
||||
super(id);
|
||||
}
|
||||
|
||||
public void setAxc(SrAXC axc) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -24,50 +25,20 @@ public class SrTrain extends SrDevice {
|
||||
* 负载质量,单位:kg
|
||||
*/
|
||||
int loadMass = 0;
|
||||
/**
|
||||
* 列车最大速度,单位: m/s
|
||||
*/
|
||||
float speedMax = 33.33f; // 120km/h
|
||||
/**
|
||||
* 列车最大牵引力
|
||||
*/
|
||||
float fkMax = 560000f; // 按2.5m/s2计算的
|
||||
/**
|
||||
* 列车最大制动力
|
||||
*/
|
||||
float fbMax = 448000f; //
|
||||
/**
|
||||
* 默认阻力
|
||||
*/
|
||||
float fbDef = 11200f;
|
||||
/**
|
||||
* 发动机牵引功率0 <= p <= 100 (%)
|
||||
*/
|
||||
int p;
|
||||
/**
|
||||
* 制动功率0 <= bp <= 100 (%)
|
||||
*/
|
||||
int bp;
|
||||
/**
|
||||
* 是否紧急制动
|
||||
*/
|
||||
boolean eb;
|
||||
int f; // 列车所受合力
|
||||
/**
|
||||
* 列车速度,单位m/s
|
||||
*/
|
||||
float speed;
|
||||
/**
|
||||
* 列车方向
|
||||
* 列车方向(列车朝向)
|
||||
*/
|
||||
boolean right;
|
||||
/**
|
||||
* 档位
|
||||
* 方向
|
||||
*/
|
||||
int gear;
|
||||
public static final int NEUTRAL = 0; //空挡
|
||||
public static final int FORWARD = 1; //前进挡
|
||||
public static final int REVERSE = -1; //后退档
|
||||
int direction;
|
||||
public static final int FORWARD = 1; //前进
|
||||
public static final int REVERSE = -1; //后退
|
||||
/**
|
||||
* 列车头位置
|
||||
*/
|
||||
@ -78,12 +49,17 @@ public class SrTrain extends SrDevice {
|
||||
TrackPosition tailPosition;
|
||||
|
||||
public SrTrain(String id, int len) {
|
||||
super(id, DeviceType.TRAIN);
|
||||
super(id);
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
public boolean isNeutralGear() {
|
||||
return NEUTRAL == this.gear;
|
||||
public boolean updateDirection(int direction) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(direction <= FORWARD && direction >= REVERSE);
|
||||
if (this.direction != direction && this.speed == 0) {
|
||||
this.direction = direction;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateRight(boolean right) {
|
||||
@ -112,21 +88,6 @@ public class SrTrain extends SrDevice {
|
||||
return change;
|
||||
}
|
||||
|
||||
public boolean updateP(int p) {
|
||||
if (this.p != p) {
|
||||
this.p = p;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateBp(int bp) {
|
||||
if (this.bp != bp) {
|
||||
this.bp = bp;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void updatePositionAndSpeed(TrackPosition headPosition, TrackPosition tailPosition, float v) {
|
||||
this.updateHeadPosition(headPosition);
|
||||
this.speed = v;
|
||||
@ -134,10 +95,8 @@ public class SrTrain extends SrDevice {
|
||||
|
||||
@Override
|
||||
public void initState() {
|
||||
this.p = 0;
|
||||
this.eb = false;
|
||||
this.speed = 0;
|
||||
this.gear = NEUTRAL;
|
||||
this.updateDirection(FORWARD);
|
||||
this.updateHeadPosition(null);
|
||||
}
|
||||
|
||||
@ -155,4 +114,8 @@ public class SrTrain extends SrDevice {
|
||||
this.updateHeadPosition(trackPosition);
|
||||
this.updateRight(right);
|
||||
}
|
||||
|
||||
public float getTotalMass() {
|
||||
return this.mass+this.loadMass;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.rt.SRD.bo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.SimulationRepository;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonRepository;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSection;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSwitch;
|
||||
@ -31,6 +32,10 @@ public class SrdRepository extends SimulationRepository {
|
||||
this.trainMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public static SrdRepository getInstanceFrom(RtSimulation simulation) {
|
||||
return simulation.getRepository(NAME, SrdRepository.class);
|
||||
}
|
||||
|
||||
public List<SrTrain> getTrainList() {
|
||||
return new ArrayList<>(this.trainMap.values());
|
||||
}
|
||||
@ -108,4 +113,10 @@ public class SrdRepository extends SimulationRepository {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotNull(srTrack);
|
||||
return srTrack;
|
||||
}
|
||||
|
||||
public SrPSD getPsdById(String id) {
|
||||
SrPSD srPSD = this.psdMap.get(id);
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotNull(srPSD);
|
||||
return srPSD;
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,46 @@
|
||||
package club.joylink.rtss.simulation.rt.TL;
|
||||
|
||||
import club.joylink.rtss.simulation.Simulation;
|
||||
import club.joylink.rtss.simulation.SimulationMessagePublisher;
|
||||
import club.joylink.rtss.simulation.SimulationScheduleMessagePublisher;
|
||||
import club.joylink.rtss.simulation.rt.TL.bo.TlTrain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class TlHmiMessagePublisher extends SimulationMessagePublisher {
|
||||
public class TlHmiMessagePublisher extends SimulationScheduleMessagePublisher {
|
||||
public static final String NAME = "TlHmiMP";
|
||||
public static final int RATE = 1000;
|
||||
public static final String DESTINATION = String.format("%s%s", Simulation.MESSAGE_SUB_PREFIX, "/trainHmi");
|
||||
public static final String DESTINATION = String.format("%s%s", Simulation.MESSAGE_SUB_PREFIX, "/train/{trainId}/Hmi");
|
||||
|
||||
Map<String, List<Object>> hmiMap = new ConcurrentHashMap<>();
|
||||
|
||||
public TlHmiMessagePublisher(List<TlTrain> tlTrainList) {
|
||||
super(NAME, RATE, DESTINATION);
|
||||
super(NAME, RATE, true, Arrays.asList(DESTINATION));
|
||||
for (TlTrain train : tlTrainList) {
|
||||
hmiMap.put(train.getId(), train.getStateList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNextSendMessage(String destination) {
|
||||
Map<String, List<List<Object>>> map = new HashMap<>();
|
||||
List<List<Object>> hmiList = new ArrayList<>();
|
||||
map.put("hmi", hmiList);
|
||||
for (List<Object> value : this.hmiMap.values()) {
|
||||
hmiList.add(value);
|
||||
}
|
||||
return hmiList.isEmpty() ? null : map;
|
||||
public boolean isValidParams(List<String> params) {
|
||||
return this.hmiMap.containsKey(params.get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildNextSendMessage(String destination) {
|
||||
Map<String, List<String>> destinationParamsMap = this.getDestinationParamsMap();
|
||||
List<String> params = destinationParamsMap.get(destination);
|
||||
String trainId = params.get(1);
|
||||
Map<String, List<Object>> map = new HashMap<>();
|
||||
map.putIfAbsent("hmi", this.hmiMap.get(trainId));
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buildMessageOfSubscribe(String destination) {
|
||||
return this.getNextSendMessage(destination);
|
||||
return this.buildNextSendMessage(destination);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
package club.joylink.rtss.simulation.rt.TL;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.TL.bo.TlRepository;
|
||||
import club.joylink.rtss.simulation.rt.TL.bo.TlTrain;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TrainDriveService {
|
||||
public void changeOverSwitch(RtSimulation simulation, String id, int pos) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(pos >= -1 && pos <= 2);
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom(simulation);
|
||||
TlTrain train = tlRepository.getTrainById(id);
|
||||
train.updateChangeOverSwitch(pos);
|
||||
}
|
||||
|
||||
public void changeGear(RtSimulation simulation, String id, int pos) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(pos >= -1 && pos <= 9);
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom(simulation);
|
||||
TlTrain train = tlRepository.getTrainById(id);
|
||||
train.updateGear(pos);
|
||||
}
|
||||
|
||||
public void changeThrottle(RtSimulation simulation, String id, int pos) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(pos >= 0 && pos <= 100);
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom(simulation);
|
||||
TlTrain train = tlRepository.getTrainById(id);
|
||||
train.updateThrottle(pos);
|
||||
}
|
||||
|
||||
public void changeSingleBreak(RtSimulation simulation, String id, int pos) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(pos >= 0 && pos <= 100);
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom(simulation);
|
||||
TlTrain train = tlRepository.getTrainById(id);
|
||||
train.updateSingleBreak(pos);
|
||||
}
|
||||
|
||||
public void changeAutoBreak(RtSimulation simulation, String id, int pos) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(pos >= 0 && pos <= 150);
|
||||
TlRepository tlRepository = TlRepository.getInstanceFrom(simulation);
|
||||
TlTrain train = tlRepository.getTrainById(id);
|
||||
train.updateAutoBreak(pos);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.rt.TL.bo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.SimulationRepository;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -20,6 +21,10 @@ public class TlRepository extends SimulationRepository {
|
||||
this.trainMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public static TlRepository getInstanceFrom(RtSimulation simulation) {
|
||||
return simulation.getRepository(NAME, TlRepository.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initState() {
|
||||
for (TlTrain train : this.trainMap.values()) {
|
||||
|
@ -17,6 +17,13 @@ public class TlTrain extends TlDevice {
|
||||
*/
|
||||
float speed;
|
||||
int controlPosition;//司控器手柄位置
|
||||
int gear; // 档位(-1~9,1挡为起步挡,2~9实际为1~8挡)
|
||||
int throttlePosition; // 油门杆位置(0~100)
|
||||
int changeOverSwitch; // 换向开关(-1, 0, 1, 2:手动)
|
||||
int changeOverState; // 换向器状态:(-1, 0, 1)
|
||||
int singleBreak; // 单独制动阀(单独操纵机车的制动)
|
||||
int autoBreak; // 自动制动阀(操纵全列车的制动)
|
||||
|
||||
|
||||
public TlTrain(SrTrain train) {
|
||||
super(train.getId());
|
||||
@ -43,16 +50,87 @@ public class TlTrain extends TlDevice {
|
||||
public boolean updateControlPosition(int controlPosition) {
|
||||
if (this.controlPosition != controlPosition) {
|
||||
this.controlPosition = controlPosition;
|
||||
if (controlPosition > 0) {
|
||||
this.srTrain.updateP(controlPosition);
|
||||
this.srTrain.updateBp(0);
|
||||
} else if (controlPosition < 0) {
|
||||
this.srTrain.updateP(0);
|
||||
this.srTrain.updateBp(Math.abs(controlPosition));
|
||||
} else {
|
||||
this.srTrain.updateP(0);
|
||||
this.srTrain.updateBp(0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateChangeOverState(int changeOverState) {
|
||||
if (this.changeOverState != changeOverState) {
|
||||
this.changeOverState = changeOverState;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateChangeOverSwitch(int changeOverSwitch) {
|
||||
if (this.changeOverSwitch != changeOverSwitch) {
|
||||
this.changeOverSwitch = changeOverSwitch;
|
||||
if (changeOverSwitch < 2) {
|
||||
this.updateChangeOverState(changeOverSwitch);
|
||||
}
|
||||
this.srTrain.updateDirection(this.calGear());
|
||||
this.stateList.set(2, this.changeOverSwitch);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateGear(int gear) {
|
||||
if (this.gear != gear) {
|
||||
this.gear = gear;
|
||||
this.srTrain.updateDirection(this.calGear());
|
||||
this.stateList.set(3, this.gear);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int calGear() {
|
||||
switch (this.changeOverState) {
|
||||
case -1:
|
||||
if (this.gear == -1) {
|
||||
return 1;
|
||||
} else if (this.gear == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
if (this.gear > 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return this.gear;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("换向器:无效的值");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateThrottle(int pos) {
|
||||
if (this.throttlePosition != pos) {
|
||||
this.throttlePosition = pos;
|
||||
this.stateList.set(4, this.throttlePosition);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateSingleBreak(int pos) {
|
||||
if (this.singleBreak != pos) {
|
||||
this.singleBreak = pos;
|
||||
this.stateList.set(5, this.singleBreak);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean updateAutoBreak(int pos) {
|
||||
if (this.autoBreak != pos) {
|
||||
this.autoBreak = pos;
|
||||
this.stateList.set(6, this.autoBreak);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -65,6 +143,121 @@ public class TlTrain extends TlDevice {
|
||||
|
||||
@Override
|
||||
List<Object> buildMessage() {
|
||||
return Arrays.asList(this.id, this.speed, this.controlPosition);
|
||||
return Arrays.asList(this.id, this.speed, this.changeOverSwitch, this.gear, this.throttlePosition,
|
||||
this.singleBreak, this.autoBreak);
|
||||
}
|
||||
|
||||
public float calculateF() {
|
||||
float f = 0;
|
||||
float speed = this.srTrain.getSpeed();
|
||||
// 根据列车档位和油门计算牵引力或制动力
|
||||
float vmin = 0;
|
||||
float vmax = 0;
|
||||
float amin = 0;
|
||||
float amax = 0;
|
||||
switch (this.gear) {
|
||||
case -1: // 倒车:3~7km/h; 1.89 ~ 1.64 m/s^2
|
||||
vmin = 3;
|
||||
vmax = 7;
|
||||
amax = 1.89f;
|
||||
amin = 1.64f;
|
||||
break;
|
||||
case 0: // 空挡
|
||||
break;
|
||||
case 1: // 起步挡:3~8km/h; 1.89 ~ 1.64 m/s^2
|
||||
vmin = 3;
|
||||
vmax = 8;
|
||||
amax = 1.89f;
|
||||
amin = 1.64f;
|
||||
break;
|
||||
case 2: // 1挡:5~15km/h; 1.38 ~ 1.15 m/s^2
|
||||
vmin = 5;
|
||||
vmax = 15;
|
||||
amax = 1.38f;
|
||||
amin = 1.15f;
|
||||
break;
|
||||
case 3: // 2挡:9~20km/h; 0.92 ~ 0.73 m/s^2
|
||||
vmin = 9;
|
||||
vmax = 20;
|
||||
amax = 0.92f;
|
||||
amin = 0.73f;
|
||||
break;
|
||||
case 4: // 3挡:13~28km/h; 0.65 ~ 0.48 m/s^2
|
||||
vmin = 13;
|
||||
vmax = 28;
|
||||
amax = 0.65f;
|
||||
amin = 0.48f;
|
||||
break;
|
||||
case 5: // 4挡:20~38km/h; 0.47 ~ 0.32 m/s^2
|
||||
vmin = 20;
|
||||
vmax = 38;
|
||||
amax = 0.47f;
|
||||
amin = 0.32f;
|
||||
break;
|
||||
case 6: // 5挡:26~50km/h; 0.30 ~ 0.21 m/s^2
|
||||
vmin = 26;
|
||||
vmax = 50;
|
||||
amax = 0.30f;
|
||||
amin = 0.21f;
|
||||
break;
|
||||
case 7: // 6挡:33~60km/h; 0.21 ~ 0.15 m/s^2
|
||||
vmin = 33;
|
||||
vmax = 60;
|
||||
amax = 0.21f;
|
||||
amin = 0.15f;
|
||||
break;
|
||||
case 8: // 7挡:52~75km/h; 0.15 ~ 0.11 m/s^2
|
||||
vmin = 52;
|
||||
vmax = 75;
|
||||
amax = 0.15f;
|
||||
amin = 0.11f;
|
||||
break;
|
||||
case 9: // 8挡:60~90km/h; 0.11 ~ 0.08 m/s^2
|
||||
vmin = 60;
|
||||
vmax = 90;
|
||||
amax = 0.11f;
|
||||
amin = 0.08f;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("无效的档位");
|
||||
}
|
||||
float fk = 0;
|
||||
float fb = 0;
|
||||
if (this.gear != 0 && this.changeOverState != 0) { // 非空挡
|
||||
float vs = (float) ((vmin + (Float.valueOf(vmax - vmin) * this.throttlePosition / 100)) / 3.6);
|
||||
if (speed > vs) {
|
||||
fb += this.calculateAccOf(speed - vs) * this.srTrain.getTotalMass();
|
||||
} else {
|
||||
fk = (float) ((amin + ((vs - vmin) / (vmax - vmin) * (amax - amin))) * this.srTrain.getTotalMass());
|
||||
}
|
||||
}
|
||||
// 根据制动阀计算制动力
|
||||
fb += this.calculateFb();
|
||||
// 计算合力
|
||||
f = fk - fb;
|
||||
// if (fk == 0) {
|
||||
// float ff = this.calculateFriction(speed, this.srTrain.getTotalMass()); // 摩擦力
|
||||
// f -= ff;
|
||||
// }
|
||||
return f;
|
||||
}
|
||||
|
||||
private float calculateFb() {
|
||||
float fb1 = (float) ((1.0 * this.autoBreak / 100) * this.srTrain.getTotalMass());
|
||||
float fb2 = (float) ((0.6 * this.singleBreak / 100) * this.srTrain.getTotalMass());
|
||||
return Math.max(fb1, fb2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算减速度(档位所在速度小于列车速度时)
|
||||
* @param v 当前速度和档位速度差
|
||||
* @return
|
||||
*/
|
||||
private float calculateAccOf(float v) {
|
||||
return v / 20;
|
||||
}
|
||||
|
||||
private float calculateFriction(float speed, float mass) {
|
||||
return (float) (0.05*mass);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package club.joylink.rtss.simulation.rt;
|
||||
|
||||
import club.joylink.rtss.simulation.SimulationManager;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrSignal;
|
||||
import club.joylink.rtss.simulation.rt.SRD.bo.SrdRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 快速测试设备状态接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/test/simulation/{id}")
|
||||
public class TestDeviceStateController {
|
||||
@Autowired
|
||||
private SimulationManager simulationManager;
|
||||
|
||||
@GetMapping("/srSignal/{signalId}/state/{state}")
|
||||
public void updateSrSignalState(@PathVariable String id, @PathVariable String signalId, @PathVariable int state) {
|
||||
RtSimulation rtSimulation = this.simulationManager.getById(id, RtSimulation.class);
|
||||
SrdRepository repository = SrdRepository.getInstanceFrom(rtSimulation);
|
||||
SrSignal srSignal = repository.getSignalById(signalId);
|
||||
srSignal.updateState(state);
|
||||
}
|
||||
|
||||
}
|
@ -4,12 +4,15 @@ import club.joylink.rtss.simulation.operation.SimulationOperationController;
|
||||
import club.joylink.rtss.simulation.operation.SimulationOperationMapping;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import club.joylink.rtss.simulation.rt.SRD.SrdTrainService;
|
||||
import club.joylink.rtss.simulation.rt.TL.TrainDriveService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@SimulationOperationController()
|
||||
public class SrTrainOperationHandler {
|
||||
@Autowired
|
||||
private SrdTrainService srdTrainService;
|
||||
@Autowired
|
||||
private TrainDriveService trainDriveService;
|
||||
|
||||
@SimulationOperationMapping("Train_Load_Spare_Train")
|
||||
public void loadTrain(RtSimulation simulation, String groupNumber,
|
||||
@ -21,4 +24,47 @@ public class SrTrainOperationHandler {
|
||||
public void powerControl(RtSimulation simulation, String id, int p) {
|
||||
this.srdTrainService.powerControl(simulation, id, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 换向开关位置
|
||||
* @param simulation
|
||||
* @param id
|
||||
* @param pos
|
||||
*/
|
||||
@SimulationOperationMapping("Train_Drive_Change_Over_Switch")
|
||||
public void changeOverSwitch(RtSimulation simulation, String id, int pos) {
|
||||
this.trainDriveService.changeOverSwitch(simulation, id, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 换挡
|
||||
*/
|
||||
@SimulationOperationMapping("Train_Drive_Gear_Change")
|
||||
public void gearChange(RtSimulation simulation, String id, int pos) {
|
||||
this.trainDriveService.changeGear(simulation, id, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 油门杆
|
||||
*/
|
||||
@SimulationOperationMapping("Train_Drive_Throttle_Change")
|
||||
public void throttleChange(RtSimulation simulation, String id, int pos) {
|
||||
this.trainDriveService.changeThrottle(simulation, id, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 头节车厢制动
|
||||
*/
|
||||
@SimulationOperationMapping("Train_Drive_Single_Break")
|
||||
public void singleBreak(RtSimulation simulation, String id, int pos) {
|
||||
this.trainDriveService.changeSingleBreak(simulation, id, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有车厢制动
|
||||
*/
|
||||
@SimulationOperationMapping("Train_Drive_Auto_Break")
|
||||
public void autoBreak(RtSimulation simulation, String id, int pos) {
|
||||
this.trainDriveService.changeAutoBreak(simulation, id, pos);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.rt.repo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.SimulationRepository;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulation;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -21,6 +22,10 @@ public class CommonRepository extends SimulationRepository {
|
||||
Map<String, CommonFls> flsMap;
|
||||
Map<String, CommonRoute> routeMap;
|
||||
Map<String, CommonOverlap> overlapMap;
|
||||
/**
|
||||
* key-sectionId 区段id
|
||||
*/
|
||||
Map<String, List<CommonSignal>> approachSignalMap;
|
||||
|
||||
public CommonRepository() {
|
||||
super(NAME);
|
||||
@ -32,6 +37,11 @@ public class CommonRepository extends SimulationRepository {
|
||||
this.flsMap = new HashMap<>();
|
||||
this.routeMap = new HashMap<>();
|
||||
this.overlapMap = new HashMap<>();
|
||||
this.approachSignalMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public static CommonRepository getInstanceFrom(RtSimulation simulation) {
|
||||
return simulation.getRepository(NAME, CommonRepository.class);
|
||||
}
|
||||
|
||||
public CommonSignal getSignalById(String id) {
|
||||
|
@ -48,11 +48,20 @@ public class CommonRepositoryBuilder {
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(signal,
|
||||
String.format("信号机接近区段关联信号机[%s]不存在", approachVO.getSignalCode()));
|
||||
List<MapSectionPathVO> sectionPathList = approachVO.getSectionPathList();
|
||||
List<TrackWay> list = new ArrayList<>();
|
||||
List<TrackPath> list = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(sectionPathList)) {
|
||||
for (MapSectionPathVO pathVO : sectionPathList) {
|
||||
list.add(buildTrackWay(pathVO.getSectionList(), pathVO.getSwitchPositionList(),
|
||||
null, !signal.isRight(), commonRepository));
|
||||
TrackPath trackPath = buildTrackPath(pathVO.getSectionList(), pathVO.getSwitchPositionList(),
|
||||
!signal.isRight(), commonRepository);
|
||||
list.add(trackPath);
|
||||
for (CommonSection commonSection : trackPath.getSectionList()) {
|
||||
List<CommonSignal> signals = commonRepository.approachSignalMap.get(commonSection.getId());
|
||||
if (signals == null) {
|
||||
signals = new ArrayList<>();
|
||||
commonRepository.approachSignalMap.put(commonSection.getId(), signals);
|
||||
}
|
||||
signals.add(signal);
|
||||
}
|
||||
}
|
||||
signal.approachList = list;
|
||||
}
|
||||
@ -169,6 +178,7 @@ public class CommonRepositoryBuilder {
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(start,
|
||||
String.format("进路[%s]的始端信号机[%s]不存在", routeVO.getId(), routeVO.getStartSignalCode()));
|
||||
commonRoute.start = start;
|
||||
start.routeList.add(commonRoute);
|
||||
if (StringUtils.hasText(routeVO.getEndSignalCode())) {
|
||||
CommonSignal end = signalMap.get(routeVO.getEndSignalCode());
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(end,
|
||||
@ -220,6 +230,30 @@ public class CommonRepositoryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static TrackPath buildTrackPath(List<String> sectionList,
|
||||
List<MapCISwitchVO> switchList,
|
||||
boolean right, CommonRepository commonRepository) {
|
||||
Map<String, CommonSection> sectionMap = commonRepository.sectionMap;
|
||||
Map<String, CommonSwitch> switchMap = commonRepository.switchMap;
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertTrue(null != sectionList && sectionList.size() >= 1);
|
||||
TrackPath trackPath = new TrackPath(right);
|
||||
for (String code : sectionList) {
|
||||
CommonSection section = sectionMap.get(code);
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(section,
|
||||
String.format("构建路径失败:不存在code为[%s]的区段", code));
|
||||
trackPath.addSection(section);
|
||||
}
|
||||
if (switchList != null) {
|
||||
for (MapCISwitchVO ciSwitchVO : switchList) {
|
||||
CommonSwitch commonSwitch = switchMap.get(ciSwitchVO.getSwitchCode());
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(commonSwitch,
|
||||
String.format("构建路径失败:不存在code为[%s]的道岔", ciSwitchVO.getSwitchCode()));
|
||||
trackPath.addSwitchPosition(commonSwitch, ciSwitchVO.isNormal());
|
||||
}
|
||||
}
|
||||
return trackPath;
|
||||
}
|
||||
|
||||
private static TrackWay buildTrackWay(List<String> sectionList,
|
||||
List<MapCISwitchVO> switchList,
|
||||
List<String> flsList,
|
||||
@ -320,6 +354,7 @@ public class CommonRepositoryBuilder {
|
||||
CommonSection section = sectionMap.get(signalVO.getSectionCode());
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotNull(section,
|
||||
String.format("信号机[%s]关联code为[%s]的区段不存在", signalVO.getCode(), signalVO.getSectionCode()));
|
||||
section.signalList.add(commonSignal);
|
||||
commonSignal.section = section;
|
||||
commonSignal.offset = (int) (signalVO.getSectionOffset() * 1000);
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package club.joylink.rtss.simulation.rt.repo;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
public class CommonSection extends CommonDevice {
|
||||
@ -13,15 +16,19 @@ public class CommonSection extends CommonDevice {
|
||||
CommonStation station;
|
||||
CommonStation ecStation;// 设备集中站
|
||||
CommonSection leftSection;
|
||||
CommonSection leftFlankSection;
|
||||
CommonSection rightSection;
|
||||
CommonSection rightFlankSection;
|
||||
CommonSection parent;
|
||||
List<CommonSection> relateList;
|
||||
CommonSwitch belongSwitch;
|
||||
List<CommonSignal> signalList; // 在此区段上的信号机
|
||||
List<CommonStand> standList;
|
||||
|
||||
public CommonSection(String id, String name) {
|
||||
super(id, name);
|
||||
this.relateList = new ArrayList<>();
|
||||
this.signalList = new ArrayList<>();
|
||||
this.standList = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -58,6 +65,37 @@ public class CommonSection extends CommonDevice {
|
||||
return this.parent == null ? this : this.parent;
|
||||
}
|
||||
|
||||
public CommonSection queryNextBy(boolean right) {
|
||||
if (right) {
|
||||
return this.getRightSection();
|
||||
} else {
|
||||
return this.getLeftSection();
|
||||
}
|
||||
}
|
||||
|
||||
public CommonSection queryNextSwitchSectionBy(boolean right, boolean normal) {
|
||||
BusinessExceptionAssertEnum.INVALID_OPERATION.assertTrue(this.isSwitchSection());
|
||||
if (!normal) {
|
||||
if (right) {
|
||||
return this.rightFlankSection != null ? this.rightFlankSection : this.rightSection;
|
||||
} else {
|
||||
return this.leftFlankSection != null ? this.leftFlankSection : this.leftSection;
|
||||
}
|
||||
} else {
|
||||
if (right) {
|
||||
return rightSection;
|
||||
} else {
|
||||
return leftSection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<CommonSignal> getSignalOf(boolean right) {
|
||||
return this.signalList.stream()
|
||||
.filter(signal -> Objects.equals(signal.isRight(), right))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
/** 一般计轴区段 */
|
||||
NAx,
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.rt.repo;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@ -15,10 +16,13 @@ public class CommonSignal extends CommonDevice {
|
||||
CommonSection section; // 所在区段
|
||||
int offset; // 所在区段偏移量,单位mm
|
||||
|
||||
List<TrackWay> approachList;
|
||||
List<TrackWay> ctcApproachList; // 暂时不使用
|
||||
List<TrackPath> approachList;
|
||||
List<TrackPath> ctcApproachList; // 暂时不使用
|
||||
|
||||
List<CommonRoute> routeList;
|
||||
|
||||
public CommonSignal(String id, String name) {
|
||||
super(id, name);
|
||||
this.routeList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,17 @@ public class CommonSwitch extends CommonDevice {
|
||||
a.belongSwitch = this;
|
||||
b.belongSwitch = this;
|
||||
c.belongSwitch = this;
|
||||
if (a.leftSection != null) {
|
||||
a.rightSection = b;
|
||||
a.rightFlankSection = c;
|
||||
b.leftSection = a;
|
||||
c.leftSection = a;
|
||||
} else if (a.rightSection != null) {
|
||||
a.leftSection = b;
|
||||
a.leftFlankSection = c;
|
||||
b.rightSection = a;
|
||||
c.rightSection = a;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isA(CommonSection section) {
|
||||
|
@ -0,0 +1,45 @@
|
||||
package club.joylink.rtss.simulation.rt.repo;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class TrackPath {
|
||||
boolean right;
|
||||
List<CommonSection> sectionList;
|
||||
List<SwitchPosition> spList;
|
||||
|
||||
public TrackPath(boolean right) {
|
||||
this.right = right;
|
||||
this.sectionList = new ArrayList<>();
|
||||
this.spList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addSection(CommonSection section) {
|
||||
this.sectionList.add(section);
|
||||
}
|
||||
|
||||
public void addSwitchPosition(CommonSwitch commonSwitch, boolean normal) {
|
||||
SwitchPosition switchPosition = SwitchPosition.buildSwitchPosition(commonSwitch, normal);
|
||||
this.spList.add(switchPosition);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.sectionList.isEmpty();
|
||||
}
|
||||
|
||||
public TrackPath clone() {
|
||||
TrackPath clone = new TrackPath(this.right);
|
||||
clone.sectionList.addAll(this.sectionList);
|
||||
clone.spList.addAll(this.spList);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public int calTotalLen() {
|
||||
return this.sectionList.stream()
|
||||
.mapToInt(CommonSection::getLen)
|
||||
.sum();
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ public class TrackWay implements Debug {
|
||||
Map<String, CommonSection> sectionMap;
|
||||
List<CommonSection> sectionList; // 不包含start和end
|
||||
List<SwitchPosition> spList; // 路径中道岔位置
|
||||
Integer reverseSwitchCount; // 路径中反位道岔数量
|
||||
List<SwitchPosition> fspList; // 非路径道岔位置
|
||||
List<CommonFls> flsList; // 侧防
|
||||
|
||||
@ -85,6 +86,18 @@ public class TrackWay implements Debug {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getReverseSwitchCount() {
|
||||
if (this.reverseSwitchCount == null) {
|
||||
this.reverseSwitchCount = 0;
|
||||
for (SwitchPosition switchPosition : this.spList) {
|
||||
if (!switchPosition.isNormal()) {
|
||||
this.reverseSwitchCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.reverseSwitchCount;
|
||||
}
|
||||
|
||||
public List<CommonSection> getAllSectionList() {
|
||||
List<CommonSection> list = new ArrayList<>();
|
||||
list.add(this.start);
|
||||
|
@ -1,10 +1,8 @@
|
||||
package club.joylink.rtss.simulation.rt.vo;
|
||||
|
||||
import club.joylink.rtss.simulation.SimulationMember;
|
||||
import club.joylink.rtss.simulation.rt.RtSimulationMember;
|
||||
import club.joylink.rtss.simulation.vo.SimulationMemberVO;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Getter
|
||||
public class RtSimulationMemberVO extends SimulationMemberVO {
|
||||
|
@ -3,6 +3,8 @@ package club.joylink.rtss.vo.client.map.newmap;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.RouteFls;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.SectionPath;
|
||||
import club.joylink.rtss.simulation.rt.repo.CommonSection;
|
||||
import club.joylink.rtss.simulation.rt.repo.TrackPath;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
@ -43,6 +45,18 @@ public class MapSectionPathVO {
|
||||
return voList;
|
||||
}
|
||||
|
||||
public static MapSectionPathVO from(TrackPath trackPath) {
|
||||
MapSectionPathVO vo = new MapSectionPathVO();
|
||||
vo.setRight(trackPath.isRight());
|
||||
vo.setSectionList(trackPath.getSectionList().stream()
|
||||
.map(CommonSection::getId)
|
||||
.collect(Collectors.toList()));
|
||||
vo.setSwitchPositionList(trackPath.getSpList().stream()
|
||||
.map(switchPosition -> new MapCISwitchVO(switchPosition.getCommonSwitch().getId(), switchPosition.isNormal()))
|
||||
.collect(Collectors.toList()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private static MapSectionPathVO from(SectionPath sectionPath) {
|
||||
MapSectionPathVO vo = new MapSectionPathVO();
|
||||
List<String> sectionList = sectionPath.getSectionList().stream()
|
||||
@ -60,4 +74,14 @@ public class MapSectionPathVO {
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
public static List<MapSectionPathVO> convertTrackPath2VOList(List<TrackPath> list) {
|
||||
List<MapSectionPathVO> voList = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(list)) {
|
||||
for (TrackPath trackPath : list) {
|
||||
voList.add(MapSectionPathVO.from(trackPath));
|
||||
}
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user