26 changed files with 260 additions and 229 deletions
@ -0,0 +1,68 @@ |
|||||||
|
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.Range; |
||||||
|
import de.srsoftware.web4rail.moving.Train; |
||||||
|
|
||||||
|
public class Autopilot extends Thread{ |
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Autopilot.class); |
||||||
|
|
||||||
|
boolean stop = false; |
||||||
|
private Train train; |
||||||
|
int waitTime = 100; |
||||||
|
|
||||||
|
public Autopilot(Train train) { |
||||||
|
this.train = train; |
||||||
|
setName(Application.threadName("Autopilot("+train+")")); |
||||||
|
start(); |
||||||
|
} |
||||||
|
|
||||||
|
public void doStop() { |
||||||
|
stop = true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
try { |
||||||
|
stop = false; |
||||||
|
while (true) { |
||||||
|
if (BaseClass.isNull(train.route())) { |
||||||
|
Thread.sleep(waitTime); |
||||||
|
if (waitTime > 100) waitTime /=2; |
||||||
|
if (stop) break; |
||||||
|
if (BaseClass.isNull(train.route())) { // may have been set by start action in between
|
||||||
|
String message = train.start(); |
||||||
|
if (BaseClass.isSet(train.route())) { |
||||||
|
LOG.debug("{}.start called, route now is {}",train,train.route()); |
||||||
|
BaseClass.plan.stream(message); |
||||||
|
//if (isSet(destination)) Thread.sleep(1000); // limit load on PathFinder
|
||||||
|
} else { |
||||||
|
LOG.debug(message); |
||||||
|
waitTime = 1000; // limit load on PathFinder
|
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (stop) break; |
||||||
|
Thread.sleep(250); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
train.autopilot = null; |
||||||
|
if (BaseClass.isSet(train.currentBlock())) BaseClass.plan.place(train.currentBlock()); |
||||||
|
} |
||||||
|
|
||||||
|
public void waitTime(Range wt) { |
||||||
|
this.waitTime = wt.random(); |
||||||
|
String msg = BaseClass.t("{} waiting {} secs...",this,waitTime/1000d); |
||||||
|
LOG.debug(msg); |
||||||
|
BaseClass.plan.stream(msg); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,145 @@ |
|||||||
|
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 BrakeProcessor extends Thread { |
||||||
|
public static final Logger LOG = LoggerFactory.getLogger(BrakeProcessor.class); |
||||||
|
|
||||||
|
|
||||||
|
private long latestTick; |
||||||
|
private static final int SPEED_STEP = 5; |
||||||
|
private Integer timeStep; |
||||||
|
private Route route; |
||||||
|
private Train train; |
||||||
|
private String brakeId; |
||||||
|
private long estimatedDistance; // Unit: s*km/h "km/h-Sekunden"
|
||||||
|
private int startSpeed,endSpeed; |
||||||
|
private boolean aborted,modified,finished; |
||||||
|
public static int defaultEndSpeed = 10; |
||||||
|
|
||||||
|
public BrakeProcessor(Route route, Train train) { |
||||||
|
this.train = train; |
||||||
|
this.route = route; |
||||||
|
|
||||||
|
aborted = false; |
||||||
|
modified = false; |
||||||
|
finished = false; |
||||||
|
brakeId = train.brakeId(); |
||||||
|
startSpeed = train.speed; |
||||||
|
endSpeed = defaultEndSpeed; |
||||||
|
|
||||||
|
timeStep = route.brakeTime(brakeId); |
||||||
|
|
||||||
|
if (BaseClass.isNull(timeStep) || timeStep>1000000) timeStep = 256; // if no brake time is available for this train
|
||||||
|
setName(Application.threadName("BrakeProcessor("+train+")")); |
||||||
|
start(); |
||||||
|
} |
||||||
|
|
||||||
|
public void abort() { |
||||||
|
aborted = true; |
||||||
|
} |
||||||
|
|
||||||
|
private long calcDistance(Integer ts) { |
||||||
|
long dist = 0; |
||||||
|
int s = startSpeed; |
||||||
|
while (s > defaultEndSpeed) { |
||||||
|
s -= SPEED_STEP; |
||||||
|
dist += s*ts; |
||||||
|
} |
||||||
|
LOG.debug("Estimated distamce with {} ms timestep: {}",ts,dist); |
||||||
|
return dist; |
||||||
|
} |
||||||
|
|
||||||
|
private void checkNextRoute() { |
||||||
|
Route nextRoute = train.nextRoute(); |
||||||
|
if (BaseClass.isSet(nextRoute) && nextRoute.state() == Route.State.PREPARED) { // auf Startgeschwindigkeit der Nachfolgeroute bremsen
|
||||||
|
Integer nextRouteStartSpeed = nextRoute.startSpeed(); |
||||||
|
if (BaseClass.isSet(nextRouteStartSpeed)) { |
||||||
|
LOG.debug("updating target velocity from {} to {}!",endSpeed,nextRouteStartSpeed); |
||||||
|
endSpeed = nextRouteStartSpeed; |
||||||
|
modified = true; |
||||||
|
if (endSpeed > train.speed) train.setSpeed(endSpeed); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is called from route.finish when train came to stop |
||||||
|
*/ |
||||||
|
public void finish() { |
||||||
|
LOG.debug("BrakeProcessor.finish()"); |
||||||
|
finished = true; |
||||||
|
if (aborted || modified) return; |
||||||
|
increaseDistance(); |
||||||
|
train.setSpeed(0); |
||||||
|
LOG.debug("Estimated distance: {}",estimatedDistance); |
||||||
|
|
||||||
|
if (startSpeed <= endSpeed) return; |
||||||
|
if (timeStep<0) timeStep = 100; |
||||||
|
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 > estimatedDistance ? -step : step); |
||||||
|
} |
||||||
|
|
||||||
|
if (!newTimeStep.equals(timeStep)) { |
||||||
|
route.brakeTime(brakeId,newTimeStep); |
||||||
|
calculated = calcDistance(newTimeStep); |
||||||
|
LOG.debug("Corrected brake timestep for {} @ {} from {} to {} ms.",train,route,timeStep,newTimeStep); |
||||||
|
LOG.debug("Differemce from estimated distance: {} ({}%)",estimatedDistance-calculated,100*(estimatedDistance-calculated)/(float)estimatedDistance); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void increaseDistance(){ |
||||||
|
long tick = BaseClass.timestamp(); |
||||||
|
estimatedDistance += train.speed * (3+tick-latestTick); |
||||||
|
latestTick = tick; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
setName(Application.threadName("BreakeProcessor("+train+")")); |
||||||
|
LOG.debug("started BrakeProcessor ({} → {}) for {} with timestep = {} ms.",train.speed,endSpeed,train,timeStep); |
||||||
|
estimatedDistance = 0; |
||||||
|
latestTick = BaseClass.timestamp(); |
||||||
|
while (train.speed > endSpeed) { |
||||||
|
if (finished || aborted) return; |
||||||
|
increaseDistance(); |
||||||
|
LOG.debug("BrakeProcessor({}) setting Speed of {}.",route,train); |
||||||
|
train.setSpeed(Math.max(train.speed - SPEED_STEP,endSpeed)); |
||||||
|
if (!modified) checkNextRoute(); |
||||||
|
try { |
||||||
|
sleep(timeStep); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
LOG.warn("BrakeProcessor interrupted!", e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
while (!finished && !aborted && !modified) { |
||||||
|
try { |
||||||
|
sleep(1000); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
LOG.warn("BrakeProcessor interrupted!", e); |
||||||
|
} |
||||||
|
checkNextRoute(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void setEndSpeed(Integer newEndSpeed) { |
||||||
|
if (BaseClass.isNull(newEndSpeed)) return; |
||||||
|
endSpeed = newEndSpeed; |
||||||
|
modified = true; |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,6 @@ |
|||||||
package de.srsoftware.web4rail; |
package de.srsoftware.web4rail.threads; |
||||||
|
|
||||||
|
import de.srsoftware.web4rail.Application; |
||||||
|
|
||||||
public abstract class DelayedExecution extends Thread { |
public abstract class DelayedExecution extends Thread { |
||||||
private int delay; |
private int delay; |
Loading…
Reference in new issue