From c2493ab90edc5d26d9b37c2bcecc3ac6fa39f190 Mon Sep 17 00:00:00 2001 From: steffen Date: Sun, 31 Jan 2021 22:13:23 +0000 Subject: [PATCH] automatic mode routing to destination works --- ChangeLog | 2 + server/locomotive.cc | 89 +++++++++++++++++++++++++++++++++++++++++--- server/locomotive.h | 4 +- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4e43db..9eebf74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ 2021-01-31: +- automtic mode is improving, manual setting of destination + autoatic routing and moving the train to the destination. - locked turnouts can not anymore been set. - assign loco and set destination is working now. diff --git a/server/locomotive.cc b/server/locomotive.cc index 415db07..a41c546 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -44,6 +44,7 @@ JSONParse Locomotives::_GetJSON(int idx) { s = locomotives[idx].blockassign; json.AddObject("blockassign", s); s = locomotives[idx].blockprev; json.AddObject("blockprev", s); s = locomotives[idx].auto_way; json.AddObject("auto_way", s); + s = locomotives[idx].auto_wayold; json.AddObject("auto_wayold", s); json.AddObject("addr", locomotives[idx].addr); json.AddObject("stepcode", locomotives[idx].stepcode); json.AddObject("speed", locomotives[idx].speed); @@ -122,6 +123,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) { l.blocknext[0] = 0; l.blockprev[0] = 0; l.auto_way[0] = 0; + l.auto_wayold[0] = 0; l.auto_onroute = 0; l.auto_data = 0; l.auto_timenext = {0}; @@ -213,6 +215,7 @@ int Locomotives::Delete(string name) { locomotives[i].vmax = 0; locomotives[i].flags = 0; locomotives[i].auto_way[0] = 0; + locomotives[i].auto_wayold[0] = 0; locomotives[i].auto_onroute = -1; locomotives[i].auto_data = -1; locomotives[i].auto_timenext = {0}; @@ -350,6 +353,7 @@ int Locomotives::Reset(string name) { locomotives[i].blockprev[0] = 0; locomotives[i].blocknext[0] = 0; locomotives[i].auto_way[0] = 0; + locomotives[i].auto_wayold[0] = 0; locomotives[i].auto_onroute = -1; break; } @@ -373,6 +377,7 @@ int Locomotives::SetMan(string name) { locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_RANDOM); locomotives[i].auto_onroute = 0; locomotives[i].auto_way[0] = 0; + locomotives[i].auto_wayold[0] = 0; break; } UnLock(); @@ -556,7 +561,7 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) { int Locomotives::Loop() { - int lnum; + int lnum, i; string way; Locomotive *loco = NULL; string block; @@ -626,24 +631,59 @@ int Locomotives::Loop() { // check if we need to clear dest strncpy (loco->blockprev, loco->blockassign, REFERENCENAME_LEN); strncpy (loco->blockassign, loco->blocknext, REFERENCENAME_LEN); + strncpy (loco->auto_wayold, loco->auto_way, WAYDATA_LEN); + loco->auto_way[0] = 0; loco->blocknext[0] = 0; if (strncmp(loco->blockassign, loco->blockdest, REFERENCENAME_LEN) == 0) { + printf ("%s:%d LOCO_OR_ONTHEWAY enter assign == dest stop\n", __FILE__, __LINE__); loco->blockdest[0] = 0; + loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP; + SetSpeed(loco->name, loco->vslow); + } + else { + // try to find new way + printf ("%s:%d LOCO_OR_ONTHEWAY try to find new way\n", __FILE__, __LINE__); + 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; + } + else { + loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP; + SetSpeed(loco->name, loco->vslow); + } + } + else { + loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP; + SetSpeed(loco->name, loco->vslow); + } + } + else { + loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP; + SetSpeed(loco->name, loco->vslow); + } } - // slow down - SetSpeed(loco->name, loco->vslow); jp.Clear(); jp.AddObject("locomotive",_GetJSON(lnum)); if(network) network->ChangeListPushToAll(jp.ToString()); - loco->auto_onroute = LOCO_OR_ENTERBLOCK; + if (loco->auto_onroute == LOCO_OR_ONTHEWAY) { + loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP; + SetSpeed(loco->name, loco->vslow); + } } } - else if (loco->auto_onroute == LOCO_OR_ENTERBLOCK) { + else if (loco->auto_onroute == LOCO_OR_ENTERBLOCKSTOP) { // check enter block + block = loco->blockassign+2; if (loco->blockassign[0] == '-') sensor = server->blocks.GetSensorPlus(block); @@ -654,13 +694,50 @@ int Locomotives::Loop() { debug (0, "Locomotives::Loop '%s' UnLockWay\n", loco->name); SetSpeed(loco->name, 0); loco->auto_onroute = LOCO_OR_STOPWAIT; - server->railways.UnLockWay(loco->auto_way, loco->name); + server->railways.UnLockWay(loco->auto_wayold, loco->name); + loco->auto_wayold[0] = 0; jp.Clear(); jp.AddObject("locomotive",_GetJSON(lnum)); if(network) network->ChangeListPushToAll(jp.ToString()); timer_start(&loco->auto_timenext); } } + + 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) + finish = 1; + else + timer_start(&loco->auto_timenext); + } + + block = loco->blockassign+2; + if (loco->blockassign[0] == '-') + sensor = server->blocks.GetSensorPlus(block); + else + sensor = server->blocks.GetSensorMinus(block); + + if (server->sensors.GetActive(sensor) == 1) { + server->railways.UnLockWay(loco->auto_wayold, loco->name); + loco->auto_wayold[0] = 0; + + if (finish == 0) { // stop train if not finished + debug (0, "Locomotives::Loop '%s' UnLockWay\n", loco->name); + SetSpeed(loco->name, 0); + 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 { + loco->auto_onroute = LOCO_OR_ONTHEWAY; + } + } + } else if (loco->auto_onroute == LOCO_OR_STOPWAIT) { if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 5000) { if (loco->blockdest[0] != 0) loco->auto_onroute = LOCO_OR_SEARCH; diff --git a/server/locomotive.h b/server/locomotive.h index ae6f9eb..256fafc 100644 --- a/server/locomotive.h +++ b/server/locomotive.h @@ -33,7 +33,8 @@ enum { LOCO_OR_ONTHEWAY, // locomotive is on the way // maybe prepare next block? // ASSIGN -> PREV, NEXT -> ASSIGN, NEXT <- (empty) // propabely searching next block (if DEST is set)? - LOCO_OR_ENTERBLOCK, // got new block ready? + LOCO_OR_ENTERBLOCKNEXT, // got new block ready? + LOCO_OR_ENTERBLOCKSTOP, // got new block ready? // if NEXT is empty and way not AutoPrepareWay not finished... slow down LOCO_OR_STOPWAIT // stopping }; @@ -64,6 +65,7 @@ struct s_Locomotive { char blockdest[REFERENCENAME_LEN]; // destination block char auto_way[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname" + char auto_wayold[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname" int auto_onroute; // LOCO_OR_.... int auto_data; // just some data needed by some steps struct timeval auto_timenext; // timeval of the next active step