hmi添加字段;计算速度曲线逻辑迁移至ATP循环;ATP速度防护逻辑修改

This commit is contained in:
joylink_zhangsai 2021-07-30 19:06:45 +08:00
parent 833d2ecb6e
commit 6f0a60a3ea
6 changed files with 213 additions and 106 deletions

View File

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

View File

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

View File

@ -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) { //匀速段

View File

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

View File

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

View File

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