Browse Source

bugfixes

lookup-tables
Stephan Richter 5 years ago
parent
commit
483ebec39e
  1. 2
      pom.xml
  2. 11
      src/main/java/de/srsoftware/web4rail/Plan.java
  3. 5
      src/main/java/de/srsoftware/web4rail/Route.java
  4. 14
      src/main/java/de/srsoftware/web4rail/moving/Train.java
  5. 48
      src/main/java/de/srsoftware/web4rail/threads/BrakeProcess.java
  6. 2
      src/main/java/de/srsoftware/web4rail/threads/ControlUnit.java
  7. 6
      src/main/java/de/srsoftware/web4rail/threads/RoutePrepper.java
  8. 10
      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>

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

@ -886,13 +886,16 @@ 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", "");
new Thread("Plan") {
@Override
public void run() {
//if (!data.startsWith("heartbeat")) LOG.debug("streaming: {}",data); //if (!data.startsWith("heartbeat")) LOG.debug("streaming: {}",data);
Vector<OutputStreamWriter> badClients = null; Vector<OutputStreamWriter> badClients = null;
for (Entry<OutputStreamWriter, Integer> entry : clients.entrySet()) { for (Entry<OutputStreamWriter, Integer> entry : clients.entrySet()) {
OutputStreamWriter client = entry.getKey(); OutputStreamWriter client = entry.getKey();
try { try {
client.write("data: "+data+"\n\n"); client.write("data: "+fixedData+"\n\n");
client.flush(); client.flush();
clients.put(client,0); clients.put(client,0);
} catch (IOException e) { } catch (IOException e) {
@ -911,6 +914,10 @@ public class Plan extends BaseClass{
LOG.info("Disconnecting client."); LOG.info("Disconnecting client.");
clients.remove(client); clients.remove(client);
} }
// TODO Auto-generated method stub
}
}.start();
} }
/** /**

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;
} }

14
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));

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

@ -5,12 +5,15 @@ 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;
private int targetSpeed = Train.defaultEndSpeed; private int targetSpeed = Train.defaultEndSpeed;
@ -20,11 +23,30 @@ public class BrakeProcess extends BaseClass implements Runnable{
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);

6
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;
} }

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

@ -84,14 +84,13 @@ 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();
} }
} }
@ -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