implemented handling of stuck trains during route search

This commit is contained in:
Stephan Richter
2021-03-14 16:15:14 +01:00
parent c4e57d2b8a
commit d86b6dcbcc
6 changed files with 28 additions and 5 deletions

View File

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

View File

@@ -380,7 +380,8 @@ public class Route extends BaseClass {
} }
private void free() { private void free() {
context.invalidate(); context.invalidate(); // do not set to null:
// this action may be called from route.contact → finishRoute, which calls train.updateTrace afterwards, which in turn requires context
Train train = context.train(); Train train = context.train();
Vector<Tile> reversedPath = reverse(path()); Vector<Tile> reversedPath = reverse(path());
for (Tile tile : reversedPath) { for (Tile tile : reversedPath) {
@@ -750,6 +751,7 @@ public class Route extends BaseClass {
Train train = context.train(); Train train = context.train();
free(); free();
train.drop(this); train.drop(this);
context = null;
return true; return true;
} }

View File

@@ -90,6 +90,8 @@ public class Train extends BaseClass implements Comparable<Train> {
private boolean shunting = false; private boolean shunting = false;
private RouteManager routeManager = null; private RouteManager routeManager = null;
private HashSet<Tile> stuckTrace = null;
public static Object action(HashMap<String, String> params, Plan plan) throws IOException { public static Object action(HashMap<String, String> params, Plan plan) throws IOException {
String action = params.get(ACTION); String action = params.get(ACTION);
if (isNull(action)) return t("No action passed to Train.action!"); if (isNull(action)) return t("No action passed to Train.action!");
@@ -405,6 +407,7 @@ public class Train extends BaseClass implements Comparable<Train> {
endBlock.add(this, direction); endBlock.add(this, direction);
currentBlock = endBlock; currentBlock = endBlock;
trace.add(endBlock); trace.add(endBlock);
stuckTrace = null;
} }
private Tag faster(int steps) { private Tag faster(int steps) {
@@ -866,10 +869,19 @@ public class Train extends BaseClass implements Comparable<Train> {
setSpeed(0); setSpeed(0);
quitAutopilot(); quitAutopilot();
if (isSet(route)) { if (isSet(route)) {
stuckTrace = new HashSet<Tile>();
for (Tile tile : route.path()) { // collect occupied tiles of route. stuckTrace is considered during next route search
if (trace.contains(tile)) stuckTrace.add(tile);
}
route.reset(); route.reset();
} }
return properties(); return properties();
} }
public HashSet<Tile> stuckTrace() {
return stuckTrace;
}
public SortedSet<String> tags() { public SortedSet<String> tags() {
TreeSet<String> list = new TreeSet<String>(tags); TreeSet<String> list = new TreeSet<String>(tags);

View File

@@ -14,6 +14,7 @@ import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.Route; import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tiles.Block; import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.Tile;
public class RouteManager extends BaseClass implements Runnable { public class RouteManager extends BaseClass implements Runnable {
@@ -66,6 +67,13 @@ public class RouteManager extends BaseClass implements Runnable {
LOG.debug("{}→ Candidate {} would create loop, skipping",inset,routeCandidate.shortName()); LOG.debug("{}→ Candidate {} would create loop, skipping",inset,routeCandidate.shortName());
continue; continue;
} }
HashSet<Tile> stuckTrace = train.stuckTrace(); // if train has been stopped in between two blocks lastly: only allow routes that do not conflict with current train position
if (isSet(stuckTrace) && !routeCandidate.path().containsAll(stuckTrace)) {
LOG.debug("Stuck train occupies tiles ({}) outside of {} not allowed.",stuckTrace,routeCandidate);
continue;
}
if (!routeCandidate.allowed(context)) { if (!routeCandidate.allowed(context)) {
if (routeCandidate.endBlock() != destination) { // allowance may be overridden by destination if (routeCandidate.endBlock() != destination) { // allowance may be overridden by destination
LOG.debug("{} not allowed for {}",routeCandidate,context); LOG.debug("{} not allowed for {}",routeCandidate,context);

View File

@@ -278,8 +278,9 @@ public abstract class Block extends StretchableTile{
if (isNull(firstTrain)) return true; if (isNull(firstTrain)) return true;
if (firstTrain != train) return false; if (firstTrain != train) return false;
trains.remove(train); trains.remove(train);
status = trains.isEmpty() ? Status.FREE : Status.OCCUPIED; if (isSet(firstTrain)) {
plan.place(this); super.free(train);
} else super.setTrain(firstTrain);
return true; return true;
} }

View File

@@ -106,7 +106,7 @@ public abstract class Tile extends BaseClass implements Comparable<Tile> {
} }
public boolean free(Train t) { public boolean free(Train t) {
if (t != train) return false; if (isSet(train) && t != train) return false;
train = null; train = null;
status = Status.FREE; status = Status.FREE;
plan.place(this); plan.place(this);