hmi添加字段;计算速度曲线逻辑迁移至ATP循环;ATP速度防护逻辑修改
This commit is contained in:
parent
833d2ecb6e
commit
6f0a60a3ea
@ -18,22 +18,34 @@ import java.util.Objects;
|
||||
@Getter
|
||||
public class TrainHmiDisplay {
|
||||
|
||||
/** 列车code */
|
||||
/**
|
||||
* 列车code
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/** 车组号 */
|
||||
/**
|
||||
* 车组号
|
||||
*/
|
||||
private String groupNumber;
|
||||
|
||||
/** 服务号 */
|
||||
/**
|
||||
* 服务号
|
||||
*/
|
||||
private String serviceNumber;
|
||||
|
||||
/** 车次号 */
|
||||
/**
|
||||
* 车次号
|
||||
*/
|
||||
private String tripNumber;
|
||||
|
||||
/** 目的地码 */
|
||||
/**
|
||||
* 目的地码
|
||||
*/
|
||||
private String destinationCode;
|
||||
|
||||
/** 列车方向:true-向右 false-向左 */
|
||||
/**
|
||||
* 列车方向:true-向右 false-向左
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
private boolean right;
|
||||
|
||||
@ -41,68 +53,113 @@ public class TrainHmiDisplay {
|
||||
// /** 列车是否被托管 */
|
||||
// private boolean trust;
|
||||
|
||||
/** 列车当前速度 */
|
||||
/**
|
||||
* 列车当前速度
|
||||
*/
|
||||
private float v;
|
||||
|
||||
/** 列车防护速度 */
|
||||
/**
|
||||
* 列车防护速度
|
||||
*/
|
||||
private float pv;
|
||||
|
||||
/** 列车目标速度 */
|
||||
/**
|
||||
* 列车目标速度
|
||||
*/
|
||||
private float tv;
|
||||
|
||||
private float maLen;
|
||||
|
||||
/** 列车运行级别 */
|
||||
/**
|
||||
* 列车运行级别
|
||||
*/
|
||||
private RunLevel runLevel;
|
||||
|
||||
/** 驾驶模式 */
|
||||
/**
|
||||
* 驾驶模式
|
||||
*/
|
||||
private DriveMode driveMode;
|
||||
|
||||
/** 列车牵引/制动状态 */
|
||||
/**
|
||||
* 列车牵引/制动状态
|
||||
*/
|
||||
private TrainTBControl tbControl;
|
||||
|
||||
/** 车门是否开门 */
|
||||
/**
|
||||
* 车门是否开门
|
||||
*/
|
||||
private boolean doorOpen;
|
||||
|
||||
/** 左门是否可以关 */
|
||||
/**
|
||||
* 左门是否可以关
|
||||
*/
|
||||
private boolean leftDoorCanClose;
|
||||
|
||||
/** 右门是否可以关 */
|
||||
/**
|
||||
* 右门是否可以关
|
||||
*/
|
||||
private boolean rightDoorCanClose;
|
||||
|
||||
/** 是否紧急停车 */
|
||||
/**
|
||||
* 是否紧急停车
|
||||
*/
|
||||
private boolean eb;
|
||||
|
||||
/** 是否电路EB */
|
||||
/**
|
||||
* 是否电路EB
|
||||
*/
|
||||
private boolean circuitEB;
|
||||
|
||||
/** 跳站信息 */
|
||||
/**
|
||||
* 跳站信息
|
||||
*/
|
||||
private boolean jump;
|
||||
|
||||
/** 是否扣车 */
|
||||
/**
|
||||
* 是否扣车
|
||||
*/
|
||||
private boolean hold;
|
||||
|
||||
/** ATO是否启用 */
|
||||
/**
|
||||
* ATO是否启用
|
||||
*/
|
||||
private boolean atoOn;
|
||||
|
||||
/** ATP是否启用 */
|
||||
/**
|
||||
* ATP是否启用
|
||||
*/
|
||||
private boolean atpOn;
|
||||
|
||||
/** 计划下一站 */
|
||||
/**
|
||||
* 计划下一站
|
||||
*/
|
||||
private String nextStation;
|
||||
|
||||
/** 是否即将到站 */
|
||||
/**
|
||||
* 是否即将到站
|
||||
*/
|
||||
private boolean beAbout2Arrive;
|
||||
|
||||
/** 计划终点站 */
|
||||
/**
|
||||
* 计划终点站
|
||||
*/
|
||||
private String endStation;
|
||||
|
||||
/** 停站 */
|
||||
/**
|
||||
* 停站
|
||||
*/
|
||||
private boolean parking;
|
||||
|
||||
/** 在站台区域 */
|
||||
/**
|
||||
* 在站台区域
|
||||
*/
|
||||
private boolean inTheStandArea;
|
||||
|
||||
/**
|
||||
* true牵引false制动
|
||||
*/
|
||||
private int tow;
|
||||
|
||||
public TrainHmiDisplay(VirtualRealityTrain train) {
|
||||
this.code = train.getCode();
|
||||
this.groupNumber = train.getGroupNumber();
|
||||
@ -138,7 +195,7 @@ public class TrainHmiDisplay {
|
||||
MovementAuthority ma = train.getMa();
|
||||
if (Objects.nonNull(ma)) {
|
||||
this.maLen = BigDecimal.valueOf(train.getTargetDistance())
|
||||
.setScale(3, RoundingMode.HALF_UP).floatValue();
|
||||
.setScale(3, RoundingMode.HALF_UP).floatValue();
|
||||
}
|
||||
this.eb = train.isEB();
|
||||
this.circuitEB = train.isCircuitEB();
|
||||
@ -155,6 +212,18 @@ public class TrainHmiDisplay {
|
||||
}
|
||||
this.parking = train.isParkingAt();
|
||||
this.inTheStandArea = train.isInTheStandArea();
|
||||
this.tow = getTow(train);
|
||||
}
|
||||
|
||||
private int getTow(VirtualRealityTrain train) {
|
||||
Boolean towed = train.isTowed();
|
||||
if (towed == null) {
|
||||
return !train.isStop() ? 3 : 4;
|
||||
} else if (towed) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> changeAndCollectDiff(VirtualRealityTrain train) {
|
||||
@ -299,6 +368,11 @@ public class TrainHmiDisplay {
|
||||
this.inTheStandArea = train.isInTheStandArea();
|
||||
map.put("inTheStandArea", this.inTheStandArea);
|
||||
}
|
||||
int tow = getTow(train);
|
||||
if (this.tow != tow) {
|
||||
this.tow = tow;
|
||||
map.put("tow", tow);
|
||||
}
|
||||
if (map.size() > 0) {
|
||||
map.put("code", this.code);
|
||||
return map;
|
||||
|
@ -9,6 +9,7 @@ import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -410,6 +411,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
*/
|
||||
private boolean autoOpenATO;
|
||||
|
||||
private SpeedCurve speedCurve;
|
||||
|
||||
public void setCommunication(boolean communication) {
|
||||
if ((Fault.COMMUNICATION_ABNORMAL.equals(this.fault) || !atpOn) && communication)
|
||||
return;
|
||||
@ -449,6 +452,8 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
if (!on) { //如果是关闭ATP,取消信号EB
|
||||
this.setSignalEB(false);
|
||||
this.communication = false;
|
||||
this.setAtoSpeed(-1);
|
||||
this.setAtpSpeed(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,6 +525,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
this.positioned = true;
|
||||
this.runningTime = 0;
|
||||
this.autoOpenATO = false;
|
||||
this.speedCurve = null;
|
||||
this.fault = null;
|
||||
}
|
||||
|
||||
@ -1026,6 +1032,16 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|| this.calculateTailPosition().getSection().isNormalStandTrack();
|
||||
}
|
||||
|
||||
public Boolean isTowed() {
|
||||
if (fk > 0) {
|
||||
return true;
|
||||
} else if (fb > 0) {
|
||||
return false;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Door {
|
||||
|
@ -94,20 +94,20 @@ public class ATOService {
|
||||
doBreakMax(train);
|
||||
return;
|
||||
}
|
||||
boolean right = train.isRight();
|
||||
// boolean right = train.isRight();
|
||||
// ATP安全防护最远可达到位置
|
||||
float trainLen = train.getLen();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, trainLen);
|
||||
float targetDistance = this.calculateTargetRemainDistance(train, ma);
|
||||
// float trainLen = train.getLen();
|
||||
// SectionPosition headPosition = train.getHeadPosition();
|
||||
// SectionPosition tailPosition = CalculateService.calculateNextPositionByStartAndLen(headPosition, !right, trainLen);
|
||||
// float targetDistance = this.calculateTargetRemainDistance(train, ma);
|
||||
// float speedMax = train.getAtpSpeedMax();
|
||||
float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
|
||||
SpeedCurve speedCurve = SpeedCurve
|
||||
.buildTargetSpeedCurve(headPosition, tailPosition, right,
|
||||
targetDistance, train.getSpeed(), speedMax);
|
||||
// 更新目标距离和建议速度
|
||||
train.setTargetDistance(targetDistance);
|
||||
train.setAtoSpeed(speedCurve.getSpeedOf(speedCurve.getTotalDistance()));
|
||||
// float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
|
||||
// SpeedCurve speedCurve = SpeedCurve
|
||||
// .buildTargetSpeedCurve(headPosition, tailPosition, right,
|
||||
// targetDistance, train.getSpeed(), speedMax);
|
||||
// // 更新目标距离和建议速度
|
||||
// train.setTargetDistance(targetDistance);
|
||||
// train.setAtoSpeed(speedCurve.getSpeedOf(speedCurve.getTotalDistance()));
|
||||
|
||||
if (!train.isAtoOn()) { // ATO未启用,不控制
|
||||
return;
|
||||
@ -121,7 +121,10 @@ public class ATOService {
|
||||
doBreakMax(train);
|
||||
return;
|
||||
}
|
||||
this.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance());
|
||||
SpeedCurve speedCurve = train.getSpeedCurve();
|
||||
if (speedCurve != null) {
|
||||
this.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance());
|
||||
}
|
||||
}
|
||||
|
||||
public static Float calculateDistanceOfMa(SectionPosition headPosition, boolean right, MovementAuthority ma) {
|
||||
@ -198,6 +201,10 @@ public class ATOService {
|
||||
}
|
||||
|
||||
public void doControlBySpeedCurve(VirtualRealityTrain train, SpeedCurve speedCurve, float remainDistance) {
|
||||
doControlBySpeedCurve(train, speedCurve, remainDistance, train.getAtoSpeed());
|
||||
}
|
||||
|
||||
public void doControlBySpeedCurve(VirtualRealityTrain train, SpeedCurve speedCurve, float remainDistance, float atoSpeed) {
|
||||
if (speedCurve.equals(SpeedCurve.ZERO)) {
|
||||
this.doBreakMax(train);
|
||||
return;
|
||||
@ -212,7 +219,6 @@ public class ATOService {
|
||||
this.doStart(train);
|
||||
return;
|
||||
}
|
||||
float atoSpeed = train.getAtoSpeed();
|
||||
float acceleration = calculator.getAcceleration();
|
||||
float diff = speed - atoSpeed;
|
||||
if (acceleration == 0) { //匀速段
|
||||
|
@ -9,12 +9,14 @@ import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.TrainStopMessage;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.StandParkedTrainActivity;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.event.SimulationTrainIsAbout2ArriveEvent;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.SpeedCurve;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATO.service.ATOService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -109,6 +111,7 @@ public class ATPLogicLoop {
|
||||
private void onboardLogicRun2(Simulation simulation, VirtualRealityTrain train) {
|
||||
this.runLevelControl(simulation, train);
|
||||
this.driveModeControl(simulation, train);
|
||||
this.calculateSpeedCurve(simulation, train);
|
||||
|
||||
boolean right = train.isRight();
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
@ -183,6 +186,63 @@ public class ATPLogicLoop {
|
||||
this.atoService.ATO(train);
|
||||
}
|
||||
|
||||
private void calculateSpeedCurve(Simulation simulation, VirtualRealityTrain train) {
|
||||
if (!train.isAtpOn())
|
||||
return;
|
||||
DriveMode driveMode = train.getDriveMode();
|
||||
float atpSpeed = 0;
|
||||
float atoSpeed = 0;
|
||||
switch (driveMode) {
|
||||
case RM: {
|
||||
atpSpeed = simulation.getRepository().getConfig().getRmAtpSpeed();
|
||||
atoSpeed = train.getAtpSpeed() - 5 / 3.6f;
|
||||
break;
|
||||
}
|
||||
case AM:
|
||||
case CM: {
|
||||
// 驾驶故障导致EB
|
||||
MovementAuthority ma = train.getMa();
|
||||
if (Objects.nonNull(ma)) { // 通信正常,移动授权可用
|
||||
// 获取移动授权剩余距离
|
||||
Float remainDistance = atpService.calculateProtectDistance(train, ma.getEnd());
|
||||
if (Objects.isNull(remainDistance) || remainDistance <= 0) {
|
||||
log.warn(String.format("列车[%s]无法计算出移动防护剩余距离或防护距离不为正", train.getGroupNumber()));
|
||||
atpSpeed = 0;
|
||||
atoSpeed = 0;
|
||||
} else {
|
||||
// 获取防护速度
|
||||
SpeedCurve protectSpeedCurve = ma.getProtectSpeedCurve();
|
||||
float protectSpeed = protectSpeedCurve.getSpeedOf(remainDistance);
|
||||
atpSpeed = protectSpeed;
|
||||
// 计算推荐速度曲线
|
||||
float targetDistance = ATOService.calculateTargetRemainDistance(train, ma);
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
SectionPosition tailPosition = train.calculateTailPosition();
|
||||
boolean right = train.isRight();
|
||||
float speedMax = Math.min(train.getAtoSpeedMax(), train.getSpeedLimit() * 0.9f);
|
||||
SpeedCurve speedCurve = SpeedCurve
|
||||
.buildTargetSpeedCurve(headPosition, tailPosition, right,
|
||||
targetDistance, train.getSpeed(), speedMax);
|
||||
// 更新目标距离和建议速度
|
||||
train.setTargetDistance(targetDistance);
|
||||
train.setSpeedCurve(speedCurve);
|
||||
atoSpeed = speedCurve.getSpeedOf(speedCurve.getTotalDistance());
|
||||
}
|
||||
} else {
|
||||
atpSpeed = 0;
|
||||
atoSpeed = 0;
|
||||
log.warn(String.format("列车[%s-%s|%s|%s]速度[%s]没有移动授权,触发EB",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(),
|
||||
train.getSpeed()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
train.setAtpSpeed(atpSpeed);
|
||||
train.setAtoSpeed(atoSpeed);
|
||||
}
|
||||
|
||||
private void driveModeControl(Simulation simulation, VirtualRealityTrain train) {
|
||||
DriveMode preDriveMode = train.getPreDriveMode();
|
||||
DriveMode driveMode = train.getDriveMode();
|
||||
@ -211,8 +271,6 @@ public class ATPLogicLoop {
|
||||
return;
|
||||
}
|
||||
train.useRMMode();
|
||||
train.setAtpSpeed(config.getRmAtpSpeed());
|
||||
train.setAtoSpeed(config.getRmAtpSpeed() - 5 / 3.6f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -282,13 +340,13 @@ public class ATPLogicLoop {
|
||||
if (simulation.getRepository().getConfig().isAdjustOperationAutomatically()) {
|
||||
if (parkRemainTime < 10000) { // 小于10秒,关门
|
||||
// if (!train.isHold()) {
|
||||
train.nextParkedTrainActivity();
|
||||
train.nextParkedTrainActivity();
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
if (parkRemainTime <= 0) {
|
||||
// if (!train.isHold()) {
|
||||
train.nextParkedTrainActivity();
|
||||
train.nextParkedTrainActivity();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class ATPService {
|
||||
/**
|
||||
* 计算列车安全防护距离
|
||||
*/
|
||||
private Float calculateProtectDistance(VirtualRealityTrain train, MovementAuthority.End end) {
|
||||
public Float calculateProtectDistance(VirtualRealityTrain train, MovementAuthority.End end) {
|
||||
SectionPosition headPosition = train.getHeadPosition();
|
||||
boolean right = train.isRight();
|
||||
SectionPosition endPosition = end.getEndPosition();
|
||||
@ -99,67 +99,19 @@ public class ATPService {
|
||||
* @param train
|
||||
*/
|
||||
public void speedProtect(Simulation simulation, VirtualRealityTrain train) {
|
||||
if (train.isEB()) {
|
||||
if (train.isEB() || !train.isAtpOn()) {
|
||||
return;
|
||||
}
|
||||
if (!train.isStop() && train.isAtpOn() && !train.isEB()) {
|
||||
DriveMode driveMode = train.getDriveMode();
|
||||
switch (driveMode) {
|
||||
case RM: {
|
||||
if (train.getSpeed() > simulation.getRepository().getConfig().getRmAtpSpeed()) {
|
||||
log.warn(String.format("%s在RM模式下超速,速度:%s", train.debugStr(), train.getSpeed()));
|
||||
this.triggerSignalEB(train);
|
||||
}
|
||||
break;
|
||||
DriveMode driveMode = train.getDriveMode();
|
||||
switch (driveMode) {
|
||||
case RM:
|
||||
case AM:
|
||||
case CM:
|
||||
if (train.getSpeed() > train.getAtpSpeed()) {
|
||||
log.warn(String.format("列车[%s]超速EB", train.debugStr()));
|
||||
triggerSignalEB(train);
|
||||
}
|
||||
case AM:
|
||||
case CM:{
|
||||
// 驾驶故障导致EB
|
||||
if (VirtualRealityTrain.Fault.DRIVE_FAULT.equals(train.getFault()) && !train.isEB()) {
|
||||
log.warn(train.debugStr() + "因驾驶故障EB");
|
||||
this.triggerSignalEB(train);
|
||||
}
|
||||
MovementAuthority ma = train.getMa();
|
||||
if (Objects.nonNull(ma)) { // 通信正常,移动授权可用
|
||||
// 获取移动授权剩余距离
|
||||
Float remainDistance = calculateProtectDistance(train, ma.getEnd());
|
||||
if (Objects.isNull(remainDistance)) {
|
||||
log.warn(String.format("列车[%s]无法计算出移动防护剩余距离", train.getGroupNumber()));
|
||||
return;
|
||||
}
|
||||
if (remainDistance <= 0) {
|
||||
// 距离小于0,触发EB
|
||||
log.info(String.format("列车[%s-%s|%s|%s]防护距离小于0,触发EB。移动授权[%s]",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(), ma.debugStr()));
|
||||
this.triggerSignalEB(train);
|
||||
train.setAtpSpeed(0);
|
||||
return;
|
||||
}
|
||||
// 获取防护速度
|
||||
SpeedCurve protectSpeedCurve = ma.getProtectSpeedCurve();
|
||||
float protectSpeed = protectSpeedCurve.getSpeedOf(remainDistance);
|
||||
train.setAtpSpeed(protectSpeed);
|
||||
if (train.getSpeed() > protectSpeed) {
|
||||
// 列车速度大于防护速度,触发EB
|
||||
log.info(String.format("列车[%s-%s|%s|%s]速度[%s]大于ATP防护速度[%s],触发EB",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(),
|
||||
train.getSpeed(), protectSpeed));
|
||||
this.triggerSignalEB(train);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.triggerSignalEB(train);
|
||||
train.setAtpSpeed(0);
|
||||
log.warn(String.format("列车[%s-%s|%s|%s]速度[%s]没有移动授权,触发EB",
|
||||
train.getGroupNumber(), train.getServiceNumber(),
|
||||
train.getTripNumber(), train.getDestinationCode(),
|
||||
train.getSpeed()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,8 +196,9 @@ public class RobotLogicLoop {
|
||||
}
|
||||
train.setTargetDistance(distance);
|
||||
if (speedCurve != null) {
|
||||
train.setAtoSpeed(speedCurve.getSpeedOf(speedCurve.getTotalDistance()));
|
||||
atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance());
|
||||
float atoSpeed = speedCurve.getSpeedOf(speedCurve.getTotalDistance());
|
||||
// train.setAtoSpeed(atoSpeed);
|
||||
atoService.doControlBySpeedCurve(train, speedCurve, speedCurve.getTotalDistance(), atoSpeed);
|
||||
}
|
||||
// doControlBySpeedCurve(simulation, train, speedCurve, speedCurve.getTotalDistance());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user