update, automatic mode improvements

origin
steffen 5 years ago
parent 39ff08c896
commit c2d69e3014

@ -1,3 +1,8 @@
2021-01-31:
- locked turnouts can not anymore been set.
- assign loco and set destination is working now.
2021-01-19:
- threading should be now more stable no deadlocks

@ -123,6 +123,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
l.blockprev[0] = 0;
l.auto_way[0] = 0;
l.auto_onroute = 0;
l.auto_data = 0;
l.auto_timenext = {0};
j->GetValue("name", &s);
@ -157,7 +158,6 @@ int Locomotives::Change(Locomotive *loco) {
int ifree = -1;
Lock();
printf ("%s:%d Change Locomotive\n", __FILE__, __LINE__);
for (i = 0; i < max; i++) {
if (locomotives[i].name[0] != 0) {
// found element
@ -214,6 +214,7 @@ int Locomotives::Delete(string name) {
locomotives[i].flags = 0;
locomotives[i].auto_way[0] = 0;
locomotives[i].auto_onroute = -1;
locomotives[i].auto_data = -1;
locomotives[i].auto_timenext = {0};
changed = 1;
break;
@ -291,12 +292,10 @@ int Locomotives::SetDestination (string name, string block, int direction) {
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction);
if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str());
else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str());
printf ("%s:%d Locomotive '%s' blockdest:%s\n", __FILE__, __LINE__, locomotives[i].name, locomotives[i].blockdest);
break;
}
UnLock();
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
return 1;
}
@ -323,7 +322,6 @@ int Locomotives::SetAssign (string name, string block, int direction) {
UnLock();
while (server->railways.FindReference(&x, &y, block)) {
printf ("%s:%d Reference found at %d, %d\n", __FILE__, __LINE__, x, y);
string bl = server->blocks.GetLockedby(block);
if(bl.length() == 0 || bl.compare(name) == 0) {
server->blocks.SetLockedby(block, name, 1);
@ -332,6 +330,8 @@ int Locomotives::SetAssign (string name, string block, int direction) {
}
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
printf ("%s:%d %s * clear old refferences from loco \n", __FILE__, __LINE__, __FUNCTION__);
printf ("%s:%d %s * stop loco \n", __FILE__, __LINE__, __FUNCTION__);
return 1;
}
@ -505,15 +505,19 @@ string Locomotives::GetName(int idx) {
// turn a turnout try to do it and return 0
// if everything is set up till the destination block return 1
//
int Locomotives::AutoCheckWaySingleStep(string way, string locname) {
int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
int res = 0;
size_t pos1, pos2;
size_t curpos;
int val, state;
int newdata = 0;
if (*data < 0) *data = 0;
curpos = 0;
do {
curpos = way.find (",t:", curpos+1);
newdata++;
if (curpos != string::npos) {
pos1 = way.find(":", curpos+3);
if (pos1 == string::npos) {
@ -528,14 +532,19 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname) {
}
if (way[pos1+1] == '0' && state != 0) {
server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 0);
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
break;
}
else if (way[pos1+1] == '1' && state != 1) {
server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 1);
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
break;
}
else if (newdata > *data) {
if (way[pos1+1] == '0') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
if (way[pos1+1] == '1') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
(*data) = newdata;
break;
}
printf ("%s:%d Checked:%s\n", __FILE__, __LINE__, way.substr(curpos+3, pos1-curpos-3).c_str());
}
} while (curpos != string::npos);
@ -561,13 +570,14 @@ int Locomotives::Loop() {
// only in automate do anything alone
//
if (loco->blockassign[0] == 0 || loco->blockdest[0] == 0) continue;
if (loco->auto_onroute == LOCO_OR_NOTHING) {
timer_start(&loco->auto_timenext);
loco->auto_onroute = LOCO_OR_SEARCH;
}
if (loco->auto_onroute == LOCO_OR_SEARCH) {
else if (loco->auto_onroute == LOCO_OR_SEARCH) {
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 1000) {
printf ("%s:%d Locomotive::Loop '%s' auto_onroute:%d\n", __FILE__, __LINE__,
loco->name, loco->auto_onroute);
if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) {
size_t pos;
@ -576,6 +586,7 @@ int Locomotives::Loop() {
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_PREPARE;
}
else timer_start(&loco->auto_timenext);
@ -587,7 +598,7 @@ int Locomotives::Loop() {
else if (loco->auto_onroute == LOCO_OR_PREPARE) {
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 1000) {
if (AutoCheckWaySingleStep(loco->auto_way, loco->name) == 1)
if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1)
loco->auto_onroute = LOCO_OR_ONTHEWAY;
else timer_start(&loco->auto_timenext);
}
@ -657,11 +668,14 @@ int Locomotives::Loop() {
int Locomotives::Test(string loco) {
int res = 0;
int i;
int j = 0;
printf ("%s:%d LocoTest.\n", __FILE__, __LINE__);
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (loco.compare(locomotives[i].name) == 0) {
res = AutoCheckWaySingleStep(locomotives[i].auto_way, loco);
res = AutoCheckWaySingleStep(locomotives[i].auto_way, loco, &j);
}
printf ("%s:%d LocoTest ---> Return %d\n", __FILE__, __LINE__, res);

@ -63,6 +63,7 @@ struct s_Locomotive {
char auto_way[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
} typedef Locomotive;
@ -101,7 +102,7 @@ class Locomotives {
int SetDestination (string name, string block, int direction);
int SetAssign (string name, string block, int direction);
int AutoCheckWaySingleStep(string way, string locname);
int AutoCheckWaySingleStep(string way, string locname, int *data);
int Loop();
string GetName(int idx);

@ -59,6 +59,28 @@ Server::~Server() {
};
int Server::TurnoutSet(string name, int active) {
int x, y, locked = 0;
string lockedby;
Railway r;
//
// check if locked
while (server->railways.FindReference(&x, &y, name)) {
r = server->railways.Get(x, y);
printf ("Reference %d,%d Name:%s Lockedby:%d\n", x, y, r.name, r.lockedby);
if (r.lockedby[0] != 0) {
locked = 1;
lockedby = r.lockedby;
}
}
if (locked == 0) return turnouts.Set(name, active);
else {
debug (0, "%s:%d SetJSONTurnout Element %s is locked by %s", __FILE__, __LINE__, name.c_str(), lockedby.c_str());
}
return 0;
}
//
// server thread will cycle as long as running is set to true

@ -143,7 +143,7 @@ public:
Turnout TurnoutFromJSON(JSONParse *j) { return turnouts.GetTurnoutFromJSON(j); };
JSONParse TurnoutGetJSON(string name) { return turnouts.GetJSON(name); };
int TurnoutDelete(string name) { return turnouts.Delete(name); };
int TurnoutSet(string name, int active) { return turnouts.Set(name, active); };
int TurnoutSet(string name, int active);
/////////////////////////////////////////
// Interface

@ -656,7 +656,11 @@ void Session::DelJSONTurnout(JSONParse *jp) {
void Session::SetJSONTurnout(JSONParse *jp) {
JSONParse jout;
string name;
string lockedby;
int active;
int x, y;
int locked = 0;
Railway r;
server->LockThread();

Loading…
Cancel
Save