39 #define HEIGH_WEIGHT 2
40 #define LOW_WEIGHT .5;
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";
184 std::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
223 std::pair<NBEdge*, NBEdge*>
225 if (incoming.size() == 1) {
227 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(),
static_cast<NBEdge*
>(
nullptr));
235 used.push_back(*incoming.begin());
238 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
242 if (used.size() < 2) {
246 #ifdef DEBUG_STREAM_ORDERING
252 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
253 if (ret.second !=
nullptr) {
254 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
292 std::vector<std::pair<NBEdge*, NBEdge*> > chosenList;
293 std::vector<std::string> straightStates;
294 std::vector<std::string> leftStates;
299 std::vector<bool> isTurnaround;
300 std::vector<bool> hasTurnLane;
301 std::vector<int> fromLanes;
302 std::vector<int> toLanes;
303 std::vector<SUMOTime> crossingTime;
304 int totalNumLinks = 0;
305 for (
NBEdge*
const fromEdge : incoming) {
306 const int numLanes = fromEdge->getNumLanes();
308 for (
int i2 = 0; i2 < numLanes; i2++) {
309 bool hasLeft =
false;
310 bool hasPartLeft =
false;
311 bool hasStraight =
false;
312 bool hasRight =
false;
313 bool hasTurnaround =
false;
315 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
318 fromEdges.push_back(fromEdge);
319 fromLanes.push_back(i2);
320 toLanes.push_back(approached.toLane);
321 toEdges.push_back(approached.toEdge);
322 if (approached.vmax < NUMERICAL_EPS || (fromEdge->getPermissions() &
SVC_PASSENGER) == 0
323 || (approached.toEdge->getPermissions() &
SVC_PASSENGER) == 0) {
324 crossingTime.push_back(0);
329 if (approached.toEdge !=
nullptr) {
330 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
332 isTurnaround.push_back(
true);
334 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
344 hasTurnaround =
true;
349 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
352 hasTurnLane.push_back(
353 (hasLeft && !hasPartLeft && !hasStraight && !hasRight)
354 || (hasPartLeft && !hasLeft && !hasStraight && !hasRight)
355 || (hasPartLeft && hasLeft && edgeHasStraight && !hasRight)
356 || (!hasLeft && !hasPartLeft && !hasTurnaround && hasRight));
362 std::vector<NBNode::Crossing*> crossings;
364 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
367 node->setCrossingTLIndices(
getID(), totalNumLinks);
369 copy(c.begin(), c.end(), std::back_inserter(crossings));
370 totalNumLinks += (int)c.size();
387 std::vector<int> greenPhases;
388 std::vector<bool> hadGreenMajor(totalNumLinks,
false);
389 while (toProc.size() > 0) {
390 bool groupTram =
false;
391 bool groupOther =
false;
392 std::pair<NBEdge*, NBEdge*> chosen;
393 std::set<const NBEdge*> chosenSet;
394 if (groupOpposites) {
395 if (incoming.size() == 2) {
398 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
401 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(
nullptr));
402 toProc.erase(toProc.begin());
408 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
410 for (
auto it = toProc.begin(); it != toProc.end();) {
411 if ((*it)->getPermissions() ==
SVC_TRAM) {
412 it = toProc.erase(it);
420 NBEdge* chosenEdge = toProc[0];
421 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge,
static_cast<NBEdge*
>(
nullptr));
422 toProc.erase(toProc.begin());
430 if (groupTram || groupOther) {
431 for (
auto it = toProc.begin(); it != toProc.end();) {
432 if ((*it)->getPermissions() == perms) {
433 it = toProc.erase(it);
441 std::string state(totalNumLinks,
'r');
447 chosenList.push_back(chosen);
448 chosenSet.insert(chosen.first);
449 if (chosen.second !=
nullptr) {
450 chosenSet.insert(chosen.second);
453 for (
const NBEdge* e : chosenSet) {
455 std::vector<NBEdge*> parallelBikeEdges;
456 for (
NBEdge* cand : toProc) {
458 double angle = fabs(
NBHelpers::relAngle(e->getAngleAtNode(e->getToNode()), cand->getAngleAtNode(cand->getToNode())));
461 parallelBikeEdges.push_back(cand);
465 for (
NBEdge* be : parallelBikeEdges) {
468 std::cout <<
" chosen=" << e->getID() <<
" be=" << be->getID() <<
"\n";
471 chosenSet.insert(be);
472 toProc.erase(std::find(toProc.begin(), toProc.end(), be));
478 bool haveGreen =
false;
479 for (
const NBEdge*
const fromEdge : incoming) {
480 const bool inChosen = chosenSet.count(fromEdge) != 0;
481 const int numLanes = fromEdge->getNumLanes();
482 for (
int i2 = 0; i2 < numLanes; i2++) {
484 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
490 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
504 std::cout <<
" state after plain straight movers " << state <<
"\n";
509 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
512 std::cout <<
" state after allowing compatible " << state <<
"\n";
517 }
else if (groupOther) {
522 std::cout <<
" state after grouping by vClass " << state <<
" (groupTram=" << groupTram <<
" groupOther=" << groupOther <<
")\n";
526 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
530 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
535 bool haveForbiddenLeftMover =
false;
536 std::vector<bool> rightTurnConflicts(pos,
false);
537 std::vector<bool> mergeConflicts(pos,
false);
538 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
539 for (
int i1 = 0; i1 < pos; ++i1) {
540 if (state[i1] ==
'G') {
541 hadGreenMajor[i1] =
true;
546 std::cout <<
" state after correcting left movers=" << state <<
"\n";
550 std::vector<bool> leftGreen(pos,
false);
552 bool foundLeftTurnLane =
false;
553 for (
int i1 = 0; i1 < pos; ++i1) {
554 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1] && hasTurnLane[i1]) {
555 foundLeftTurnLane =
true;
558 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
559 && groupOpposites && !groupTram && !groupOther);
562 for (
int i1 = 0; i1 < pos; ++i1) {
563 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1]
565 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
566 leftGreen[i1] =
true;
567 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
568 if (buildLeftGreenPhase) {
571 }
else if (!isTurnaround[i1]) {
572 WRITE_WARNINGF(
TL(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing."),
573 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
581 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
582 <<
" \nrtC=" <<
toString(rightTurnConflicts)
583 <<
" \nmC=" <<
toString(mergeConflicts)
584 <<
" \nhTL=" <<
toString(hasTurnLane)
589 straightStates.push_back(state);
591 const std::string vehicleState = state;
592 greenPhases.push_back((
int)logic->
getPhases().size());
595 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
597 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
600 bool tramExclusive =
true;
601 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
602 if (state[i1] ==
'G') {
603 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
605 tramExclusive =
false;
616 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, earliestEnd, latestEnd, state, crossings, fromEdges, toEdges);
618 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
621 if (brakingTime > 0) {
624 for (
int i1 = 0; i1 < pos; ++i1) {
625 if (state[i1] !=
'G' && state[i1] !=
'g') {
628 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
629 && buildLeftGreenPhase
630 && !rightTurnConflicts[i1]
631 && !mergeConflicts[i1]
636 maxCross =
MAX2(maxCross, crossingTime[i1]);
639 logic->
addStep(brakingTime, state);
641 if (!buildLeftGreenPhase) {
650 if (buildLeftGreenPhase) {
652 for (
int i1 = 0; i1 < pos; ++i1) {
653 if (state[i1] ==
'Y' || state[i1] ==
'y') {
661 leftStates.push_back(state);
662 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
663 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
664 bool buildMixedGreenPhase =
false;
665 std::vector<bool> mixedGreen(pos,
false);
666 const std::string oldState = state;
668 state =
correctMixed(state, fromEdges, fromLanes, buildMixedGreenPhase, mixedGreen);
670 if (state != oldState) {
671 for (
int i1 = 0; i1 < pos; ++i1) {
672 if (mixedGreen[i1]) {
674 int yellowIndex = (int)logic->
getPhases().size() - 1;
675 if (allRedTime > 0) {
678 if (brakingTime > 0) {
683 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
687 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
690 if (brakingTime > 0) {
692 for (
int i1 = 0; i1 < pos; ++i1) {
693 if (state[i1] !=
'G' && state[i1] !=
'g') {
697 maxCross =
MAX2(maxCross, crossingTime[i1]);
700 logic->
addStep(brakingTime, state);
705 if (buildMixedGreenPhase) {
711 for (
int i1 = 0; i1 < pos; ++i1) {
712 if (state[i1] ==
'Y' || state[i1] ==
'y') {
716 if (mixedGreen[i1]) {
720 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
721 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
724 logic->
addStep(leftTurnTime, state, minDur, maxDur, earliestEnd, latestEnd);
727 if (brakingTime > 0) {
729 for (
int i1 = 0; i1 < pos; ++i1) {
730 if (state[i1] !=
'G' && state[i1] !=
'g') {
734 maxCross =
MAX2(maxCross, crossingTime[i1]);
737 logic->
addStep(brakingTime, state);
744 std::string& s = straightStates.back();
745 std::string leftState = s;
746 for (
int ii = 0; ii < pos; ++ii) {
748 NBEdge* fromEdge = fromEdges[ii];
749 NBEdge* toEdge = toEdges[ii];
759 leftStates.push_back(leftState);
762 if (
myEdgesWithin.size() > 0 && !isNEMA && toProc.size() == 0) {
767 if (crossings.size() > 0) {
771 if (logic->
getPhases().size() == 2 && brakingTime > 0
774 logic->
addStep(redTime, std::string(totalNumLinks,
'r'));
777 if (crossings.size() > 0 && !onlyConts) {
787 if (nemaLogic ==
nullptr) {
788 WRITE_WARNINGF(
TL(
"Generating NEMA phases is not support for traffic light '%' with % incoming edges. Using tlType 'actuated' as fallback"),
getID(), incoming.size());
803 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
805 minGreenDuration =
MIN2(minGreenDuration, dur);
807 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / (double)greenPhases.size());
808 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
812 || greenPhases.size() == 0) {
818 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
821 if (greenPhases.size() > 0) {
829 const std::vector<NBTrafficLightLogic::PhaseDefinition>& allPhases = logic->
getPhases();
830 const int phaseCount = (int)allPhases.size();
832 for (
int i = 0; i < phaseCount; ++i) {
833 std::string currState = allPhases[i].state;
834 const int prevIndex = (i == 0) ? phaseCount - 1 : i - 1;
835 const std::string prevState = allPhases[prevIndex].state;
836 const std::string nextState = allPhases[(i + 1) % phaseCount].state;
837 bool updatedState =
false;
838 for (
int i1 = 0; i1 < stateSize; ++i1) {
839 if (currState[i1] ==
'y' && (nextState[i1] ==
'g' || nextState[i1] ==
'G') && (prevState[i1] ==
'g' || prevState[i1] ==
'G')) {
849 std::cout <<
getID() <<
" state of phase index " << i <<
" was patched due to yellow in between green\n";
860 if (totalDuration > 0) {
861 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime) && !isNEMA) {
876 for (
auto c : crossings) {
880 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
881 const NBEdge* edge = *it_e;
882 if (edge == from || edge == to) {
895 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
900 const std::string orig = state;
904 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
906 const SUMOTime pedTime = greenTime - pedClearingTime;
907 if (pedTime >= minPedTime) {
909 const int pedStates = (int)crossings.size();
910 logic->
addStep(pedTime, state, minDur, maxDur, earliestEnd, latestEnd);
913 std::cout <<
" intermidate state for addPedestrianPhases " << state <<
"\n";
916 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
917 logic->
addStep(pedClearingTime, state);
921 logic->
addStep(greenTime, state, minDur, maxDur, earliestEnd, latestEnd);
926 std::cout <<
" state after addPedestrianPhases " << state <<
"\n";
935 std::string result = state;
936 const int pos = (int)(state.size() - crossings.size());
937 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
938 const int i1 = pos + ic;
943 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
944 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
947 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
963 for (
int i1 = 0; i1 < pos; ++i1) {
964 if (result[i1] ==
'G') {
965 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
967 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
968 const int i2 = pos + ic;
983 const std::vector<NBNode::Crossing*>& crossings,
987 std::string result = state;
988 const int pos = (int)(state.size() - crossings.size());
990 EdgeVector::const_iterator start = std::find(all.begin(), all.end(), greenEdge);
993 const NBEdge* endEdge =
nullptr;
994 for (
int i = 0; i < (int)state.size(); i++) {
995 if (state[i] ==
'G' && fromEdges[i] == greenEdge
998 endEdge = toEdges[i];
1002 if (endEdge ==
nullptr) {
1003 endEdge = otherChosen;
1005 if (endEdge ==
nullptr) {
1009 if ((*itCW)->getFromNode() == greenEdge->
getToNode()) {
1013 if (endEdge ==
nullptr) {
1015 endEdge = greenEdge;
1019 EdgeVector::const_iterator end = std::find(all.begin(), all.end(), endEdge);
1023 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1024 const int i1 = pos + ic;
1028 if (crossed == *it) {
1036 for (
int i1 = 0; i1 < pos; ++i1) {
1037 if (result[i1] ==
'G') {
1038 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
1040 const int i2 = pos + ic;
1078 NBEdge* ,
int ,
bool ) {}
1086 std::vector<bool> edgeInsideTLS;
1088 edgeInsideTLS.push_back(e->isInsideTLS());
1098 n->removeTrafficLight(&dummy);
1103 e->setInsideTLS(edgeInsideTLS[i]);
1107 #ifdef DEBUG_CONTRELATION
1109 std::cout <<
" contRelations at " <<
getID() <<
" prog=" <<
getProgramID() <<
":\n";
1111 std::cout <<
" " << s.from1->getID() <<
"->" << s.to1->getID() <<
" foe " << s.from2->getID() <<
"->" << s.to2->getID() <<
"\n";
1125 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
1126 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
1127 it = result.erase(it);
1138 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1142 std::cout <<
" state after allowSingle " << state <<
"\n";
1149 std::cout <<
" state after allowFollowers " << state <<
"\n";
1155 std::cout <<
" state after allowPredecessors " << state <<
"\n";
1166 const int size = (int)fromEdges.size();
1167 NBEdge* greenEdge =
nullptr;
1168 for (
int i1 = 0; i1 < size; ++i1) {
1169 if (state[i1] ==
'G') {
1170 if (greenEdge ==
nullptr) {
1171 greenEdge = fromEdges[i1];
1172 }
else if (greenEdge != fromEdges[i1]) {
1177 if (greenEdge !=
nullptr) {
1178 for (
int i1 = 0; i1 < size; ++i1) {
1179 if (fromEdges[i1] == greenEdge) {
1194 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1195 if (state[i1] ==
'G') {
1198 if (
forbidden(state, i1, fromEdges, toEdges,
true)) {
1201 bool followsChosen =
false;
1202 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1203 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
1204 followsChosen =
true;
1208 if (followsChosen) {
1220 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
1226 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1227 if (state[i1] ==
'G') {
1230 if (
forbidden(state, i1, fromEdges, toEdges,
false)) {
1233 bool preceedsChosen =
false;
1234 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1235 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
1236 && fromLanes[i2] == toLanes[i1]) {
1237 preceedsChosen =
true;
1241 if (preceedsChosen) {
1253 const std::vector<bool>& isTurnaround,
1254 const std::vector<NBNode::Crossing*>& crossings) {
1255 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1256 if (state[i1] ==
'G') {
1260 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1261 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1262 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1277 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1278 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1279 if ((linkPerm & ~perm) == 0) {
1289 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1290 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1292 !
needsCont(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index]) &&
1293 !
needsCont(fromEdges[index], toEdges[index], fromEdges[i2], toEdges[i2]))) {
1304 const std::vector<bool>& isTurnaround,
1305 const std::vector<int>& fromLanes,
1306 const std::vector<int>& toLanes,
1307 const std::vector<bool>& hadGreenMajor,
1308 bool& haveForbiddenLeftMover,
1309 std::vector<bool>& rightTurnConflicts,
1310 std::vector<bool>& mergeConflicts) {
1312 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1313 if (state[i1] ==
'G') {
1314 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1315 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1317 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1318 rightTurnConflicts[i1] =
true;
1320 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1324 #ifdef DEBUG_CONTRELATION
1326 std::cout <<
getID() <<
" p=" <<
getProgramID() <<
" contRel: " << fromEdges[i1]->getID() <<
"->" << toEdges[i1]->getID()
1327 <<
" foe " << fromEdges[i2]->getID() <<
"->" << toEdges[i2]->getID() <<
"\n";
1331 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1332 haveForbiddenLeftMover =
true;
1334 }
else if (fromEdges[i1] == fromEdges[i2]
1335 && fromLanes[i1] != fromLanes[i2]
1336 && toEdges[i1] == toEdges[i2]
1337 && toLanes[i1] == toLanes[i2]
1338 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1339 mergeConflicts[i1] =
true;
1345 if (state[i1] ==
'r') {
1347 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1350 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1351 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1352 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1353 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1354 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1361 if (state[i1] ==
's') {
1363 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1364 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1365 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1366 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1380 const std::vector<int>& fromLanes,
1381 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1382 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1383 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1384 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1385 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1386 && state[i2] !=
'G' && state[i2] !=
'g') {
1387 state[i1] = state[i2];
1389 mixedGreen[i1] =
true;
1390 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1391 buildMixedGreenPhase =
true;
1403 std::vector<bool> foundGreen(fromEdges.size(),
false);
1404 for (
const auto& phase : logic->
getPhases()) {
1405 const std::string state = phase.state;
1406 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1409 foundGreen[j] =
true;
1413 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1414 if (!foundGreen[j]) {
1415 NBEdge* e = fromEdges[j];
1416 if (std::find(toProc.begin(), toProc.end(), e) == toProc.end()) {
1417 toProc.push_back(e);
1426 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1427 const int vehLinks = totalNumLinks - (int)crossings.size();
1428 std::vector<bool> foundGreen(crossings.size(),
false);
1429 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1430 for (
int i = 0; i < (int)phases.size(); i++) {
1431 const std::string state = phases[i].state;
1432 for (
int j = 0; j < (int)crossings.size(); j++) {
1435 foundGreen[j] =
true;
1441 std::cout <<
" foundCrossingGreen=" <<
toString(foundGreen) <<
"\n";
1444 for (
int j = 0; j < (int)foundGreen.size(); j++) {
1445 if (!foundGreen[j]) {
1447 if (phases.size() > 0) {
1448 bool needYellowPhase =
false;
1449 std::string state = phases.back().state;
1450 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1451 if (state[i1] ==
'G' || state[i1] ==
'g') {
1453 needYellowPhase =
true;
1457 if (needYellowPhase && brakingTime > 0) {
1458 logic->
addStep(brakingTime, state);
1473 if (allRedTime > 0) {
1475 std::string allRedState = state;
1476 for (
int i = 0; i < (int)state.size(); i++) {
1477 if (allRedState[i] ==
'Y' || allRedState[i] ==
'y') {
1478 allRedState[i] =
'r';
1488 int minCustomIndex = -1;
1489 int maxCustomIndex = -1;
1492 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1493 for (
auto crossing : c) {
1494 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1495 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1496 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1497 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1513 const int p = (int)logic->
getPhases().size();
1514 for (
int i1 = 0; i1 < n; ++i1) {
1516 for (
int i2 = 0; i2 < p; ++i2) {
1533 std::vector<bool> alwaysGreen(n,
true);
1534 for (
int i1 = 0; i1 < n; ++i1) {
1535 for (
const auto& phase : logic->
getPhases()) {
1536 if (phase.state[i1] !=
'G') {
1537 alwaysGreen[i1] =
false;
1542 const int p = (int)logic->
getPhases().size();
1543 for (
int i1 = 0; i1 < n; ++i1) {
1544 if (alwaysGreen[i1]) {
1545 for (
int i2 = 0; i2 < p; ++i2) {
1555 const int n = (int)fromEdges.size();
1556 const int p = (int)logic->
getPhases().size();
1557 for (
int i1 = 0; i1 < n; ++i1) {
1558 if (fromEdges[i1]->isInsideTLS()) {
1559 for (
int i2 = 0; i2 < p; ++i2) {
1569 const int n = (int)fromEdges.size();
1571 for (
int i1 = 0; i1 < n; ++i1) {
1572 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1573 for (
int i2 = 0; i2 < n; ++i2) {
1574 if (fromEdges[i2]->isInsideTLS()) {
1575 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1576 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1577 maxTime =
MAX2(maxTime, time);
1591 if (logic !=
nullptr) {
1609 int greenPhases = 0;
1610 for (
const auto& phase : tllDummy->
getPhases()) {
1611 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1617 controlledNode->removeTrafficLight(&dummy);
1619 return greenPhases <= 2;
1627 const std::vector<NBNode::Crossing*>& crossings,
1628 const std::vector<std::pair<NBEdge*, NBEdge*> >& chosenList,
1629 const std::vector<std::string>& straightStates,
1630 const std::vector<std::string>& leftStates) {
1631 if (chosenList.size() != 2) {
1643 const int totalNumLinks = (int)straightStates[0].size();
1645 std::vector<int> ring1({1, 2, 3, 4});
1646 std::vector<int> ring2({5, 6, 7, 8});
1647 std::vector<int> barrier1({4, 8});
1648 std::vector<int> barrier2({2, 6});
1649 int phaseNameLeft = 1;
1650 for (
int i = 0; i < (int)chosenList.size(); i++) {
1651 NBEdge* e1 = chosenList[i].first;
1652 assert(e1 !=
nullptr);
1653 NBEdge* e2 = chosenList[i].second;
1654 if (i < (
int)leftStates.size()) {
1655 std::string left1 =
filterState(leftStates[i], fromEdges, e1);
1657 logic->
addStep(dur, left1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft));
1660 if (e2 !=
nullptr) {
1661 std::string straight2 =
filterState(straightStates[i], fromEdges, e2);
1664 logic->
addStep(dur, straight2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 1));
1665 if (i < (
int)leftStates.size()) {
1666 std::string left2 =
filterState(leftStates[i], fromEdges, e2);
1668 logic->
addStep(dur, left2, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 4));
1673 std::string straight1 =
filterState(straightStates[i], fromEdges, e1);
1674 if (straight1 ==
"") {
1679 logic->
addStep(dur, straight1, minMinDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red,
toString(phaseNameLeft + 5));
1682 std::map<int, int> names;
1683 for (
int i = 0; i < (int)logic->
getPhases().size(); i++) {
1691 if (ring1[0] == 0 && ring1[1] == 0) {
1694 if (ring1[2] == 0 && ring1[3] == 0) {
1697 fixDurationSum(logic, names, ring1[0], ring1[1], ring2[0], ring2[1]);
1698 fixDurationSum(logic, names, ring1[2], ring1[3], ring2[2], ring2[3]);
1710 bool haveGreen =
false;
1711 for (
int j = 0; j < (int)fromEdges.size(); j++) {
1712 if (fromEdges[j] != e) {
1714 }
else if (state[j] !=
'r') {
1727 for (
int i = 0; i < (int)vec.size(); i++) {
1728 if (names.count(vec[i]) == 0) {
1730 if (names.count(vec[i] - 1) > 0) {
1731 vec[i] = vec[i] - 1;
1733 vec[i] = barrierDefault;
1744 std::set<int> ring1existing;
1745 std::set<int> ring2existing;
1746 if (names.count(ring1a) != 0) {
1747 ring1existing.insert(ring1a);
1749 if (names.count(ring1b) != 0) {
1750 ring1existing.insert(ring1b);
1752 if (names.count(ring2a) != 0) {
1753 ring2existing.insert(ring2a);
1755 if (names.count(ring2b) != 0) {
1756 ring2existing.insert(ring2b);
1758 if (ring1existing.size() > 0 && ring2existing.size() > 0 &&
1759 ring1existing.size() != ring2existing.size()) {
1761 if (ring1existing.size() < ring2existing.size()) {
1762 pI = names.find(*ring1existing.begin())->second;
1764 pI = names.find(*ring2existing.begin())->second;
1767 SUMOTime newMaxDur = 2 * p.maxDur + p.yellow + p.red;
#define WRITE_WARNINGF(...)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge.
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permissions is a forbidden edge.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_DELIVERY
vehicle is a small delivery vehicle
@ SVC_TRAM
vehicle is a light rail
@ SVC_PEDESTRIAN
pedestrian
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ PARTRIGHT
The link is a partial right direction.
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_YELLOW_MINOR
The link has yellow light, has to brake anyway.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
@ TRAFFIC_LIGHT_RIGHT_ON_RED
#define UNUSED_PARAMETER(x)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
NBEdge * getFrom() const
returns the from-edge (start of the connection)
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
The representation of a single edge during network building.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
const std::string & getID() const
NBNode * getToNode() const
Returns the destination node of the edge.
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)
NBEdge * getTurnDestination(bool possibleDestination=false) const
const std::vector< Connection > & getConnections() const
Returns the connections.
NBNode * getFromNode() const
Returns the origin node of the edge.
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
A definition of a pedestrian crossing.
const NBNode * node
The parent node of this crossing.
EdgeVector edges
The edges being crossed.
Represents a single node (junction) during network building.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
bool mustBrakeForCrossing(const NBEdge *const from, const NBEdge *const to, const Crossing &crossing) const
Returns the information whether the described flow must brake for the given crossing.
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node)
Sorts edges by their priority within the node they end at.
A traffic light logics which must be computed (only nodes/edges are given)
void fixSuperfluousYellow(NBTrafficLightLogic *logic) const
avoid yellow signal between successive green (major) phases
std::string correctConflicting(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< int > &fromLanes, const std::vector< int > &toLanes, const std::vector< bool > &hadGreenMajor, bool &haveForbiddenLeftMover, std::vector< bool > &rightTurnConflicts, std::vector< bool > &mergeConflicts)
change 'G' to 'g' for conflicting connections
NBTrafficLightLogic * buildNemaPhases(const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< NBNode::Crossing * > &crossings, const std::vector< std::pair< NBEdge *, NBEdge * > > &chosenList, const std::vector< std::string > &straightStates, const std::vector< std::string > &leftStates)
void checkCustomCrossingIndices(NBTrafficLightLogic *logic) const
fix states in regard to custom crossing indices
static std::string patchStateForCrossings(const std::string &state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
compute phase state in regard to pedestrian crossings
std::string allowByVClass(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, SVCPermissions perm)
int getMaxIndex()
Returns the maximum index controlled by this traffic light.
bool myHaveSinglePhase
Whether left-mover should not have an additional phase.
bool corridorLike() const
test whether a joined tls with layout 'opposites' would be built without dedicated left-turn phase
SUMOTime computeEscapeTime(const std::string &state, const EdgeVector &fromEdges, const EdgeVector &toEdges) const
compute time to clear all vehicles from within an alternateOneWay layout
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane, bool incoming)
Replaces a removed edge/lane.
std::pair< NBEdge *, NBEdge * > getBestPair(EdgeVector &incoming)
Returns the combination of two edges from the given which has most unblocked streams.
void collectLinks()
Collects the links participating in this traffic light.
void deactivateAlwaysGreen(NBTrafficLightLogic *logic) const
switch of signal for links that are always green
static void addGreenWithin(NBTrafficLightLogic *logic, const EdgeVector &fromEdges, EdgeVector &toProc)
ensure inner edges all get the green light eventually
NBTrafficLightLogic * computeLogicAndConts(int brakingTimeSeconds, bool onlyConts=false)
helper function for myCompute
static bool hasCrossing(const NBEdge *from, const NBEdge *to, const std::vector< NBNode::Crossing * > &crossings)
compute whether the given connection is crossed by pedestrians
std::string allowPredecessors(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< int > &fromLanes, const std::vector< int > &toLanes)
void deactivateInsideEdges(NBTrafficLightLogic *logic, const EdgeVector &fromEdges) const
switch of signal for links that are inside a joined tls
double computeUnblockedWeightedStreamNumber(const NBEdge *const e1, const NBEdge *const e2)
Returns how many streams outgoing from the edges can pass the junction without being blocked.
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurrences of the removed edge in incoming/outgoing edges of all definitions.
int getToPrio(const NBEdge *const e)
Returns this edge's priority at the node it ends at.
std::string allowCompatible(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< int > &fromLanes, const std::vector< int > &toLanes)
allow connections that are compatible with the chosen edges
std::string correctMixed(std::string state, const EdgeVector &fromEdges, const std::vector< int > &fromLanes, bool &buildMixedGreenPhase, std::vector< bool > &mixedGreen)
prevent green and red from the same lane
void fixDurationSum(NBTrafficLightLogic *logic, const std::map< int, int > &names, int ring1a, int ring1b, int ring2a, int ring2b)
ensure that phase max durations before each barrier have the same sum in both rings
NBTrafficLightLogic * myCompute(int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
static std::string patchNEMAStateForCrossings(const std::string &state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges, const NBEdge *greenEdge, NBEdge *otherChosen)
std::string filterState(std::string state, const EdgeVector &fromEdges, const NBEdge *e)
mask out all greens that do not originate at the given edge
std::string allowFollowers(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges)
void buildAllRedState(SUMOTime allRedTime, NBTrafficLightLogic *logic, const std::string &state)
double getDirectionalWeight(LinkDirection dir)
Returns the weight of a stream given its direction.
std::string allowSingleEdge(std::string state, const EdgeVector &fromEdges)
bool hasStraightConnection(const NBEdge *fromEdge)
check whether there is a straight connection from this edge
std::pair< NBEdge *, NBEdge * > getBestCombination(const EdgeVector &edges)
Returns the combination of two edges from the given which has most unblocked streams.
void initNeedsContRelation() const
static void addPedestrianScramble(NBTrafficLightLogic *logic, int totalNumLinks, SUMOTime greenTime, SUMOTime yellowTime, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add an additional pedestrian phase if there are crossings that did not get green yet
NBOwnTLDef(const std::string &id, const std::vector< NBNode * > &junctions, SUMOTime offset, TrafficLightType type)
Constructor.
static EdgeVector getConnectedOuterEdges(const EdgeVector &incoming)
get edges that have connections
TrafficLightLayout myLayout
the layout for generated signal plans
bool forbidden(const std::string &state, int index, const EdgeVector &fromEdges, const EdgeVector &toEdges, bool allowCont)
whether the given index is forbidden by a green link in the current state
static std::string addPedestrianPhases(NBTrafficLightLogic *logic, const SUMOTime greenTime, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd, const SUMOTime latestEnd, std::string state, const std::vector< NBNode::Crossing * > &crossings, const EdgeVector &fromEdges, const EdgeVector &toEdges)
add 1 or 2 phases depending on the presence of pedestrian crossings
std::string allowUnrelated(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< NBNode::Crossing * > &crossings)
void filterMissingNames(std::vector< int > &vec, const std::map< int, int > &names, bool isBarrier, int barrierDefault=0)
keep only valid NEMA phase names (for params)
void setTLControllingInformation() const
Informs edges about being controlled by a tls.
static const double MIN_SPEED_CROSSING_TIME
minimum speed for computing time to cross intersection
The base class for traffic light logic definitions.
const std::string & getProgramID() const
Returns the ProgramID.
const EdgeVector & getIncomingEdges() const
Returns the list of incoming edges (must be build first)
bool needsCont(const NBEdge *fromE, const NBEdge *toE, const NBEdge *otherFromE, const NBEdge *otherToE) const
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
TrafficLightType getType() const
get the algorithm type (static etc..)
EdgeVector myIncomingEdges
The list of incoming edges.
NBTrafficLightLogic * compute(const OptionsCont &oc)
Computes the traffic light logic.
RightOnRedConflicts myRightOnRedConflicts
TrafficLightType myType
The algorithm type for the traffic light.
EdgeVector myEdgesWithin
The list of edges within the area controlled by the tls.
static const std::string DummyID
id for temporary definitions
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority, bool sameNodeOnly=false) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
NBConnectionVector myControlledLinks
The list of controlled links.
virtual void setType(TrafficLightType type)
set the algorithm type (static etc..)
bool myNeedsContRelationReady
virtual void setParticipantsInformation()
Builds the list of participating nodes/edges/links.
void collectAllLinks(NBConnectionVector &into)
helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
SUMOTime myOffset
The offset in the program.
static const SUMOTime UNSPECIFIED_DURATION
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
bool myRightOnRedConflictsReady
NeedsContRelation myNeedsContRelation
A SUMO-compliant built logic for a traffic light.
SUMOTime getDuration() const
Returns the duration of the complete cycle.
void closeBuilding(bool checkVarDurations=true)
closes the building process
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
void setPhaseDuration(int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by netedit)
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by netedit)
void setPhaseMaxDuration(int phaseIndex, SUMOTime duration)
Modifies the max duration for an existing phase (used by netedit)
int getNumLinks()
Returns the number of participating links.
void setType(TrafficLightType type)
set the algorithm type (static etc..)
void setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
void addStep(const SUMOTime duration, const std::string &state, const std::vector< int > &next=std::vector< int >(), const std::string &name="", const int index=-1)
Adds a phase to the logic (static)
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
static StringBijection< TrafficLightLayout > TrafficLightLayouts
traffic light layouts
T get(const std::string &str) const
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
A structure which describes a connection between edges or lanes.
data structure for caching needsCont information