|
|
@ -729,55 +729,15 @@ void::Locomotives::SendUpdate (Locomotive *loc) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Locomotives::Loop() {
|
|
|
|
/*
|
|
|
|
int lnum;
|
|
|
|
* locomotive searching for a new way
|
|
|
|
|
|
|
|
* loco->way and loco->blocknext will be overwritten
|
|
|
|
|
|
|
|
* loco->way must be saved to loco->wayold before calling this function
|
|
|
|
|
|
|
|
* it will not set the auto_onroute step
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Locomotives::Loco_SearchAndLock(Locomotive *loco) {
|
|
|
|
string way;
|
|
|
|
string way;
|
|
|
|
Locomotive *loco = NULL;
|
|
|
|
|
|
|
|
string block;
|
|
|
|
|
|
|
|
string s_enter;
|
|
|
|
|
|
|
|
string s_slow;
|
|
|
|
|
|
|
|
string s_stop;
|
|
|
|
|
|
|
|
string s_shortstop;
|
|
|
|
|
|
|
|
JSONParse jp;
|
|
|
|
|
|
|
|
int reverse = 1;
|
|
|
|
|
|
|
|
int dir_reverse = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (lnum = 0; lnum < max; lnum++) if (locomotives[lnum].name[0] != 0) {
|
|
|
|
|
|
|
|
loco = &locomotives[lnum];
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_REVERSE) reverse = -1;
|
|
|
|
|
|
|
|
else reverse = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTO) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// only in automate do anything alone
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
if (loco->blockassign[0] == 0) {
|
|
|
|
|
|
|
|
debug (0, "%s:%d Locomotive [%s] not assigned to any block. Set Mode to Man", __FILE__, __LINE__, loco->name);
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->auto_onroute == LOCO_OR_NOTHING) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// check if the loco mode is set to autostop
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTOSTOP) {
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_SEARCH;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_SEARCH) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// check if the loco mode is set to autostop
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTOSTOP) {
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// try to find and prepare(lock) a new way.
|
|
|
|
// try to find and prepare(lock) a new way.
|
|
|
@ -787,7 +747,7 @@ int Locomotives::Loop() {
|
|
|
|
// destination empty? true -> random
|
|
|
|
// destination empty? true -> random
|
|
|
|
// false -> find way to destination
|
|
|
|
// false -> find way to destination
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TRYAGAIN) {
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TRYAGAIN) {
|
|
|
|
debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, reverse);
|
|
|
|
debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, loco->flags && LOCO_F_REVERSE ? 1 : 0);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -795,23 +755,24 @@ int Locomotives::Loop() {
|
|
|
|
if (loco->blockdest[0] == 0) {
|
|
|
|
if (loco->blockdest[0] == 0) {
|
|
|
|
if (loco->flags & LOCO_F_RANDOM) {
|
|
|
|
if (loco->flags & LOCO_F_RANDOM) {
|
|
|
|
if (server->railways.FindRandomWay(loco->blockassign, loco->name, &way)) {
|
|
|
|
if (server->railways.FindRandomWay(loco->blockassign, loco->name, &way)) {
|
|
|
|
size_t pos;
|
|
|
|
size_t pos, pos1;
|
|
|
|
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);
|
|
|
|
if ((pos1 = way.find(",", pos+3)) != string::npos) {
|
|
|
|
|
|
|
|
strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else 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);
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
loco->auto_data = -1;
|
|
|
|
loco->auto_data = -1;
|
|
|
|
loco->auto_onroute = LOCO_OR_PREPARE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
server->railways.UnLockWay(way, loco->name);
|
|
|
|
server->railways.UnLockWay(way, loco->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
// nothing found -> try reverse
|
|
|
|
// nothing found -> try reverse
|
|
|
|
if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) {
|
|
|
|
if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) {
|
|
|
|
debug (0, "* Reverse Loco %s", loco->name);
|
|
|
|
debug (0, "* Loco_SearchAndLock Reverse Loco %s", loco->name);
|
|
|
|
if (loco->blockassign[0] == '-') loco->blockassign[0] = '+';
|
|
|
|
if (loco->blockassign[0] == '-') loco->blockassign[0] = '+';
|
|
|
|
else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-';
|
|
|
|
else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-';
|
|
|
|
|
|
|
|
|
|
|
@ -829,60 +790,68 @@ int Locomotives::Loop() {
|
|
|
|
// we assume a destination is set, and try to find a new way to the destination
|
|
|
|
// we assume a destination is set, and try to find a new way to the destination
|
|
|
|
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, pos1;
|
|
|
|
debug (0, "Locomotives::Loop %s:%d Found Way:%s", __FILE__, __LINE__, way.c_str());
|
|
|
|
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);
|
|
|
|
if ((pos1 = way.find(",", pos+3)) != string::npos) {
|
|
|
|
|
|
|
|
strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else 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);
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
loco->auto_data = -1;
|
|
|
|
loco->auto_data = -1;
|
|
|
|
loco->auto_onroute = LOCO_OR_PREPARE;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
server->railways.UnLockWay(way, loco->name);
|
|
|
|
server->railways.UnLockWay(way, loco->name);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
// no way found, can we reverse?
|
|
|
|
|
|
|
|
if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) {
|
|
|
|
|
|
|
|
debug (0, "* Reverse Loco %s", loco->name);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->blockassign[0] == '-') loco->blockassign[0] = '+';
|
|
|
|
|
|
|
|
else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_REVERSE) loco->flags &= ~LOCO_F_REVERSE;
|
|
|
|
return 0;
|
|
|
|
else loco->flags |= LOCO_F_REVERSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_PREPARE) {
|
|
|
|
|
|
|
|
//
|
|
|
|
/*
|
|
|
|
// the way is set and locked already, The turnouts will be set one by one with a time delay
|
|
|
|
* prepare to lock the way set up in way
|
|
|
|
// between the commands. All turnouts will get a SetWay command in case some turnout was set
|
|
|
|
* the way is set and locked already, The turnouts will be set one by one with a time delay
|
|
|
|
// manualy without feedback to the server.
|
|
|
|
* between the commands. All turnouts will get a SetWay command in case some turnout was set
|
|
|
|
//
|
|
|
|
* manualy without feedback to the server.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Locomotives::Loco_PrepareWay(Locomotive *loco) {
|
|
|
|
|
|
|
|
string block;
|
|
|
|
|
|
|
|
|
|
|
|
block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
|
|
|
|
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.
|
|
|
|
|
|
|
|
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)) return 1;
|
|
|
|
SetSpeed(loco->name, reverse * loco->vmid);
|
|
|
|
else return 2;
|
|
|
|
else SetSpeed(loco->name, reverse * loco->vfast);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else timer_start(&loco->auto_timenext);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ONTHEWAY) {
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* loco is on route, check if entered a block
|
|
|
|
|
|
|
|
* returns if we entered the block, set the locos speed
|
|
|
|
|
|
|
|
* search for next way and set auto_onroute to LOCO_OR_ENTERBLOCKNEXT or ENTERBLOCKSTOP
|
|
|
|
|
|
|
|
* copy way to wayold. If a new way is found set the way if not leave empty
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Locomotives::Loco_OnRoute(Locomotive *loco) {
|
|
|
|
|
|
|
|
string block;
|
|
|
|
|
|
|
|
string s_enter;
|
|
|
|
|
|
|
|
string s_slow;
|
|
|
|
|
|
|
|
string s_stop;
|
|
|
|
|
|
|
|
string s_shortstop;
|
|
|
|
|
|
|
|
int dir_reverse = 0;
|
|
|
|
|
|
|
|
char *tmpc = NULL;
|
|
|
|
|
|
|
|
string way;
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: move this code to the block class -> we will need a better code for multiple sensors
|
|
|
|
// 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.
|
|
|
@ -906,87 +875,56 @@ int Locomotives::Loop() {
|
|
|
|
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
|
|
|
|
// assignment <-- next, the assignment has to be checked
|
|
|
|
if (loco->blockassign[0] != 0) server->blocks.SetLockedby((string)(loco->blockassign+2), loco->name, 0);
|
|
|
|
// against long trains and split blocks
|
|
|
|
|
|
|
|
|
|
|
|
// assignment <-- next
|
|
|
|
|
|
|
|
// check if we need to clear dest
|
|
|
|
// check if we need to clear dest
|
|
|
|
strncpy (loco->blockprev, loco->blockassign, REFERENCENAME_LEN);
|
|
|
|
strncpy (loco->blockprev, loco->blockassign, REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
tmpc = strstr (loco->blocknext, ",b:");
|
|
|
|
|
|
|
|
if (tmpc) {
|
|
|
|
|
|
|
|
strncpy (loco->blockassign, tmpc+3, REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
strncpy (loco->blockassignsplit, loco->blocknext, REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
strncpy (loco->blockassign, loco->blocknext, REFERENCENAME_LEN);
|
|
|
|
strncpy (loco->blockassign, loco->blocknext, REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
loco->blockassignsplit[0] = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
strncpy (loco->auto_wayold, loco->auto_way, WAYDATA_LEN);
|
|
|
|
strncpy (loco->auto_wayold, loco->auto_way, WAYDATA_LEN);
|
|
|
|
loco->auto_way[0] = 0;
|
|
|
|
loco->auto_way[0] = 0;
|
|
|
|
loco->blocknext[0] = 0;
|
|
|
|
loco->blocknext[0] = 0;
|
|
|
|
|
|
|
|
debug (0, "Locomotive::Loop Loco:'%s' Prev:'%s' Assign:'%s' AssignSplit:'%s' Next:'%s'",
|
|
|
|
|
|
|
|
loco->name, loco->blockprev, loco->blockassign, loco->blockassignsplit, loco->blocknext);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// if destination reached or AUTO-MAN mode: stop train.
|
|
|
|
if (Loco_SearchAndLock(loco) == 1) {
|
|
|
|
if ((strncmp(loco->blockassign, loco->blockdest, REFERENCENAME_LEN) == 0)
|
|
|
|
|
|
|
|
|| (loco->flags & LOCO_F_AUTOSTOP)) {
|
|
|
|
|
|
|
|
printf ("%s:%d LOCO_OR_ONTHEWAY enter assign == dest stop train\n", __FILE__, __LINE__);
|
|
|
|
|
|
|
|
loco->blockdest[0] = 0;
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vslow);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// if not try to find next block.
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
printf ("%s:%d LOCO_OR_ONTHEWAY try to find new way\n", __FILE__, __LINE__);
|
|
|
|
|
|
|
|
if (loco->blockdest[0] == 0) {
|
|
|
|
|
|
|
|
if ((loco->flags & LOCO_F_RANDOM) && ((loco->flags & LOCO_F_CARGO) || !(server->blocks.GetFlags(block) & BLOCK_F_STATION)))
|
|
|
|
|
|
|
|
if (server->railways.FindRandomWay(loco->blockassign, loco->name, &way)) {
|
|
|
|
|
|
|
|
size_t pos;
|
|
|
|
|
|
|
|
if ((pos = way.find(",b:", 1)) != string::npos) {
|
|
|
|
|
|
|
|
strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN);
|
|
|
|
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
|
|
|
|
loco->auto_data = -1;
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKNEXT;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
server->railways.UnLockWay(way, loco->name);
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) {
|
|
|
|
|
|
|
|
size_t pos;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((pos = way.find(",b:", 1)) != string::npos) {
|
|
|
|
|
|
|
|
strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN);
|
|
|
|
|
|
|
|
strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN);
|
|
|
|
|
|
|
|
if (server->railways.LockWay(way, loco->name) == 1) {
|
|
|
|
|
|
|
|
loco->auto_data = -1;
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKNEXT;
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKNEXT;
|
|
|
|
|
|
|
|
debug (0, "Locomotives::Loco_OnRoute Found Way Prepare '%s'\n", loco->name);
|
|
|
|
|
|
|
|
SetSpeed(loco->name, loco->vmid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
SetSpeed(loco->name, reverse * loco->vslow);
|
|
|
|
debug (0, "Locomotives::Loco_OnRoute Slow Down '%s'\n", loco->name);
|
|
|
|
|
|
|
|
SetSpeed(loco->name, loco->vslow);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vslow);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vslow);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->auto_onroute == LOCO_OR_ONTHEWAY) {
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vslow);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKSTOP) {
|
|
|
|
/*
|
|
|
|
|
|
|
|
* loco entered a block, check if need to stop
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Locomotives::Loco_BlockEnterStop(Locomotive *loco) {
|
|
|
|
|
|
|
|
string block;
|
|
|
|
|
|
|
|
string s_enter;
|
|
|
|
|
|
|
|
string s_slow;
|
|
|
|
|
|
|
|
string s_stop;
|
|
|
|
|
|
|
|
string s_shortstop;
|
|
|
|
|
|
|
|
int dir_reverse = 0;
|
|
|
|
|
|
|
|
string way;
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// check if the train is in its stop position
|
|
|
|
// check if the train is in its stop position
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -1009,25 +947,30 @@ int Locomotives::Loop() {
|
|
|
|
server->railways.UnLockWay(loco->auto_wayold, loco->name);
|
|
|
|
server->railways.UnLockWay(loco->auto_wayold, loco->name);
|
|
|
|
server->blocks.SetLockedby(loco->blockprev+2, loco->name, 0);
|
|
|
|
server->blocks.SetLockedby(loco->blockprev+2, loco->name, 0);
|
|
|
|
loco->auto_wayold[0] = 0;
|
|
|
|
loco->auto_wayold[0] = 0;
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKNEXT) {
|
|
|
|
|
|
|
|
// check enter block
|
|
|
|
|
|
|
|
int finish = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
* loco entered a block, check if need to stop
|
|
|
|
finish = 1;
|
|
|
|
*/
|
|
|
|
else
|
|
|
|
int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
int dir_reverse;
|
|
|
|
}
|
|
|
|
string block;
|
|
|
|
|
|
|
|
string s_enter;
|
|
|
|
|
|
|
|
string s_slow;
|
|
|
|
|
|
|
|
string s_stop;
|
|
|
|
|
|
|
|
string s_shortstop;
|
|
|
|
|
|
|
|
string way;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// check if the train is in its stop position
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
block = ((string)(loco->blockassign+2)).substr(0, ((string)(loco->blockassign+2)).find(","));
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
@ -1039,39 +982,173 @@ int Locomotives::Loop() {
|
|
|
|
if ( server->sensors.GetActive(s_stop) == 1 ||
|
|
|
|
if ( server->sensors.GetActive(s_stop) == 1 ||
|
|
|
|
((loco->flags & LOCO_F_SHORTTRAIN) && server->sensors.GetActive(s_shortstop) == 1)) {
|
|
|
|
((loco->flags & LOCO_F_SHORTTRAIN) && server->sensors.GetActive(s_shortstop) == 1)) {
|
|
|
|
|
|
|
|
|
|
|
|
debug (0, "Locomotives::Loop EnterBlockNext Loco:'%s' Block: '%s' UnLockWay", loco->name, block.c_str());
|
|
|
|
if (loco->auto_timenext.tv_sec > 0) {
|
|
|
|
debug (0, "* %s,%d Sensor Enter '%s' = %d", __FILE__, __LINE__, s_enter.c_str(), server->sensors.GetActive(s_enter));
|
|
|
|
//
|
|
|
|
debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow));
|
|
|
|
// end of block and not finished preparing the way.
|
|
|
|
debug (0, "* %s,%d Sensor Sh.Stop '%s' = %d", __FILE__, __LINE__, s_shortstop.c_str(), server->sensors.GetActive(s_shortstop));
|
|
|
|
// stop everything
|
|
|
|
debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop));
|
|
|
|
debug (0, "Locomotives::Loco_BlockEnterNext ********** Loco:%s could not prepare way in time. STOP", loco->name);
|
|
|
|
|
|
|
|
server->PowerOnOff(0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
debug (0, "* Locomotives::Loco_BlockEnterNext endblock reached %s", loco->name);
|
|
|
|
|
|
|
|
|
|
|
|
server->railways.UnLockWay(loco->auto_wayold, loco->name);
|
|
|
|
server->railways.UnLockWay(loco->auto_wayold, loco->name);
|
|
|
|
server->blocks.SetLockedby(loco->blockprev+2, loco->name, 0);
|
|
|
|
server->blocks.SetLockedby(loco->blockprev+2, loco->name, 0);
|
|
|
|
loco->auto_wayold[0] = 0;
|
|
|
|
loco->auto_wayold[0] = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (finish == 0) { // stop train if not finished
|
|
|
|
if ((loco->flags & LOCO_F_CARGO) ||
|
|
|
|
debug (0, "Locomotives::Loop '%s' UnLockWay\n", loco->name);
|
|
|
|
(server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT)) return 1;
|
|
|
|
SetSpeed(loco->name, 0);
|
|
|
|
else return 2;
|
|
|
|
loco->auto_onroute = LOCO_OR_STOPWAIT;
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
if (server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT) {
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vmid);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
if (loco->auto_timenext.tv_sec > 0 && timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
|
|
|
|
|
|
|
|
debug (0, "* Locomotives::Loco_BlockEnterNext prepare way for loco: %s", loco->name);
|
|
|
|
|
|
|
|
if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// finished preparing new way, need to stay in ENTERBLOCKNEXT to unlock old way
|
|
|
|
|
|
|
|
debug (0, "* Locomotives::Loco_BlockEnterNext finished preparing way for loco: %s", loco->name);
|
|
|
|
|
|
|
|
loco->auto_timenext.tv_sec = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else timer_start(&loco->auto_timenext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_STOPWAIT) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* loco stopped on block, wait some time and continue with the next destination
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int Locomotives::Loco_BlockStopWait(Locomotive *loco) {
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 5000) {
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 5000) {
|
|
|
|
if (loco->blockdest[0] != 0) loco->auto_onroute = LOCO_OR_SEARCH;
|
|
|
|
if (loco->blockdest[0] != 0) loco->auto_onroute = LOCO_OR_SEARCH;
|
|
|
|
else loco->auto_onroute = LOCO_OR_NOTHING;
|
|
|
|
else loco->auto_onroute = LOCO_OR_NOTHING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Locomotives::Loop() {
|
|
|
|
|
|
|
|
int lnum;
|
|
|
|
|
|
|
|
string way;
|
|
|
|
|
|
|
|
Locomotive *loco = NULL;
|
|
|
|
|
|
|
|
JSONParse jp;
|
|
|
|
|
|
|
|
int reverse = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (lnum = 0; lnum < max; lnum++) if (locomotives[lnum].name[0] != 0) {
|
|
|
|
|
|
|
|
loco = &locomotives[lnum];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTO) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// only in automate do anything alone
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
debug (0, "* Locomotives::Loop (%s:%d) Loco:%s auto_onroute:%d assign:'%s' assignsplit:'%s' next:'%s' prev:'%s' dest:'%s' way:'%s' wayold:'%s'"
|
|
|
|
|
|
|
|
, __FILE__, __LINE__, loco->name, loco->auto_onroute, loco->blockassign, loco->blockassignsplit
|
|
|
|
|
|
|
|
, loco->blocknext, loco->blockprev, loco->blockdest, loco->auto_way, loco->auto_wayold);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->blockassign[0] == 0) {
|
|
|
|
|
|
|
|
debug (0, "%s:%d Locomotive [%s] not assigned to any block. Set Mode to Man", __FILE__, __LINE__, loco->name);
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (loco->auto_onroute == LOCO_OR_NOTHING) {
|
|
|
|
|
|
|
|
// loco mode is set to autostop -> set loco to man
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTOSTOP) {
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_SEARCH;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_SEARCH) {
|
|
|
|
|
|
|
|
// loco mode is set to autostop -> set loco to man
|
|
|
|
|
|
|
|
if (loco->flags & LOCO_F_AUTOSTOP) {
|
|
|
|
|
|
|
|
SetModeMan(loco->name);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// try to find and lock a way
|
|
|
|
|
|
|
|
if (Loco_SearchAndLock(loco)) {
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_PREPARE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_PREPARE) {
|
|
|
|
|
|
|
|
switch (Loco_PrepareWay(loco)) {
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vmid);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
|
|
|
|
debug (0, "* Locomotive '%s' Way Prepared -> Speed: VMID", loco->name);
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vfast);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
|
|
|
|
debug (0, "* Locomotive '%s' Way Prepared -> Speed: VFAST", loco->name);
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ONTHEWAY) {
|
|
|
|
|
|
|
|
if (Loco_OnRoute(loco)) {
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKSTOP) {
|
|
|
|
|
|
|
|
if (Loco_BlockEnterStop(loco)) {
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKNEXT) {
|
|
|
|
|
|
|
|
switch (Loco_BlockEnterNext(loco)) {
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vmid);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
|
|
|
|
debug (0, "* Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VMID", loco->name);
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vfast);
|
|
|
|
|
|
|
|
loco->auto_onroute = LOCO_OR_ONTHEWAY;
|
|
|
|
|
|
|
|
debug (0, "* Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VFAST", loco->name);
|
|
|
|
|
|
|
|
jp.Clear();
|
|
|
|
|
|
|
|
jp.AddObject("locomotive",_GetJSON(lnum));
|
|
|
|
|
|
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_STOPWAIT) {
|
|
|
|
|
|
|
|
Loco_BlockStopWait(loco);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1080,6 +1157,7 @@ int Locomotives::Loop() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Locomotives::Test(string loco) {
|
|
|
|
int Locomotives::Test(string loco) {
|
|
|
|
int res = 0;
|
|
|
|
int res = 0;
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|