45#define DEBUG_COND (getID()=="C")
51 "**",
"^",
"*",
"/",
"+",
"-",
"%",
52 "=",
"==",
"!=",
"<",
">",
"<=",
">=",
53 "and",
"&&",
"or",
"||",
59#define DEFAULT_MAX_GAP "3.0"
60#define DEFAULT_PASSING_TIME "1.9"
61#define DEFAULT_DETECTOR_GAP "2.0"
62#define DEFAULT_INACTIVE_THRESHOLD "180"
63#define DEFAULT_CURRENT_PRIORITY 10
64#define DEFAULT_CROSSING_PRIORITY 100
66#define DEFAULT_LENGTH_WITH_GAP 7.5
67#define DEFAULT_BIKE_LENGTH_WITH_GAP (getDefaultVehicleLength(SVC_BICYCLE) + 0.5)
68#define DEFAULT_STATIC_MINDUR TIME2STEPS(0)
70#define NO_DETECTOR "NO_DETECTOR"
71#define DEFAULT_CONDITION "DEFAULT"
77 const std::string&
id,
const std::string& programID,
82 const std::string& basePath,
87 myHasMultiTarget(false),
88 myLastTrySwitchTime(0),
89 myConditions(conditions),
90 myAssignments(assignments),
91 myFunctions(functions),
93 myDetectorPrefix(id +
"_" + programID +
"_") {
107 std::set<std::string> hiddenSet(hidden.begin(), hidden.end());
109 if (hiddenSet.count(item.first) == 0) {
114 const bool showAll =
getParameter(
"show-conditions",
"") ==
"";
116 std::set<std::string> shownSet(shown.begin(), shown.end());
118 if (showAll || shownSet.count(item.first) != 0) {
124 const std::string extraIDs =
getParameter(
"extra-detectors",
"");
127 myExtraLoops.push_back(retrieveDetExpression<MSInductLoop, SUMO_TAG_INDUCTION_LOOP>(customID, extraIDs,
true));
129 myExtraE2.push_back(retrieveDetExpression<MSE2Collector, SUMO_TAG_LANE_AREA_DETECTOR>(customID, extraIDs,
true));
133 myStack.push_back(std::map<std::string, double>());
144 for (
int i = 0; i < (int)
myPhases.size(); i++) {
152 const int numLinks = (int)
myLinks.size();
176 std::map<const MSLane*, MSInductLoop*> laneInductLoopMap;
177 std::map<MSInductLoop*, int> inductLoopInfoMap;
178 int detEdgeIndex = -1;
179 int detLaneIndex = 0;
182 MSEdge* prevDetEdge =
nullptr;
184 for (
MSLane* lane : lanes) {
185 const std::string customID =
getParameter(lane->getID());
186 if (
noVehicles(lane->getPermissions()) && customID ==
"") {
190 if (laneInductLoopMap.find(lane) != laneInductLoopMap.end()) {
195 if (minDur == std::numeric_limits<SUMOTime>::max() && customID ==
"" && !
myBuildAllDetectors) {
199 double length = lane->getLength();
201 double inductLoopPosition;
203 if (&lane->getEdge() != prevDetEdge) {
206 prevDetEdge = &lane->getEdge();
210 const bool isBikeLane = (lane->getPermissions() & ~SVC_PEDESTRIAN) ==
SVC_BICYCLE;
212 if (customID ==
"") {
214 inductLoopPosition =
MIN2(
219 ilpos = length - inductLoopPosition;
220 MSLane* placementLane = lane;
221 while (ilpos < 0 && placementLane->getIncomingLanes().size() == 1
222 && placementLane->
getIncomingLanes().front().viaLink->getCorrespondingEntryLink()->getTLLogic() ==
nullptr) {
230 const double detLength =
getDouble(
"detector-length:" + lane->getID(), detDefaultLength);
238 if (loop ==
nullptr) {
242 inductLoopPosition = length - ilpos;
246 laneInductLoopMap[lane] = loop;
277 std::map<int, std::set<MSInductLoop*> > linkToLoops;
278 std::set<int> actuatedLinks;
280 std::vector<bool> neverMajor(numLinks,
true);
282 const std::string& state = phase->getState();
283 for (
int i = 0; i < numLinks; i++) {
285 neverMajor[i] =
false;
289 std::vector<bool> oneLane(numLinks,
false);
290 std::vector<bool> turnaround(numLinks,
true);
291 for (
int i = 0; i < numLinks; i++) {
294 int numMotorized = 0;
295 for (
MSLane* l : lane->getEdge().getLanes()) {
296 if ((l->getPermissions() & motorized) != 0) {
300 if (numMotorized == 1) {
306 if (!link->isTurnaround()) {
307 turnaround[i] =
false;
315 std::set<MSInductLoop*> loops;
316 if (phase->isActuated() || multiNextTargets.count(phaseIndex) != 0) {
317 const std::string& state = phase->getState();
319 std::set<int> greenLinks;
321 std::set<int> greenLinksPermissive;
323 std::map<MSInductLoop*, std::set<int> > loopLinks;
325 for (
int i = 0; i < numLinks; i++) {
327 greenLinks.insert(i);
328 if (phase->isActuated()) {
329 actuatedLinks.insert(i);
333 if (link->getLane()->isCrossing()) {
342 if (((neverMajor[i] || turnaround[i])
346 greenLinks.insert(i);
347 if (!turnaround[i]) {
348 if (phase->isActuated()) {
349 actuatedLinks.insert(i);
353 greenLinksPermissive.insert(i);
356#ifdef DEBUG_DETECTORS
358 std::cout <<
" phase=" << phaseIndex <<
" i=" << i <<
" state=" << state[i] <<
" green=" << greenLinks.count(i) <<
" oneLane=" << oneLane[i]
359 <<
" turn=" << turnaround[i] <<
" loopLanes=";
361 if (laneInductLoopMap.count(lane) != 0) {
362 std::cout << lane->getID() <<
" ";
369 if (laneInductLoopMap.count(lane) != 0) {
370 loopLinks[laneInductLoopMap[lane]].insert(i);
374 for (
auto& item : loopLinks) {
379 bool foundUsable =
false;
381 for (
int j : item.second) {
382 if (greenLinks.count(j) == 0 && (info.
jamThreshold <= 0 || greenLinksPermissive.count(j) == 0)) {
384#ifdef DEBUG_DETECTORS
386 std::cout <<
" phase=" << phaseIndex <<
" check1: loopLane=" << loopLane->
getID() <<
" notGreen=" << j <<
" oneLane[j]=" << oneLane[j] <<
"\n";
400 if (link->isTurnaround()) {
403 const MSLane* next = link->getLane();
404 if (laneInductLoopMap.count(next) != 0) {
406 for (
int j : loopLinks[nextLoop]) {
407 if (greenLinks.count(j) == 0) {
409#ifdef DEBUG_DETECTORS
410 if (
DEBUG_COND) std::cout <<
" phase=" << phaseIndex <<
" check2: loopLane=" << loopLane->
getID()
411 <<
" nextLane=" << next->
getID() <<
" nextLink=" << j <<
" nextState=" << state[j] <<
"\n";
421 loops.insert(item.first);
422#ifdef DEBUG_DETECTORS
424 std::cout <<
" phase=" << phaseIndex <<
" usableLoops=" << item.first->getID() <<
" links=" <<
joinToString(item.second,
" ") <<
"\n";
427 for (
int j : item.second) {
428 linkToLoops[j].insert(item.first);
432 if (loops.size() == 0 && phase->isActuated()) {
436#ifdef DEBUG_DETECTORS
438 std::cout <<
" phase=" << phaseIndex <<
" loops=" <<
joinNamedToString(loops,
" ") <<
"\n";
441 std::cout <<
" linkToLoops:\n";
442 for (
auto item : linkToLoops) {
443 std::cout <<
" link=" << item.first <<
" loops=" <<
joinNamedToString(item.second,
" ") <<
"\n";
447 std::vector<InductLoopInfo*> loopInfos;
451 if (loopInfo.loop == loop) {
453 loopInfo.servedPhase[phaseIndex] =
true;
458#ifdef DEBUG_DETECTORS
460 std::cout <<
"final linkToLoops:\n";
461 for (
auto item : linkToLoops) {
462 std::cout <<
" link=" << item.first <<
" loops=" <<
joinNamedToString(item.second,
" ") <<
"\n";
466 std::vector<int> warnLinks;
467 for (
int i : actuatedLinks) {
468 if (linkToLoops[i].size() == 0 &&
myLinks[i].size() > 0
469 && (
myLinks[i].front()->getLaneBefore()->getPermissions() & motorized) != 0) {
471 warnLinks.push_back(i);
475 if (warnLinks.size() > 0) {
483 WRITE_ERRORF(
TL(
"Invalid link '%' given as linkMaxDur parameter for actuated tlLogic '%', program '%."), kv.first.substr(11),
getID(),
getProgramID());
493 WRITE_ERRORF(
TL(
"Invalid link '%' given as linkMinDur parameter for actuated tlLogic '%', program '%."), kv.first.substr(11),
getID(),
getProgramID());
505 haveSwitchingRules =
true;
520 int linkIndex = link->getIndex();
521 const MSJunction* junction = link->getJunction();
522 for (
int i = 0; i < (int)
myLinks.size(); i++) {
529 int foeIndex = foe->getIndex();
530 const MSJunction* junction2 = foe->getJunction();
531 if (junction == junction2) {
534 if (logic->
getFoesFor(linkIndex).test(foeIndex)
535 && (foe->getPermissions() & ~SVC_VULNERABLE) != 0
536 && &foe->getLaneBefore()->getEdge() != &link->getLaneBefore()->getEdge()) {
553 step = step < 0 ?
myStep : step;
562 step = step < 0 ?
myStep : step;
571 step = step < 0 ?
myStep : step;
580 step = step < 0 ?
myStep : step;
591 for (
int i = 0; i < (int)
myPhases.size(); i++) {
593 const std::string errorSuffix =
"' for overriding attribute in phase " +
toString(i) +
" of tlLogic '" +
getID() +
"' in program '" +
getProgramID() +
"'.";
595 const std::string cond =
"minDur:" +
toString(i);
597 throw ProcessError(
"Missing condition '" + cond + errorSuffix);
601 const std::string cond =
"maxDur:" +
toString(i);
603 throw ProcessError(
"Missing condition '" + cond + errorSuffix);
607 const std::string cond =
"earliestEnd:" +
toString(i);
609 throw ProcessError(
"Missing condition '" + cond + errorSuffix);
613 const std::string cond =
"latestEnd:" +
toString(i);
615 throw ProcessError(
"Missing condition '" + cond + errorSuffix);
624 for (
int i = 0; i < (int)
myPhases.size(); i++) {
627 std::vector<int> nextPhases = phase->
nextPhases;
628 if (nextPhases.size() == 0) {
629 nextPhases.push_back((i + 1) % (int)
myPhases.size());
630 }
else if (nextPhases.size() > 1) {
633 for (
int next : nextPhases) {
634 if (next >= 0 && next < (
int)
myPhases.size()) {
651 std::map<int, std::map<int, SUMOTime> > reached;
652 const std::vector<int>& next =
myPhases[step]->nextPhases;
656 for (
int target = 0; target < (int)
myPhases.size(); target++) {
657 int bestNext = next[0];
659 for (
auto item : reached) {
660 auto it = item.second.find(target);
661 if (it != item.second.end()) {
662 SUMOTime transitionTime = it->second;
663 if (transitionTime < bestTime) {
664 bestTime = transitionTime;
665 bestNext = item.first;
670 myTargets[step][bestNext].push_back(target);
679 std::pair<int, SUMOTime> tDur =
getTarget(n);
680 int target = tDur.first;
681 SUMOTime transitionTime = tDur.second + priorTransition;
683 if (target == origStep) {
688 auto it = found.find(target);
689 if (it != found.end()) {
690 if (it->second <= transitionTime) {
700 found[target] = transitionTime;
702 for (
int n2 :
myPhases[target]->nextPhases) {
710 std::set<int> result;
714 for (
int next : p->nextPhases) {
725 SUMOTime result = std::numeric_limits<SUMOTime>::max();
726 for (
int pI = 0; pI < (int)
myPhases.size(); pI++) {
728 const std::string& state = phase->
getState();
729 for (
int i = 0; i < (int)state.size(); i++) {
735 }
else if (multiNextTargets.count(pI) != 0) {
748 for (
int i = 0; i < (int)state.size(); i++) {
751 for (
MSLane* lane : lanes) {
777 loopInfo.loop->setVisible(
false);
785 if (step >= 0 && step !=
myStep) {
790 }
else if (step < 0) {
804 const SUMOTime lastSwitch = t - spentDuration;
830 if (state[i] ==
'G' || state[i] ==
'g') {
835 if (state[i] ==
'r' || state[i] ==
'u') {
845 const int origStep =
myStep;
855#ifdef DEBUG_PHASE_SELECTION
858 <<
" trySwitch dGap=" << (detectionGap == std::numeric_limits<double>::max() ?
"inf" :
toString(detectionGap))
859 <<
" multi=" << multiTarget <<
"\n";
862 if (detectionGap < std::numeric_limits<double>::max() && !multiTarget && !
myTraCISwitch) {
879 if (linkMinDur > 0) {
882 return multiTarget ?
TIME2STEPS(1) : linkMinDur;
891 myPhases[origStep]->myLastEnd = now;
899 if (loopInfo->isJammed()) {
904 loopInfo->lastGreenTime = now;
908#ifdef DEBUG_PHASE_SELECTION
931 if (newDuration % 1000 != 0) {
932 const SUMOTime totalDur = newDuration + actDuration;
933 newDuration = (totalDur / 1000 + 1) * 1000 - actDuration;
945 double result = std::numeric_limits<double>::max();
952 if (loopInfo.lastGreenTime < loopInfo.loop->getLastDetectionTime()) {
955 loopInfo.loop->setSpecialColor(
nullptr);
966#ifdef DEBUG_PHASE_SELECTION
978 if (loopInfo->isJammed()) {
984 if (actualGap < loopInfo->maxGap && !loopInfo->isJammed()) {
985 result =
MIN2(result, actualGap);
997 int result = cands.front();
1005#ifdef DEBUG_PHASE_SELECTION
1008 if (currentPrio > maxPrio) {
1010 maxPrio = currentPrio;
1013 for (
int step : cands) {
1017#ifdef DEBUG_PHASE_SELECTION
1019 std::cout <<
SIMTIME <<
" p=" <<
myStep <<
" step=" << step <<
" target=" << target <<
" loops=" <<
myInductLoopsForPhase[target].size() <<
" prio=" << prio <<
"\n";
1032std::pair<int, SUMOTime>
1035 int origStep = step;
1039 while (!
myPhases[step]->isGreenPhase()) {
1042 if (
myPhases[step]->nextPhases.size() > 0 &&
myPhases[step]->nextPhases.front() >= 0) {
1043 for (
int next :
myPhases[step]->nextPhases) {
1050 step = (step + 1) % (
int)
myPhases.size();
1052 if (step == origStep || seen > (
int)
myPhases.size()) {
1054 return std::make_pair(0, 0);
1057 return std::make_pair(step, dur);
1069#ifdef DEBUG_PHASE_SELECTION
1081#ifdef DEBUG_PHASE_SELECTION
1083 std::cout <<
" loop=" << loop->
getID()
1084 <<
" actDuration=" <<
STEPS2TIME(actDuration)
1087 <<
" canExtend=" << canExtend
1111 auto* aPersons = crossingEntry->getApproachingPersons();
1112 if (aPersons !=
nullptr && aPersons->size() > 0) {
1149 const std::string& targetState =
myPhases[target]->getState();
1152 targetState[i] ==
'G' || targetState[i] ==
'g')) {
1165 const std::string& targetState =
myPhases[target]->getState();
1168 && (state[i] ==
'G' || state[i] ==
'g')
1169 && !(targetState[i] ==
'G' || targetState[i] ==
'g')) {
1184#ifdef DEBUG_PHASE_SELECTION_CUSTOM
1186 std::cout <<
SIMTIME <<
" mustSwitch=" << mustSwitch <<
" cur=" <<
myStep <<
" next=" << next <<
" condition=" << condition
1187 <<
" eval=" << (condition ==
"" ? NAN :
evalExpression(condition)) <<
"\n";
1190 if (condition !=
"") {
1193 if (
gapControl() == std::numeric_limits<double>::max()) {
1207 const size_t bracketOpen = condition.find(
'(');
1208 if (bracketOpen != std::string::npos) {
1210 size_t bracketClose = std::string::npos;
1212 for (
size_t i = bracketOpen + 1; i < condition.size(); i++) {
1213 if (condition[i] ==
'(') {
1215 }
else if (condition[i] ==
')') {
1223 if (bracketClose == std::string::npos) {
1224 throw ProcessError(
TLF(
"Unmatched parentheses in condition %'", condition));
1226 std::string cond2 = condition;
1227 const std::string inBracket = condition.substr(bracketOpen + 1, bracketClose - bracketOpen - 1);
1229 cond2.replace(bracketOpen, bracketClose - bracketOpen + 1,
toString(bracketVal));
1233 throw ProcessError(
TLF(
"Error when evaluating expression '%':\n %", condition, e.what()));
1238 if (tokens.size() == 0) {
1240 }
else if (tokens.size() == 1) {
1244 throw ProcessError(
TLF(
"Error when evaluating expression '%':\n %", condition, e.what()));
1246 }
else if (tokens.size() == 2) {
1247 if (tokens[0] ==
"not") {
1251 throw ProcessError(
TLF(
"Error when evaluating expression '%':\n %", condition, e.what()));
1256 }
else if (tokens.size() == 3) {
1260 const std::string& o = tokens[1];
1265 throw ProcessError(
TLF(
"Error when evaluating expression '%':\n %", condition, e.what()));
1268 const int iEnd = (int)tokens.size() - 1;
1270 for (
int i = 1; i < iEnd; i++) {
1271 if (tokens[i] == o) {
1276 std::vector<std::string> newTokens(tokens.begin(), tokens.begin() + (i - 1));
1277 newTokens.push_back(
toString(val));
1278 newTokens.insert(newTokens.end(), tokens.begin() + (i + 2), tokens.end());
1281 throw ProcessError(
TLF(
"Error when evaluating expression '%':\n %", condition, e.what()));
1286 throw ProcessError(
TLF(
"Parsing expressions with % elements ('%') is not supported",
toString(tokens.size()), condition));
1293 if (o ==
"=" || o ==
"==") {
1294 return (
double)(a == b);
1295 }
else if (o ==
"<") {
1296 return (
double)(a < b);
1297 }
else if (o ==
">") {
1298 return (
double)(a > b);
1299 }
else if (o ==
"<=") {
1300 return (
double)(a <= b);
1301 }
else if (o ==
">=") {
1302 return (
double)(a >= b);
1303 }
else if (o ==
"!=") {
1304 return (
double)(a != b);
1305 }
else if (o ==
"or" || o ==
"||") {
1306 return (
double)(a || b);
1307 }
else if (o ==
"and" || o ==
"&&") {
1308 return (
double)(a && b);
1309 }
else if (o ==
"+") {
1311 }
else if (o ==
"-") {
1313 }
else if (o ==
"*") {
1315 }
else if (o ==
"/") {
1321 }
else if (o ==
"%") {
1323 }
else if (o ==
"**" || o ==
"^") {
1326 throw ProcessError(
TLF(
"Unsupported operator '%' in condition '%'", o, condition));
1334 if ((
int)args.size() != f.
nArgs) {
1337 std::vector<double> args2;
1338 for (
auto a : args) {
1343 for (
int i = 0; i < (int)args2.size(); i++) {
1352 double result =
myStack.back()[
"$0"];
1360 for (
const auto& assignment : assignments) {
1362 const std::string&
id = std::get<0>(assignment);
1364 ConditionMap::iterator it = conditions.find(
id);
1365 if (it != conditions.end()) {
1367 }
else if (forbidden.find(
id) != forbidden.end()) {
1368 throw ProcessError(
TLF(
"Modifying global condition '%' is forbidden",
id));
1379 if (expr.size() == 0) {
1381 }
else if (expr[0] ==
'!') {
1383 }
else if (expr[0] ==
'-') {
1387 const size_t pos = expr.find(
':');
1388 if (pos == std::string::npos) {
1395 auto it2 =
myStack.back().find(expr);
1396 if (it2 !=
myStack.back().end()) {
1403 const std::string fun = expr.substr(0, pos);
1404 const std::string arg = expr.substr(pos + 1);
1406 return retrieveDetExpression<MSInductLoop, SUMO_TAG_INDUCTION_LOOP>(arg, expr,
true)->getTimeSinceLastDetection();
1407 }
else if (fun ==
"a") {
1409 return retrieveDetExpression<MSInductLoop, SUMO_TAG_INDUCTION_LOOP>(arg, expr,
true)->getTimeSinceLastDetection() == 0;
1411 return retrieveDetExpression<MSE2Collector, SUMO_TAG_LANE_AREA_DETECTOR>(arg, expr,
true)->getCurrentVehicleNumber();
1413 }
else if (fun ==
"w") {
1415 return retrieveDetExpression<MSInductLoop, SUMO_TAG_INDUCTION_LOOP>(arg, expr,
true)->getOccupancyTime();
1417 return retrieveDetExpression<MSE2Collector, SUMO_TAG_LANE_AREA_DETECTOR>(arg, expr,
true)->getCurrentJamDuration();
1419 }
else if (fun ==
"d") {
1421 return retrieveDetExpression<MSInductLoop, SUMO_TAG_INDUCTION_LOOP>(arg, expr,
true)->getArrivalDelay();
1423 return retrieveDetExpression<MSE2Collector, SUMO_TAG_LANE_AREA_DETECTOR>(arg, expr,
true)->getArrivalDelay();
1425 }
else if (fun ==
"g" || fun ==
"r") {
1428 if (linkIndex >= 0 && linkIndex <
myNumLinks) {
1430 if (times.empty()) {
1442 return STEPS2TIME(times[linkIndex] + currentGreen);
1451 throw ProcessError(
TLF(
"Invalid link index '%' in expression '%'", arg, expr));
1452 }
else if (fun ==
"p") {
1455 if (linkIndex >= 0 && linkIndex <
myNumLinks) {
1456 double approachingPersons = 0;
1458 auto* aPersons = link->getApproachingPersons();
1459 if (aPersons !=
nullptr) {
1460 approachingPersons += (double)aPersons->size();
1463 return approachingPersons;
1466 throw ProcessError(
TLF(
"Invalid link index '%' in expression '%'", arg, expr));
1467 }
else if (fun ==
"c") {
1471 throw ProcessError(
TLF(
"Unsupported function '%' in expression '%'", fun, expr));
1480std::map<std::string, double>
1482 std::map<std::string, double> result;
1484 result[li.loop->getID()] = li.loop->getOccupancy() > 0 ? 1 : 0;
1487 result[loop->getID()] = loop->getOccupancy() > 0 ? 1 : 0;
1490 result[loop->getID()] = loop->getCurrentVehicleNumber();
1497 double result = 0.0;
1499 if (li.lane->getID() == laneID) {
1500 result = li.loop->getOccupancy() > 0 ? 1 : 0;
1507std::map<std::string, double>
1509 std::map<std::string, double> result;
1515 WRITE_ERRORF(
TL(
"Error when retrieving conditions '%' for tlLogic '%' (%)"), item.first,
getID(), e.what());
1525 const std::string cond = key.substr(10);
1540 if (key ==
"detector-gap" || key ==
"passing-time" || key ==
"file" || key ==
"freq" || key ==
"vTypes"
1541 || key ==
"build-all-detectors"
1544 throw InvalidArgument(key +
" cannot be changed dynamically for actuated traffic light '" +
getID() +
"'");
1545 }
else if (key ==
"max-gap") {
1553 const std::string laneID = key.substr(8);
1555 if (loopInfo.lane->getID() == laneID) {
1561 throw InvalidArgument(
TLF(
"Invalid lane '%' in key '%' for actuated traffic light '%'", laneID, key,
getID()));
1562 }
else if (key ==
"jam-threshold") {
1570 const std::string laneID = key.substr(14);
1572 if (loopInfo.lane->getID() == laneID) {
1578 throw InvalidArgument(
TLF(
"Invalid lane '%' in key '%' for actuated traffic light '%'", laneID, key,
getID()));
1579 }
else if (key ==
"show-detectors") {
1585 }
else if (key ==
"inactive-threshold") {
1599 std::vector<double> state;
1615 if (i < (
int)timeGaps.size()) {
#define DEFAULT_DETECTOR_GAP
#define DEFAULT_STATIC_MINDUR
#define DEFAULT_PASSING_TIME
#define DEFAULT_BIKE_LENGTH_WITH_GAP
#define DEFAULT_LENGTH_WITH_GAP
#define DEFAULT_INACTIVE_THRESHOLD
#define DEFAULT_CROSSING_PRIORITY
#define DEFAULT_CONDITION
#define DEFAULT_CURRENT_PRIORITY
#define WRITE_WARNINGF(...)
#define WRITE_ERRORF(...)
#define WRITE_WARNING(msg)
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
bool noVehicles(SVCPermissions permissions)
Returns whether an edge with the given permissions forbids vehicles.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const double DEFAULT_BICYCLE_SPEED
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_TAG_INDUCTION_LOOP
alternative tag for e1 detector
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ SUMO_ATTR_STATE
The state of a link.
std::string joinNamedToString(const std::set< T *, C > &ns, const T_BETWEEN &between)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessible from the current working directory.
double myDetectorGap
The detector distance in seconds.
void findTargets(int origStep, int n, SUMOTime priorTransition, std::map< int, SUMOTime > &found)
FunctionMap myFunctions
The loaded functions.
double myJamThreshold
The minimum continuous occupancy time to mark a detector as jammed.
bool myBuildAllDetectors
Whether all detectors shall be built.
double myMaxGap
The maximum gap to check in seconds.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const override
try to get the value of the given parameter (including prefixed parameters)
std::map< int, std::map< int, std::vector< int > > > myTargets
std::vector< SwitchingRules > mySwitchingRules
~MSActuatedTrafficLightLogic()
Destructor.
std::vector< std::map< std::string, double > > myStack
The function call stack;.
double evalAtomicExpression(const std::string &expr) const
evaluate atomic expression
SUMOTime trySwitch() override
Switches to the next phase.
std::set< int > getMultiNextTargets() const
find green phases target by a next attribute
SUMOTime myLastTrySwitchTime
last time trySwitch was called
int getDetectorPriority(const InductLoopInfo &loopInfo) const
SUMOTime myFreq
The frequency for aggregating detector output.
void saveState(OutputDevice &out) const override
Saves the current tls states into the given stream.
std::vector< const MSInductLoop * > myExtraLoops
extra loops for output/tracking
bool myShowDetectors
Whether the detectors shall be shown in the GUI.
std::vector< SUMOTime > myLinkMaxGreenTimes
maximum consecutive time that the given link may remain green
MSActuatedTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const SUMOTime offset, const MSSimpleTrafficLightLogic::Phases &phases, int step, SUMOTime delay, const Parameterised::Map ¶meter, const std::string &basePath, const ConditionMap &conditions=ConditionMap(), const AssignmentMap &assignments=AssignmentMap(), const FunctionMap &functions=FunctionMap())
Constructor.
SUMOTime getMaxDur(int step=-1) const override
std::vector< std::vector< const MSLink * > > myCrossingsForPhase
AssignmentMap myAssignments
The condition assignments.
std::string myVehicleTypes
Whether detector output separates by vType.
double gapControl()
Return the minimum detection gap of all detectors if the current phase should be extended and double:...
std::vector< std::tuple< std::string, std::string, std::string > > AssignmentMap
std::set< std::string > myListedConditions
the conditions which shall be listed in GUITLLogicPhasesTrackerWindow
double evalExpression(const std::string &condition) const
evaluate custom switching condition
std::vector< SUMOTime > myLinkMinGreenTimes
minimum consecutive time that the given link must remain green
void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration) override
Changes the current phase and her duration.
bool weakConflict(int linkIndex, const std::string &state) const
whether a given link has only weak mode foes that are green in the given state
static const std::vector< std::string > OPERATOR_PRECEDENCE
void deactivateProgram() override
bool myHasMultiTarget
Whether any of the phases has multiple targets.
double myPassingTime
The passing time used in seconds.
SUMOTime getLinkMinDuration(int target) const
the minimum duratin for keeping the current phase due to linkMinDur constraints
SUMOTime getMinDur(int step=-1) const override
bool canExtendLinkGreen(int target)
whether the target phase is acceptable in light of linkMaxDur constraints
InductLoopMap myInductLoopsForPhase
A map from phase to induction loops to be used for gap control.
SUMOTime getMinimumMinDuration(MSLane *lane, const std::set< int > &multiNextTargets) const
get the minimum min duration for all stretchable phases that affect the given lane
int decideNextPhaseCustom(bool mustSwitch)
select among candidate phases based on detector states and custom switching rules
double evalTernaryExpression(double a, const std::string &o, double b, const std::string &condition) const
evaluate atomic expression
void executeAssignments(const AssignmentMap &assignments, ConditionMap &conditions, const ConditionMap &forbidden=ConditionMap()) const
execute assignemnts of the logic or a custom function
void setShowDetectors(bool show)
void initTargets(int step)
bool myTraCISwitch
whether the next switch time was requested via TraCI
int getPhasePriority(int step) const
count the number of active detectors for the given step
SUMOTime duration(const double detectionGap) const
Returns the minimum duration of the current phase.
void activateProgram() override
called when switching programs
std::vector< InductLoopInfo > myInductLoops
bool maxLinkDurationReached()
whether the current phase cannot be continued due to linkMaxDur constraints
double evalCustomFunction(const std::string &fun, const std::string &arg) const
evaluate function expression
void initAttributeOverride()
initialize custom switching rules
std::map< std::string, double > getConditions() const override
return all named conditions defined for this traffic light
bool hasMajor(const std::string &state, const LaneVector &lanes) const
return whether there is a major link from the given lane in the given phase
std::vector< const MSE2Collector * > myExtraE2
SUMOTime getEarliestEnd(int step=-1) const override
std::map< std::string, Function > FunctionMap
std::map< std::string, double > getDetectorStates() const override
retrieve all detectors used by this program
double getDetectorState(const std::string laneID) const override
retrieve a specific detector used by this program
void setParameter(const std::string &key, const std::string &value) override
Sets a parameter and updates internal constants.
std::vector< SUMOTime > myLinkGreenTimes
consecutive time that the given link index has been green
void loadExtraState(const std::string &state) override
SUMOTime getLatestEnd(int step=-1) const override
std::vector< SUMOTime > myLinkRedTimes
Parameterised::Map ConditionMap
std::string myFile
The output file for generated detectors.
void initSwitchingRules()
std::pair< int, SUMOTime > getTarget(int step) const
get the green phase following step and the transition time
ConditionMap myConditions
The custom switching conditions.
const std::string myDetectorPrefix
void loadState(MSTLLogicControl &tlcontrol, SUMOTime t, int step, SUMOTime spentDuration, SUMOTime nextSwitch, SUMOTime timeInCycle, bool active) override
restores the tls state
void init(NLDetectorBuilder &nb) override
Initialises the tls with information about incoming lanes.
int decideNextPhase()
select among candidate phases based on detector states
SUMOTime myInactiveThreshold
The time threshold to avoid starved phases.
const NamedObjectCont< MSDetectorFileOutput * > & getTypedDetectors(SumoXMLTag type) const
Returns the list of detectors of the given type.
void add(SumoXMLTag type, MSDetectorFileOutput *d, const std::string &device, SUMOTime interval, SUMOTime begin=-1)
Adds a detector/output combination into the containers.
A road/street connecting two junctions.
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
An unextended detector measuring at a fixed position on a fixed lane.
double getPosition() const
Returns the position of the detector on the lane.
virtual void setSpecialColor(const RGBColor *)
allows for special color in the gui version
void loadTimeSinceLastDetection(double time)
double getTimeSinceLastDetection() const
Returns the time since the last vehicle left the detector.
SUMOTime getLastDetectionTime() const
return last time a vehicle was on the detector
The base class for an intersection.
virtual const MSJunctionLogic * getLogic() const
virtual const MSLogicJunction::LinkBits & getFoesFor(int linkIndex) const
Returns the foes for the given link.
Representation of a lane in the micro simulation.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
double getLength() const
Returns the lane's length.
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
MSDetectorControl & getDetectorControl()
Returns the detector control.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
The definition of a single phase of a tls logic.
SUMOTime maxDuration
The maximum duration of the phase.
LinkState getSignalState(int pos) const
Returns the state of the tls signal at the given position.
static const SUMOTime OVERRIDE_DURATION
SUMOTime latestEnd
The maximum time within the cycle for switching (for coordinated actuation)
SUMOTime minDuration
The minimum duration of the phase.
const std::string & getState() const
Returns the state within this phase.
bool isGreenPhase() const
Returns whether this phase is a pure "green" phase.
std::vector< int > nextPhases
The index of the phase that suceeds this one (or -1)
std::string finalTarget
The condition expression for switching into this phase when the active phase must end.
std::string earlyTarget
The condition expression for an early switch into this phase.
SUMOTime earliestEnd
The minimum time within the cycle for switching (for coordinated actuation)
A fixed traffic light logic.
SUMOTime getLatest() const
the maximum duration for keeping the current phase when considering 'latestEnd'
Phases myPhases
The list of phases this logic uses.
SUMOTime getEarliest(SUMOTime prevStart) const
the minimum duration for keeping the current phase when considering 'earliestEnd'
void saveStateAttrs(OutputDevice &out) const
int myStep
The current step.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const override
gets a parameter
virtual void setParameter(const std::string &key, const std::string &value) override
Sets a parameter and updates internal constants.
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current phase.
void executeOnSwitchActions() const
A class that stores and controls tls and switching of their programs.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
Class realising the switch between the traffic light phases.
void deschedule(MSTrafficLightLogic *tlLogic)
Marks this swicth as invalid (if the phase duration has changed, f.e.)
const LaneVector & getLanesAt(int i) const
Returns the list of lanes that are controlled by the signals at the given position.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
virtual void deactivateProgram()
SUMOTime getTimeInCycle() const
return time within the current cycle
const std::string & getProgramID() const
Returns this tl-logic's id.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
SwitchCommand * mySwitchCommand
The current switch command.
int myNumLinks
number of controlled links
virtual void activateProgram()
called when switching programs
bool myAmActive
whether the current program is active
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
Builds detectors for microsim.
virtual MSDetectorFileOutput * createInductLoop(const std::string &id, MSLane *lane, double pos, double length, const std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons, bool show)
Creates an instance of an e1 detector using the given values.
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
std::map< std::string, std::string > Map
parameters map
double getDouble(const std::string &key, const double defaultValue) const
Returns the value for a given key converted to a double.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
static const RGBColor ORANGE
static const RGBColor GREEN
static const RGBColor RED
named colors
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
AssignmentMap assignments
std::vector< bool > servedPhase