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));
309 std::vector<std::pair<NBEdge*, NBEdge*> > chosenList;
310 std::vector<std::string> straightStates;
311 std::vector<std::string> leftStates;
316 std::vector<bool> isTurnaround;
317 std::vector<bool> hasTurnLane;
318 std::vector<int> fromLanes;
319 std::vector<int> toLanes;
320 std::vector<SUMOTime> crossingTime;
321 int totalNumLinks = 0;
322 for (
NBEdge*
const fromEdge : incoming) {
323 const int numLanes = fromEdge->getNumLanes();
325 for (
int i2 = 0; i2 < numLanes; i2++) {
326 bool hasLeft =
false;
327 bool hasPartLeft =
false;
328 bool hasStraight =
false;
329 bool hasRight =
false;
330 bool hasTurnaround =
false;
332 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
335 fromEdges.push_back(fromEdge);
336 fromLanes.push_back(i2);
337 toLanes.push_back(approached.toLane);
338 toEdges.push_back(approached.toEdge);
339 if (approached.vmax < NUMERICAL_EPS || (fromEdge->getPermissions() &
SVC_PASSENGER) == 0
340 || (approached.toEdge->getPermissions() &
SVC_PASSENGER) == 0) {
341 crossingTime.push_back(0);
346 if (approached.toEdge !=
nullptr) {
347 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
349 isTurnaround.push_back(
true);
351 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
361 hasTurnaround =
true;
366 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
369 hasTurnLane.push_back(
370 (hasLeft && !hasPartLeft && !hasStraight && !hasRight)
371 || (hasPartLeft && !hasLeft && !hasStraight && !hasRight)
372 || (hasPartLeft && hasLeft && edgeHasStraight && !hasRight)
373 || (!hasLeft && !hasPartLeft && !hasTurnaround && hasRight));
379 std::vector<NBNode::Crossing*> crossings;
381 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
382 node->setCrossingTLIndices(
getID(), totalNumLinks, onlyConts);
384 copy(c.begin(), c.end(), std::back_inserter(crossings));
391 std::vector<int> greenPhases;
392 std::vector<bool> hadGreenMajor(totalNumLinks,
false);
393 while (toProc.size() > 0) {
394 bool groupTram =
false;
395 bool groupOther =
false;
396 std::pair<NBEdge*, NBEdge*> chosen;
397 std::set<const NBEdge*> chosenSet;
398 if (groupOpposites) {
399 if (incoming.size() == 2) {
402 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
405 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(
nullptr));
406 toProc.erase(toProc.begin());
412 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
414 for (
auto it = toProc.begin(); it != toProc.end();) {
415 if ((*it)->getPermissions() ==
SVC_TRAM) {
416 it = toProc.erase(it);
424 NBEdge* chosenEdge = toProc[0];
425 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge,
static_cast<NBEdge*
>(
nullptr));
426 toProc.erase(toProc.begin());
438 if (groupTram || groupOther) {
439 for (
auto it = toProc.begin(); it != toProc.end();) {
440 if ((*it)->getPermissions() == perms) {
441 it = toProc.erase(it);
449 std::string state(totalNumLinks,
'r');
455 chosenList.push_back(chosen);
456 chosenSet.insert(chosen.first);
457 if (chosen.second !=
nullptr) {
458 chosenSet.insert(chosen.second);
461 for (
const NBEdge* e : chosenSet) {
463 std::vector<NBEdge*> parallelBikeEdges;
464 for (
NBEdge* cand : toProc) {
466 double angle = fabs(
NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), cand->getAngleAtNode(cand->getToNode())));
469 parallelBikeEdges.push_back(cand);
473 for (
NBEdge* be : parallelBikeEdges) {
476 std::cout <<
" chosen=" << e->getID() <<
" be=" << be->getID() <<
"\n";
479 chosenSet.insert(be);
480 toProc.erase(std::find(toProc.begin(), toProc.end(), be));
486 bool haveGreen =
false;
487 for (
const NBEdge*
const fromEdge : incoming) {
488 const bool inChosen = chosenSet.count(fromEdge) != 0;
489 const int numLanes = fromEdge->getNumLanes();
490 for (
int i2 = 0; i2 < numLanes; i2++) {
492 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
498 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
512 std::cout <<
" state after plain straight movers " << state <<
"\n";
517 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
520 std::cout <<
" state after allowing compatible " << state <<
"\n";
525 }
else if (groupOther) {
530 std::cout <<
" state after grouping by vClass " << state <<
" (groupTram=" << groupTram <<
" groupOther=" << groupOther <<
")\n";
534 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
538 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
543 bool haveForbiddenLeftMover =
false;
544 std::vector<bool> rightTurnConflicts(pos,
false);
545 std::vector<bool> mergeConflicts(pos,
false);
546 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
547 for (
int i1 = 0; i1 < pos; ++i1) {
548 if (state[i1] ==
'G') {
549 hadGreenMajor[i1] =
true;
554 std::cout <<
" state after correcting left movers=" << state <<
"\n";
558 std::vector<bool> leftGreen(pos,
false);
560 bool foundLeftTurnLane =
false;
561 for (
int i1 = 0; i1 < pos; ++i1) {
562 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1] && hasTurnLane[i1]) {
563 foundLeftTurnLane =
true;
566 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
567 && groupOpposites && !groupTram && !groupOther);
570 for (
int i1 = 0; i1 < pos; ++i1) {
571 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1]
573 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
574 leftGreen[i1] =
true;
575 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
576 if (buildLeftGreenPhase) {
579 }
else if (!isTurnaround[i1]) {
580 WRITE_WARNINGF(
TL(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing."),
581 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
589 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
590 <<
" \nrtC=" <<
toString(rightTurnConflicts)
591 <<
" \nmC=" <<
toString(mergeConflicts)
592 <<
" \nhTL=" <<
toString(hasTurnLane)
597 straightStates.push_back(state);
599 const std::string vehicleState = state;
600 greenPhases.push_back((
int)logic->
getPhases().size());
603 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
605 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
608 bool tramExclusive =
true;
609 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
610 if (state[i1] ==
'G') {
611 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
613 tramExclusive =
false;
624 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, earliestEnd, latestEnd, state, crossings, fromEdges, toEdges);
626 for (
int i1 = pos; i1 < (int)state.size(); ++i1) {
629 if (brakingTime > 0) {
632 for (
int i1 = 0; i1 < pos; ++i1) {
633 if (state[i1] !=
'G' && state[i1] !=
'g') {
636 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
637 && buildLeftGreenPhase
638 && !rightTurnConflicts[i1]
639 && !mergeConflicts[i1]
644 maxCross =
MAX2(maxCross, crossingTime[i1]);
647 logic->
addStep(brakingTime, state);
649 if (!buildLeftGreenPhase) {
658 if (buildLeftGreenPhase) {
660 for (
int i1 = 0; i1 < pos; ++i1) {
661 if (state[i1] ==
'Y' || state[i1] ==
'y') {
669 leftStates.push_back(state);
670 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
671 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
672 bool buildMixedGreenPhase =
false;
673 std::vector<bool> mixedGreen(pos,
false);
674 const std::string oldState = state;
676 state =
correctMixed(state, fromEdges, fromLanes, buildMixedGreenPhase, mixedGreen);
678 if (state != oldState) {
679 for (
int i1 = 0; i1 < pos; ++i1) {
680 if (mixedGreen[i1]) {
682 int yellowIndex = (int)logic->
getPhases().size() - 1;
683 if (allRedTime > 0) {
686 if (brakingTime > 0) {
691 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
695 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
698 if (brakingTime > 0) {
700 for (
int i1 = 0; i1 < pos; ++i1) {
701 if (state[i1] !=
'G' && state[i1] !=
'g') {
705 maxCross =
MAX2(maxCross, crossingTime[i1]);
708 logic->
addStep(brakingTime, state);
713 if (buildMixedGreenPhase) {
719 for (
int i1 = 0; i1 < pos; ++i1) {
720 if (state[i1] ==
'Y' || state[i1] ==
'y') {
724 if (mixedGreen[i1]) {
728 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
729 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
732 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
735 if (brakingTime > 0) {
737 for (
int i1 = 0; i1 < pos; ++i1) {
738 if (state[i1] !=
'G' && state[i1] !=
'g') {
742 maxCross =
MAX2(maxCross, crossingTime[i1]);
745 logic->
addStep(brakingTime, state);
752 std::string& s = straightStates.back();
753 std::string leftState = s;
754 for (
int ii = 0; ii < pos; ++ii) {
756 NBEdge* fromEdge = fromEdges[ii];
757 NBEdge* toEdge = toEdges[ii];
767 leftStates.push_back(leftState);
770 if (
myEdgesWithin.size() > 0 && !isNEMA && toProc.size() == 0 && !onlyConts) {
775 if (crossings.size() > 0) {
779 if (logic->
getPhases().size() == 2 && brakingTime > 0
782 logic->
addStep(redTime, std::string(totalNumLinks,
'r'));
791 if (nemaLogic ==
nullptr) {
792 WRITE_WARNINGF(
TL(
"Generating NEMA phases is not supported 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] == prevState[i1] || nextState[i1] ==
'G') && (prevState[i1] ==
'g' || prevState[i1] ==
'G')) {
852 std::cout <<
getID() <<
" state of phase index " << i <<
" was patched due to yellow in between green\n";
865 if (totalDuration > 0) {
866 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime) && !isNEMA &&
getID() !=
DummyID) {
881 for (
auto c : crossings) {
885 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
886 const NBEdge* edge = *it_e;
887 if (edge == from || edge == to) {
900 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
905 const std::string orig = state;
909 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
911 const SUMOTime pedTime = greenTime - pedClearingTime;
912 if (pedTime >= minPedTime) {
916 if (isSimpleActuatedCrossing) {
920 logic->
addStep(pedTime, state, minDur, maxDur, earliestEnd, latestEnd);
923 std::cout <<
" intermidate state for addPedestrianPhases " << state <<
"\n";
926 for (
auto cross : crossings) {
927 if (cross->tlLinkIndex >= (
int)fromEdges.size() || fromEdges[cross->tlLinkIndex] ==
nullptr) {
928 state[cross->tlLinkIndex] =
'r';
930 if (cross->tlLinkIndex2 >= 0 && (cross->tlLinkIndex2 >= (
int)fromEdges.size() || fromEdges[cross->tlLinkIndex2] ==
nullptr)) {
931 state[cross->tlLinkIndex2] =
'r';
934 logic->
addStep(pedClearingTime, state);
938 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
943 std::cout <<
" state after addPedestrianPhases " << state <<
"\n";
952 std::string result = state;
955 for (
int i2 = 0; i2 < (int)fromEdges.size() && !
isForbidden; ++i2) {
957 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross->node) {
958 for (EdgeVector::const_iterator it = cross->edges.begin(); it != cross->edges.end(); ++it) {
960 const LinkDirection i2dir = cross->node->getDirection(fromEdges[i2], toEdges[i2]);
961 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
969 const int i1 = cross->tlLinkIndex;
970 assert(i1 >= 0 && i1 < (
int)result.size());
972 if (i1 < (
int)toEdges.size() && toEdges[i1] !=
nullptr && (result[i1] != newState || !
isForbidden)) {
974 WRITE_WARNINGF(
TL(
"Custom crossing linkIndex % conflicts with vehicular connections at tlLogic '%'"), i1, cross->tlID);
977 result[i1] = newState;
979 if (cross->tlLinkIndex2 >= 0) {
980 const int i2 = cross->tlLinkIndex2;
981 if (i2 < (
int)toEdges.size() && toEdges[i2] !=
nullptr && (result[i2] != newState || !
isForbidden)) {
983 WRITE_WARNINGF(
TL(
"Custom crossing linkIndex2 % conflicts with vehicular connections at tlLogic '%'"), i2, cross->tlID);
986 result[i2] = newState;
992 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
993 if (result[i1] ==
'G') {
995 const int i2 = cross->tlLinkIndex;
996 const int i3 = cross->tlLinkIndex2;
997 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == cross->node) {
998 if ((result[i2] ==
'G' || (i3 >= 0 && result[i3] ==
'G'))
999 && cross->node->mustBrakeForCrossing(fromEdges[i1], toEdges[i1], *cross)) {
1013 const std::vector<NBNode::Crossing*>& crossings,
1017 std::string result = state;
1018 const int pos = (int)(state.size() - crossings.size());
1020 EdgeVector::const_iterator start = std::find(all.begin(), all.end(), greenEdge);
1023 const NBEdge* endEdge =
nullptr;
1024 for (
int i = 0; i < (int)state.size(); i++) {
1025 if (state[i] ==
'G' && fromEdges[i] == greenEdge
1028 endEdge = toEdges[i];
1032 if (endEdge ==
nullptr) {
1033 endEdge = otherChosen;
1035 if (endEdge ==
nullptr) {
1039 if ((*itCW)->getFromNode() == greenEdge->
getToNode()) {
1043 if (endEdge ==
nullptr) {
1045 endEdge = greenEdge;
1049 EdgeVector::const_iterator end = std::find(all.begin(), all.end(), endEdge);
1050 if (end == all.end()) {
1057 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1058 const int i1 = pos + ic;
1062 if (crossed == *it) {
1070 for (
int i1 = 0; i1 < pos; ++i1) {
1071 if (result[i1] ==
'G') {
1072 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1074 const int i2 = pos + ic;
1112 NBEdge* ,
int ,
bool ) {}
1127 n->removeTrafficLight(&dummy);
1129#ifdef DEBUG_CONTRELATION
1131 std::cout <<
" contRelations at " <<
getID() <<
" prog=" <<
getProgramID() <<
":\n";
1133 std::cout <<
" " << s.from1->
getID() <<
"->" << s.to1->getID() <<
" foe " << s.from2->getID() <<
"->" << s.to2->getID() <<
"\n";
1147 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
1148 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
1149 it = result.erase(it);
1160 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1164 std::cout <<
" state after allowSingle " << state <<
"\n";
1171 std::cout <<
" state after allowFollowers " << state <<
"\n";
1177 std::cout <<
" state after allowPredecessors " << state <<
"\n";
1188 const int size = (int)fromEdges.size();
1189 NBEdge* greenEdge =
nullptr;
1190 for (
int i1 = 0; i1 < size; ++i1) {
1191 if (state[i1] ==
'G') {
1192 if (greenEdge ==
nullptr) {
1193 greenEdge = fromEdges[i1];
1194 }
else if (greenEdge != fromEdges[i1]) {
1199 if (greenEdge !=
nullptr) {
1200 for (
int i1 = 0; i1 < size; ++i1) {
1201 if (fromEdges[i1] == greenEdge) {
1216 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1217 if (state[i1] ==
'G') {
1220 if (
forbidden(state, i1, fromEdges, toEdges,
true)) {
1223 bool followsChosen =
false;
1224 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1225 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
1226 followsChosen =
true;
1230 if (followsChosen) {
1242 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1248 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1249 if (state[i1] ==
'G') {
1252 if (
forbidden(state, i1, fromEdges, toEdges,
false)) {
1255 bool preceedsChosen =
false;
1256 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1257 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
1258 && fromLanes[i2] == toLanes[i1]) {
1259 preceedsChosen =
true;
1263 if (preceedsChosen) {
1275 const std::vector<bool>& isTurnaround,
1276 const std::vector<NBNode::Crossing*>& crossings) {
1277 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1278 if (state[i1] ==
'G') {
1282 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1283 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1284 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1299 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1300 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1301 if ((linkPerm & ~perm) == 0) {
1311 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1312 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1314 !
needsCont(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index]) &&
1315 !
needsCont(fromEdges[index], toEdges[index], fromEdges[i2], toEdges[i2]))) {
1326 const std::vector<bool>& isTurnaround,
1327 const std::vector<int>& fromLanes,
1328 const std::vector<int>& toLanes,
1329 const std::vector<bool>& hadGreenMajor,
1330 bool& haveForbiddenLeftMover,
1331 std::vector<bool>& rightTurnConflicts,
1332 std::vector<bool>& mergeConflicts) {
1334 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1335 if (state[i1] ==
'G') {
1336 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1337 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1339 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1340 rightTurnConflicts[i1] =
true;
1342 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1346#ifdef DEBUG_CONTRELATION
1348 std::cout <<
getID() <<
" p=" <<
getProgramID() <<
" contRel: " << fromEdges[i1]->getID() <<
"->" << toEdges[i1]->getID()
1349 <<
" foe " << fromEdges[i2]->getID() <<
"->" << toEdges[i2]->getID() <<
"\n";
1353 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1354 haveForbiddenLeftMover =
true;
1356 }
else if (fromEdges[i1] == fromEdges[i2]
1357 && fromLanes[i1] != fromLanes[i2]
1358 && toEdges[i1] == toEdges[i2]
1359 && toLanes[i1] == toLanes[i2]
1360 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1361 mergeConflicts[i1] =
true;
1367 if (state[i1] ==
'r') {
1369 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1372 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1373 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1374 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1375 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1376 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1383 if (state[i1] ==
's') {
1385 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1386 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1387 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1388 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1402 const std::vector<int>& fromLanes,
1403 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1404 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1405 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1406 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1407 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1408 && state[i2] !=
'G' && state[i2] !=
'g') {
1409 state[i1] = state[i2];
1411 mixedGreen[i1] =
true;
1412 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1413 buildMixedGreenPhase =
true;
1425 std::vector<bool> foundGreen(fromEdges.size(),
false);
1426 for (
const auto& phase : logic->
getPhases()) {
1427 const std::string state = phase.state;
1428 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1431 foundGreen[j] =
true;
1435 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1436 if (!foundGreen[j]) {
1437 NBEdge* e = fromEdges[j];
1438 if (std::find(toProc.begin(), toProc.end(), e) == toProc.end()) {
1439 toProc.push_back(e);
1448 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1450 std::vector<bool> foundGreen(crossings.size() * 2,
false);
1451 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1452 for (
int i = 0; i < (int)phases.size(); i++) {
1453 const std::string state = phases[i].state;
1455 for (
auto cross : crossings) {
1457 LinkState ls2 = cross->tlLinkIndex2 >= 0 ? (
LinkState)state[cross->tlLinkIndex2] : ls;
1459 foundGreen[j] =
true;
1462 foundGreen[j + crossings.size()] =
true;
1469 std::cout <<
" foundCrossingGreen=" <<
toString(foundGreen) <<
"\n";
1472 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1473 if (!foundGreen[j]) {
1475 if (phases.size() > 0) {
1476 bool needYellowPhase =
false;
1477 std::string state = phases.back().state;
1478 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1479 if (state[i1] ==
'G' || state[i1] ==
'g') {
1481 needYellowPhase =
true;
1485 if (needYellowPhase && brakingTime > 0) {
1486 logic->
addStep(brakingTime, state);
1501 if (allRedTime > 0) {
1503 std::string allRedState = state;
1504 for (
int i = 0; i < (int)state.size(); i++) {
1505 if (allRedState[i] ==
'Y' || allRedState[i] ==
'y') {
1506 allRedState[i] =
'r';
1518 result =
MAX2(result, crossing->tlLinkIndex);
1519 result =
MAX2(result, crossing->tlLinkIndex2);
1528 const int p = (int)logic->
getPhases().size();
1529 for (
int i1 = 0; i1 < n; ++i1) {
1531 for (
int i2 = 0; i2 < p; ++i2) {
1548 std::vector<bool> alwaysGreen(n,
true);
1549 for (
int i1 = 0; i1 < n; ++i1) {
1550 for (
const auto& phase : logic->
getPhases()) {
1551 if (phase.state[i1] !=
'G') {
1552 alwaysGreen[i1] =
false;
1557 const int p = (int)logic->
getPhases().size();
1558 for (
int i1 = 0; i1 < n; ++i1) {
1559 if (alwaysGreen[i1]) {
1560 for (
int i2 = 0; i2 < p; ++i2) {
1570 const int n = (int)fromEdges.size();
1571 const int p = (int)logic->
getPhases().size();
1572 for (
int i1 = 0; i1 < n; ++i1) {
1573 if (fromEdges[i1]->isInsideTLS()) {
1574 for (
int i2 = 0; i2 < p; ++i2) {
1584 const int n = (int)fromEdges.size();
1586 for (
int i1 = 0; i1 < n; ++i1) {
1587 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1588 for (
int i2 = 0; i2 < n; ++i2) {
1589 if (fromEdges[i2]->isInsideTLS()) {
1590 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1591 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1592 maxTime =
MAX2(maxTime, time);
1606 if (logic !=
nullptr) {
1621 std::vector<bool> edgeInsideTLS;
1623 edgeInsideTLS.push_back(e->isInsideTLS());
1629 int greenPhases = 0;
1630 for (
const auto& phase : tllDummy->
getPhases()) {
1631 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1637 controlledNode->removeTrafficLight(&dummy);
1641 e->setInsideTLS(edgeInsideTLS[i]);
1644 return greenPhases <= 2;
1652 const std::vector<NBNode::Crossing*>& crossings,
1653 const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
1654 const std::vector<std::string>& straightStates,
1655 const std::vector<std::string>& leftStates) {
1656 if (chosenList.size() != 2) {
1668 const int totalNumLinks = (int)straightStates[0].size();
1670 std::vector<int> ring1({1, 2, 3, 4});
1671 std::vector<int> ring2({5, 6, 7, 8});
1672 std::vector<int> barrier1({4, 8});
1673 std::vector<int> barrier2({2, 6});
1674 int phaseNameLeft = 1;
1675 for (
int i = 0; i < (int)chosenList.size(); i++) {
1676 NBEdge* e1 = chosenList[i].first;
1677 assert(e1 !=
nullptr);
1678 NBEdge* e2 = chosenList[i].second;
1679 if (i < (
int)leftStates.size()) {
1680 std::string left1 =
filterState(leftStates[i], fromEdges, e1);
1682 logic->
addStep(dur, left1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft));
1685 if (e2 !=
nullptr) {
1686 std::string straight2 =
filterState(straightStates[i], fromEdges, e2);
1689 logic->
addStep(dur, straight2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 1));
1690 if (i < (
int)leftStates.size()) {
1691 std::string left2 =
filterState(leftStates[i], fromEdges, e2);
1693 logic->
addStep(dur, left2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 4));
1698 std::string straight1 =
filterState(straightStates[i], fromEdges, e1);
1699 if (straight1 ==
"") {
1704 logic->
addStep(dur, straight1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 5));
1707 std::map<int, int> names;
1708 for (
int i = 0; i < (int)logic->
getPhases().size(); i++) {
1716 if (ring1[0] == 0 && ring1[1] == 0) {
1719 if (ring1[2] == 0 && ring1[3] == 0) {
1722 fixDurationSum(logic, names, ring1[0], ring1[1], ring2[0], ring2[1]);
1723 fixDurationSum(logic, names, ring1[2], ring1[3], ring2[2], ring2[3]);
1735 bool haveGreen =
false;
1736 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1737 if (fromEdges[j] != e) {
1739 }
else if (state[j] !=
'r') {
1752 for (
int i = 0; i < (int)vec.size(); i++) {
1753 if (names.count(vec[i]) == 0) {
1755 if (names.count(vec[i] - 1) > 0) {
1756 vec[i] = vec[i] - 1;
1758 vec[i] = barrierDefault;
1769 std::set<int> ring1existing;
1770 std::set<int> ring2existing;
1771 if (names.count(ring1a) != 0) {
1772 ring1existing.insert(ring1a);
1774 if (names.count(ring1b) != 0) {
1775 ring1existing.insert(ring1b);
1777 if (names.count(ring2a) != 0) {
1778 ring2existing.insert(ring2a);
1780 if (names.count(ring2b) != 0) {
1781 ring2existing.insert(ring2b);
1783 if (ring1existing.size() > 0 && ring2existing.size() > 0 &&
1784 ring1existing.size() != ring2existing.size()) {
1786 if (ring1existing.size() < ring2existing.size()) {
1787 pI = names.find(*ring1existing.begin())->second;
1789 pI = names.find(*ring2existing.begin())->second;
1792 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 (exclusive) 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
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.
std::vector< Crossing * > getCrossings() const
return this junctions pedestrian crossings
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)
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)
int maxCrossingIndex(const NBNode *node) const
find maximum crossing index
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.
ExtraConflicts myExtraConflicts
NBTrafficLightLogic * compute(const OptionsCont &oc)
Computes the traffic light logic.
bool myExtraConflictsReady
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.
NeedsContRelation myNeedsContRelation
virtual void collectEdges()
Build the list of participating edges.
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)
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
get key
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
#define UNUSED_PARAMETER(x)
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