39 #define HEIGH_WEIGHT 2
40 #define LOW_WEIGHT .5;
42 #define MIN_GREEN_TIME 5
55 const std::vector<NBNode*>& junctions,
SUMOTime offset,
58 myHaveSinglePhase(false) {
65 myHaveSinglePhase(false) {
72 myHaveSinglePhase(false) {
104 for (
int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
106 for (
int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
108 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
112 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
116 const double sign = (
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)
117 ||
forbids(e2, (*e2c).toEdge, e1, (*e1c).toEdge,
true)) ? -1 : 1;
139 #ifdef DEBUG_STREAM_ORDERING
140 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
141 std::cout <<
" sign=" << sign <<
" w1=" << w1 <<
" w2=" << w2 <<
" val=" << val
142 <<
" c1=" << (*e1c).getDescription(e1)
143 <<
" c2=" << (*e2c).getDescription(e2)
151 #ifdef DEBUG_STREAM_ORDERING
152 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
153 std::cout <<
" computeUnblockedWeightedStreamNumber e1=" << e1->
getID() <<
" e2=" << e2->
getID() <<
" val=" << val <<
"\n";
160 std::pair<NBEdge*, NBEdge*>
162 std::pair<NBEdge*, NBEdge*> bestPair(static_cast<NBEdge*>(
nullptr), static_cast<NBEdge*>(
nullptr));
163 double bestValue = -std::numeric_limits<double>::max();
164 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
165 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
167 if (value > bestValue) {
169 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
170 }
else if (value == bestValue) {
172 const double oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
174 if (bestPair.first->getID() < (*i)->getID()) {
175 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
177 }
else if (oa < ca) {
178 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
183 if (bestValue <= 0) {
185 bestPair.second =
nullptr;
188 #ifdef DEBUG_STREAM_ORDERING
197 std::pair<NBEdge*, NBEdge*>
199 if (incoming.size() == 1) {
201 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(), static_cast<NBEdge*>(
nullptr));
209 used.push_back(*incoming.begin());
212 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
216 if (used.size() < 2) {
220 #ifdef DEBUG_STREAM_ORDERING
226 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
227 if (ret.second !=
nullptr) {
228 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
250 std::vector<bool> isTurnaround;
251 std::vector<bool> hasTurnLane;
252 std::vector<int> fromLanes;
253 std::vector<int> toLanes;
255 for (
NBEdge*
const fromEdge : incoming) {
256 const int numLanes = fromEdge->getNumLanes();
257 for (
int i2 = 0; i2 < numLanes; i2++) {
258 bool hasLeft =
false;
259 bool hasStraight =
false;
260 bool hasRight =
false;
261 bool hasTurnaround =
false;
263 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
266 fromEdges.push_back(fromEdge);
267 fromLanes.push_back(i2);
268 toLanes.push_back(approached.toLane);
269 toEdges.push_back(approached.toEdge);
270 if (approached.toEdge !=
nullptr) {
271 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
273 isTurnaround.push_back(
true);
275 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
283 hasTurnaround =
true;
288 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
291 hasTurnLane.push_back(
292 (hasLeft && !hasStraight && !hasRight)
293 || (!hasLeft && !hasTurnaround && hasRight));
299 std::vector<NBNode::Crossing*> crossings;
301 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
304 node->setCrossingTLIndices(
getID(), noLinksAll);
306 copy(c.begin(), c.end(), std::back_inserter(crossings));
307 noLinksAll += (int)c.size();
320 std::vector<int> greenPhases;
321 std::vector<bool> hadGreenMajor(noLinksAll,
false);
322 while (toProc.size() > 0) {
323 bool groupTram =
false;
324 bool groupOther =
false;
325 std::pair<NBEdge*, NBEdge*> chosen;
326 if (groupOpposites) {
327 if (incoming.size() == 2) {
330 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
333 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], static_cast<NBEdge*>(
nullptr));
334 toProc.erase(toProc.begin());
340 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
342 for (
auto it = toProc.begin(); it != toProc.end();) {
343 if ((*it)->getPermissions() ==
SVC_TRAM) {
344 it = toProc.erase(it);
352 NBEdge* chosenEdge = toProc[0];
353 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge, static_cast<NBEdge*>(
nullptr));
354 toProc.erase(toProc.begin());
362 if (groupTram || groupOther) {
363 for (
auto it = toProc.begin(); it != toProc.end();) {
364 if ((*it)->getPermissions() == perms) {
365 it = toProc.erase(it);
373 std::string state((
int) noLinksAll,
'r');
381 bool haveGreen =
false;
382 for (
const NBEdge*
const fromEdge : incoming) {
383 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
384 const int numLanes = fromEdge->getNumLanes();
385 for (
int i2 = 0; i2 < numLanes; i2++) {
387 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
393 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
407 std::cout <<
" state after plain straight movers " << state <<
"\n";
411 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
414 }
else if (groupOther) {
419 std::cout <<
" state after grouping by vClass " << state <<
"\n";
423 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
427 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
431 bool haveForbiddenLeftMover =
false;
432 std::vector<bool> rightTurnConflicts(pos,
false);
433 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
434 for (
int i1 = 0; i1 < pos; ++i1) {
435 if (state[i1] ==
'G') {
436 hadGreenMajor[i1] =
true;
441 std::cout <<
" state after correcting left movers=" << state <<
"\n";
445 std::vector<bool> leftGreen(pos,
false);
447 bool foundLeftTurnLane =
false;
448 for (
int i1 = 0; i1 < pos; ++i1) {
449 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && hasTurnLane[i1]) {
450 foundLeftTurnLane =
true;
453 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
454 && groupOpposites && !groupTram && !groupOther);
457 for (
int i1 = 0; i1 < pos; ++i1) {
458 if (state[i1] ==
'g' && !rightTurnConflicts[i1]
460 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
461 leftGreen[i1] =
true;
462 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
463 if (buildLeftGreenPhase) {
466 }
else if (!isTurnaround[i1]) {
467 WRITE_WARNINGF(
"Minor green from edge '%' to edge '%' exceeds %m/s. Maybe a left-turn lane is missing.",
468 fromEdges[i1]->
getID(), toEdges[i1]->
getID(), minorLeftSpeedThreshold);
476 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
477 <<
" \nrtC=" <<
toString(rightTurnConflicts)
478 <<
" \nhTL=" <<
toString(hasTurnLane)
484 const std::string vehicleState = state;
485 greenPhases.push_back((
int)logic->
getPhases().size());
488 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
490 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
493 bool tramExclusive =
true;
494 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
495 if (state[i1] ==
'G') {
496 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
498 tramExclusive =
false;
509 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, state, crossings, fromEdges, toEdges);
511 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
514 if (brakingTime > 0) {
516 for (
int i1 = 0; i1 < pos; ++i1) {
517 if (state[i1] !=
'G' && state[i1] !=
'g') {
520 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
521 && buildLeftGreenPhase
522 && !rightTurnConflicts[i1]
529 logic->
addStep(brakingTime, state);
535 if (buildLeftGreenPhase) {
537 for (
int i1 = 0; i1 < pos; ++i1) {
538 if (state[i1] ==
'Y' || state[i1] ==
'y') {
546 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
547 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
550 logic->
addStep(leftTurnTime, state, minDur, maxDur);
553 if (brakingTime > 0) {
554 for (
int i1 = 0; i1 < pos; ++i1) {
555 if (state[i1] !=
'G' && state[i1] !=
'g') {
561 logic->
addStep(brakingTime, state);
568 if (crossings.size() > 0) {
572 if (logic->
getPhases().size() == 2 && brakingTime > 0
575 logic->
addStep(redTime, std::string(noLinksAll,
'r'));
578 if (crossings.size() > 0 && !onlyConts) {
588 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
590 greenPhaseTime += dur;
591 minGreenDuration =
MIN2(minGreenDuration, dur);
593 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / greenPhases.size());
594 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
598 || greenPhases.size() == 0) {
604 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
607 if (greenPhases.size() > 0) {
617 if (totalDuration > 0) {
618 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
633 for (
auto c : crossings) {
637 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
638 const NBEdge* edge = *it_e;
639 if (edge == from || edge == to) {
652 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
657 const std::string orig = state;
661 logic->
addStep(greenTime, state, minDur, maxDur);
663 const SUMOTime pedTime = greenTime - pedClearingTime;
664 if (pedTime >= minPedTime) {
666 const int pedStates = (int)crossings.size();
667 logic->
addStep(pedTime, state, minDur, maxDur);
668 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
669 logic->
addStep(pedClearingTime, state);
673 logic->
addStep(greenTime, state, minDur, maxDur);
682 std::string result = state;
683 const int pos = (int)(state.size() - crossings.size());
684 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
685 const int i1 = pos + ic;
690 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
691 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
694 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
710 for (
int i1 = 0; i1 < pos; ++i1) {
711 if (result[i1] ==
'G') {
712 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
714 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
715 const int i2 = pos + ic;
768 (*i)->removeTrafficLight(&dummy);
779 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
780 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
781 it = result.erase(it);
792 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
803 const int size = (int)fromEdges.size();
804 NBEdge* greenEdge =
nullptr;
805 for (
int i1 = 0; i1 < size; ++i1) {
806 if (state[i1] ==
'G') {
807 if (greenEdge ==
nullptr) {
808 greenEdge = fromEdges[i1];
809 }
else if (greenEdge != fromEdges[i1]) {
814 if (greenEdge !=
nullptr) {
815 for (
int i1 = 0; i1 < size; ++i1) {
816 if (fromEdges[i1] == greenEdge) {
831 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
832 if (state[i1] ==
'G') {
838 bool followsChosen =
false;
839 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
840 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
841 followsChosen =
true;
857 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
863 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
864 if (state[i1] ==
'G') {
867 if (
forbidden(state, i1, fromEdges, toEdges)) {
870 bool preceedsChosen =
false;
871 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
872 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
873 && fromLanes[i2] == toLanes[i1]) {
874 preceedsChosen =
true;
878 if (preceedsChosen) {
890 const std::vector<bool>& isTurnaround,
891 const std::vector<NBNode::Crossing*>& crossings) {
892 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
893 if (state[i1] ==
'G') {
897 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
898 if (state[i2] ==
'G' && !isTurnaround[i2] &&
899 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
914 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
915 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
916 if ((linkPerm & ~perm) == 0) {
926 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
927 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
937 const std::vector<bool>& isTurnaround,
938 const std::vector<int>& fromLanes,
939 const std::vector<bool>& hadGreenMajor,
940 bool& haveForbiddenLeftMover,
941 std::vector<bool>& rightTurnConflicts) {
943 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
944 if (state[i1] ==
'G') {
945 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
946 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
948 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
949 rightTurnConflicts[i1] =
true;
951 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
954 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
955 haveForbiddenLeftMover =
true;
961 if (state[i1] ==
'r') {
963 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LINKDIR_RIGHT) {
966 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
967 if (state[i2] ==
'G' && !isTurnaround[i2] &&
968 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
969 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
970 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
977 if (state[i1] ==
's') {
979 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
980 if (state[i2] ==
'G' && !isTurnaround[i2] &&
981 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
982 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
996 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
997 const int vehLinks = noLinksAll - (int)crossings.size();
998 std::vector<bool> foundGreen(crossings.size(),
false);
999 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1000 for (
int i = 0; i < (int)phases.size(); ++i) {
1001 const std::string state = phases[i].state;
1002 for (
int j = 0; j < (int)crossings.size(); ++j) {
1005 foundGreen[j] =
true;
1009 for (
int j = 0; j < (int)foundGreen.size(); ++j) {
1010 if (!foundGreen[j]) {
1013 if (phases.size() > 0) {
1014 bool needYellowPhase =
false;
1015 std::string state = phases.back().state;
1016 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1017 if (state[i1] ==
'G' || state[i1] ==
'g') {
1019 needYellowPhase =
true;
1023 if (needYellowPhase && brakingTime > 0) {
1024 logic->
addStep(brakingTime, state);
1038 if (allRedTime > 0) {
1040 std::string allRedState = state;
1041 for (
int i1 = 0; i1 < (int)state.size(); ++i1) {
1042 if (allRedState[i1] ==
'Y' || allRedState[i1] ==
'y') {
1043 allRedState[i1] =
'r';
1046 logic->
addStep(allRedTime, allRedState);
1052 int minCustomIndex = -1;
1053 int maxCustomIndex = -1;
1056 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1057 for (
auto crossing : c) {
1058 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1059 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1060 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1061 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1078 if (logic !=
nullptr) {
1094 dummy.setParticipantsInformation();
1096 int greenPhases = 0;
1097 for (
const auto& phase : tllDummy->
getPhases()) {
1098 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1104 (*i)->removeTrafficLight(&dummy);
1106 return greenPhases <= 2;