增加大铁列车自动驾驶逻辑;将大铁不需要的仿真任务去除
This commit is contained in:
parent
8dcba7a311
commit
afbb57d1a8
@ -5,6 +5,8 @@ import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.RegulationParam;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.ars.AtsTriggerRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsRealRunRecordService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.stage.AtsTrainStageHandler;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.ISCS.OnBoardPisService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
@ -24,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
@ -212,36 +215,57 @@ public class AtsTrainMonitorService {
|
||||
*/
|
||||
private int getParkTimeOf(Simulation simulation, TrainInfo train, Section standTrack) {
|
||||
int parkTime = 0;
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (train.isPlanTrain()) { // 计划车
|
||||
TripPlan tripPlan = repository.getTripPlan(train.getServiceNumber(), train.getTripNumber());
|
||||
StationPlan stationPlan = tripPlan.queryStationPlan(standTrack);
|
||||
if (stationPlan != null) {
|
||||
if (standTrack.isNormalStandTrack() && tripPlan.isFirstPlan(stationPlan)) { // 折返第一站
|
||||
parkTime = this.getFirstStationPlanParkTime(stationPlan, systemTime);
|
||||
} else if (standTrack.isNormalStandTrack() && tripPlan.isLastPlan(stationPlan) &&
|
||||
tripPlan.isFrontTurnBack()) { // 站前折返终点站
|
||||
TripPlan nextPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
StationPlan firstStationPlan = nextPlan.getFirstStationPlan();
|
||||
parkTime = this.getFirstStationPlanParkTime(firstStationPlan, systemTime);
|
||||
} else {
|
||||
parkTime = stationPlan.getParkTime();
|
||||
if (!simulation.getRepository().getConfig().isRailway()) { //地铁线路
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (train.isPlanTrain()) { // 计划车
|
||||
TripPlan tripPlan = repository.getTripPlan(train.getServiceNumber(), train.getTripNumber());
|
||||
StationPlan stationPlan = tripPlan.queryStationPlan(standTrack);
|
||||
if (stationPlan != null) {
|
||||
if (standTrack.isNormalStandTrack() && tripPlan.isFirstPlan(stationPlan)) { // 折返第一站
|
||||
parkTime = this.getFirstStationPlanParkTime(stationPlan, systemTime);
|
||||
} else if (standTrack.isNormalStandTrack() && tripPlan.isLastPlan(stationPlan) &&
|
||||
tripPlan.isFrontTurnBack()) { // 站前折返终点站
|
||||
TripPlan nextPlan = repository.queryNextTripPlanOf(tripPlan);
|
||||
StationPlan firstStationPlan = nextPlan.getFirstStationPlan();
|
||||
parkTime = this.getFirstStationPlanParkTime(firstStationPlan, systemTime);
|
||||
} else {
|
||||
parkTime = stationPlan.getParkTime();
|
||||
}
|
||||
} else if (standTrack.isNormalStandTrack()) {
|
||||
stationPlan = tripPlan.queryStationPlan(standTrack.getStation());
|
||||
if (stationPlan != null) { // 未停靠在计划的站台轨
|
||||
parkTime = stationPlan.getParkTime();
|
||||
}
|
||||
}
|
||||
} else if (standTrack.isNormalStandTrack()) {
|
||||
stationPlan = tripPlan.queryStationPlan(standTrack.getStation());
|
||||
if (stationPlan != null) { // 未停靠在计划的站台轨
|
||||
parkTime = stationPlan.getParkTime();
|
||||
} else { // 头码车或人工车,按默认停站时间
|
||||
StationParkTime stationParkTime = repository.queryStandParkTime(standTrack);
|
||||
if (stationParkTime != null) {
|
||||
parkTime = stationParkTime.getParkTime();
|
||||
} else { // 没有数据,默认30s
|
||||
parkTime = 30;
|
||||
}
|
||||
}
|
||||
} else { // 头码车或人工车,按默认停站时间
|
||||
StationParkTime stationParkTime = repository.queryStandParkTime(standTrack);
|
||||
if (stationParkTime != null) {
|
||||
parkTime = stationParkTime.getParkTime();
|
||||
} else { // 没有数据,默认30s
|
||||
parkTime = 30;
|
||||
} else { //大铁线路
|
||||
Station station = standTrack.getStation();
|
||||
if (station != null) {
|
||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||
CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), train.getTripNumber());
|
||||
CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan();
|
||||
if (departRunPlan != null) { //有发车计划
|
||||
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan();
|
||||
if (arriveRunPlan != null) { //有接车计划,用计划停站时间
|
||||
parkTime = (int) Duration.between(arriveRunPlan.getPlanTime(), departRunPlan.getPlanTime()).toSeconds();
|
||||
} else { //无接车计划,停到计划发车时间
|
||||
LocalDateTime correctSystemTime = simulation.getCorrectSystemTime();
|
||||
parkTime = (int) Duration.between(correctSystemTime, departRunPlan.getPlanTime()).toSeconds();
|
||||
}
|
||||
} else { //无发车计划,固定停站1分钟吧
|
||||
parkTime = 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
parkTime = Math.max(parkTime, 0);
|
||||
return parkTime;
|
||||
}
|
||||
|
||||
|
@ -356,6 +356,12 @@ public class CtcRepository {
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Collection<CtcStationRunPlanLog> findRunPlans(String tripNumber) {
|
||||
return this.allRunPlanList.stream()
|
||||
.filter(plan -> Objects.equals(tripNumber, plan.getTripNumber()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public RouteSequence.Line getRouteSequenceLine(String stationCode, String tripNumber, boolean departure) {
|
||||
RouteSequence routeSequence = routeSequenceMap.get(stationCode);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(routeSequence);
|
||||
|
@ -67,11 +67,11 @@ public class CtcDispatchCommandService {
|
||||
|
||||
private void dispatchCommandParamValid(RailDispatchCommandVO vo) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(vo.getTitle(), "命令标题不能为空");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getTitle().length() < 20, "命令标题最大长度20");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getTitle().length() <= 20, "命令标题最大长度20");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(vo.getContent(), "命令正文不能为空");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getContent().length() < 200, "命令正文最大长度200");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getContent().length() <= 200, "命令正文最大长度200");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(vo.getNumber(), "命令号不能为空");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getNumber().length() < 10, "命令号最大长度10");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(vo.getNumber().length() <= 10, "命令号最大长度10");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertHasText(vo.getSenderName(), "发令人不能为空");
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(vo.getReceiverIds(), "收令人不能为空");
|
||||
}
|
||||
|
@ -179,28 +179,26 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
|
||||
}
|
||||
|
||||
private void addJobs(Simulation simulation) {
|
||||
atsLogicLoop.addJobs(simulation);
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
ctcLogicLoop.addJobs(simulation);
|
||||
} else {
|
||||
depotService.addJobs(simulation);
|
||||
trainTargetUpdateService.addJobs(simulation);
|
||||
iVirtualRealityIbpService.addJobs(simulation);
|
||||
powerSupplyService.addJobs(simulation);
|
||||
iVirtualRealityPslService.addJobs(simulation);
|
||||
iscsMessageCollectAndDispatcher.addJob(simulation);
|
||||
iscsLogicLoop.addJob(simulation);
|
||||
}
|
||||
atpLogicLoop.addJobs(simulation);
|
||||
depotService.addJobs(simulation);
|
||||
trainTargetUpdateService.addJobs(simulation);
|
||||
atsLogicLoop.addJobs(simulation);
|
||||
vrTrainRunningService.addJobs(simulation);
|
||||
ciLogic.addJobs(simulation);
|
||||
vrDeviceLogicLoop.addJobs(simulation);
|
||||
// zcLogicLoop.addJobs(simulation);
|
||||
atsMessageCollectAndDispatcher.addJobs(simulation);
|
||||
joylink3DMessageService.addJobs(simulation);
|
||||
faultGenerator.addJobs(simulation);
|
||||
iVirtualRealityIbpService.addJobs(simulation);
|
||||
powerSupplyService.addJobs(simulation);
|
||||
robotLogicLoop.addJobs(simulation);
|
||||
iVirtualRealityPslService.addJobs(simulation);
|
||||
iscsMessageCollectAndDispatcher.addJob(simulation);
|
||||
iscsLogicLoop.addJob(simulation);
|
||||
//////////////////////////////////////////////
|
||||
// simulationRealDeviceConnectManager.addJobs(simulation);
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
ctcLogicLoop.addJobs(simulation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -179,6 +179,11 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
*/
|
||||
private int parkRemainTime;
|
||||
|
||||
/**
|
||||
* 最后一次停站的区段
|
||||
*/
|
||||
private Section parkSection;
|
||||
|
||||
/**
|
||||
* 发车提示
|
||||
*/
|
||||
@ -538,6 +543,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
this.beAbout2Arrive = false;
|
||||
this.target = null;
|
||||
this.parkTime = 0;
|
||||
this.parkRemainTime = 0;
|
||||
this.parkSection = null;
|
||||
this.departure = false;
|
||||
this.breaking = false;
|
||||
this.standParkedTrainActivity = null;
|
||||
@ -780,15 +787,6 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return this.tailPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parkTime 单位s
|
||||
*/
|
||||
public synchronized void park(int parkTime) {
|
||||
int ms = parkTime * 1000;
|
||||
this.parkTime = ms;
|
||||
this.parkRemainTime = ms;
|
||||
}
|
||||
|
||||
public synchronized void depart() {
|
||||
this.standParkedTrainActivity = null;
|
||||
this.parkTime = 0;
|
||||
@ -968,6 +966,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
} else {
|
||||
this.standParkedTrainActivity = StandParkedTrainActivity.START;
|
||||
}
|
||||
this.parkSection = headSection;
|
||||
}
|
||||
|
||||
public boolean isParkingAt() {
|
||||
|
@ -31,14 +31,6 @@ public interface OnboardAtpApiService {
|
||||
*/
|
||||
void updateTripPlan(Simulation simulation, String groupNumber, TripPlan tripPlan);
|
||||
|
||||
/**
|
||||
* 更新站台停靠时间
|
||||
* @param simulation
|
||||
* @param groupNumber
|
||||
* @param parkTime 停站时间,单位s
|
||||
*/
|
||||
void updateStationParkTime(Simulation simulation, String groupNumber, int parkTime);
|
||||
|
||||
/**
|
||||
* 发车
|
||||
* @param simulation
|
||||
|
@ -110,21 +110,6 @@ public class OnboardAtpApiServiceImpl implements OnboardAtpApiService {
|
||||
serviceNumber, tripNumber, destinationCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStationParkTime(Simulation simulation,
|
||||
String groupNumber,
|
||||
int parkTime) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
VirtualRealityTrain train = repository.getVRByCode(groupNumber, VirtualRealityTrain.class);
|
||||
train.park(parkTime);
|
||||
log.debug(String.format("列车[%s]停站时间[%s s]",
|
||||
train.getGroupNumber(), parkTime));
|
||||
// if (parkTime > 0) {
|
||||
// // 开屏蔽门
|
||||
// this.ATOService.syncOpenDoor(simulation, train);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void departure(Simulation simulation, String groupNumber) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
|
@ -4,6 +4,8 @@ import club.joylink.rtss.services.psl.IVirtualRealityPslService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATP.ground.MaService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.handler.DriverOperateHandler;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStationService;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
@ -14,6 +16,7 @@ import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.ControlTransferReplyVO;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.*;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
@ -23,10 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain.ConfirmationMessage.Confirm_Release_Speed;
|
||||
@ -64,7 +64,10 @@ public class RobotLogicLoop {
|
||||
robotStationControlAutoTransfer(simulation);
|
||||
}
|
||||
|
||||
private void robotOpenATO(Simulation simulation, VirtualRealityTrain train) {
|
||||
/**
|
||||
* 机器人准备发车
|
||||
*/
|
||||
private void robotReadyForDeparture(Simulation simulation, VirtualRealityTrain train) {
|
||||
StandParkedTrainActivity activity = train.getStandParkedTrainActivity();
|
||||
if (activity != null) {
|
||||
switch (activity) {
|
||||
@ -142,6 +145,7 @@ public class RobotLogicLoop {
|
||||
*/
|
||||
private void robotDriverLogicLoop(Simulation simulation) {
|
||||
List<SimulationMember> drivers = simulation.querySimulationMembersOfRole(SimulationMember.Type.DRIVER);
|
||||
boolean railway = simulation.getRepository().getConfig().isRailway();
|
||||
for (SimulationMember driver : drivers) {
|
||||
if (!driver.isRobot())
|
||||
continue;
|
||||
@ -150,15 +154,78 @@ public class RobotLogicLoop {
|
||||
if (!repository.isVrTrainOnline(train.getGroupNumber())) { //如果列车不在线
|
||||
continue;
|
||||
}
|
||||
robotOpenATO(simulation, train);
|
||||
robotDrive(simulation, driver, train);
|
||||
//准备发车
|
||||
robotReadyForDeparture(simulation, train);
|
||||
//机器人驾驶
|
||||
if (train.getRobotTargetPosition() != null) {
|
||||
robotDriveByCommand(simulation, driver, train);
|
||||
} else if (railway) {
|
||||
railRobotDrive(simulation, train);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 机器人驾驶
|
||||
* 大铁机器人自动驾驶。
|
||||
* 在确认列车自身状态正确的情况下(车门是关闭状态等),如果是没有计划的车次,则只看信号;如果是有计划的车次,还需要看计划
|
||||
*/
|
||||
private void robotDrive(Simulation simulation, SimulationMember driver, VirtualRealityTrain train) {
|
||||
private void railRobotDrive(Simulation simulation, VirtualRealityTrain train) {
|
||||
if (!train.getDoor1().isCloseAndLock() || !train.getDoor2().isCloseAndLock())
|
||||
return;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
boolean right = train.isRight();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
Section nextSection = headPosition.getSection();
|
||||
TrainInfo trainInfo = repository.getSupervisedTrainByGroup(train.getGroupNumber());
|
||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||
Collection<CtcStationRunPlanLog> runPlans = ctcRepository.findRunPlans(trainInfo.getTripNumber());
|
||||
Set<Section> tracks = new HashSet<>();
|
||||
for (CtcStationRunPlanLog runPlan : runPlans) {
|
||||
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan();
|
||||
if (arriveRunPlan != null)
|
||||
tracks.add(arriveRunPlan.getTrackSection());
|
||||
CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan();
|
||||
if (departRunPlan != null)
|
||||
tracks.add(departRunPlan.getTrackSection());
|
||||
}
|
||||
|
||||
SectionPosition targetPosition = null;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (tracks.contains(nextSection) && !nextSection.equals(train.getParkSection())) { //这个判断感觉迟早要出问题
|
||||
targetPosition = nextSection.buildStopPointPosition(right); //站台轨停车点
|
||||
break;
|
||||
}
|
||||
Signal signal = nextSection.getSignalOf(right);
|
||||
if (signal != null && !signal.isShunting()) { //有同向非通过信号机
|
||||
SectionPosition signalPosition = signal.getPosition();
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
if (vrSignal != null && !headPosition.isAheadOf(signalPosition, right)) { //有物理信号机并且车头没有越过信号机
|
||||
if (!SignalAspect.G.equals(vrSignal.getAspect())
|
||||
&& !SignalAspect.Y.equals(vrSignal.getAspect())
|
||||
&& !SignalAspect.YY.equals(vrSignal.getAspect())) { //大铁线路暂时默认绿灯和黄/双黄灯是正常通行信号
|
||||
targetPosition = CalculateService.calculateNextPositionByStartAndLen(signalPosition, !right, 5, true); //信号机前5m处
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Section next = nextSection.getNextRunningSectionOf(right);
|
||||
if (next == null) {
|
||||
targetPosition = new SectionPosition(nextSection, right ? nextSection.getLen() - 10 : 10); //轨道尽头10m处
|
||||
break;
|
||||
}
|
||||
nextSection = next;
|
||||
}
|
||||
if (targetPosition == null && nextSection != null) {
|
||||
targetPosition = new SectionPosition(nextSection, right ? 0 : nextSection.getMaxOffset());
|
||||
}
|
||||
if (targetPosition != null)
|
||||
robotDrive(simulation, train, targetPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* 机器人根据指令驾驶列车
|
||||
*/
|
||||
private void robotDriveByCommand(Simulation simulation, SimulationMember driver, VirtualRealityTrain train) {
|
||||
SectionPosition targetPosition = train.getRobotTargetPosition();
|
||||
if (targetPosition == null)
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user