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 assert(fromEdges.size() <= result.size());
993 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
994 if (result[i1] ==
'G') {
996 const int i2 = cross->tlLinkIndex;
997 const int i3 = cross->tlLinkIndex2;
998 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == cross->node) {
999 if ((result[i2] ==
'G' || (i3 >= 0 && result[i3] ==
'G'))
1000 && cross->node->mustBrakeForCrossing(fromEdges[i1], toEdges[i1], *cross)) {
1014 const std::vector<NBNode::Crossing*>& crossings,
1018 std::string result = state;
1019 const int pos = (int)(state.size() - crossings.size());
1021 EdgeVector::const_iterator start = std::find(all.begin(), all.end(), greenEdge);
1024 const NBEdge* endEdge =
nullptr;
1025 for (
int i = 0; i < (int)state.size(); i++) {
1026 if (state[i] ==
'G' && fromEdges[i] == greenEdge
1029 endEdge = toEdges[i];
1033 if (endEdge ==
nullptr) {
1034 endEdge = otherChosen;
1036 if (endEdge ==
nullptr) {
1040 if ((*itCW)->getFromNode() == greenEdge->
getToNode()) {
1044 if (endEdge ==
nullptr) {
1046 endEdge = greenEdge;
1050 EdgeVector::const_iterator end = std::find(all.begin(), all.end(), endEdge);
1051 if (end == all.end()) {
1058 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1059 const int i1 = pos + ic;
1063 if (crossed == *it) {
1071 for (
int i1 = 0; i1 < pos; ++i1) {
1072 if (result[i1] ==
'G') {
1073 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1075 const int i2 = pos + ic;
1113 NBEdge* ,
int ,
bool ) {}
1128 n->removeTrafficLight(&dummy);
1130#ifdef DEBUG_CONTRELATION
1132 std::cout <<
" contRelations at " <<
getID() <<
" prog=" <<
getProgramID() <<
":\n";
1134 std::cout <<
" " << s.from1->
getID() <<
"->" << s.to1->getID() <<
" foe " << s.from2->getID() <<
"->" << s.to2->getID() <<
"\n";
1148 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
1149 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
1150 it = result.erase(it);
1161 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1165 std::cout <<
" state after allowSingle " << state <<
"\n";
1172 std::cout <<
" state after allowFollowers " << state <<
"\n";
1178 std::cout <<
" state after allowPredecessors " << state <<
"\n";
1189 const int size = (int)fromEdges.size();
1190 NBEdge* greenEdge =
nullptr;
1191 for (
int i1 = 0; i1 < size; ++i1) {
1192 if (state[i1] ==
'G') {
1193 if (greenEdge ==
nullptr) {
1194 greenEdge = fromEdges[i1];
1195 }
else if (greenEdge != fromEdges[i1]) {
1200 if (greenEdge !=
nullptr) {
1201 for (
int i1 = 0; i1 < size; ++i1) {
1202 if (fromEdges[i1] == greenEdge) {
1217 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1218 if (state[i1] ==
'G') {
1221 if (
forbidden(state, i1, fromEdges, toEdges,
true)) {
1224 bool followsChosen =
false;
1225 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1226 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
1227 followsChosen =
true;
1231 if (followsChosen) {
1243 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1249 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1250 if (state[i1] ==
'G') {
1253 if (
forbidden(state, i1, fromEdges, toEdges,
false)) {
1256 bool preceedsChosen =
false;
1257 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1258 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
1259 && fromLanes[i2] == toLanes[i1]) {
1260 preceedsChosen =
true;
1264 if (preceedsChosen) {
1276 const std::vector<bool>& isTurnaround,
1277 const std::vector<NBNode::Crossing*>& crossings) {
1278 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1279 if (state[i1] ==
'G') {
1283 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1284 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1285 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1300 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1301 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1302 if ((linkPerm & ~perm) == 0) {
1312 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1313 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1315 !
needsCont(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index]) &&
1316 !
needsCont(fromEdges[index], toEdges[index], fromEdges[i2], toEdges[i2]))) {
1327 const std::vector<bool>& isTurnaround,
1328 const std::vector<int>& fromLanes,
1329 const std::vector<int>& toLanes,
1330 const std::vector<bool>& hadGreenMajor,
1331 bool& haveForbiddenLeftMover,
1332 std::vector<bool>& rightTurnConflicts,
1333 std::vector<bool>& mergeConflicts) {
1335 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1336 if (state[i1] ==
'G') {
1337 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1338 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1340 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1341 rightTurnConflicts[i1] =
true;
1343 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1347#ifdef DEBUG_CONTRELATION
1349 std::cout <<
getID() <<
" p=" <<
getProgramID() <<
" contRel: " << fromEdges[i1]->getID() <<
"->" << toEdges[i1]->getID()
1350 <<
" foe " << fromEdges[i2]->getID() <<
"->" << toEdges[i2]->getID() <<
"\n";
1354 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1355 haveForbiddenLeftMover =
true;
1357 }
else if (fromEdges[i1] == fromEdges[i2]
1358 && fromLanes[i1] != fromLanes[i2]
1359 && toEdges[i1] == toEdges[i2]
1360 && toLanes[i1] == toLanes[i2]
1361 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1362 mergeConflicts[i1] =
true;
1368 if (state[i1] ==
'r') {
1370 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1373 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1374 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1375 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1376 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1377 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1384 if (state[i1] ==
's') {
1386 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1387 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1388 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1389 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1403 const std::vector<int>& fromLanes,
1404 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1405 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1406 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1407 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1408 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1409 && state[i2] !=
'G' && state[i2] !=
'g') {
1410 state[i1] = state[i2];
1412 mixedGreen[i1] =
true;
1413 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1414 buildMixedGreenPhase =
true;
1426 std::vector<bool> foundGreen(fromEdges.size(),
false);
1427 for (
const auto& phase : logic->
getPhases()) {
1428 const std::string state = phase.state;
1429 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1432 foundGreen[j] =
true;
1436 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1437 if (!foundGreen[j]) {
1438 NBEdge* e = fromEdges[j];
1439 if (std::find(toProc.begin(), toProc.end(), e) == toProc.end()) {
1440 toProc.push_back(e);
1449 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1451 std::vector<bool> foundGreen(crossings.size() * 2,
false);
1452 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1453 for (
int i = 0; i < (int)phases.size(); i++) {
1454 const std::string state = phases[i].state;
1456 for (
auto cross : crossings) {
1458 LinkState ls2 = cross->tlLinkIndex2 >= 0 ? (
LinkState)state[cross->tlLinkIndex2] : ls;
1460 foundGreen[j] =
true;
1463 foundGreen[j + crossings.size()] =
true;
1470 std::cout <<
" foundCrossingGreen=" <<
toString(foundGreen) <<
"\n";
1473 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1474 if (!foundGreen[j]) {
1476 if (phases.size() > 0) {
1477 bool needYellowPhase =
false;
1478 std::string state = phases.back().state;
1479 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1480 if (state[i1] ==
'G' || state[i1] ==
'g') {
1482 needYellowPhase =
true;
1486 if (needYellowPhase && brakingTime > 0) {
1487 logic->
addStep(brakingTime, state);
1502 if (allRedTime > 0) {
1504 std::string allRedState = state;
1505 for (
int i = 0; i < (int)state.size(); i++) {
1506 if (allRedState[i] ==
'Y' || allRedState[i] ==
'y') {
1507 allRedState[i] =
'r';
1519 result =
MAX2(result, crossing->tlLinkIndex);
1520 result =
MAX2(result, crossing->tlLinkIndex2);
1529 const int p = (int)logic->
getPhases().size();
1530 for (
int i1 = 0; i1 < n; ++i1) {
1532 for (
int i2 = 0; i2 < p; ++i2) {
1549 std::vector<bool> alwaysGreen(n,
true);
1550 for (
int i1 = 0; i1 < n; ++i1) {
1551 for (
const auto& phase : logic->
getPhases()) {
1552 if (phase.state[i1] !=
'G') {
1553 alwaysGreen[i1] =
false;
1558 const int p = (int)logic->
getPhases().size();
1559 for (
int i1 = 0; i1 < n; ++i1) {
1560 if (alwaysGreen[i1]) {
1561 for (
int i2 = 0; i2 < p; ++i2) {
1571 const int n = (int)fromEdges.size();
1572 const int p = (int)logic->
getPhases().size();
1573 for (
int i1 = 0; i1 < n; ++i1) {
1574 if (fromEdges[i1]->isInsideTLS()) {
1575 for (
int i2 = 0; i2 < p; ++i2) {
1585 const int n = (int)fromEdges.size();
1587 for (
int i1 = 0; i1 < n; ++i1) {
1588 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1589 for (
int i2 = 0; i2 < n; ++i2) {
1590 if (fromEdges[i2]->isInsideTLS()) {
1591 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1592 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1593 maxTime =
MAX2(maxTime, time);
1607 if (logic !=
nullptr) {
1622 std::vector<bool> edgeInsideTLS;
1624 edgeInsideTLS.push_back(e->isInsideTLS());
1630 int greenPhases = 0;
1631 for (
const auto& phase : tllDummy->
getPhases()) {
1632 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1638 controlledNode->removeTrafficLight(&dummy);
1642 e->setInsideTLS(edgeInsideTLS[i]);
1645 return greenPhases <= 2;
1653 const std::vector<NBNode::Crossing*>& crossings,
1654 const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
1655 const std::vector<std::string>& straightStates,
1656 const std::vector<std::string>& leftStates) {
1657 if (chosenList.size() != 2) {
1669 const int totalNumLinks = (int)straightStates[0].size();
1671 std::vector<int> ring1({1, 2, 3, 4});
1672 std::vector<int> ring2({5, 6, 7, 8});
1673 std::vector<int> barrier1({4, 8});
1674 std::vector<int> barrier2({2, 6});
1675 int phaseNameLeft = 1;
1676 for (
int i = 0; i < (int)chosenList.size(); i++) {
1677 NBEdge* e1 = chosenList[i].first;
1678 assert(e1 !=
nullptr);
1679 NBEdge* e2 = chosenList[i].second;
1680 if (i < (
int)leftStates.size()) {
1681 std::string left1 =
filterState(leftStates[i], fromEdges, e1);
1683 logic->
addStep(dur, left1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft));
1686 if (e2 !=
nullptr) {
1687 std::string straight2 =
filterState(straightStates[i], fromEdges, e2);
1690 logic->
addStep(dur, straight2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 1));
1691 if (i < (
int)leftStates.size()) {
1692 std::string left2 =
filterState(leftStates[i], fromEdges, e2);
1694 logic->
addStep(dur, left2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 4));
1699 std::string straight1 =
filterState(straightStates[i], fromEdges, e1);
1700 if (straight1 ==
"") {
1705 logic->
addStep(dur, straight1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 5));
1708 std::map<int, int> names;
1709 for (
int i = 0; i < (int)logic->
getPhases().size(); i++) {
1717 if (ring1[0] == 0 && ring1[1] == 0) {
1720 if (ring1[2] == 0 && ring1[3] == 0) {
1723 fixDurationSum(logic, names, ring1[0], ring1[1], ring2[0], ring2[1]);
1724 fixDurationSum(logic, names, ring1[2], ring1[3], ring2[2], ring2[3]);
1736 bool haveGreen =
false;
1737 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1738 if (fromEdges[j] != e) {
1740 }
else if (state[j] !=
'r') {
1753 for (
int i = 0; i < (int)vec.size(); i++) {
1754 if (names.count(vec[i]) == 0) {
1756 if (names.count(vec[i] - 1) > 0) {
1757 vec[i] = vec[i] - 1;
1759 vec[i] = barrierDefault;
1770 std::set<int> ring1existing;
1771 std::set<int> ring2existing;
1772 if (names.count(ring1a) != 0) {
1773 ring1existing.insert(ring1a);
1775 if (names.count(ring1b) != 0) {
1776 ring1existing.insert(ring1b);
1778 if (names.count(ring2a) != 0) {
1779 ring2existing.insert(ring2a);
1781 if (names.count(ring2b) != 0) {
1782 ring2existing.insert(ring2b);
1784 if (ring1existing.size() > 0 && ring2existing.size() > 0 &&
1785 ring1existing.size() != ring2existing.size()) {
1787 if (ring1existing.size() < ring2existing.size()) {
1788 pI = names.find(*ring1existing.begin())->second;
1790 pI = names.find(*ring2existing.begin())->second;
1793 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