42#define MIN_GREEN_TIME 5
48#define DEBUGCOND (getID() == DEBUGID)
49#define DEBUGCOND2(obj) (obj->getID() == DEBUGID)
52#define DEBUGEDGE(edge) (true)
64 const std::vector<NBNode*>& junctions,
SUMOTime offset,
67 myHaveSinglePhase(false),
75 myHaveSinglePhase(false),
83 myHaveSinglePhase(false),
116 for (
int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
118 for (
int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
120 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
124 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
128 const double sign = (
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)
129 ||
forbids(e2, (*e2c).toEdge, e1, (*e1c).toEdge,
true)) ? -1 : 1;
134 if (prio1 == prio2) {
163#ifdef DEBUG_STREAM_ORDERING
165 std::cout <<
" sign=" << sign <<
" w1=" << w1 <<
" w2=" << w2 <<
" val=" << val
166 <<
" c1=" << (*e1c).getDescription(e1)
167 <<
" c2=" << (*e2c).getDescription(e2)
175#ifdef DEBUG_STREAM_ORDERING
177 std::cout <<
" computeUnblockedWeightedStreamNumber e1=" << e1->
getID() <<
" e2=" << e2->
getID() <<
" val=" << val <<
"\n";
184std::pair<NBEdge*, NBEdge*>
186 std::pair<NBEdge*, NBEdge*> bestPair(
static_cast<NBEdge*
>(
nullptr),
static_cast<NBEdge*
>(
nullptr));
187 double bestValue = -std::numeric_limits<double>::max();
188 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
189 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
191 if (value > bestValue) {
193 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
194 }
else if (value == bestValue) {
196 const double oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
197 if (fabs(oa - ca) < NUMERICAL_EPS) {
198 if (bestPair.first->getID() < (*i)->getID()) {
199 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
201 }
else if (oa < ca) {
202 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
207 if (bestValue <= 0) {
209 if (bestPair.first->getPriority() < bestPair.second->getPriority()) {
210 std::swap(bestPair.first, bestPair.second);
212 bestPair.second =
nullptr;
214#ifdef DEBUG_STREAM_ORDERING
223std::pair<NBEdge*, NBEdge*>
225 if (incoming.size() == 1) {
227 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(),
static_cast<NBEdge*
>(
nullptr));
235 used.push_back(*incoming.begin());
238 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
242 if (used.size() < 2) {
246#ifdef DEBUG_STREAM_ORDERING
252 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
253 if (ret.second !=
nullptr) {
254 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
292 std::vector<std::pair<NBEdge*, NBEdge*> > chosenList;
293 std::vector<std::string> straightStates;
294 std::vector<std::string> leftStates;
299 std::vector<bool> isTurnaround;
300 std::vector<bool> hasTurnLane;
301 std::vector<int> fromLanes;
302 std::vector<int> toLanes;
303 std::vector<SUMOTime> crossingTime;
304 int totalNumLinks = 0;
305 for (
NBEdge*
const fromEdge : incoming) {
306 const int numLanes = fromEdge->getNumLanes();
308 for (
int i2 = 0; i2 < numLanes; i2++) {
309 bool hasLeft =
false;
310 bool hasPartLeft =
false;
311 bool hasStraight =
false;
312 bool hasRight =
false;
313 bool hasTurnaround =
false;
315 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
318 fromEdges.push_back(fromEdge);
319 fromLanes.push_back(i2);
320 toLanes.push_back(approached.toLane);
321 toEdges.push_back(approached.toEdge);
322 if (approached.vmax < NUMERICAL_EPS || (fromEdge->getPermissions() &
SVC_PASSENGER) == 0
323 || (approached.toEdge->getPermissions() &
SVC_PASSENGER) == 0) {
324 crossingTime.push_back(0);
329 if (approached.toEdge !=
nullptr) {
330 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
332 isTurnaround.push_back(
true);
334 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
344 hasTurnaround =
true;
349 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
352 hasTurnLane.push_back(
353 (hasLeft && !hasPartLeft && !hasStraight && !hasRight)
354 || (hasPartLeft && !hasLeft && !hasStraight && !hasRight)
355 || (hasPartLeft && hasLeft && edgeHasStraight && !hasRight)
356 || (!hasLeft && !hasPartLeft && !hasTurnaround && hasRight));
362 std::vector<NBNode::Crossing*> crossings;
364 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
367 node->setCrossingTLIndices(
getID(), totalNumLinks);
369 copy(c.begin(), c.end(), std::back_inserter(crossings));
370 totalNumLinks += (int)c.size();
387 std::vector<int> greenPhases;
388 std::vector<bool> hadGreenMajor(totalNumLinks,
false);
389 while (toProc.size() > 0) {
390 bool groupTram =
false;
391 bool groupOther =
false;
392 std::pair<NBEdge*, NBEdge*> chosen;
393 std::set<const NBEdge*> chosenSet;
394 if (groupOpposites) {
395 if (incoming.size() == 2) {
398 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
401 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(
nullptr));
402 toProc.erase(toProc.begin());
408 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
410 for (
auto it = toProc.begin(); it != toProc.end();) {
411 if ((*it)->getPermissions() ==
SVC_TRAM) {
412 it = toProc.erase(it);
420 NBEdge* chosenEdge = toProc[0];
421 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge,
static_cast<NBEdge*
>(
nullptr));
422 toProc.erase(toProc.begin());
434 if (groupTram || groupOther) {
435 for (
auto it = toProc.begin(); it != toProc.end();) {
436 if ((*it)->getPermissions() == perms) {
437 it = toProc.erase(it);
445 std::string state(totalNumLinks,
'r');
451 chosenList.push_back(chosen);
452 chosenSet.insert(chosen.first);
453 if (chosen.second !=
nullptr) {
454 chosenSet.insert(chosen.second);
457 for (
const NBEdge* e : chosenSet) {
459 std::vector<NBEdge*> parallelBikeEdges;
460 for (
NBEdge* cand : toProc) {
462 double angle = fabs(
NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), cand->getAngleAtNode(cand->getToNode())));
465 parallelBikeEdges.push_back(cand);
469 for (
NBEdge* be : parallelBikeEdges) {
472 std::cout <<
" chosen=" << e->getID() <<
" be=" << be->getID() <<
"\n";
475 chosenSet.insert(be);
476 toProc.erase(std::find(toProc.begin(), toProc.end(), be));
482 bool haveGreen =
false;
483 for (
const NBEdge*
const fromEdge : incoming) {
484 const bool inChosen = chosenSet.count(fromEdge) != 0;
485 const int numLanes = fromEdge->getNumLanes();
486 for (
int i2 = 0; i2 < numLanes; i2++) {
488 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
494 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
508 std::cout <<
" state after plain straight movers " << state <<
"\n";
513 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
516 std::cout <<
" state after allowing compatible " << state <<
"\n";
521 }
else if (groupOther) {
526 std::cout <<
" state after grouping by vClass " << state <<
" (groupTram=" << groupTram <<
" groupOther=" << groupOther <<
")\n";
530 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
534 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
539 bool haveForbiddenLeftMover =
false;
540 std::vector<bool> rightTurnConflicts(pos,
false);
541 std::vector<bool> mergeConflicts(pos,
false);
542 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
543 for (
int i1 = 0; i1 < pos; ++i1) {
544 if (state[i1] ==
'G') {
545 hadGreenMajor[i1] =
true;
550 std::cout <<
" state after correcting left movers=" << state <<
"\n";
554 std::vector<bool> leftGreen(pos,
false);
556 bool foundLeftTurnLane =
false;
557 for (
int i1 = 0; i1 < pos; ++i1) {
558 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1] && hasTurnLane[i1]) {
559 foundLeftTurnLane =
true;
562 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
563 && groupOpposites && !groupTram && !groupOther);
566 for (
int i1 = 0; i1 < pos; ++i1) {
567 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1]
569 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
570 leftGreen[i1] =
true;
571 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
572 if (buildLeftGreenPhase) {
575 }
else if (!isTurnaround[i1]) {
576 WRITE_WARNINGF(
TL(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing."),
577 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
585 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
586 <<
" \nrtC=" <<
toString(rightTurnConflicts)
587 <<
" \nmC=" <<
toString(mergeConflicts)
588 <<
" \nhTL=" <<
toString(hasTurnLane)
593 straightStates.push_back(state);
595 const std::string vehicleState = state;
596 greenPhases.push_back((
int)logic->
getPhases().size());
599 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
601 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
604 bool tramExclusive =
true;
605 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
606 if (state[i1] ==
'G') {
607 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
609 tramExclusive =
false;
620 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, earliestEnd, latestEnd, state, crossings, fromEdges, toEdges);
622 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
625 if (brakingTime > 0) {
628 for (
int i1 = 0; i1 < pos; ++i1) {
629 if (state[i1] !=
'G' && state[i1] !=
'g') {
632 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
633 && buildLeftGreenPhase
634 && !rightTurnConflicts[i1]
635 && !mergeConflicts[i1]
640 maxCross =
MAX2(maxCross, crossingTime[i1]);
643 logic->
addStep(brakingTime, state);
645 if (!buildLeftGreenPhase) {
654 if (buildLeftGreenPhase) {
656 for (
int i1 = 0; i1 < pos; ++i1) {
657 if (state[i1] ==
'Y' || state[i1] ==
'y') {
665 leftStates.push_back(state);
666 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
667 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
668 bool buildMixedGreenPhase =
false;
669 std::vector<bool> mixedGreen(pos,
false);
670 const std::string oldState = state;
672 state =
correctMixed(state, fromEdges, fromLanes, buildMixedGreenPhase, mixedGreen);
674 if (state != oldState) {
675 for (
int i1 = 0; i1 < pos; ++i1) {
676 if (mixedGreen[i1]) {
678 int yellowIndex = (int)logic->
getPhases().size() - 1;
679 if (allRedTime > 0) {
682 if (brakingTime > 0) {
687 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
691 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
694 if (brakingTime > 0) {
696 for (
int i1 = 0; i1 < pos; ++i1) {
697 if (state[i1] !=
'G' && state[i1] !=
'g') {
701 maxCross =
MAX2(maxCross, crossingTime[i1]);
704 logic->
addStep(brakingTime, state);
709 if (buildMixedGreenPhase) {
715 for (
int i1 = 0; i1 < pos; ++i1) {
716 if (state[i1] ==
'Y' || state[i1] ==
'y') {
720 if (mixedGreen[i1]) {
724 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
725 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
728 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
731 if (brakingTime > 0) {
733 for (
int i1 = 0; i1 < pos; ++i1) {
734 if (state[i1] !=
'G' && state[i1] !=
'g') {
738 maxCross =
MAX2(maxCross, crossingTime[i1]);
741 logic->
addStep(brakingTime, state);
748 std::string& s = straightStates.back();
749 std::string leftState = s;
750 for (
int ii = 0; ii < pos; ++ii) {
752 NBEdge* fromEdge = fromEdges[ii];
753 NBEdge* toEdge = toEdges[ii];
763 leftStates.push_back(leftState);
766 if (
myEdgesWithin.size() > 0 && !isNEMA && toProc.size() == 0) {
771 if (crossings.size() > 0) {
775 if (logic->
getPhases().size() == 2 && brakingTime > 0
778 logic->
addStep(redTime, std::string(totalNumLinks,
'r'));
781 if (crossings.size() > 0 && !onlyConts) {
791 if (nemaLogic ==
nullptr) {
792 WRITE_WARNINGF(
TL(
"Generating NEMA phases is not support for traffic light '%' with % incoming edges. Using tlType 'actuated' as fallback"),
getID(), incoming.size());
807 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
809 minGreenDuration =
MIN2(minGreenDuration, dur);
811 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / (double)greenPhases.size());
812 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
816 || greenPhases.size() == 0) {
822 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
825 if (greenPhases.size() > 0) {
833 const std::vector<NBTrafficLightLogic::PhaseDefinition>& allPhases = logic->
getPhases();
834 const int phaseCount = (int)allPhases.size();
836 for (
int i = 0; i < phaseCount; ++i) {
837 std::string currState = allPhases[i].state;
838 const int prevIndex = (i == 0) ? phaseCount - 1 : i - 1;
839 const std::string prevState = allPhases[prevIndex].state;
840 const std::string nextState = allPhases[(i + 1) % phaseCount].state;
841 bool updatedState =
false;
842 for (
int i1 = 0; i1 < stateSize; ++i1) {
843 if (currState[i1] ==
'y' && (nextState[i1] ==
'g' || nextState[i1] ==
'G') && (prevState[i1] ==
'g' || prevState[i1] ==
'G')) {
853 std::cout <<
getID() <<
" state of phase index " << i <<
" was patched due to yellow in between green\n";
864 if (totalDuration > 0) {
865 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime) && !isNEMA) {
880 for (
auto c : crossings) {
884 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
885 const NBEdge* edge = *it_e;
886 if (edge == from || edge == to) {
899 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
904 const std::string orig = state;
908 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
910 const SUMOTime pedTime = greenTime - pedClearingTime;
911 if (pedTime >= minPedTime) {
913 const int pedStates = (int)crossings.size();
916 if (isSimpleActuatedCrossing) {
920 logic->
addStep(pedTime, state, minDur, maxDur, earliestEnd, latestEnd);
923 std::cout <<
" intermidate state for addPedestrianPhases " << state <<
"\n";
926 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
927 logic->
addStep(pedClearingTime, state);
931 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
936 std::cout <<
" state after addPedestrianPhases " << state <<
"\n";
945 std::string result = state;
946 const int pos = (int)(state.size() - crossings.size());
947 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
948 const int i1 = pos + ic;
953 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
954 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
957 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
973 for (
int i1 = 0; i1 < pos; ++i1) {
974 if (result[i1] ==
'G') {
975 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
977 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
978 const int i2 = pos + ic;
993 const std::vector<NBNode::Crossing*>& crossings,
997 std::string result = state;
998 const int pos = (int)(state.size() - crossings.size());
1000 EdgeVector::const_iterator start = std::find(all.begin(), all.end(), greenEdge);
1003 const NBEdge* endEdge =
nullptr;
1004 for (
int i = 0; i < (int)state.size(); i++) {
1005 if (state[i] ==
'G' && fromEdges[i] == greenEdge
1008 endEdge = toEdges[i];
1012 if (endEdge ==
nullptr) {
1013 endEdge = otherChosen;
1015 if (endEdge ==
nullptr) {
1019 if ((*itCW)->getFromNode() == greenEdge->
getToNode()) {
1023 if (endEdge ==
nullptr) {
1025 endEdge = greenEdge;
1029 EdgeVector::const_iterator end = std::find(all.begin(), all.end(), endEdge);
1030 if (end == all.end()) {
1037 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1038 const int i1 = pos + ic;
1042 if (crossed == *it) {
1050 for (
int i1 = 0; i1 < pos; ++i1) {
1051 if (result[i1] ==
'G') {
1052 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1054 const int i2 = pos + ic;
1092 NBEdge* ,
int ,
bool ) {}
1100 std::vector<bool> edgeInsideTLS;
1102 edgeInsideTLS.push_back(e->isInsideTLS());
1112 n->removeTrafficLight(&dummy);
1117 e->setInsideTLS(edgeInsideTLS[i]);
1121#ifdef DEBUG_CONTRELATION
1123 std::cout <<
" contRelations at " <<
getID() <<
" prog=" <<
getProgramID() <<
":\n";
1125 std::cout <<
" " << s.from1->
getID() <<
"->" << s.to1->getID() <<
" foe " << s.from2->getID() <<
"->" << s.to2->getID() <<
"\n";
1139 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
1140 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
1141 it = result.erase(it);
1152 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1156 std::cout <<
" state after allowSingle " << state <<
"\n";
1163 std::cout <<
" state after allowFollowers " << state <<
"\n";
1169 std::cout <<
" state after allowPredecessors " << state <<
"\n";
1180 const int size = (int)fromEdges.size();
1181 NBEdge* greenEdge =
nullptr;
1182 for (
int i1 = 0; i1 < size; ++i1) {
1183 if (state[i1] ==
'G') {
1184 if (greenEdge ==
nullptr) {
1185 greenEdge = fromEdges[i1];
1186 }
else if (greenEdge != fromEdges[i1]) {
1191 if (greenEdge !=
nullptr) {
1192 for (
int i1 = 0; i1 < size; ++i1) {
1193 if (fromEdges[i1] == greenEdge) {
1208 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1209 if (state[i1] ==
'G') {
1212 if (
forbidden(state, i1, fromEdges, toEdges,
true)) {
1215 bool followsChosen =
false;
1216 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1217 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
1218 followsChosen =
true;
1222 if (followsChosen) {
1234 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1240 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1241 if (state[i1] ==
'G') {
1244 if (
forbidden(state, i1, fromEdges, toEdges,
false)) {
1247 bool preceedsChosen =
false;
1248 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1249 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
1250 && fromLanes[i2] == toLanes[i1]) {
1251 preceedsChosen =
true;
1255 if (preceedsChosen) {
1267 const std::vector<bool>& isTurnaround,
1268 const std::vector<NBNode::Crossing*>& crossings) {
1269 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1270 if (state[i1] ==
'G') {
1274 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1275 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1276 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1291 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1292 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1293 if ((linkPerm & ~perm) == 0) {
1303 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1304 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1306 !
needsCont(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index]) &&
1307 !
needsCont(fromEdges[index], toEdges[index], fromEdges[i2], toEdges[i2]))) {
1318 const std::vector<bool>& isTurnaround,
1319 const std::vector<int>& fromLanes,
1320 const std::vector<int>& toLanes,
1321 const std::vector<bool>& hadGreenMajor,
1322 bool& haveForbiddenLeftMover,
1323 std::vector<bool>& rightTurnConflicts,
1324 std::vector<bool>& mergeConflicts) {
1326 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1327 if (state[i1] ==
'G') {
1328 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1329 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1331 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1332 rightTurnConflicts[i1] =
true;
1334 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1338#ifdef DEBUG_CONTRELATION
1340 std::cout <<
getID() <<
" p=" <<
getProgramID() <<
" contRel: " << fromEdges[i1]->getID() <<
"->" << toEdges[i1]->getID()
1341 <<
" foe " << fromEdges[i2]->getID() <<
"->" << toEdges[i2]->getID() <<
"\n";
1345 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1346 haveForbiddenLeftMover =
true;
1348 }
else if (fromEdges[i1] == fromEdges[i2]
1349 && fromLanes[i1] != fromLanes[i2]
1350 && toEdges[i1] == toEdges[i2]
1351 && toLanes[i1] == toLanes[i2]
1352 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1353 mergeConflicts[i1] =
true;
1359 if (state[i1] ==
'r') {
1361 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1364 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1365 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1366 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1367 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1368 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1375 if (state[i1] ==
's') {
1377 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1378 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1379 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1380 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1394 const std::vector<int>& fromLanes,
1395 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1396 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1397 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1398 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1399 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1400 && state[i2] !=
'G' && state[i2] !=
'g') {
1401 state[i1] = state[i2];
1403 mixedGreen[i1] =
true;
1404 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1405 buildMixedGreenPhase =
true;
1417 std::vector<bool> foundGreen(fromEdges.size(),
false);
1418 for (
const auto& phase : logic->
getPhases()) {
1419 const std::string state = phase.state;
1420 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1423 foundGreen[j] =
true;
1427 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1428 if (!foundGreen[j]) {
1429 NBEdge* e = fromEdges[j];
1430 if (std::find(toProc.begin(), toProc.end(), e) == toProc.end()) {
1431 toProc.push_back(e);
1440 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1441 const int vehLinks = totalNumLinks - (int)crossings.size();
1442 std::vector<bool> foundGreen(crossings.size(),
false);
1443 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1444 for (
int i = 0; i < (int)phases.size(); i++) {
1445 const std::string state = phases[i].state;
1446 for (
int j = 0; j < (int)crossings.size(); j++) {
1449 foundGreen[j] =
true;
1455 std::cout <<
" foundCrossingGreen=" <<
toString(foundGreen) <<
"\n";
1458 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1459 if (!foundGreen[j]) {
1461 if (phases.size() > 0) {
1462 bool needYellowPhase =
false;
1463 std::string state = phases.back().state;
1464 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1465 if (state[i1] ==
'G' || state[i1] ==
'g') {
1467 needYellowPhase =
true;
1471 if (needYellowPhase && brakingTime > 0) {
1472 logic->
addStep(brakingTime, state);
1487 if (allRedTime > 0) {
1489 std::string allRedState = state;
1490 for (
int i = 0; i < (int)state.size(); i++) {
1491 if (allRedState[i] ==
'Y' || allRedState[i] ==
'y') {
1492 allRedState[i] =
'r';
1502 int minCustomIndex = -1;
1503 int maxCustomIndex = -1;
1506 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1507 for (
auto crossing : c) {
1508 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1509 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1510 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1511 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1527 const int p = (int)logic->
getPhases().size();
1528 for (
int i1 = 0; i1 < n; ++i1) {
1530 for (
int i2 = 0; i2 < p; ++i2) {
1547 std::vector<bool> alwaysGreen(n,
true);
1548 for (
int i1 = 0; i1 < n; ++i1) {
1549 for (
const auto& phase : logic->
getPhases()) {
1550 if (phase.state[i1] !=
'G') {
1551 alwaysGreen[i1] =
false;
1556 const int p = (int)logic->
getPhases().size();
1557 for (
int i1 = 0; i1 < n; ++i1) {
1558 if (alwaysGreen[i1]) {
1559 for (
int i2 = 0; i2 < p; ++i2) {
1569 const int n = (int)fromEdges.size();
1570 const int p = (int)logic->
getPhases().size();
1571 for (
int i1 = 0; i1 < n; ++i1) {
1572 if (fromEdges[i1]->isInsideTLS()) {
1573 for (
int i2 = 0; i2 < p; ++i2) {
1583 const int n = (int)fromEdges.size();
1585 for (
int i1 = 0; i1 < n; ++i1) {
1586 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1587 for (
int i2 = 0; i2 < n; ++i2) {
1588 if (fromEdges[i2]->isInsideTLS()) {
1589 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1590 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1591 maxTime =
MAX2(maxTime, time);
1605 if (logic !=
nullptr) {
1623 int greenPhases = 0;
1624 for (
const auto& phase : tllDummy->
getPhases()) {
1625 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1631 controlledNode->removeTrafficLight(&dummy);
1633 return greenPhases <= 2;
1641 const std::vector<NBNode::Crossing*>& crossings,
1642 const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
1643 const std::vector<std::string>& straightStates,
1644 const std::vector<std::string>& leftStates) {
1645 if (chosenList.size() != 2) {
1657 const int totalNumLinks = (int)straightStates[0].size();
1659 std::vector<int> ring1({1, 2, 3, 4});
1660 std::vector<int> ring2({5, 6, 7, 8});
1661 std::vector<int> barrier1({4, 8});
1662 std::vector<int> barrier2({2, 6});
1663 int phaseNameLeft = 1;
1664 for (
int i = 0; i < (int)chosenList.size(); i++) {
1665 NBEdge* e1 = chosenList[i].first;
1666 assert(e1 !=
nullptr);
1667 NBEdge* e2 = chosenList[i].second;
1668 if (i < (
int)leftStates.size()) {
1669 std::string left1 =
filterState(leftStates[i], fromEdges, e1);
1671 logic->
addStep(dur, left1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft));
1674 if (e2 !=
nullptr) {
1675 std::string straight2 =
filterState(straightStates[i], fromEdges, e2);
1678 logic->
addStep(dur, straight2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 1));
1679 if (i < (
int)leftStates.size()) {
1680 std::string left2 =
filterState(leftStates[i], fromEdges, e2);
1682 logic->
addStep(dur, left2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 4));
1687 std::string straight1 =
filterState(straightStates[i], fromEdges, e1);
1688 if (straight1 ==
"") {
1693 logic->
addStep(dur, straight1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 5));
1696 std::map<int, int> names;
1697 for (
int i = 0; i < (int)logic->
getPhases().size(); i++) {
1705 if (ring1[0] == 0 && ring1[1] == 0) {
1708 if (ring1[2] == 0 && ring1[3] == 0) {
1711 fixDurationSum(logic, names, ring1[0], ring1[1], ring2[0], ring2[1]);
1712 fixDurationSum(logic, names, ring1[2], ring1[3], ring2[2], ring2[3]);
1724 bool haveGreen =
false;
1725 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1726 if (fromEdges[j] != e) {
1728 }
else if (state[j] !=
'r') {
1741 for (
int i = 0; i < (int)vec.size(); i++) {
1742 if (names.count(vec[i]) == 0) {
1744 if (names.count(vec[i] - 1) > 0) {
1745 vec[i] = vec[i] - 1;
1747 vec[i] = barrierDefault;
1758 std::set<int> ring1existing;
1759 std::set<int> ring2existing;
1760 if (names.count(ring1a) != 0) {
1761 ring1existing.insert(ring1a);
1763 if (names.count(ring1b) != 0) {
1764 ring1existing.insert(ring1b);
1766 if (names.count(ring2a) != 0) {
1767 ring2existing.insert(ring2a);
1769 if (names.count(ring2b) != 0) {
1770 ring2existing.insert(ring2b);
1772 if (ring1existing.size() > 0 && ring2existing.size() > 0 &&
1773 ring1existing.size() != ring2existing.size()) {
1775 if (ring1existing.size() < ring2existing.size()) {
1776 pI = names.find(*ring1existing.begin())->second;
1778 pI = names.find(*ring2existing.begin())->second;
1781 SUMOTime newMaxDur = 2 * p.maxDur + p.yellow + p.red;
#define WRITE_WARNINGF(...)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge.
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permissions is a forbidden edge.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_DELIVERY
vehicle is a small delivery vehicle
@ SVC_TRAM
vehicle is a light rail
@ SVC_PEDESTRIAN
pedestrian
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ PARTRIGHT
The link is a partial right direction.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
@ TRAFFIC_LIGHT_RIGHT_ON_RED
#define UNUSED_PARAMETER(x)
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 double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
NBEdge * getFrom() const
returns the from-edge (start of the connection)
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
The representation of a single edge during network building.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
const std::vector< Connection > & getConnections() const
Returns the connections.
NBNode * getToNode() const
Returns the destination node of the edge.
const std::string & getID() const
bool setControllingTLInformation(const NBConnection &c, const std::string &tlID)
Returns if the link could be set as to be controlled.
int getNumLanes() const
Returns the number of lanes.
std::vector< Connection > getConnectionsFromLane(int lane, const NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
int getJunctionPriority(const NBNode *const node) const
Returns the junction priority (normalised for the node currently build)
NBNode * getFromNode() const
Returns the origin node of the edge.
NBEdge * getTurnDestination(bool possibleDestination=false) const
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
A definition of a pedestrian crossing.
const NBNode * node
The parent node of this crossing.
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
bool mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Sorts edges by their priority within the node they end at.
A traffic light logics which must be computed (only nodes/edges are given)
void fixSuperfluousYellow(NBTrafficLightLogic *logic) const
avoid yellow signal between successive green (major) phases
std::string correctConflicting(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< int > &fromLanes, const std::vector< int > &toLanes, const std::vector< bool > &hadGreenMajor, bool &haveForbiddenLeftMover, std::vector< bool > &rightTurnConflicts, std::vector< bool > &mergeConflicts)
change 'G' to 'g' for conflicting connections
NBTrafficLightLogic * buildNemaPhases(const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< NBNode::Crossing * > &crossings, const std::vector< std::pair< NBEdge *, NBEdge * > > &chosenList, const std::vector< std::string > &straightStates, const std::vector< std::string > &leftStates)
void checkCustomCrossingIndices(NBTrafficLightLogic *logic) const
fix states in regard to custom crossing indices
static std::string patchStateForCrossings(const std::string &state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
compute phase state in regard to pedestrian crossings
std::string allowByVClass(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, SVCPermissions perm)
int getMaxIndex()
Returns the maximum index controlled by this traffic light.
bool myHaveSinglePhase
Whether left-mover should not have an additional phase.
bool corridorLike() const
test whether a joined tls with layout 'opposites' would be built without dedicated left-turn phase
SUMOTime computeEscapeTime(const std::string &state, const EdgeVector &fromEdges, const EdgeVector &toEdges) const
compute time to clear all vehicles from within an alternateOneWay layout
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane, bool incoming)
Replaces a removed edge/lane.
std::pair< NBEdge *, NBEdge * > getBestPair(EdgeVector &incoming)
Returns the combination of two edges from the given which has most unblocked streams.
void collectLinks()
Collects the links participating in this traffic light.
void deactivateAlwaysGreen(NBTrafficLightLogic *logic) const
switch of signal for links that are always green
static void addGreenWithin(NBTrafficLightLogic *logic, const EdgeVector &fromEdges, EdgeVector &toProc)
ensure inner edges all get the green light eventually
NBTrafficLightLogic * computeLogicAndConts(int brakingTimeSeconds, bool onlyConts=false)
helper function for myCompute
static bool hasCrossing(const NBEdge *from, const NBEdge *to, const std::vector< NBNode::Crossing * > &crossings)
compute whether the given connection is crossed by pedestrians
std::string allowPredecessors(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< int > &fromLanes, const std::vector< int > &toLanes)
void deactivateInsideEdges(NBTrafficLightLogic *logic, const EdgeVector &fromEdges) const
switch of signal for links that are inside a joined tls
double computeUnblockedWeightedStreamNumber(const NBEdge *const e1, const NBEdge *const e2)
Returns how many streams outgoing from the edges can pass the junction without being blocked.
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurrences of the removed edge in incoming/outgoing edges of all definitions.
int getToPrio(const NBEdge *const e)
Returns this edge's priority at the node it ends at.
std::string allowCompatible(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< int > &fromLanes, const std::vector< int > &toLanes)
allow connections that are compatible with the chosen edges
std::string correctMixed(std::string state, const EdgeVector &fromEdges, const std::vector< int > &fromLanes, bool &buildMixedGreenPhase, std::vector< bool > &mixedGreen)
prevent green and red from the same lane
void fixDurationSum(NBTrafficLightLogic *logic, const std::map< int, int > &names, int ring1a, int ring1b, int ring2a, int ring2b)
ensure that phase max durations before each barrier have the same sum in both rings
NBTrafficLightLogic * myCompute(int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
static std::string patchNEMAStateForCrossings(const std::string &state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges, const NBEdge *greenEdge, NBEdge *otherChosen)
std::string filterState(std::string state, const EdgeVector &fromEdges, const NBEdge *e)
mask out all greens that do not originate at the given edge
std::string allowFollowers(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges)
void buildAllRedState(SUMOTime allRedTime, NBTrafficLightLogic *logic, const std::string &state)
double getDirectionalWeight(LinkDirection dir)
Returns the weight of a stream given its direction.
std::string allowSingleEdge(std::string state, const EdgeVector &fromEdges)
bool hasStraightConnection(const NBEdge *fromEdge)
check whether there is a straight connection from this edge
std::pair< NBEdge *, NBEdge * > getBestCombination(const EdgeVector &edges)
Returns the combination of two edges from the given which has most unblocked streams.
void initNeedsContRelation() const
static void addPedestrianScramble(NBTrafficLightLogic *logic, int totalNumLinks, SUMOTime greenTime, SUMOTime yellowTime, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add an additional pedestrian phase if there are crossings that did not get green yet
NBOwnTLDef(const std::string &id, const std::vector< NBNode * > &junctions, SUMOTime offset, TrafficLightType type)
Constructor.
static EdgeVector getConnectedOuterEdges(const EdgeVector &incoming)
get edges that have connections
TrafficLightLayout myLayout
the layout for generated signal plans
bool forbidden(const std::string &state, int index, const EdgeVector &fromEdges, const EdgeVector &toEdges, bool allowCont)
whether the given index is forbidden by a green link in the current state
static std::string addPedestrianPhases(NBTrafficLightLogic *logic, const SUMOTime greenTime, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd, const SUMOTime latestEnd, std::string state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add 1 or 2 phases depending on the presence of pedestrian crossings
std::string allowUnrelated(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< NBNode::Crossing * > &crossings)
void filterMissingNames(std::vector< int > &vec, const std::map< int, int > &names, bool isBarrier, int barrierDefault=0)
keep only valid NEMA phase names (for params)
void setTLControllingInformation() const
Informs edges about being controlled by a tls.
static const double MIN_SPEED_CROSSING_TIME
minimum speed for computing time to cross intersection
The base class for traffic light logic definitions.
const std::string & getProgramID() const
Returns the ProgramID.
const EdgeVector & getIncomingEdges() const
Returns the list of incoming edges (must be build first)
bool needsCont(const NBEdge *fromE, const NBEdge *toE, const NBEdge *otherFromE, const NBEdge *otherToE) const
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
TrafficLightType getType() const
get the algorithm type (static etc..)
EdgeVector myIncomingEdges
The list of incoming edges.
NBTrafficLightLogic * compute(const OptionsCont &oc)
Computes the traffic light logic.
RightOnRedConflicts myRightOnRedConflicts
TrafficLightType myType
The algorithm type for the traffic light.
EdgeVector myEdgesWithin
The list of edges within the area controlled by the tls.
static const std::string DummyID
id for temporary definitions
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority, bool sameNodeOnly=false) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
NBConnectionVector myControlledLinks
The list of controlled links.
virtual void setType(TrafficLightType type)
set the algorithm type (static etc..)
bool myNeedsContRelationReady
virtual void setParticipantsInformation()
Builds the list of participating nodes/edges/links.
void collectAllLinks(NBConnectionVector &into)
helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
SUMOTime myOffset
The offset in the program.
static const SUMOTime UNSPECIFIED_DURATION
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
bool myRightOnRedConflictsReady
NeedsContRelation myNeedsContRelation
A SUMO-compliant built logic for a traffic light.
SUMOTime getDuration() const
Returns the duration of the complete cycle.
void closeBuilding(bool checkVarDurations=true)
closes the building process
void setPhaseDuration(int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by netedit)
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by netedit)
void setPhaseMaxDuration(int phaseIndex, SUMOTime duration)
Modifies the max duration for an existing phase (used by netedit)
int getNumLinks()
Returns the number of participating links.
void setType(TrafficLightType type)
set the algorithm type (static etc..)
void setPhaseNext(int phaseIndex, const std::vector< int > &next)
Modifies the next phase (used by netedit)
void setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
TrafficLightType getType() const
get the algorithm type (static etc..)
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
void addStep(const SUMOTime duration, const std::string &state, const std::vector< int > &next=std::vector< int >(), const std::string &name="", const int index=-1)
Adds a phase to the logic (static)
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
static StringBijection< TrafficLightLayout > TrafficLightLayouts
traffic light layouts
T get(const std::string &str) const
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
A structure which describes a connection between edges or lanes.
data structure for caching needsCont information