38 #define HEIGH_WEIGHT 2
39 #define LOW_WEIGHT .5;
41 #define MIN_GREEN_TIME 5
54 const std::vector<NBNode*>& junctions,
SUMOTime offset,
57 myHaveSinglePhase(false),
65 myHaveSinglePhase(false),
73 myHaveSinglePhase(false),
106 for (
int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
108 for (
int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
110 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
114 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
118 const double sign = (
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)
119 ||
forbids(e2, (*e2c).toEdge, e1, (*e1c).toEdge,
true)) ? -1 : 1;
141 #ifdef DEBUG_STREAM_ORDERING
142 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
143 std::cout <<
" sign=" << sign <<
" w1=" << w1 <<
" w2=" << w2 <<
" val=" << val
144 <<
" c1=" << (*e1c).getDescription(e1)
145 <<
" c2=" << (*e2c).getDescription(e2)
153 #ifdef DEBUG_STREAM_ORDERING
154 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
155 std::cout <<
" computeUnblockedWeightedStreamNumber e1=" << e1->
getID() <<
" e2=" << e2->
getID() <<
" val=" << val <<
"\n";
162 std::pair<NBEdge*, NBEdge*>
164 std::pair<NBEdge*, NBEdge*> bestPair(
static_cast<NBEdge*
>(
nullptr),
static_cast<NBEdge*
>(
nullptr));
165 double bestValue = -std::numeric_limits<double>::max();
166 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
167 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
169 if (value > bestValue) {
171 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
172 }
else if (value == bestValue) {
174 const double oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
175 if (fabs(oa - ca) < NUMERICAL_EPS) {
176 if (bestPair.first->getID() < (*i)->getID()) {
177 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
179 }
else if (oa < ca) {
180 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
185 if (bestValue <= 0) {
187 bestPair.second =
nullptr;
190 #ifdef DEBUG_STREAM_ORDERING
199 std::pair<NBEdge*, NBEdge*>
201 if (incoming.size() == 1) {
203 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(),
static_cast<NBEdge*
>(
nullptr));
211 used.push_back(*incoming.begin());
214 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
218 if (used.size() < 2) {
222 #ifdef DEBUG_STREAM_ORDERING
228 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
229 if (ret.second !=
nullptr) {
230 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
263 std::vector<bool> isTurnaround;
264 std::vector<bool> hasTurnLane;
265 std::vector<int> fromLanes;
266 std::vector<int> toLanes;
268 for (
NBEdge*
const fromEdge : incoming) {
269 const int numLanes = fromEdge->getNumLanes();
271 for (
int i2 = 0; i2 < numLanes; i2++) {
272 bool hasLeft =
false;
273 bool hasPartLeft =
false;
274 bool hasStraight =
false;
275 bool hasRight =
false;
276 bool hasTurnaround =
false;
278 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
281 fromEdges.push_back(fromEdge);
282 fromLanes.push_back(i2);
283 toLanes.push_back(approached.toLane);
284 toEdges.push_back(approached.toEdge);
285 if (approached.toEdge !=
nullptr) {
286 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
288 isTurnaround.push_back(
true);
290 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
300 hasTurnaround =
true;
305 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
308 hasTurnLane.push_back(
309 (hasLeft && !hasPartLeft && !hasStraight && !hasRight)
310 || (hasPartLeft && !hasLeft && !hasStraight && !hasRight)
311 || (hasPartLeft && hasLeft && edgeHasStraight && !hasRight)
312 || (!hasLeft && !hasPartLeft && !hasTurnaround && hasRight));
318 std::vector<NBNode::Crossing*> crossings;
320 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
323 node->setCrossingTLIndices(
getID(), noLinksAll);
325 copy(c.begin(), c.end(), std::back_inserter(crossings));
326 noLinksAll += (int)c.size();
343 std::vector<int> greenPhases;
344 std::vector<bool> hadGreenMajor(noLinksAll,
false);
345 while (toProc.size() > 0) {
346 bool groupTram =
false;
347 bool groupOther =
false;
348 std::pair<NBEdge*, NBEdge*> chosen;
349 if (groupOpposites) {
350 if (incoming.size() == 2) {
353 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
356 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0],
static_cast<NBEdge*
>(
nullptr));
357 toProc.erase(toProc.begin());
363 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
365 for (
auto it = toProc.begin(); it != toProc.end();) {
366 if ((*it)->getPermissions() ==
SVC_TRAM) {
367 it = toProc.erase(it);
375 NBEdge* chosenEdge = toProc[0];
376 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge,
static_cast<NBEdge*
>(
nullptr));
377 toProc.erase(toProc.begin());
385 if (groupTram || groupOther) {
386 for (
auto it = toProc.begin(); it != toProc.end();) {
387 if ((*it)->getPermissions() == perms) {
388 it = toProc.erase(it);
396 std::string state((
int) noLinksAll,
'r');
404 bool haveGreen =
false;
405 for (
const NBEdge*
const fromEdge : incoming) {
406 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
407 const int numLanes = fromEdge->getNumLanes();
408 for (
int i2 = 0; i2 < numLanes; i2++) {
410 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
416 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
430 std::cout <<
" state after plain straight movers " << state <<
"\n";
434 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
437 }
else if (groupOther) {
442 std::cout <<
" state after grouping by vClass " << state <<
"\n";
446 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
450 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
454 bool haveForbiddenLeftMover =
false;
455 std::vector<bool> rightTurnConflicts(pos,
false);
456 std::vector<bool> mergeConflicts(pos,
false);
457 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
458 for (
int i1 = 0; i1 < pos; ++i1) {
459 if (state[i1] ==
'G') {
460 hadGreenMajor[i1] =
true;
465 std::cout <<
" state after correcting left movers=" << state <<
"\n";
469 std::vector<bool> leftGreen(pos,
false);
471 bool foundLeftTurnLane =
false;
472 for (
int i1 = 0; i1 < pos; ++i1) {
473 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1] && hasTurnLane[i1]) {
474 foundLeftTurnLane =
true;
477 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
478 && groupOpposites && !groupTram && !groupOther);
481 for (
int i1 = 0; i1 < pos; ++i1) {
482 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && !mergeConflicts[i1]
484 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
485 leftGreen[i1] =
true;
486 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
487 if (buildLeftGreenPhase) {
490 }
else if (!isTurnaround[i1]) {
491 WRITE_WARNINGF(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing.",
492 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
500 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
501 <<
" \nrtC=" <<
toString(rightTurnConflicts)
502 <<
" \nmC=" <<
toString(mergeConflicts)
503 <<
" \nhTL=" <<
toString(hasTurnLane)
509 const std::string vehicleState = state;
510 greenPhases.push_back((
int)logic->
getPhases().size());
513 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
515 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
518 bool tramExclusive =
true;
519 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
520 if (state[i1] ==
'G') {
521 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
523 tramExclusive =
false;
534 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, state, crossings, fromEdges, toEdges);
536 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
539 if (brakingTime > 0) {
541 for (
int i1 = 0; i1 < pos; ++i1) {
542 if (state[i1] !=
'G' && state[i1] !=
'g') {
545 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
546 && buildLeftGreenPhase
547 && !rightTurnConflicts[i1]
548 && !mergeConflicts[i1]
555 logic->
addStep(brakingTime, state);
564 if (buildLeftGreenPhase) {
566 for (
int i1 = 0; i1 < pos; ++i1) {
567 if (state[i1] ==
'Y' || state[i1] ==
'y') {
575 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
576 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
577 bool buildMixedGreenPhase =
false;
578 std::vector<bool> mixedGreen(pos,
false);
579 const std::string oldState = state;
581 state =
correctMixed(state, fromEdges, fromLanes, buildMixedGreenPhase, mixedGreen);
583 if (state != oldState) {
584 for (
int i1 = 0; i1 < pos; ++i1) {
585 if (mixedGreen[i1]) {
587 int yellowIndex = (int)logic->
getPhases().size() - 1;
588 if (allRedTime > 0) {
591 if (brakingTime > 0) {
596 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
600 logic->
addStep(leftTurnTime, state, minDur, maxDur);
603 if (brakingTime > 0) {
604 for (
int i1 = 0; i1 < pos; ++i1) {
605 if (state[i1] !=
'G' && state[i1] !=
'g') {
611 logic->
addStep(brakingTime, state);
616 if (buildMixedGreenPhase) {
622 for (
int i1 = 0; i1 < pos; ++i1) {
623 if (state[i1] ==
'Y' || state[i1] ==
'y') {
627 if (mixedGreen[i1]) {
631 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
632 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, toLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts, mergeConflicts);
635 logic->
addStep(leftTurnTime, state, minDur, maxDur);
638 if (brakingTime > 0) {
639 for (
int i1 = 0; i1 < pos; ++i1) {
640 if (state[i1] !=
'G' && state[i1] !=
'g') {
646 logic->
addStep(brakingTime, state);
656 if (crossings.size() > 0) {
660 if (logic->
getPhases().size() == 2 && brakingTime > 0
663 logic->
addStep(redTime, std::string(noLinksAll,
'r'));
666 if (crossings.size() > 0 && !onlyConts) {
681 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
683 greenPhaseTime += dur;
684 minGreenDuration =
MIN2(minGreenDuration, dur);
686 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / greenPhases.size());
687 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
691 || greenPhases.size() == 0) {
697 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
700 if (greenPhases.size() > 0) {
710 if (totalDuration > 0) {
711 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
726 for (
auto c : crossings) {
730 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
731 const NBEdge* edge = *it_e;
732 if (edge == from || edge == to) {
745 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
750 const std::string orig = state;
754 logic->
addStep(greenTime, state, minDur, maxDur);
756 const SUMOTime pedTime = greenTime - pedClearingTime;
757 if (pedTime >= minPedTime) {
759 const int pedStates = (int)crossings.size();
760 logic->
addStep(pedTime, state, minDur, maxDur);
761 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
762 logic->
addStep(pedClearingTime, state);
766 logic->
addStep(greenTime, state, minDur, maxDur);
775 std::string result = state;
776 const int pos = (int)(state.size() - crossings.size());
777 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
778 const int i1 = pos + ic;
783 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
784 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
787 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
803 for (
int i1 = 0; i1 < pos; ++i1) {
804 if (result[i1] ==
'G') {
805 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
807 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
808 const int i2 = pos + ic;
862 (*i)->removeTrafficLight(&dummy);
873 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
874 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
875 it = result.erase(it);
886 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
897 const int size = (int)fromEdges.size();
898 NBEdge* greenEdge =
nullptr;
899 for (
int i1 = 0; i1 < size; ++i1) {
900 if (state[i1] ==
'G') {
901 if (greenEdge ==
nullptr) {
902 greenEdge = fromEdges[i1];
903 }
else if (greenEdge != fromEdges[i1]) {
908 if (greenEdge !=
nullptr) {
909 for (
int i1 = 0; i1 < size; ++i1) {
910 if (fromEdges[i1] == greenEdge) {
925 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
926 if (state[i1] ==
'G') {
932 bool followsChosen =
false;
933 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
934 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
935 followsChosen =
true;
951 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
957 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
958 if (state[i1] ==
'G') {
961 if (
forbidden(state, i1, fromEdges, toEdges)) {
964 bool preceedsChosen =
false;
965 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
966 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
967 && fromLanes[i2] == toLanes[i1]) {
968 preceedsChosen =
true;
972 if (preceedsChosen) {
984 const std::vector<bool>& isTurnaround,
985 const std::vector<NBNode::Crossing*>& crossings) {
986 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
987 if (state[i1] ==
'G') {
991 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
992 if (state[i2] ==
'G' && !isTurnaround[i2] &&
993 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1008 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1009 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
1010 if ((linkPerm & ~perm) == 0) {
1020 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1021 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
1031 const std::vector<bool>& isTurnaround,
1032 const std::vector<int>& fromLanes,
1033 const std::vector<int>& toLanes,
1034 const std::vector<bool>& hadGreenMajor,
1035 bool& haveForbiddenLeftMover,
1036 std::vector<bool>& rightTurnConflicts,
1037 std::vector<bool>& mergeConflicts) {
1039 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1040 if (state[i1] ==
'G') {
1041 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1042 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
1044 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
1045 rightTurnConflicts[i1] =
true;
1047 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
1050 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
1051 haveForbiddenLeftMover =
true;
1053 }
else if (fromEdges[i1] == fromEdges[i2]
1054 && fromLanes[i1] != fromLanes[i2]
1055 && toEdges[i1] == toEdges[i2]
1056 && toLanes[i1] == toLanes[i2]
1057 && fromEdges[i1]->getToNode()->mergeConflictYields(fromEdges[i1], fromLanes[i1], fromLanes[i2], toEdges[i1], toLanes[i1])) {
1058 mergeConflicts[i1] =
true;
1064 if (state[i1] ==
'r') {
1066 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LinkDirection::RIGHT) {
1069 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1070 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1071 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1072 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1073 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
1080 if (state[i1] ==
's') {
1082 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1083 if (state[i2] ==
'G' && !isTurnaround[i2] &&
1084 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
1085 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
1099 const std::vector<int>& fromLanes,
1100 bool& buildMixedGreenPhase, std::vector<bool>& mixedGreen) {
1101 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
1102 if ((state[i1] ==
'G' || state[i1] ==
'g')) {
1103 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
1104 if (i1 != i2 && fromEdges[i1] == fromEdges[i2] && fromLanes[i1] == fromLanes[i2]
1105 && state[i2] !=
'G' && state[i2] !=
'g') {
1106 state[i1] = state[i2];
1108 mixedGreen[i1] =
true;
1109 if (fromEdges[i1]->getNumLanesThatAllow(
SVC_PASSENGER) > 1) {
1110 buildMixedGreenPhase =
true;
1122 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
1123 const int vehLinks = noLinksAll - (int)crossings.size();
1124 std::vector<bool> foundGreen(crossings.size(),
false);
1125 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1126 for (
int i = 0; i < (int)phases.size(); ++i) {
1127 const std::string state = phases[i].state;
1128 for (
int j = 0; j < (int)crossings.size(); ++j) {
1131 foundGreen[j] =
true;
1135 for (
int j = 0; j < (int)foundGreen.size(); ++j) {
1136 if (!foundGreen[j]) {
1139 if (phases.size() > 0) {
1140 bool needYellowPhase =
false;
1141 std::string state = phases.back().state;
1142 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1143 if (state[i1] ==
'G' || state[i1] ==
'g') {
1145 needYellowPhase =
true;
1149 if (needYellowPhase && brakingTime > 0) {
1150 logic->
addStep(brakingTime, state);
1164 if (allRedTime > 0) {
1166 std::string allRedState = state;
1167 for (
int i1 = 0; i1 < (int)state.size(); ++i1) {
1168 if (allRedState[i1] ==
'Y' || allRedState[i1] ==
'y') {
1169 allRedState[i1] =
'r';
1172 logic->
addStep(allRedTime, allRedState);
1178 int minCustomIndex = -1;
1179 int maxCustomIndex = -1;
1182 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1183 for (
auto crossing : c) {
1184 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1185 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1186 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1187 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1203 const int p = (int)logic->
getPhases().size();
1204 for (
int i1 = 0; i1 < n; ++i1) {
1206 for (
int i2 = 0; i2 < p; ++i2) {
1223 std::vector<bool> alwaysGreen(n,
true);
1224 for (
int i1 = 0; i1 < n; ++i1) {
1225 for (
const auto& phase : logic->
getPhases()) {
1226 if (phase.state[i1] !=
'G') {
1227 alwaysGreen[i1] =
false;
1232 const int p = (int)logic->
getPhases().size();
1233 for (
int i1 = 0; i1 < n; ++i1) {
1234 if (alwaysGreen[i1]) {
1235 for (
int i2 = 0; i2 < p; ++i2) {
1246 const int p = (int)logic->
getPhases().size();
1247 for (
int i1 = 0; i1 < n; ++i1) {
1248 if (fromEdges[i1]->isInsideTLS()) {
1249 for (
int i2 = 0; i2 < p; ++i2) {
1259 const int n = (int)state.size();
1261 for (
int i1 = 0; i1 < n; ++i1) {
1262 if (state[i1] ==
'y' && !fromEdges[i1]->isInsideTLS()) {
1263 for (
int i2 = 0; i2 < n; ++i2) {
1264 if (fromEdges[i2]->isInsideTLS()) {
1265 double gapSpeed = (toEdges[i1]->getSpeed() + fromEdges[i2]->getSpeed()) / 2;
1266 double time = fromEdges[i1]->getGeometry().back().distanceTo2D(fromEdges[i2]->getGeometry().back()) / gapSpeed;
1267 maxTime =
MAX2(maxTime, time);
1281 if (logic !=
nullptr) {
1299 int greenPhases = 0;
1300 for (
const auto& phase : tllDummy->
getPhases()) {
1301 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1307 (*i)->removeTrafficLight(&dummy);
1309 return greenPhases <= 2;
#define WRITE_WARNINGF(...)
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
std::string time2string(SUMOTime t)
convert SUMOTime to string
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
@ 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
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
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 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)
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.
std::vector< Connection > getConnectionsFromLane(int lane, NBEdge *to=nullptr, int toLane=-1) const
Returns connections from a given lane.
int getNumLanes() const
Returns the number of lanes.
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.
Sorts edges by their priority within the node they end at.
A traffic light logics which must be computed (only nodes/edges are given)
bool forbidden(const std::string &state, int index, const EdgeVector &fromEdges, const EdgeVector &toEdges)
whether the given index is forbidden by a green link in the current state
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
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
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 occurences 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
NBTrafficLightLogic * myCompute(int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
static std::string addPedestrianPhases(NBTrafficLightLogic *logic, SUMOTime greenTime, SUMOTime minDur, SUMOTime maxDur, 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 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
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
static void addPedestrianScramble(NBTrafficLightLogic *logic, int noLinksAll, 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
TrafficLightLayout myLayout
the layout for generated signal plans
std::string allowUnrelated(std::string state, const EdgeVector &fromEdges, const EdgeVector &toEdges, const std::vector< bool > &isTurnaround, const std::vector< NBNode::Crossing * > &crossings)
void setTLControllingInformation() const
Informs edges about being controlled by a tls.
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)
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
RightOnRedConflicts myRightOnRedConflicts
TrafficLightType myType
The algorithm type for the traffic light.
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.
NBTrafficLightLogic * compute(OptionsCont &oc)
Computes the traffic light logic.
NBConnectionVector myControlledLinks
The list of controlled links.
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)
int getNumLinks()
Returns the number of participating links.
void addStep(SUMOTime duration, const std::string &state, const std::vector< int > &next=std::vector< int >(), const std::string &name="", int index=-1)
Adds a phase to the logic.
void setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
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.
static StringBijection< TrafficLightLayout > TrafficLightLayouts
traffic light layouts
T get(const std::string &str) const
A structure which describes a connection between edges or lanes.
data structure for caching needsCont information