Browse Source

removed route managing code: preparing to re-implement

lookup-tables
Stephan Richter 4 years ago
parent
commit
4cade0a12e
  1. 2
      pom.xml
  2. 11
      src/main/java/de/srsoftware/web4rail/Plan.java
  3. 114
      src/main/java/de/srsoftware/web4rail/Route.java
  4. 200
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  5. 68
      src/main/java/de/srsoftware/web4rail/threads/Autopilot.java
  6. 145
      src/main/java/de/srsoftware/web4rail/threads/BrakeProcessor.java
  7. 2
      src/main/java/de/srsoftware/web4rail/tiles/Block.java

2
pom.xml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.srsoftware</groupId>
<artifactId>web4rail</artifactId>
<version>1.3.50</version>
<version>1.3.51</version>
<name>Web4Rail</name>
<packaging>jar</packaging>
<description>Java Model Railway Control</description>

11
src/main/java/de/srsoftware/web4rail/Plan.java

@ -36,7 +36,6 @@ import de.srsoftware.web4rail.tags.Input; @@ -36,7 +36,6 @@ import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Table;
import de.srsoftware.web4rail.tags.Window;
import de.srsoftware.web4rail.threads.BrakeProcessor;
import de.srsoftware.web4rail.threads.ControlUnit;
import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.BlockContact;
@ -153,7 +152,7 @@ public class Plan extends BaseClass{ @@ -153,7 +152,7 @@ public class Plan extends BaseClass{
private static final String SPEED_UNIT = "speed_unit";
private static final String LENGTH_UNIT = "length_unit";
private static final String CONFIRM = "confirm";
private static final String FINAL_SPEED = "final_speed";
// private static final String FINAL_SPEED = "final_speed"; // TODO
private static final String FREE_BEHIND_TRAIN = "free_behind_train";
private static final String RENAME = "rename";
private String name = DEFAULT_NAME;
@ -357,7 +356,7 @@ public class Plan extends BaseClass{ @@ -357,7 +356,7 @@ public class Plan extends BaseClass{
new Input(ACTION,ACTION_UPDATE).hideIn(form);
new Input(LENGTH_UNIT, lengthUnit).addTo(new Label(t("Length unit")+COL)).addTo(form);
new Input(SPEED_UNIT, speedUnit).addTo(new Label(t("Speed unit")+COL)).addTo(form);
new Input(FINAL_SPEED, BrakeProcessor.defaultEndSpeed).addTo(new Label(t("Lower speed limit")+COL)).attr("title", t("Final speed after breaking, before halting")).addTo(form);
//new Input(FINAL_SPEED, BrakeProcessor.defaultEndSpeed).addTo(new Label(t("Lower speed limit")+COL)).attr("title", t("Final speed after breaking, before halting")).addTo(form); // TODO
new Checkbox(FREE_BEHIND_TRAIN, t("Free tiles behind train"), Route.freeBehindTrain).attr("title", t("If checked, tiles behind the train are freed according to the length of the train and the tiles. If it is unchecked, tiles will not get free before route is finished.")).addTo(form);
new Button(t("Save"), form).addTo(form);
form.addTo(fieldset);
@ -491,7 +490,7 @@ public class Plan extends BaseClass{ @@ -491,7 +490,7 @@ public class Plan extends BaseClass{
.forEach(jTiles::put);
return new JSONObject()
.put(FINAL_SPEED, BrakeProcessor.defaultEndSpeed)
// .put(FINAL_SPEED, BrakeProcessor.defaultEndSpeed) // TODO
.put(FREE_BEHIND_TRAIN, Route.freeBehindTrain)
.put(LENGTH_UNIT, lengthUnit)
.put(SPEED_UNIT, speedUnit)
@ -525,7 +524,7 @@ public class Plan extends BaseClass{ @@ -525,7 +524,7 @@ public class Plan extends BaseClass{
if (json.has(TILE)) json.getJSONArray(TILE).forEach(object -> Tile.load(object, plan));
if (json.has(LENGTH_UNIT)) lengthUnit = json.getString(LENGTH_UNIT);
if (json.has(SPEED_UNIT)) speedUnit = json.getString(SPEED_UNIT);
if (json.has(FINAL_SPEED)) BrakeProcessor.defaultEndSpeed = json.getInt(FINAL_SPEED);
// if (json.has(FINAL_SPEED)) BrakeProcessor.defaultEndSpeed = json.getInt(FINAL_SPEED); // TODOO
if (json.has(FREE_BEHIND_TRAIN)) Route.freeBehindTrain = json.getBoolean(FREE_BEHIND_TRAIN);
try {
@ -984,7 +983,7 @@ public class Plan extends BaseClass{ @@ -984,7 +983,7 @@ public class Plan extends BaseClass{
if (params.containsKey(LENGTH_UNIT)) lengthUnit = params.get(LENGTH_UNIT);
if (params.containsKey(SPEED_UNIT)) speedUnit = params.get(SPEED_UNIT);
if (params.containsKey(FINAL_SPEED)) BrakeProcessor.defaultEndSpeed = Integer.parseInt(params.get(FINAL_SPEED));
// if (params.containsKey(FINAL_SPEED)) BrakeProcessor.defaultEndSpeed = Integer.parseInt(params.get(FINAL_SPEED)); // TODO
Route.freeBehindTrain = "on".equalsIgnoreCase(params.get(FREE_BEHIND_TRAIN));
return t("Plan updated.");

114
src/main/java/de/srsoftware/web4rail/Route.java

@ -37,7 +37,6 @@ import de.srsoftware.web4rail.tags.Fieldset; @@ -37,7 +37,6 @@ import de.srsoftware.web4rail.tags.Fieldset;
import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Table;
import de.srsoftware.web4rail.tags.Window;
import de.srsoftware.web4rail.threads.BrakeProcessor;
import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.BlockContact;
import de.srsoftware.web4rail.tiles.Contact;
@ -79,7 +78,7 @@ public class Route extends BaseClass { @@ -79,7 +78,7 @@ public class Route extends BaseClass {
private static HashMap<Id, String> names = new HashMap<Id, String>(); // maps id to name. needed to keep names during plan.analyze()
private BrakeProcessor brakeProcessor = null;
// private BrakeProcessor brakeProcessor = null;
private HashMap<String,Integer> brakeTimes = new HashMap<String, Integer>();
private ConditionList conditions;
private Vector<Contact> contacts;
@ -270,7 +269,7 @@ public class Route extends BaseClass { @@ -270,7 +269,7 @@ public class Route extends BaseClass {
public void brakeStart() {
if (isNull(train)) return;
brakeProcessor = new BrakeProcessor(this,train);
// brakeProcessor = new BrakeProcessor(this,train);
}
protected Route clone() {
@ -388,51 +387,9 @@ public class Route extends BaseClass { @@ -388,51 +387,9 @@ public class Route extends BaseClass {
public void finish() {
LOG.debug("{}.finish()",this);
if (isSet(train)) {
Route nextRoute = train.nextRoute();
if (isSet(nextRoute)) {
LOG.debug("{} has next route: {}",train,nextRoute);
if (isSet(brakeProcessor)) brakeProcessor.abort();
} else {
LOG.debug("{} has no next route.",train);
if (isSet(brakeProcessor)) {
brakeProcessor.finish();
} else train.setSpeed(0);
}
}
brakeProcessor = null;
free();
if (isSet(train)) {
moveTrainToEndBlock();
if (train.route() == this) train.route(null);
train = null;
}
state = State.FREE;
// TODO
}
/**
* sets all signals of this route to RED,
* frees all tiles occupied by this route
*/
private void free() {
LOG.debug("{}.free()",this);
context.clear(); // prevent delayed actions from firing after route has finished
setSignals(Signal.RED);
for (Tile tile : path) try { // remove route from tiles on path
tile.unset(this);
} catch (IllegalArgumentException e) {}
/* Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) {
lastTile.setTrain(null);
if (isSet(train)) train.removeChild(lastTile);
}*/
}
private String generateName() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<path.size();i++) {
@ -693,57 +650,6 @@ public class Route extends BaseClass { @@ -693,57 +650,6 @@ public class Route extends BaseClass {
return success;
}
private void moveTrainToEndBlock() {
if (isNull(train)) return;
LOG.debug("{}.moveTrainToEndBlock()",this);
train.set(endBlock);
traceTrainFrom(endBlock);
train.heading(endDirection);
if (endBlock == train.destination()) {
train.destination(null); // unset old destination
String destTag = train.destinationTag();
if (isSet(destTag)) {
LOG.debug("destination list: {}",destTag);
String[] parts = destTag.split(Train.DESTINATION_PREFIX);
for (int i=0; i<parts.length;i++) LOG.debug(" part {}: {}",i+1,parts[i]);
String destId = parts[1];
LOG.debug("destination tag: {}",destId);
boolean turn = false;
for (int i=destId.length()-1; i>0; i--) {
switch (destId.charAt(i)) {
case Train.FLAG_SEPARATOR:
destId = destId.substring(0,i);
i=0;
break;
case Train.TURN_FLAG:
turn = true;
LOG.debug("Turn flag is set!");
break;
}
}
if (destId.equals(endBlock.id().toString())) {
if (turn) train.turn();
// update destination tag: remove and add altered tag:
train.removeTag(destTag);
destTag = destTag.substring(parts[1].length()+1);
if (destTag.isEmpty()) { // no further destinations
destTag = null;
} else train.addTag(destTag);
}
}
if (isNull(destTag)) {
train.quitAutopilot();
plan.stream(t("{} reached it`s destination!",train));
}
} else train.setWaitTime(endBlock.getWaitTime(train,train.direction()));
if (startBlock.train() == train && !train.onTrace(startBlock)) startBlock.setTrain(null); // withdraw train from start block only if trace does not go back there
}
public List<Route> multiply(int size) {
Vector<Route> routes = new Vector<Route>();
for (int i=0; i<size; i++) routes.add(i==0 ? this : this.clone());
@ -788,11 +694,6 @@ public class Route extends BaseClass { @@ -788,11 +694,6 @@ public class Route extends BaseClass {
return script;
}
public Route prolong(Route nextRoute) {
if (isSet(brakeProcessor)) brakeProcessor.setEndSpeed(nextRoute.startSpeed());
return nextRoute;
}
@Override
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) {
@ -853,15 +754,8 @@ public class Route extends BaseClass { @@ -853,15 +754,8 @@ public class Route extends BaseClass {
public boolean reset() {
LOG.debug("{}.reset()",this);
free();
if (isSet(brakeProcessor)) brakeProcessor.abort();
if (isSet(train)) {
train.set(startBlock);
train.heading(startDirection);
if (train.route() == this) train.route(null);
train = null;
}
// TODO
state = State.FREE;
return true;
}

200
src/main/java/de/srsoftware/web4rail/moving/Train.java

@ -23,12 +23,9 @@ import org.slf4j.Logger; @@ -23,12 +23,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.PathFinder;
import de.srsoftware.web4rail.Plan;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.Range;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Checkbox;
@ -39,9 +36,7 @@ import de.srsoftware.web4rail.tags.Label; @@ -39,9 +36,7 @@ import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tags.Select;
import de.srsoftware.web4rail.tags.Table;
import de.srsoftware.web4rail.tags.Window;
import de.srsoftware.web4rail.threads.Autopilot;
import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.Contact;
import de.srsoftware.web4rail.tiles.Tile;
/**
@ -89,13 +84,9 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -89,13 +84,9 @@ public class Train extends BaseClass implements Comparable<Train> {
private Vector<Block> lastBlocks = new Vector<Block>();
public int speed = 0;
public Autopilot autopilot = null;
private Route nextRoute;
private static final String SHUNTING = "shunting";
private boolean shunting = false;
private boolean reserving; // used to prevent recursive calls of reserveNext
public static Object action(HashMap<String, String> params, Plan plan) throws IOException {
String action = params.get(ACTION);
if (isNull(action)) return t("No action passed to Train.action!");
@ -178,11 +169,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -178,11 +169,8 @@ public class Train extends BaseClass implements Comparable<Train> {
}
public String automatic() {
if (isNull(autopilot)) {
autopilot = new Autopilot(this);
if (isSet(currentBlock)) plan.place(currentBlock);
}
return t("{} now in auto-mode",this);
return "not implemented";
}
private Fieldset blockHistory() {
@ -349,38 +337,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -349,38 +337,8 @@ public class Train extends BaseClass implements Comparable<Train> {
return properties();
}
public Block destination() {
//LOG.debug("{}.destination()",this);
if (isNull(destination)) {
String destTag = destinationTag();
//LOG.debug("→ processing \"{}\"...",destTag);
if (isSet(destTag)) {
destTag = destTag.split(DESTINATION_PREFIX)[1];
//LOG.debug("....processing \"{}\"…",destTag);
for (int i=destTag.length()-1; i>0; i--) {
switch (destTag.charAt(i)) {
case FLAG_SEPARATOR:
destTag = destTag.substring(0,i);
i=0;
break;
case SHUNTING_FLAG:
//LOG.debug("....enabled shunting option");
shunting = true;
break;
}
}
Block block = BaseClass.get(new Id(destTag));
if (isSet(block)) destination(block);
}
}// else LOG.debug("→ heading towards {}",destination);
return destination;
}
public Train destination(Block dest) {
LOG.debug("destination({})",dest);
destination = dest;
return this;
public Block destination(){
return null; // TODO
}
public String destinationTag() {
@ -393,7 +351,7 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -393,7 +351,7 @@ public class Train extends BaseClass implements Comparable<Train> {
public String directedName() {
String result = name();
String mark = isSet(autopilot) ? "ⓐ" : "";
String mark = ""; //isSet(autopilot) ? "ⓐ" : "";
if (isNull(direction)) return result;
switch (direction) {
case NORTH:
@ -553,8 +511,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -553,8 +511,8 @@ public class Train extends BaseClass implements Comparable<Train> {
String.join(", ", train.tags()),
train.route,
isSet(train.currentBlock) ? train.currentBlock.link() : null,
train.destination(),
t(isSet(train.autopilot)?"On":"Off")
null, // TODO: show destination here!
null // TODO: show state of autopilot here
);
});
table.addTo(win);
@ -617,10 +575,6 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -617,10 +575,6 @@ public class Train extends BaseClass implements Comparable<Train> {
return this;
}
public Route nextRoute() {
return nextRoute;
}
public boolean onTrace(Tile t) {
return trace.contains(t);
}
@ -681,16 +635,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -681,16 +635,8 @@ public class Train extends BaseClass implements Comparable<Train> {
}
public Object quitAutopilot() {
if (isSet(nextRoute)) {
nextRoute.reset();
nextRoute = null;
}
if (isSet(autopilot)) {
autopilot.doStop();
autopilot = null;
if (isSet(currentBlock)) plan.place(currentBlock);
return t("{} stopping at next block.",this);
} else return t("autopilot not active.");
// TODO Auto-generated method stub
return "not implemented";
}
@Override
@ -711,7 +657,7 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -711,7 +657,7 @@ public class Train extends BaseClass implements Comparable<Train> {
public void removeChild(BaseClass child) {
LOG.debug("{}.removeChild({})",this,child);
if (child == route) route = null;
if (child == nextRoute) nextRoute = null;
//if (child == nextRoute) nextRoute = null; // TODO
if (child == currentBlock) currentBlock = null;
if (child == destination) destination = null;
cars.remove(child);
@ -725,35 +671,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -725,35 +671,8 @@ public class Train extends BaseClass implements Comparable<Train> {
}
public void reserveNext() {
if (reserving) return;
LOG.debug("{}.reserveNext()",this);
if (isSet(nextRoute)) {
LOG.debug("Train already has next route: {}",nextRoute);
return;
}
Context context = new Context(this).route(route).block(route.endBlock()).direction(route.endDirection);
Route newRoute = PathFinder.chooseRoute(context);
if (isNull(newRoute)) {
LOG.debug("{}.reserveNext() found no available route!",this);
return;
}
reserving = true;
LOG.debug("next route: {}",newRoute);
newRoute.set(context);
boolean error = !newRoute.lockIgnoring(route);
error = error || !newRoute.prepare();
if (error) {
newRoute.reset(); // may unlock tiles belonging to the current route.
LOG.debug("failed to prepare new route {}",newRoute);
route.lock(); // corrects unlocked tiles of nextRoute
} else {
nextRoute = newRoute;
LOG.debug("prepared next route: {}",nextRoute);
}
reserving = false;
// TODO
}
/**
* This turns the train as if it went through a loop. Example:
* before: CabCar MiddleCar Loco
@ -782,12 +701,6 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -782,12 +701,6 @@ public class Train extends BaseClass implements Comparable<Train> {
return route;
}
public Train route(Route newRoute) {
route = newRoute;
if (isNull(route)) shunting = false; // quit shunting on finish route
return this;
}
public static void saveAll(String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
for (Train train:BaseClass.listElements(Train.class)) file.write(train.json()+"\n");
@ -831,7 +744,7 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -831,7 +744,7 @@ public class Train extends BaseClass implements Comparable<Train> {
if (isNull(tile)) return t("Tile {} not known!",dest);
if (tile instanceof Block) {
destination = (Block) tile;
automatic();
start();
return t("{} now heading for {}",this,destination);
}
return t("{} is not a block!",tile);
@ -883,11 +796,6 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -883,11 +796,6 @@ public class Train extends BaseClass implements Comparable<Train> {
LOG.debug("new trace of {}: {}",this,trace);
}
public void setWaitTime(Range waitTime) {
if (isNull(autopilot)) return;
autopilot.waitTime(waitTime);
}
private Tag slower(int steps) {
setSpeed(speed-steps);
return properties();
@ -921,44 +829,8 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -921,44 +829,8 @@ public class Train extends BaseClass implements Comparable<Train> {
}
public String start() throws IOException {
LOG.debug("{}.start()",this);
if (isNull(currentBlock)) return t("{} not in a block",this);
if (maxSpeed() == 0) return t("Train has maximum speed of 0 {}, cannot go!",speedUnit);
if (isSet(route)) route.reset(); // reset route previously chosen
String error = null;
if (isSet(nextRoute)) {
LOG.debug("{}.nextRoute = {}",this,nextRoute);
route = nextRoute;
if (!route.lock()) return t("Was not able to lock {}",route);
nextRoute = null;
route.set(new Context(this).block(currentBlock).direction(direction));
} else {
if (reserving) return t("Route chooser already active");
Context context = new Context(this).block(currentBlock).direction(direction);
route = PathFinder.chooseRoute(context);
if (isNull(route)) return t("No free routes from {}",currentBlock);
LOG.debug("Chosen route: {}",route);
if (!route.lock()) error = t("Was not able to lock {}",route);
route.set(context);
if (isNull(error) && !route.prepare()) error = t("Was not able to fire all setup actions of route!");
}
if (isNull(route)) return t("Route cancelled"); // route may have been canceled in between
if (isNull(error) && direction != route.startDirection) turn();
if (isNull(error) && !route.start(this)) error = t("Was not able to assign {} to {}!",this,route);
if (isSet(error)) {
LOG.debug("{}.start:error = {}",this,error);
route.reset();
route = null;
return error;
}
startSimulation();
String res = t("Started {}",this);
plan.stream(res);
return res;
public String start() {
return "not implemented, yet";
}
public static void startAll() {
@ -966,49 +838,7 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -966,49 +838,7 @@ public class Train extends BaseClass implements Comparable<Train> {
for (Train train : BaseClass.listElements(Train.class)) LOG.info(train.automatic());
}
private void startSimulation() {
LOG.debug("{}.startSimulation()",this);
for (Contact contact : route.contacts()) {
if (contact.addr() != 0) {
LOG.debug("{}.startSimulation aborted!",this);
return; // simulate train only when all contacts are non-physical
}
}
try {
Thread.sleep(1000);
plan.stream(t("Simulating movement of {}...",this));
Thread simulation = new Thread() {
public void run() {
for (Tile tile : route.path()) {
if (isNull(route)) break;
try {
if (tile instanceof Contact) {
Contact contact = (Contact) tile;
contact.activate(true);
sleep(200);
contact.activate(false);
}
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
};
simulation.setName(Application.threadName("Simulation("+Train.this+")"));
simulation.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Object stopNow() {
quitAutopilot();
if (isSet(route)) {
route.reset();
route = null;
}
setSpeed(0);
return properties();
}
@ -1073,6 +903,6 @@ public class Train extends BaseClass implements Comparable<Train> { @@ -1073,6 +903,6 @@ public class Train extends BaseClass implements Comparable<Train> {
}
public boolean usesAutopilot() {
return isSet(autopilot);
return false; // TODO
}
}

68
src/main/java/de/srsoftware/web4rail/threads/Autopilot.java

@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
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);
}
}

145
src/main/java/de/srsoftware/web4rail/threads/BrakeProcessor.java

@ -1,145 +0,0 @@ @@ -1,145 +0,0 @@
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;
}
}

2
src/main/java/de/srsoftware/web4rail/tiles/Block.java

@ -407,7 +407,7 @@ public abstract class Block extends StretchableTile{ @@ -407,7 +407,7 @@ public abstract class Block extends StretchableTile{
Train newTrain = Train.get(trainId);
if (isSet(newTrain) && newTrain != train) {
newTrain.dropTrace();
if (connections(newTrain.direction()).isEmpty()) newTrain.heading(null);
if (connections(newTrain.direction()).isEmpty()) newTrain.heading(null);
newTrain.set(this);
}
}

Loading…
Cancel
Save