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());
430 if (groupTram || groupOther) {
431 for (
auto it = toProc.begin(); it != toProc.end();) {
432 if ((*it)->getPermissions() == perms) {
433 it = toProc.erase(it);
441 std::string state(totalNumLinks,
'r');
447 chosenList.push_back(chosen);
448 chosenSet.insert(chosen.first);
449 if (chosen.second !=
nullptr) {
450 chosenSet.insert(chosen.second);
453 for (
const NBEdge* e : chosenSet) {
455 std::vector<NBEdge*> parallelBikeEdges;
456 for (
NBEdge* cand : toProc) {
458 double angle = fabs(
NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), cand->getAngleAtNode(cand->getToNode())));
461 parallelBikeEdges.push_back(cand);
465 for (
NBEdge* be : parallelBikeEdges) {
468 std::cout <<
" chosen=" << e->getID() <<
" be=" << be->getID() <<
"\n";
471 chosenSet.insert(be);
472 toProc.erase(std::find(toProc.begin(), toProc.end(), be));
478 bool haveGreen =
false;
479 for (
const NBEdge*
const fromEdge : incoming) {
480 const bool inChosen = chosenSet.count(fromEdge) != 0;
481 const int numLanes = fromEdge->getNumLanes();
482 for (
int i2 = 0; i2 < numLanes; i2++) {
484 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
490 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
504 std::cout <<
" state after plain straight movers " << state <<
"\n";
509 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
512 std::cout <<
" state after allowing compatible " << state <<
"\n";
517 }
else if (groupOther) {
522 std::cout <<
" state after grouping by vClass " << state <<
" (groupTram=" << groupTram <<
" groupOther=" << groupOther <<
")\n";
526 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
530 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
535 bool haveForbiddenLeftMover =
false;
536 std::vector<bool> rightTurnConflicts(pos,
false);
537 std::vector<bool> mergeConflicts(pos,
false);
538 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
539 for (
int i1 = 0; i1 < pos; ++i1) {
540 if (state[i1] ==
'G') {
541 hadGreenMajor[i1] =
true;
546 std::cout <<
" state after correcting left movers=" << state <<
"\n";
550 std::vector<bool> leftGreen(pos,
false);
552 bool foundLeftTurnLane =
false;
553 for (
int i1 = 0; i1 < pos; ++i1) {
554 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1] && hasTurnLane[i1]) {
555 foundLeftTurnLane =
true;
558 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
559 && groupOpposites && !groupTram && !groupOther);
562 for (
int i1 = 0; i1 < pos; ++i1) {
563 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1]
565 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
566 leftGreen[i1] =
true;
567 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
568 if (buildLeftGreenPhase) {
571 }
else if (!isTurnaround[i1]) {
572 WRITE_WARNINGF(
TL(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing."),
573 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
581 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
582 <<
" \nrtC=" <<
toString(rightTurnConflicts)
583 <<
" \nmC=" <<
toString(mergeConflicts)
584 <<
" \nhTL=" <<
toString(hasTurnLane)
589 straightStates.push_back(state);
591 const std::string vehicleState = state;
592 greenPhases.push_back((
int)logic->
getPhases().size());
595 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
597 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
600 bool tramExclusive =
true;
601 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
602 if (state[i1] ==
'G') {
603 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
605 tramExclusive =
false;
616 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, earliestEnd, latestEnd, state, crossings, fromEdges, toEdges);
618 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
621 if (brakingTime > 0) {
624 for (
int i1 = 0; i1 < pos; ++i1) {
625 if (state[i1] !=
'G' && state[i1] !=
'g') {
628 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
629 && buildLeftGreenPhase
630 && !rightTurnConflicts[i1]
631 && !mergeConflicts[i1]
636 maxCross =
MAX2(maxCross, crossingTime[i1]);
639 logic->
addStep(brakingTime, state);
641 if (!buildLeftGreenPhase) {
650 if (buildLeftGreenPhase) {
652 for (
int i1 = 0; i1 < pos; ++i1) {
653 if (state[i1] ==
'Y' || state[i1] ==
'y') {
661 leftStates.push_back(state);
662 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
663 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
664 bool buildMixedGreenPhase =
false;
665 std::vector<bool> mixedGreen(pos,
false);
666 const std::string oldState = state;
668 state =
correctMixed(state, fromEdges, fromLanes, buildMixedGreenPhase, mixedGreen);
670 if (state != oldState) {
671 for (
int i1 = 0; i1 < pos; ++i1) {
672 if (mixedGreen[i1]) {
674 int yellowIndex = (int)logic->
getPhases().size() - 1;
675 if (allRedTime > 0) {
678 if (brakingTime > 0) {
683 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
687 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
690 if (brakingTime > 0) {
692 for (
int i1 = 0; i1 < pos; ++i1) {
693 if (state[i1] !=
'G' && state[i1] !=
'g') {
697 maxCross =
MAX2(maxCross, crossingTime[i1]);
700 logic->
addStep(brakingTime, state);
705 if (buildMixedGreenPhase) {
711 for (
int i1 = 0; i1 < pos; ++i1) {
712 if (state[i1] ==
'Y' || state[i1] ==
'y') {
716 if (mixedGreen[i1]) {
720 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
721 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
724 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
727 if (brakingTime > 0) {
729 for (
int i1 = 0; i1 < pos; ++i1) {
730 if (state[i1] !=
'G' && state[i1] !=
'g') {
734 maxCross =
MAX2(maxCross, crossingTime[i1]);
737 logic->
addStep(brakingTime, state);
744 std::string& s = straightStates.back();
745 std::string leftState = s;
746 for (
int ii = 0; ii < pos; ++ii) {
748 NBEdge* fromEdge = fromEdges[ii];
749 NBEdge* toEdge = toEdges[ii];
759 leftStates.push_back(leftState);
762 if (
myEdgesWithin.size() > 0 && !isNEMA && toProc.size() == 0) {
767 if (crossings.size() > 0) {
771 if (logic->
getPhases().size() == 2 && brakingTime > 0
774 logic->
addStep(redTime, std::string(totalNumLinks,
'r'));
777 if (crossings.size() > 0 && !onlyConts) {
787 if (nemaLogic ==
nullptr) {
788 WRITE_WARNINGF(
TL(
"Generating NEMA phases is not support for traffic light '%' with % incoming edges. Using tlType 'actuated' as fallback"),
getID(), incoming.size());
803 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
805 minGreenDuration =
MIN2(minGreenDuration, dur);
807 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / (double)greenPhases.size());
808 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
812 || greenPhases.size() == 0) {
818 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
821 if (greenPhases.size() > 0) {
829 const std::vector<NBTrafficLightLogic::PhaseDefinition>& allPhases = logic->
getPhases();
830 const int phaseCount = (int)allPhases.size();
832 for (
int i = 0; i < phaseCount; ++i) {
833 std::string currState = allPhases[i].state;
834 const int prevIndex = (i == 0) ? phaseCount - 1 : i - 1;
835 const std::string prevState = allPhases[prevIndex].state;
836 const std::string nextState = allPhases[(i + 1) % phaseCount].state;
837 bool updatedState =
false;
838 for (
int i1 = 0; i1 < stateSize; ++i1) {
839 if (currState[i1] ==
'y' && (nextState[i1] ==
'g' || nextState[i1] ==
'G') && (prevState[i1] ==
'g' || prevState[i1] ==
'G')) {
849 std::cout <<
getID() <<
" state of phase index " << i <<
" was patched due to yellow in between green\n";
860 if (totalDuration > 0) {
861 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime) && !isNEMA) {
876 for (
auto c : crossings) {
880 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
881 const NBEdge* edge = *it_e;
882 if (edge == from || edge == to) {
895 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
900 const std::string orig = state;
904 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
906 const SUMOTime pedTime = greenTime - pedClearingTime;
907 if (pedTime >= minPedTime) {
909 const int pedStates = (int)crossings.size();
910 logic->
addStep(pedTime, state, minDur, maxDur, earliestEnd, latestEnd);
913 std::cout <<
" intermidate state for addPedestrianPhases " << state <<
"\n";
916 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
917 logic->
addStep(pedClearingTime, state);
921 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
926 std::cout <<
" state after addPedestrianPhases " << state <<
"\n";
935 std::string result = state;
936 const int pos = (int)(state.size() - crossings.size());
937 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
938 const int i1 = pos + ic;
943 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
944 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
947 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
963 for (
int i1 = 0; i1 < pos; ++i1) {
964 if (result[i1] ==
'G') {
965 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
967 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
968 const int i2 = pos + ic;
983 const std::vector<NBNode::Crossing*>& crossings,
987 std::string result = state;
988 const int pos = (int)(state.size() - crossings.size());
990 EdgeVector::const_iterator start = std::find(all.begin(), all.end(), greenEdge);
993 const NBEdge* endEdge =
nullptr;
994 for (
int i = 0; i < (int)state.size(); i++) {
995 if (state[i] ==
'G' && fromEdges[i] == greenEdge
998 endEdge = toEdges[i];
1002 if (endEdge ==
nullptr) {
1003 endEdge = otherChosen;
1005 if (endEdge ==
nullptr) {
1009 if ((*itCW)->getFromNode() == greenEdge->
getToNode()) {
1013 if (endEdge ==
nullptr) {
1015 endEdge = greenEdge;
1019 EdgeVector::const_iterator end = std::find(all.begin(), all.end(), endEdge);
1020 if (end == all.end()) {
1027 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1028 const int i1 = pos + ic;
1032 if (crossed == *it) {
1040 for (
int i1 = 0; i1 < pos; ++i1) {
1041 if (result[i1] ==
'G') {
1042 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1044 const int i2 = pos + ic;
1082 NBEdge* ,
int ,
bool ) {}
1090 std::vector<bool> edgeInsideTLS;
1092 edgeInsideTLS.push_back(e->isInsideTLS());
1102 n->removeTrafficLight(&dummy);
1107 e->setInsideTLS(edgeInsideTLS[i]);
1111#ifdef DEBUG_CONTRELATION
1113 std::cout <<
" contRelations at " <<
getID() <<
" prog=" <<
getProgramID() <<
":\n";
1115 std::cout <<
" " << s.from1->
getID() <<
"->" << s.to1->getID() <<
" foe " << s.from2->getID() <<
"->" << s.to2->getID() <<
"\n";
1129 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
1130 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
1131 it = result.erase(it);
1142 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1146 std::cout <<
" state after allowSingle " << state <<
"\n";
1153 std::cout <<
" state after allowFollowers " << state <<
"\n";
1159 std::cout <<
" state after allowPredecessors " << state <<
"\n";
1170 const int size = (int)fromEdges.size();
1171 NBEdge* greenEdge =
nullptr;
1172 for (
int i1 = 0; i1 < size; ++i1) {
1173 if (state[i1] ==
'G') {
1174 if (greenEdge ==
nullptr) {
1175 greenEdge = fromEdges[i1];
1176 }
else if (greenEdge != fromEdges[i1]) {
1181 if (greenEdge !=
nullptr) {
1182 for (
int i1 = 0; i1 < size; ++i1) {
1183 if (fromEdges[i1] == greenEdge) {
1198 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1199 if (state[i1] ==
'G') {
1202 if (
forbidden(state, i1, fromEdges, toEdges,
true)) {
1205 bool followsChosen =
false;
1206 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1207 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
1208 followsChosen =
true;
1212 if (followsChosen) {
1224 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1230 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1231 if (state[i1] ==
'G') {
1234 if (
forbidden(state, i1, fromEdges, toEdges,
false)) {
1237 bool preceedsChosen =
false;
1238 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1239 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
1240 && fromLanes[i2] == toLanes[i1]) {
1241 preceedsChosen =
true;
1245 if (preceedsChosen) {
1257 const std::vector<bool>& isTurnaround,
1258 const std::vector<NBNode::Crossing*>& crossings) {
1259 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1260 if (state[i1] ==
'G') {
1264 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1265 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1266 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1281 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1282 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1283 if ((linkPerm & ~perm) == 0) {
1293 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1294 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1296 !
needsCont(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index]) &&
1297 !
needsCont(fromEdges[index], toEdges[index], fromEdges[i2], toEdges[i2]))) {
1308 const std::vector<bool>& isTurnaround,
1309 const std::vector<int>& fromLanes,
1310 const std::vector<int>& toLanes,
1311 const std::vector<bool>& hadGreenMajor,
1312 bool& haveForbiddenLeftMover,
1313 std::vector<bool>& rightTurnConflicts,
1314 std::vector<bool>& mergeConflicts) {
1316 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1317 if (state[i1] ==
'G') {
1318 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1319 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1321 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1322 rightTurnConflicts[i1] =
true;
1324 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1328#ifdef DEBUG_CONTRELATION
1330 std::cout <<
getID() <<
" p=" <<
getProgramID() <<
" contRel: " << fromEdges[i1]->getID() <<
"->" << toEdges[i1]->getID()
1331 <<
" foe " << fromEdges[i2]->getID() <<
"->" << toEdges[i2]->getID() <<
"\n";
1335 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1336 haveForbiddenLeftMover =
true;
1338 }
else if (fromEdges[i1] == fromEdges[i2]
1339 && fromLanes[i1] != fromLanes[i2]
1340 && toEdges[i1] == toEdges[i2]
1341 && toLanes[i1] == toLanes[i2]
1342 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1343 mergeConflicts[i1] =
true;
1349 if (state[i1] ==
'r') {
1351 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1354 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1355 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1356 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1357 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1358 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1365 if (state[i1] ==
's') {
1367 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1368 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1369 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1370 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1384 const std::vector<int>& fromLanes,
1385 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1386 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1387 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1388 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1389 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1390 && state[i2] !=
'G' && state[i2] !=
'g') {
1391 state[i1] = state[i2];
1393 mixedGreen[i1] =
true;
1394 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1395 buildMixedGreenPhase =
true;
1407 std::vector<bool> foundGreen(fromEdges.size(),
false);
1408 for (
const auto& phase : logic->
getPhases()) {
1409 const std::string state = phase.state;
1410 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1413 foundGreen[j] =
true;
1417 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1418 if (!foundGreen[j]) {
1419 NBEdge* e = fromEdges[j];
1420 if (std::find(toProc.begin(), toProc.end(), e) == toProc.end()) {
1421 toProc.push_back(e);
1430 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1431 const int vehLinks = totalNumLinks - (int)crossings.size();
1432 std::vector<bool> foundGreen(crossings.size(),
false);
1433 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1434 for (
int i = 0; i < (int)phases.size(); i++) {
1435 const std::string state = phases[i].state;
1436 for (
int j = 0; j < (int)crossings.size(); j++) {
1439 foundGreen[j] =
true;
1445 std::cout <<
" foundCrossingGreen=" <<
toString(foundGreen) <<
"\n";
1448 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1449 if (!foundGreen[j]) {
1451 if (phases.size() > 0) {
1452 bool needYellowPhase =
false;
1453 std::string state = phases.back().state;
1454 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1455 if (state[i1] ==
'G' || state[i1] ==
'g') {
1457 needYellowPhase =
true;
1461 if (needYellowPhase && brakingTime > 0) {
1462 logic->
addStep(brakingTime, state);
1477 if (allRedTime > 0) {
1479 std::string allRedState = state;
1480 for (
int i = 0; i < (int)state.size(); i++) {
1481 if (allRedState[i] ==
'Y' || allRedState[i] ==
'y') {
1482 allRedState[i] =
'r';
1492 int minCustomIndex = -1;
1493 int maxCustomIndex = -1;
1496 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1497 for (
auto crossing : c) {
1498 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1499 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1500 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1501 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1517 const int p = (int)logic->
getPhases().size();
1518 for (
int i1 = 0; i1 < n; ++i1) {
1520 for (
int i2 = 0; i2 < p; ++i2) {
1537 std::vector<bool> alwaysGreen(n,
true);
1538 for (
int i1 = 0; i1 < n; ++i1) {
1539 for (
const auto& phase : logic->
getPhases()) {
1540 if (phase.state[i1] !=
'G') {
1541 alwaysGreen[i1] =
false;
1546 const int p = (int)logic->
getPhases().size();
1547 for (
int i1 = 0; i1 < n; ++i1) {
1548 if (alwaysGreen[i1]) {
1549 for (
int i2 = 0; i2 < p; ++i2) {
1559 const int n = (int)fromEdges.size();
1560 const int p = (int)logic->
getPhases().size();
1561 for (
int i1 = 0; i1 < n; ++i1) {
1562 if (fromEdges[i1]->isInsideTLS()) {
1563 for (
int i2 = 0; i2 < p; ++i2) {
1573 const int n = (int)fromEdges.size();
1575 for (
int i1 = 0; i1 < n; ++i1) {
1576 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1577 for (
int i2 = 0; i2 < n; ++i2) {
1578 if (fromEdges[i2]->isInsideTLS()) {
1579 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1580 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1581 maxTime =
MAX2(maxTime, time);
1595 if (logic !=
nullptr) {
1613 int greenPhases = 0;
1614 for (
const auto& phase : tllDummy->
getPhases()) {
1615 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1621 controlledNode->removeTrafficLight(&dummy);
1623 return greenPhases <= 2;
1631 const std::vector<NBNode::Crossing*>& crossings,
1632 const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
1633 const std::vector<std::string>& straightStates,
1634 const std::vector<std::string>& leftStates) {
1635 if (chosenList.size() != 2) {
1647 const int totalNumLinks = (int)straightStates[0].size();
1649 std::vector<int> ring1({1, 2, 3, 4});
1650 std::vector<int> ring2({5, 6, 7, 8});
1651 std::vector<int> barrier1({4, 8});
1652 std::vector<int> barrier2({2, 6});
1653 int phaseNameLeft = 1;
1654 for (
int i = 0; i < (int)chosenList.size(); i++) {
1655 NBEdge* e1 = chosenList[i].first;
1656 assert(e1 !=
nullptr);
1657 NBEdge* e2 = chosenList[i].second;
1658 if (i < (
int)leftStates.size()) {
1659 std::string left1 =
filterState(leftStates[i], fromEdges, e1);
1661 logic->
addStep(dur, left1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft));
1664 if (e2 !=
nullptr) {
1665 std::string straight2 =
filterState(straightStates[i], fromEdges, e2);
1668 logic->
addStep(dur, straight2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 1));
1669 if (i < (
int)leftStates.size()) {
1670 std::string left2 =
filterState(leftStates[i], fromEdges, e2);
1672 logic->
addStep(dur, left2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 4));
1677 std::string straight1 =
filterState(straightStates[i], fromEdges, e1);
1678 if (straight1 ==
"") {
1683 logic->
addStep(dur, straight1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 5));
1686 std::map<int, int> names;
1687 for (
int i = 0; i < (int)logic->
getPhases().size(); i++) {
1695 if (ring1[0] == 0 && ring1[1] == 0) {
1698 if (ring1[2] == 0 && ring1[3] == 0) {
1701 fixDurationSum(logic, names, ring1[0], ring1[1], ring2[0], ring2[1]);
1702 fixDurationSum(logic, names, ring1[2], ring1[3], ring2[2], ring2[3]);
1714 bool haveGreen =
false;
1715 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1716 if (fromEdges[j] != e) {
1718 }
else if (state[j] !=
'r') {
1731 for (
int i = 0; i < (int)vec.size(); i++) {
1732 if (names.count(vec[i]) == 0) {
1734 if (names.count(vec[i] - 1) > 0) {
1735 vec[i] = vec[i] - 1;
1737 vec[i] = barrierDefault;
1748 std::set<int> ring1existing;
1749 std::set<int> ring2existing;
1750 if (names.count(ring1a) != 0) {
1751 ring1existing.insert(ring1a);
1753 if (names.count(ring1b) != 0) {
1754 ring1existing.insert(ring1b);
1756 if (names.count(ring2a) != 0) {
1757 ring2existing.insert(ring2a);
1759 if (names.count(ring2b) != 0) {
1760 ring2existing.insert(ring2b);
1762 if (ring1existing.size() > 0 && ring2existing.size() > 0 &&
1763 ring1existing.size() != ring2existing.size()) {
1765 if (ring1existing.size() < ring2existing.size()) {
1766 pI = names.find(*ring1existing.begin())->second;
1768 pI = names.find(*ring2existing.begin())->second;
1771 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 setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
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