|
|
|
@ -253,10 +253,8 @@ int Locomotives::SetReverse(string name, int reverse) {
|
|
|
|
|
Lock();
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
|
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
|
|
|
if (reverse)
|
|
|
|
|
locomotives[i].flags |= LOCO_F_REVERSE;
|
|
|
|
|
else
|
|
|
|
|
locomotives[i].flags &= ~LOCO_F_REVERSE;
|
|
|
|
|
if (reverse) locomotives[i].flags |= LOCO_F_REVERSE;
|
|
|
|
|
else locomotives[i].flags &= ~LOCO_F_REVERSE;
|
|
|
|
|
|
|
|
|
|
server->interfaces.SetLocoSpeed(&locomotives[i], locomotives[i].speed);
|
|
|
|
|
break;
|
|
|
|
@ -294,14 +292,12 @@ int Locomotives::SetDestination (string name, string block, int direction) {
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
|
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
|
|
|
|
|
|
|
|
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction);
|
|
|
|
|
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)", name.c_str(), block.c_str(), direction);
|
|
|
|
|
|
|
|
|
|
blflags = server->blocks.GetFlags(block);
|
|
|
|
|
if ((blflags & BLOCK_F_SHORT) && !(locomotives[i].flags & LOCO_F_SHORTTRAIN)) break;
|
|
|
|
|
if ((blflags & BLOCK_F_ENDSTATION) && !(locomotives[i].flags & LOCO_F_CANREVERSE)) break;
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d blflags:%d locoflags:%d\n", __FILE__, __LINE__, blflags, locomotives[i].flags);
|
|
|
|
|
|
|
|
|
|
if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str());
|
|
|
|
|
else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str());
|
|
|
|
|
break;
|
|
|
|
@ -319,7 +315,13 @@ int Locomotives::SetAssign (string name, string block, int direction) {
|
|
|
|
|
Lock();
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
|
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
|
|
|
debug (0, "Locomotives::SetAssign (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction);
|
|
|
|
|
debug (0, "Locomotives::SetAssign (Name:%s Block:%s Direction:%d)", name.c_str(), block.c_str(), direction);
|
|
|
|
|
|
|
|
|
|
if (locomotives[i].flags & LOCO_F_AUTO) {
|
|
|
|
|
debug (0, "Locomotives::SetAssign not possible Loco is stil in AUTO mode.");
|
|
|
|
|
i = max;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (locomotives[i].blockassign[0] != 0) // still locked unlock
|
|
|
|
|
server->blocks.SetLockedby(locomotives[i].blockassign+2, name, 0);
|
|
|
|
@ -333,11 +335,13 @@ int Locomotives::SetAssign (string name, string block, int direction) {
|
|
|
|
|
}
|
|
|
|
|
UnLock();
|
|
|
|
|
|
|
|
|
|
while (server->railways.FindReference(&x, &y, block)) {
|
|
|
|
|
string bl = server->blocks.GetLockedby(block);
|
|
|
|
|
if(bl.length() == 0 || bl.compare(name) == 0) {
|
|
|
|
|
server->blocks.SetLockedby(block, name, 1);
|
|
|
|
|
server->railways.SetLockedby(x, y, name, 1);
|
|
|
|
|
if (i < max && i >=0) {
|
|
|
|
|
while (server->railways.FindReference(&x, &y, block)) {
|
|
|
|
|
string bl = server->blocks.GetLockedby(block);
|
|
|
|
|
if(bl.length() == 0 || bl.compare(name) == 0) {
|
|
|
|
|
server->blocks.SetLockedby(block, name, 1);
|
|
|
|
|
server->railways.SetLockedby(x, y, name, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -371,7 +375,7 @@ int Locomotives::Reset(string name) {
|
|
|
|
|
Lock();
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
|
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
|
|
|
debug (0, "Locomotives::Reset (Name:%s)\n", name.c_str());
|
|
|
|
|
debug (0, "Locomotives::Reset (Name:%s)", name.c_str());
|
|
|
|
|
locomotives[i].blockassign[0] = 0;
|
|
|
|
|
locomotives[i].blockdest[0] = 0;
|
|
|
|
|
locomotives[i].blockprev[0] = 0;
|
|
|
|
@ -467,7 +471,7 @@ int Locomotives::SetSpeedFromBus(string ifname, int addr, int speed) {
|
|
|
|
|
JSONParse jp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
debug (0, "%s:%d SetSpeedFromBus IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
|
|
|
|
|
debug (0, "Locomotives::SetSpeedFromBus IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
|
|
|
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
|
|
|
|
@ -500,7 +504,7 @@ int Locomotives::SetFunctionFromBus(string ifname, int addr, int func) {
|
|
|
|
|
int i;
|
|
|
|
|
JSONParse jp;
|
|
|
|
|
|
|
|
|
|
debug (0, "%s:%d SetDirectionFromBus IfName:%s Addr:%d function:%d", __FILE__, __LINE__, ifname.c_str(), addr, func);
|
|
|
|
|
debug (0, "Locomotives::SetDirectionFromBus IfName:%s Addr:%d function:%d", __FILE__, __LINE__, ifname.c_str(), addr, func);
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
|
|
|
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
|
|
|
|
|
if (func & 32) locomotives[i].flags |= LOCO_F_REVERSE;
|
|
|
|
@ -611,13 +615,20 @@ int Locomotives::Loop() {
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_SEARCH) {
|
|
|
|
|
//
|
|
|
|
|
// find way, if nothing found check if we can reverse direction
|
|
|
|
|
// try to find and prepare(lock) a new way.
|
|
|
|
|
// nothing found check if we can reverse direction, this will be done only
|
|
|
|
|
// once a second (LOCO_TO_TRYAGAIN)
|
|
|
|
|
//
|
|
|
|
|
// destination empty? true -> random
|
|
|
|
|
// false -> find way to destination
|
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TRYAGAIN) {
|
|
|
|
|
debug (0, "* Loco Loop Search '%s' Reverse:%d", loco->name, reverse);
|
|
|
|
|
debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, reverse);
|
|
|
|
|
timer_start(&loco->auto_timenext);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// destination set? - need to find a random block?
|
|
|
|
|
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)) {
|
|
|
|
|
size_t pos;
|
|
|
|
|
if ((pos = way.find(",b:", 1)) != string::npos) {
|
|
|
|
@ -633,6 +644,7 @@ int Locomotives::Loop() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// nothing found -> try 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] = '+';
|
|
|
|
@ -642,8 +654,17 @@ int Locomotives::Loop() {
|
|
|
|
|
else loco->flags |= LOCO_F_REVERSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// in here we need to put code for scheduled ways. ?
|
|
|
|
|
printf ("%s:%d scheduled ways: not even started to work on this.\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 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)) {
|
|
|
|
|
// try to lock way.
|
|
|
|
|
size_t pos;
|
|
|
|
|
|
|
|
|
|
if ((pos = way.find(",b:", 1)) != string::npos) {
|
|
|
|
@ -660,6 +681,7 @@ int Locomotives::Loop() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// no way found, can we reverse?
|
|
|
|
|
if (loco->blockassign[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) {
|
|
|
|
|
debug (0, "* Reverse Loco %s", loco->name);
|
|
|
|
|
|
|
|
|
@ -675,10 +697,16 @@ int Locomotives::Loop() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
// between the commands. All turnouts will get a SetWay command in case some turnout was set
|
|
|
|
|
// manualy without feedback to the server.
|
|
|
|
|
//
|
|
|
|
|
block = loco->blocknext+2;
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
// all turnouts are set, start the train.
|
|
|
|
|
if ((loco->flags & LOCO_F_CARGO) ||
|
|
|
|
|
(server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT))
|
|
|
|
|
SetSpeed(loco->name, reverse * loco->vmid);
|
|
|
|
@ -690,20 +718,20 @@ int Locomotives::Loop() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (loco->auto_onroute == LOCO_OR_ONTHEWAY) {
|
|
|
|
|
// check enter block
|
|
|
|
|
//
|
|
|
|
|
// the train is on the way, check for entering the block.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// 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] == '-')
|
|
|
|
|
sensor = server->blocks.GetSensorMinus(block);
|
|
|
|
|
else
|
|
|
|
|
sensor = server->blocks.GetSensorPlus(block);
|
|
|
|
|
if (loco->blocknext[0] == '-') sensor = server->blocks.GetSensorMinus(block);
|
|
|
|
|
else sensor = server->blocks.GetSensorPlus(block);
|
|
|
|
|
|
|
|
|
|
if (server->sensors.GetActive(sensor) == 1) { // entering block?
|
|
|
|
|
debug (0, "* Locomotive '%s' EnterBlock '%s'", loco->name, loco->blocknext);
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
// assignment <-- next
|
|
|
|
|
// check if we need to clear dest
|
|
|
|
@ -722,7 +750,7 @@ int Locomotives::Loop() {
|
|
|
|
|
// try to find new way
|
|
|
|
|
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)
|
|
|
|
|
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) {
|
|
|
|
|