bugfixes
This commit is contained in:
2
pom.xml
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>
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user