Browse Source

bugfixes

lookup-tables
Stephan Richter 4 years ago
parent
commit
483ebec39e
  1. 2
      pom.xml
  2. 53
      src/main/java/de/srsoftware/web4rail/Plan.java
  3. 5
      src/main/java/de/srsoftware/web4rail/Route.java
  4. 16
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  5. 50
      src/main/java/de/srsoftware/web4rail/threads/BrakeProcess.java
  6. 2
      src/main/java/de/srsoftware/web4rail/threads/ControlUnit.java
  7. 8
      src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java
  8. 12
      src/main/java/de/srsoftware/web4rail/tiles/Contact.java
  9. 6
      src/main/java/de/srsoftware/web4rail/tiles/Tile.java

2
pom.xml

@ -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.4.2</version> <version>1.4.3</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>

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

@ -886,31 +886,38 @@ public class Plan extends BaseClass{
* @param data * @param data
*/ */
public synchronized void stream(String data) { public synchronized void stream(String data) {
data = data.replaceAll("\n", "").replaceAll("\r", ""); String fixedData = data.replaceAll("\n", "").replaceAll("\r", "");
//if (!data.startsWith("heartbeat")) LOG.debug("streaming: {}",data); new Thread("Plan") {
Vector<OutputStreamWriter> badClients = null; @Override
for (Entry<OutputStreamWriter, Integer> entry : clients.entrySet()) { public void run() {
OutputStreamWriter client = entry.getKey(); //if (!data.startsWith("heartbeat")) LOG.debug("streaming: {}",data);
try { Vector<OutputStreamWriter> badClients = null;
client.write("data: "+data+"\n\n"); for (Entry<OutputStreamWriter, Integer> entry : clients.entrySet()) {
client.flush(); OutputStreamWriter client = entry.getKey();
clients.put(client,0);
} catch (IOException e) {
int errorCount = entry.getValue()+1;
LOG.info("Error #{} on client: {}",errorCount,e.getMessage());
if (errorCount > 4) {
if (isNull(badClients)) badClients = new Vector<OutputStreamWriter>();
try { try {
client.close(); client.write("data: "+fixedData+"\n\n");
} catch (IOException e1) {} client.flush();
badClients.add(client); clients.put(client,0);
} else clients.put(client,errorCount); } catch (IOException e) {
int errorCount = entry.getValue()+1;
LOG.info("Error #{} on client: {}",errorCount,e.getMessage());
if (errorCount > 4) {
if (isNull(badClients)) badClients = new Vector<OutputStreamWriter>();
try {
client.close();
} catch (IOException e1) {}
badClients.add(client);
} else clients.put(client,errorCount);
}
}
if (badClients != null) for (OutputStreamWriter client: badClients) {
LOG.info("Disconnecting client.");
clients.remove(client);
}
// TODO Auto-generated method stub
} }
} }.start();
if (badClients != null) for (OutputStreamWriter client: badClients) {
LOG.info("Disconnecting client.");
clients.remove(client);
}
} }
/** /**

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

@ -232,9 +232,7 @@ public class Route extends BaseClass {
} }
public Integer brakeTime(String brakeId) { public Integer brakeTime(String brakeId) {
Integer result = brakeTimes.get(brakeId); return brakeTimes.get(brakeId);
Collection<Integer> values = brakeTimes.values();
return values.isEmpty() ? BrakeProcess.defaultTimeStep : values.stream().mapToInt(Integer::intValue).sum()/values.size();
} }
public void brakeTime(String brakeId, Integer newTimeStep) { public void brakeTime(String brakeId, Integer newTimeStep) {
@ -392,6 +390,7 @@ public class Route extends BaseClass {
public void finish(Train train) { public void finish(Train train) {
LOG.debug("{}.finish()",this); LOG.debug("{}.finish()",this);
train.endRoute(endBlock,endDirection); train.endRoute(endBlock,endDirection);
setSignals(Signal.RED);
freeIgnoring(null); freeIgnoring(null);
train = null; train = null;
} }

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

@ -362,7 +362,7 @@ public class Train extends BaseClass implements Comparable<Train> {
public String directedName(Direction dir) { public String directedName(Direction dir) {
String result = name(); String result = name();
String mark = ""; //isSet(autopilot) ? "ⓐ" : ""; String mark = autopilot ? "ⓐ" : "";
if (isNull(dir)) return result; if (isNull(dir)) return result;
switch (dir) { switch (dir) {
case NORTH: case NORTH:
@ -418,6 +418,10 @@ public class Train extends BaseClass implements Comparable<Train> {
public void endRoute(Block endBlock, Direction endDirection) { public void endRoute(Block endBlock, Direction endDirection) {
BrakeProcess brake = endBrake(); BrakeProcess brake = endBrake();
if (endBlock == destination) {
quitAutopilot();
destination = null;
}
if (isSet(brake)) brake.updateTime(); if (isSet(brake)) brake.updateTime();
Integer waitTime = route.waitTime(); Integer waitTime = route.waitTime();
nextPreparedRoute = route.dropNextPreparedRoute(); nextPreparedRoute = route.dropNextPreparedRoute();
@ -721,11 +725,11 @@ public class Train extends BaseClass implements Comparable<Train> {
public String quitAutopilot() { public String quitAutopilot() {
if (isSet(routePrepper)) routePrepper.stop(); if (isSet(routePrepper)) routePrepper.stop();
try { if (autopilot) {
return autopilot ? t("Autopilot disabled") : t("Autopilot already was disabled!");
} finally {
autopilot = false; autopilot = false;
} if (isSet(currentBlock)) plan.place(currentBlock);
}
return null;
} }
@Override @Override
@ -826,7 +830,7 @@ public class Train extends BaseClass implements Comparable<Train> {
if (isNull(tile)) return properties(t("Tile {} not known!",dest)); if (isNull(tile)) return properties(t("Tile {} not known!",dest));
if (tile instanceof Block) { if (tile instanceof Block) {
destination = (Block) tile; destination = (Block) tile;
start(false); start(true);
return t("{} now heading for {}",this,destination); return t("{} now heading for {}",this,destination);
} }
return properties(t("{} is not a block!",tile)); return properties(t("{} is not a block!",tile));

50
src/main/java/de/srsoftware/web4rail/threads/BrakeProcess.java

@ -5,11 +5,14 @@ import org.slf4j.LoggerFactory;
import de.srsoftware.web4rail.Application; import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass; import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.moving.Train; import de.srsoftware.web4rail.moving.Train;
public class BrakeProcess extends BaseClass implements Runnable{ public class BrakeProcess extends BaseClass implements Runnable{
private static final Logger LOG = LoggerFactory.getLogger(BrakeProcess.class); private static final Logger LOG = LoggerFactory.getLogger(BrakeProcess.class);
private static final int SPEED_STEP = 10;
public static int defaultTimeStep = 500; public static int defaultTimeStep = 500;
private Train train; private Train train;
@ -19,12 +22,31 @@ public class BrakeProcess extends BaseClass implements Runnable{
private int startSpeed; private int startSpeed;
private int lastSpeed; private int lastSpeed;
private long lastTime; private long lastTime;
private Integer timeStep;
private Route route;
private String brakeId;
public BrakeProcess(Train train) { public BrakeProcess(Train train) {
this.train = train; this.train = train;
this.brakeId = train.brakeId();
this.route = train.route();
new Thread(this, Application.threadName(this)).start(); new Thread(this, Application.threadName(this)).start();
} }
private long calcDistance(Integer ts) {
long dist = 0;
int s = startSpeed;
while (s > Train.defaultEndSpeed) {
s -= SPEED_STEP;
dist += s*ts;
}
LOG.debug("Estimated distamce with {} ms timestep: {}",ts,dist);
return dist;
}
public BrakeProcess end() { public BrakeProcess end() {
LOG.debug("{}.end()",this); LOG.debug("{}.end()",this);
ended = true; ended = true;
@ -33,14 +55,15 @@ public class BrakeProcess extends BaseClass implements Runnable{
@Override @Override
public void run() { public void run() {
Integer delay = train.route().brakeTime(train.brakeId()); timeStep = train.route().brakeTime(train.brakeId());
if (timeStep == null) timeStep = defaultTimeStep;
startSpeed = train.speed; startSpeed = train.speed;
lastTime = timestamp(); lastTime = timestamp();
while (!train.hasNextPreparedRoute()) { while (!train.hasNextPreparedRoute()) {
sleep(delay); sleep(timeStep);
lastSpeed = train.speed; lastSpeed = train.speed;
updateDistance(); updateDistance();
if (lastSpeed > targetSpeed) lastSpeed -= 10; if (lastSpeed > targetSpeed) lastSpeed -= SPEED_STEP;
if (ended) break; if (ended) break;
if (lastSpeed <= targetSpeed && (ended = true)) lastSpeed = targetSpeed; if (lastSpeed <= targetSpeed && (ended = true)) lastSpeed = targetSpeed;
train.setSpeed(lastSpeed); train.setSpeed(lastSpeed);
@ -62,6 +85,23 @@ public class BrakeProcess extends BaseClass implements Runnable{
public void updateTime() { public void updateTime() {
updateDistance(); updateDistance();
LOG.debug("updateTime(): start speed was {} {}.",startSpeed,BaseClass.speedUnit); LOG.debug("updateTime(): start speed was {} {}.",startSpeed,BaseClass.speedUnit);
// TODO 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 for {} @ {} from {} to {} ms.",train,route,timeStep,newTimeStep);
LOG.debug("Differemce from estimated distance: {} ({}%)",distance-calculated,100*(distance-calculated)/(float)distance);
}
} }
} }

2
src/main/java/de/srsoftware/web4rail/threads/ControlUnit.java

@ -318,7 +318,7 @@ public class ControlUnit extends Thread implements Constants{
case FEEDBACK: case FEEDBACK:
int addr = Integer.parseInt(parts[5]); int addr = Integer.parseInt(parts[5]);
boolean active = !parts[6].equals("0"); boolean active = !parts[6].equals("0");
new Thread(Application.threadName("CU.FeedBack("+addr+")")) { new Thread(Application.threadName("CU.Feedback("+addr+")")) {
@Override @Override
public void run() { public void run() {
plan.sensor(addr,active); plan.sensor(addr,active);

8
src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java

@ -51,13 +51,13 @@ public class RoutePrepper extends BaseClass implements Runnable{
LOG.warn("{}→ {}.availableRoutes called without context.train!", inset, Train.class.getSimpleName()); LOG.warn("{}→ {}.availableRoutes called without context.train!", inset, Train.class.getSimpleName());
if (error) return availableRoutes; if (error) return availableRoutes;
Block destination = train.destination();
if (isSet(startDirection)) { if (isSet(startDirection)) {
LOG.debug("{}- Looking for {}-bound routes from {}", inset, startDirection, block); LOG.debug("{}- Looking for {}-bound routes from {}", inset, startDirection, block);
} else { } else {
LOG.debug("{}- Looking for all routes from {}", inset, block); LOG.debug("{}- Looking for all routes from {}", inset, block);
} }
Block destination = train.destination();
if (isSet(destination) && visitedRoutes.isEmpty()) LOG.debug("{}- Destination: {}", inset, destination); if (isSet(destination) && visitedRoutes.isEmpty()) LOG.debug("{}- Destination: {}", inset, destination);
for (Route routeCandidate : block.leavingRoutes()) { for (Route routeCandidate : block.leavingRoutes()) {
@ -68,9 +68,9 @@ public class RoutePrepper extends BaseClass implements Runnable{
} }
HashSet<Tile> stuckTrace = train.stuckTrace(); // if train has been stopped in between two blocks lastly: 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 // only allow starting routes that do not conflict with current train
// position // position
if (isSet(stuckTrace) && !routeCandidate.path().containsAll(stuckTrace)) { if (isSet(stuckTrace) && visitedRoutes.isEmpty() && !routeCandidate.path().containsAll(stuckTrace)) {
LOG.debug("Stuck train occupies tiles ({}) outside of {} – not allowed.", stuckTrace, routeCandidate); LOG.debug("Stuck train occupies tiles ({}) outside of {} – not allowed.", stuckTrace, routeCandidate);
continue; continue;
} }

12
src/main/java/de/srsoftware/web4rail/tiles/Contact.java

@ -84,17 +84,16 @@ public class Contact extends Tile{
} else { } else {
LOG.debug("{} activated.",this); LOG.debug("{} activated.",this);
state = true; state = true;
stream();
if (isSet(timer)) timer.abort(); if (isSet(timer)) timer.abort();
Train train = train(); Train train = train();
Context context = isSet(train) ? train.contact(this) : new Context(this); Context context = isSet(train) ? train.contact(this) : new Context(this);
actions.fire(context,"Contact("+addr+")"); actions.fire(context,"Contact("+addr+")");
for (Listener listener : listeners) listener.fired("Contact("+addr+")"); for (Listener listener : listeners) listener.fired("Contact("+addr+")");
stream();
} }
} }
public int addr() { public int addr() {
return addr; return addr;
} }
@ -112,12 +111,7 @@ public class Contact extends Tile{
@Override @Override
public Object click(boolean shift) throws IOException { public Object click(boolean shift) throws IOException {
if (!shift) new Thread(Application.threadName(this)) { if (!shift) trigger(200);
@Override
public void run() {
trigger(200);
}
}.start();
return super.click(shift); return super.click(shift);
} }

6
src/main/java/de/srsoftware/web4rail/tiles/Tile.java

@ -540,7 +540,11 @@ public abstract class Tile extends BaseClass implements Comparable<Tile> {
oneWay = null; oneWay = null;
} }
} }
if ("on".equals(params.get(DISABLED))) status = Status.DISABLED; if ("on".equals(params.get(DISABLED))) {
status = Status.DISABLED;
} else {
status = isSet(train) ? Status.OCCUPIED : Status.FREE;
}
String len = params.get(LENGTH); String len = params.get(LENGTH);
if (isSet(len)) length(Integer.parseInt(len)); if (isSet(len)) length(Integer.parseInt(len));
super.update(params); super.update(params);

Loading…
Cancel
Save