You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.6 KiB
99 lines
2.6 KiB
package de.srsoftware.web4rail.threads; |
|
|
|
import org.slf4j.Logger; |
|
import org.slf4j.LoggerFactory; |
|
|
|
import de.srsoftware.web4rail.BaseClass; |
|
import de.srsoftware.web4rail.Route; |
|
import de.srsoftware.web4rail.moving.Train; |
|
|
|
/** |
|
* @author Stephan Richter, SRSoftware |
|
* |
|
*/ |
|
public class BrakeProcessor extends BaseClass implements Runnable { |
|
|
|
private enum State { |
|
IDLE, BRAKING, ABORTED, ENDED; |
|
} |
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(BrakeProcessor.class); |
|
public static int defaultEndSpeed; |
|
private Train train; |
|
private State state = State.IDLE; |
|
private long measuredDistance; |
|
private long lastTime; |
|
private Integer brakeTime; |
|
private int startSpeed; |
|
|
|
public BrakeProcessor(Train train) { |
|
this.train = train; |
|
} |
|
|
|
public void end() { |
|
state = State.ENDED; |
|
measuredDistance += train.speed * (BaseClass.timestamp() - lastTime); |
|
Route route = train.route(); |
|
if (isNull(route)) return; |
|
LOG.debug("old brake time: {}, measured distance: {}", brakeTime, measuredDistance); |
|
int step = brakeTime; |
|
for (int i = 0; i < 15; i++) { |
|
long calculatedDistance = calculate(brakeTime, startSpeed); |
|
if (measuredDistance > calculatedDistance) brakeTime += brakeTime/2; |
|
if (measuredDistance < calculatedDistance) { |
|
step /= 2; |
|
if (step < 1) step = 1; |
|
brakeTime -= step; |
|
} |
|
LOG.debug("new brake time: {}, calculated distance: {}", brakeTime, calculatedDistance); |
|
} |
|
route.brakeTime(train.brakeId(), brakeTime); |
|
} |
|
|
|
private static long calculate(int brakeTime, int speed) { |
|
long dist = 0; |
|
while (speed > defaultEndSpeed) { |
|
dist += speed * brakeTime; |
|
speed -= 10; |
|
} |
|
return dist; |
|
} |
|
|
|
@Override |
|
public void run() { |
|
LOG.debug("run()"); |
|
Route route = train.route(); |
|
if (isNull(route)) return; |
|
brakeTime = route.brakeTime(train.brakeId()); |
|
if (isNull(brakeTime)) brakeTime = 250; |
|
|
|
state = State.BRAKING; |
|
measuredDistance = 0; |
|
lastTime = BaseClass.timestamp(); |
|
startSpeed = train.speed; |
|
int targetSpeed = defaultEndSpeed; |
|
while (state == State.BRAKING) { |
|
sleep(brakeTime); |
|
long newTime = BaseClass.timestamp(); |
|
if (isNull(train.route())) state = State.ABORTED; |
|
if (state != State.BRAKING) break; |
|
measuredDistance += train.speed * (newTime - lastTime); |
|
int newSpeed = train.speed - 10; |
|
if (newSpeed < targetSpeed) { |
|
train.setSpeed(targetSpeed); |
|
break; |
|
} |
|
train.setSpeed(newSpeed); |
|
lastTime = newTime; |
|
} |
|
LOG.debug("{} reached final speed.", train); |
|
} |
|
|
|
public BrakeProcessor start() { |
|
Thread thread = new Thread(this); |
|
thread.setName(getClass().getSimpleName()); |
|
thread.start(); |
|
return this; |
|
} |
|
|
|
}
|
|
|