Files
Web4Rail/src/main/java/de/srsoftware/web4rail/threads/BrakeProcess.java
2021-04-01 19:09:17 +02:00

107 lines
2.9 KiB
Java

package de.srsoftware.web4rail.threads;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.moving.Train;
public class BrakeProcess extends BaseClass implements Runnable{
private static final Logger LOG = LoggerFactory.getLogger(BrakeProcess.class);
public static int defaultTimeStep = 500;
private Train train;
private int targetSpeed = Train.defaultEndSpeed;
boolean ended = false;
long distance = 0;
private int startSpeed;
private int lastSpeed;
private long lastTime;
private Integer timeStep;
private Route route;
private String brakeId;
public BrakeProcess(Train train) {
this.train = train;
this.brakeId = train.brakeId();
this.route = train.route();
new Thread(this, Application.threadName(this)).start();
}
private long calcDistance(Integer ts) {
long dist = 0;
int s = startSpeed;
while (s > Train.defaultEndSpeed) {
dist += s*ts;
s -= Train.defaultSpeedStep;
}
LOG.debug("Estimated distamce with {} ms timestep: {}",ts,dist);
return dist;
}
public BrakeProcess end() {
LOG.debug("{}.end()",this);
ended = true;
return this;
}
@Override
public void run() {
timeStep = train.route().brakeTime(train.brakeId());
LOG.debug("{}.run() with timestep = {} ms",this,timeStep);
if (timeStep == null) timeStep = defaultTimeStep;
startSpeed = train.speed;
lastTime = timestamp();
while (!train.hasNextPreparedRoute()) {
sleep(timeStep);
lastSpeed = train.speed;
updateDistance();
if (lastSpeed > targetSpeed) lastSpeed -= Train.defaultSpeedStep;
if (ended) break;
if (lastSpeed <= targetSpeed && (ended = true)) lastSpeed = targetSpeed;
train.setSpeed(lastSpeed);
}
}
private void updateDistance() {
long newTime = timestamp();
distance += (newTime-lastTime)*lastSpeed;
lastTime = newTime;
LOG.debug("measured distance: {} units",distance);
}
@Override
public String toString() {
return getClass().getSimpleName()+"("+train+")";
}
public void updateTime() {
updateDistance();
LOG.debug("updateTime(): start speed was {} {}.",startSpeed,BaseClass.speedUnit);
Integer newTimeStep = timeStep;
long calculated;
int step = 32*newTimeStep;
for (int i=0; i<20; i++) {
step = step/2;
if (step<1) step = 1;
calculated = calcDistance(newTimeStep);
LOG.debug("Calculated distance for step = {} ms: {}",newTimeStep,calculated);
LOG.debug("Update step: {}",step);
newTimeStep = newTimeStep + (calculated > distance ? -step : step);
}
if (!newTimeStep.equals(timeStep)) {
route.brakeTime(brakeId,newTimeStep);
calculated = calcDistance(newTimeStep);
LOG.debug("Corrected brake timestep from {} to {} ms for {} @ {}.",timeStep,newTimeStep,train,route);
LOG.debug("Differemce from estimated distance: {} ({}%)",distance-calculated,100*(distance-calculated)/(float)distance);
}
}
}