working on split blocks and short trains..

master
Steffen Pohle 2 years ago
parent 54e3342a5e
commit 1018ec5990

@ -229,6 +229,8 @@ void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
int i; int i;
int step = 0, maxstep = 0; int step = 0, maxstep = 0;
debug (0, "Interfaces::SetLocoSpeed Loco:'%s' Speed:%d", l->name, speed);
switch(l->stepcode) { switch(l->stepcode) {
case LOCO_INT_DCC14: maxstep = 14; break; case LOCO_INT_DCC14: maxstep = 14; break;
case LOCO_INT_DCC28: maxstep = 28; break; case LOCO_INT_DCC28: maxstep = 28; break;
@ -257,6 +259,8 @@ void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
void Interfaces::SetLocoFunction(Locomotive *l, int func, int value) { void Interfaces::SetLocoFunction(Locomotive *l, int func, int value) {
int i; int i;
debug (0, "Interfaces::SetLocoFunction Loco:'%s' Function:%d Value:%d", l->name, func, value);
LockThread(); LockThread();
for (i = 0; i < max; i++) if (interfaces[i] != NULL) { for (i = 0; i < max; i++) if (interfaces[i] != NULL) {

@ -830,7 +830,7 @@ int Locomotives::Loop() {
else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) { else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) {
// try to lock way. // try to lock way.
size_t pos; size_t pos;
debug (0, "Locomotives::Loop %s:%d Found Way:%s", __FILE__, __LINE__, way.c_str());
if ((pos = way.find(",b:", 1)) != string::npos) { if ((pos = way.find(",b:", 1)) != string::npos) {
strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN);
strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN);
@ -866,11 +866,12 @@ int Locomotives::Loop() {
// between the commands. All turnouts will get a SetWay command in case some turnout was set // between the commands. All turnouts will get a SetWay command in case some turnout was set
// manualy without feedback to the server. // manualy without feedback to the server.
// //
block = loco->blocknext+2; block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) { if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) { if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) {
// all turnouts are set, start the train. // all turnouts are set, start the train.
debug (0, "* Locomotive '%s' Way Locked Start", loco->name);
if ((loco->flags & LOCO_F_CARGO) || if ((loco->flags & LOCO_F_CARGO) ||
(server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT)) (server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT))
SetSpeed(loco->name, reverse * loco->vmid); SetSpeed(loco->name, reverse * loco->vmid);
@ -882,12 +883,11 @@ int Locomotives::Loop() {
} }
else if (loco->auto_onroute == LOCO_OR_ONTHEWAY) { else if (loco->auto_onroute == LOCO_OR_ONTHEWAY) {
// FIXME: move this code to the block class -> we will need a better code for multiple sensors
// //
// the train is on the way, check for entering the block. // the train is on the way, check for entering the block.
// //
block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
// FIXME: move this code to the block class -> we will need a better code for multiple sensors
block = loco->blocknext+2;
if (loco->blocknext[0] == '-') dir_reverse = 1; if (loco->blocknext[0] == '-') dir_reverse = 1;
else dir_reverse = 0; else dir_reverse = 0;
@ -896,6 +896,7 @@ int Locomotives::Loop() {
s_stop = server->blocks.GetSensorStop(dir_reverse, block); s_stop = server->blocks.GetSensorStop(dir_reverse, block);
s_slow = server->blocks.GetSensorSlow(dir_reverse, block); s_slow = server->blocks.GetSensorSlow(dir_reverse, block);
s_enter = server->blocks.GetSensorEnter(dir_reverse, block); s_enter = server->blocks.GetSensorEnter(dir_reverse, block);
if ( server->sensors.GetActive(s_enter) == 1 || server->sensors.GetActive(s_stop) == 1 || if ( server->sensors.GetActive(s_enter) == 1 || server->sensors.GetActive(s_stop) == 1 ||
server->sensors.GetActive(s_slow) == 1 || server->sensors.GetActive(s_shortstop) == 1) { // entering block? server->sensors.GetActive(s_slow) == 1 || server->sensors.GetActive(s_shortstop) == 1) { // entering block?
@ -904,6 +905,7 @@ int Locomotives::Loop() {
debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow)); debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow));
debug (0, "* %s,%d Sensor Sh.Stop '%s' = %d", __FILE__, __LINE__, s_shortstop.c_str(), server->sensors.GetActive(s_shortstop)); debug (0, "* %s,%d Sensor Sh.Stop '%s' = %d", __FILE__, __LINE__, s_shortstop.c_str(), server->sensors.GetActive(s_shortstop));
debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop)); debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop));
// unlock old assigned block // unlock old assigned block
if (loco->blockassign[0] != 0) server->blocks.SetLockedby((string)(loco->blockassign+2), loco->name, 0); if (loco->blockassign[0] != 0) server->blocks.SetLockedby((string)(loco->blockassign+2), loco->name, 0);
@ -985,9 +987,10 @@ int Locomotives::Loop() {
} }
else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKSTOP) { else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKSTOP) {
// check enter block //
// check if the train is in its stop position
block = loco->blockassign+2; //
block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
if (loco->blockassign[0] == '-') dir_reverse = 1; if (loco->blockassign[0] == '-') dir_reverse = 1;
else dir_reverse = 0; else dir_reverse = 0;
@ -1024,7 +1027,7 @@ int Locomotives::Loop() {
timer_start(&loco->auto_timenext); timer_start(&loco->auto_timenext);
} }
block = loco->blockassign+2; block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
if (loco->blockassign[0] == '-') dir_reverse = 1; if (loco->blockassign[0] == '-') dir_reverse = 1;
else dir_reverse = 0; else dir_reverse = 0;

@ -505,6 +505,8 @@ string Railways::GetDestBlock(int locoflags, string blockend) {
if (blockend[0] == '+') blockend = "+:" + blockn; if (blockend[0] == '+') blockend = "+:" + blockn;
else blockend = "-:" + blockp; else blockend = "-:" + blockp;
block = blockend;
} }
else { else {
block = blockend; block = blockend;
@ -514,7 +516,7 @@ string Railways::GetDestBlock(int locoflags, string blockend) {
, (block_f & BLOCK_F_SPLIT) ? 1 : 0 , (block_f & BLOCK_F_SPLIT) ? 1 : 0
, block.c_str()); , block.c_str());
return 0; return block;
} }
@ -572,6 +574,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
fd_end.enterfrom = fd_start.enterfrom = -1; fd_end.enterfrom = fd_start.enterfrom = -1;
if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) { if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) {
debug (0, "Railway::FindWay found startblock (%s).", blockstart.c_str());
if (Get(fd_start.x, fd_start.y).dir == 1) { if (Get(fd_start.x, fd_start.y).dir == 1) {
if (blockstart[0] == '+') fd_start.enterfrom = 0; if (blockstart[0] == '+') fd_start.enterfrom = 0;
else fd_start.enterfrom = 2; else fd_start.enterfrom = 2;
@ -591,6 +594,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
} }
if (FindReference(&fd_end.x, &fd_end.y, blockend.substr(2, string::npos))) { if (FindReference(&fd_end.x, &fd_end.y, blockend.substr(2, string::npos))) {
debug (0, "Railway::FindWay found endblock (%s).", blockend.c_str());
if (Get(fd_end.x, fd_end.y).dir == 1) { if (Get(fd_end.x, fd_end.y).dir == 1) {
if (blockend[0] == '+') fd_end.enterfrom = 0; if (blockend[0] == '+') fd_end.enterfrom = 0;
else fd_end.enterfrom = 2; else fd_end.enterfrom = 2;
@ -636,6 +640,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
} }
else if (fd_pos.enterfrom >= 0 && fd_end.x == fd_pos.x && fd_pos.y == fd_end.y && fd_pos.enterfrom == fd_end.enterfrom) { else if (fd_pos.enterfrom >= 0 && fd_end.x == fd_pos.x && fd_pos.y == fd_end.y && fd_pos.enterfrom == fd_end.enterfrom) {
// destination found // destination found
debug (0, "Railway::FindWay %s:%d found way.", __FILE__, __LINE__);
found = 1; found = 1;
*next = fd_pos.way + ",b:" + blockend; *next = fd_pos.way + ",b:" + blockend;
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
@ -715,6 +720,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
} }
else if (rpos->type == RAILWAY_BLOCK) { else if (rpos->type == RAILWAY_BLOCK) {
int blflags = server->blocks.GetFlags(rpos->name); int blflags = server->blocks.GetFlags(rpos->name);
debug (0, "Railways::FindWay %s:%d found block: %s", __FILE__, __LINE__, rpos->name);
// //
// check if block is available for entering // check if block is available for entering
@ -768,7 +774,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
// //
// check if way found a block. // check if way found a block.
size_t npos; size_t npos;
if ((npos = next->find(",b:")) != string::npos) if ((npos = next->rfind(",b:")) != string::npos)
*next = next->substr(0, next->find(",", npos+1)); *next = next->substr(0, next->find(",", npos+1));
else // nothing found? else // nothing found?
*next = ""; *next = "";
@ -1098,8 +1104,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
* try to lock or unlock the way for the loco(lockedby) * try to lock or unlock the way for the loco(lockedby)
* Will also do the check for long trains and split blocks. * Will also do the check for long trains and split blocks.
*/ */
#warning check for split blocks and long trains not yet finished.
//FIXME: check for split blocks and long trains not yet finished.
int Railways::LockWay (string way, string lockedby, int lockonoff) { int Railways::LockWay (string way, string lockedby, int lockonoff) {
int res = 0; int res = 0;
size_t pos1, pos2; size_t pos1, pos2;
@ -1107,10 +1111,12 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
struct s_findway_data start; struct s_findway_data start;
struct s_findway_data end; struct s_findway_data end;
struct s_findway_data pos; struct s_findway_data pos;
string startblock, endblock; string startblock, endblock, endblock2;
Railway *r; Railway *r;
int finished = 0; int finished = 0;
JSONParse jp; JSONParse jp;
int locoflags = 0;
int blockflags = 0;
debug (0, "* LockWay Way:'%s' for '%s' lockonoff:%d", way.c_str(), lockedby.c_str(), lockonoff); debug (0, "* LockWay Way:'%s' for '%s' lockonoff:%d", way.c_str(), lockedby.c_str(), lockonoff);
@ -1118,16 +1124,25 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
end.y = start.y = -1; end.y = start.y = -1;
end.enterfrom = start.enterfrom = -1; end.enterfrom = start.enterfrom = -1;
if ((pos1 = way.find("b:", 0)) == string::npos) return 0; if ((pos1 = way.find("b:")) == string::npos) return 0;
if ((pos2 = way.find(",", pos1+1)) == string::npos) return 0; if ((pos2 = way.find(",", pos1+1)) == string::npos) return 0;
startblock = way.substr (pos1+2, pos2-pos1-2); startblock = way.substr (pos1+2, pos2-pos1-2);
if ((pos1 = way.find(",b:", 0)) == string::npos) return 0; if ((pos1 = way.rfind(",b:")) == string::npos) return 0;
if ((pos2 = way.find(",", pos1+1)) == string::npos) endblock = way.substr (pos1+3, pos2); if ((pos2 = way.find(",", pos1+1)) == string::npos) endblock = way.substr (pos1+3, pos2);
else endblock = way.substr (pos1+3, pos2-pos1-3); else endblock = way.substr (pos1+3, pos2-pos1-3);
printf ("%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s'\n", __FILE__, __LINE__, way.c_str(), //
startblock.c_str(), endblock.c_str()); // take care of split blocks and long trains.
// if the second block is not needed endblock2 will remain empty
locoflags = server->locomotives.GetFlags(lockedby);
blockflags = server->blocks.GetFlags(endblock.substr(2, string::npos));
if (!(locoflags & LOCO_F_SHORTTRAIN) && (blockflags & BLOCK_F_SPLIT))
endblock2 = server->blocks.GetSecondBlock(endblock.substr(2, string::npos));
else endblock2 = "";
debug (0, "%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s' Endblock2: '%s'", __FILE__, __LINE__, way.c_str(),
startblock.c_str(), endblock.c_str(), endblock2.c_str());
// //
// find start position // find start position
@ -1148,8 +1163,9 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
} }
// //
// find end position, this needs to take care of the SPLIT blocks. // find end position. Long trains and Split blocks is being taken care of in
// if split BLOCK and LONG train check for the currect end block // the Findwaypart.
// when unlocking we are not unlocking the way between these blocks.
if (FindReference(&end.x, &end.y, endblock.substr(2,string::npos))) { if (FindReference(&end.x, &end.y, endblock.substr(2,string::npos))) {
if (Get(end.x, end.y).dir == 1) { if (Get(end.x, end.y).dir == 1) {
if (endblock[0] == '+') end.enterfrom = 0; if (endblock[0] == '+') end.enterfrom = 0;
@ -1192,7 +1208,9 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
} }
// do lock start and endpoint... unlock only start // do lock start and endpoint... unlock only start
if (pos.x == end.x && pos.y == end.y && r->type == RAILWAY_BLOCK) { if ((pos.x == end.x && pos.y == end.y) || (r->type == RAILWAY_BLOCK &&
((endblock.compare(r->name) == 0) ||
(endblock2.length() > 0 && endblock2.compare(r->name) == 0)))) {
if (lockonoff == 1) { if (lockonoff == 1) {
UnLock(); UnLock();
server->blocks.SetLockedby(r->name, lockedby, 1); server->blocks.SetLockedby(r->name, lockedby, 1);
@ -1220,7 +1238,17 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
if(network) network->ChangeListPushToAll(jp.ToString()); if(network) network->ChangeListPushToAll(jp.ToString());
} }
if ((pos.x == end.x && pos.y == end.y) || pos.x < 0 || pos.y < 0 || pos.x >= width || pos.y >= height) { if (pos.x < 0 || pos.y < 0 || pos.x >= width || pos.y >= height) {
server->interfaces.PowerOnOff(false);
debug (0, "Railway::LockWay %s:%d Error: routing out of surface [%d,%d]", __FILE__, __LINE__, pos.x, pos.y);
finished = 1;
break;
}
if ((pos.x == end.x && pos.y == end.y) ||
(lockonoff == 0 &&
((endblock.compare(r->name) == 0) ||
(endblock2.length() > 0 && endblock2.compare(r->name) == 0)))) {
finished = 1; finished = 1;
break; break;
} }

Loading…
Cancel
Save