40 #define HEIGH_WEIGHT 2
41 #define LOW_WEIGHT .5;
43 #define MIN_GREEN_TIME 5
56 const std::vector<NBNode*>& junctions,
SUMOTime offset,
59 myHaveSinglePhase(false) {
66 myHaveSinglePhase(false) {
73 myHaveSinglePhase(false) {
105 for (
int e1l = 0; e1l < e1->
getNumLanes(); e1l++) {
107 for (
int e2l = 0; e2l < e2->
getNumLanes(); e2l++) {
109 for (std::vector<NBEdge::Connection>::iterator e1c = approached1.begin(); e1c != approached1.end(); ++e1c) {
113 for (std::vector<NBEdge::Connection>::iterator e2c = approached2.begin(); e2c != approached2.end(); ++e2c) {
117 const double sign = (
forbids(e1, (*e1c).toEdge, e2, (*e2c).toEdge,
true)
118 ||
forbids(e2, (*e2c).toEdge, e1, (*e1c).toEdge,
true)) ? -1 : 1;
140 #ifdef DEBUG_STREAM_ORDERING
141 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
142 std::cout <<
" sign=" << sign <<
" w1=" << w1 <<
" w2=" << w2 <<
" val=" << val
143 <<
" c1=" << (*e1c).getDescription(e1)
144 <<
" c2=" << (*e2c).getDescription(e2)
152 #ifdef DEBUG_STREAM_ORDERING
153 if (
DEBUGCOND && DEBUGEDGE(e2) && DEBUGEDGE(e1)) {
154 std::cout <<
" computeUnblockedWeightedStreamNumber e1=" << e1->
getID() <<
" e2=" << e2->
getID() <<
" val=" << val <<
"\n";
161 std::pair<NBEdge*, NBEdge*>
163 std::pair<NBEdge*, NBEdge*> bestPair(static_cast<NBEdge*>(
nullptr), static_cast<NBEdge*>(
nullptr));
164 double bestValue = -std::numeric_limits<double>::max();
165 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
166 for (EdgeVector::const_iterator j = i + 1; j != edges.end(); ++j) {
168 if (value > bestValue) {
170 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
171 }
else if (value == bestValue) {
173 const double oa =
GeomHelper::getMinAngleDiff(bestPair.first->getAngleAtNode(bestPair.first->getToNode()), bestPair.second->getAngleAtNode(bestPair.second->getToNode()));
175 if (bestPair.first->getID() < (*i)->getID()) {
176 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
178 }
else if (oa < ca) {
179 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
184 if (bestValue <= 0) {
186 bestPair.second =
nullptr;
189 #ifdef DEBUG_STREAM_ORDERING
198 std::pair<NBEdge*, NBEdge*>
200 if (incoming.size() == 1) {
202 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(), static_cast<NBEdge*>(
nullptr));
210 used.push_back(*incoming.begin());
213 for (EdgeVector::iterator i = incoming.begin() + 1; i != incoming.end() && prio ==
getToPrio(*i); ++i) {
217 if (used.size() < 2) {
221 #ifdef DEBUG_STREAM_ORDERING
227 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
228 if (ret.second !=
nullptr) {
229 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
251 std::vector<bool> isTurnaround;
252 std::vector<bool> hasTurnLane;
253 std::vector<int> fromLanes;
254 std::vector<int> toLanes;
256 for (
NBEdge*
const fromEdge : incoming) {
257 const int numLanes = fromEdge->getNumLanes();
258 for (
int i2 = 0; i2 < numLanes; i2++) {
259 bool hasLeft =
false;
260 bool hasStraight =
false;
261 bool hasRight =
false;
262 bool hasTurnaround =
false;
264 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
267 fromEdges.push_back(fromEdge);
268 fromLanes.push_back(i2);
269 toLanes.push_back(approached.toLane);
270 toEdges.push_back(approached.toEdge);
271 if (approached.toEdge !=
nullptr) {
272 isTurnaround.push_back(fromEdge->isTurningDirectionAt(approached.toEdge));
274 isTurnaround.push_back(
true);
276 LinkDirection dir = fromEdge->getToNode()->getDirection(fromEdge, approached.toEdge);
284 hasTurnaround =
true;
289 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
292 hasTurnLane.push_back(
293 (hasLeft && !hasStraight && !hasRight)
294 || (!hasLeft && !hasTurnaround && hasRight));
300 std::vector<NBNode::Crossing*> crossings;
302 const std::vector<NBNode::Crossing*>& c = node->getCrossings();
305 node->setCrossingTLIndices(
getID(), noLinksAll);
307 copy(c.begin(), c.end(), std::back_inserter(crossings));
308 noLinksAll += (int)c.size();
321 std::vector<int> greenPhases;
322 std::vector<bool> hadGreenMajor(noLinksAll,
false);
323 while (toProc.size() > 0) {
324 bool groupTram =
false;
325 bool groupOther =
false;
326 std::pair<NBEdge*, NBEdge*> chosen;
327 if (groupOpposites) {
328 if (incoming.size() == 2) {
331 double angle = fabs(
NBHelpers::relAngle(incoming[0]->getAngleAtNode(incoming[0]->getToNode()), incoming[1]->getAngleAtNode(incoming[1]->getToNode())));
334 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], static_cast<NBEdge*>(
nullptr));
335 toProc.erase(toProc.begin());
341 if (chosen.second ==
nullptr && chosen.first->getPermissions() ==
SVC_TRAM) {
343 for (
auto it = toProc.begin(); it != toProc.end();) {
344 if ((*it)->getPermissions() ==
SVC_TRAM) {
345 it = toProc.erase(it);
353 NBEdge* chosenEdge = toProc[0];
354 chosen = std::pair<NBEdge*, NBEdge*>(chosenEdge, static_cast<NBEdge*>(
nullptr));
355 toProc.erase(toProc.begin());
363 if (groupTram || groupOther) {
364 for (
auto it = toProc.begin(); it != toProc.end();) {
365 if ((*it)->getPermissions() == perms) {
366 it = toProc.erase(it);
374 std::string state((
int) noLinksAll,
'r');
382 bool haveGreen =
false;
383 for (
const NBEdge*
const fromEdge : incoming) {
384 const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second;
385 const int numLanes = fromEdge->getNumLanes();
386 for (
int i2 = 0; i2 < numLanes; i2++) {
388 if (!fromEdge->mayBeTLSControlled(i2, approached.toEdge, approached.toLane)) {
394 maxSpeed =
MAX2(maxSpeed, fromEdge->getSpeed());
408 std::cout <<
" state after plain straight movers " << state <<
"\n";
412 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
415 }
else if (groupOther) {
420 std::cout <<
" state after grouping by vClass " << state <<
"\n";
424 state =
allowUnrelated(state, fromEdges, toEdges, isTurnaround, crossings);
428 std::cout <<
" state after finding allowUnrelated " << state <<
"\n";
432 bool haveForbiddenLeftMover =
false;
433 std::vector<bool> rightTurnConflicts(pos,
false);
434 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
435 for (
int i1 = 0; i1 < pos; ++i1) {
436 if (state[i1] ==
'G') {
437 hadGreenMajor[i1] =
true;
442 std::cout <<
" state after correcting left movers=" << state <<
"\n";
446 std::vector<bool> leftGreen(pos,
false);
448 bool foundLeftTurnLane =
false;
449 for (
int i1 = 0; i1 < pos; ++i1) {
450 if (state[i1] ==
'g' && !rightTurnConflicts[i1] && hasTurnLane[i1]) {
451 foundLeftTurnLane =
true;
454 const bool buildLeftGreenPhase = (haveForbiddenLeftMover && !
myHaveSinglePhase && leftTurnTime > 0 && foundLeftTurnLane
455 && groupOpposites && !groupTram && !groupOther);
458 for (
int i1 = 0; i1 < pos; ++i1) {
459 if (state[i1] ==
'g' && !rightTurnConflicts[i1]
461 && (!isTurnaround[i1] || (i1 > 0 && leftGreen[i1 - 1]))) {
462 leftGreen[i1] =
true;
463 if (fromEdges[i1]->getSpeed() > minorLeftSpeedThreshold) {
464 if (buildLeftGreenPhase) {
467 }
else if (!isTurnaround[i1]) {
468 WRITE_WARNING(
"Minor green from edge '" + fromEdges[i1]->
getID() +
"' to edge '" + toEdges[i1]->
getID() +
"' exceeds "
469 +
toString(minorLeftSpeedThreshold) +
"m/s. Maybe a left-turn lane is missing.");
477 std::cout <<
getID() <<
" state=" << state <<
" buildLeft=" << buildLeftGreenPhase <<
" hFLM=" << haveForbiddenLeftMover <<
" turnLane=" << foundLeftTurnLane
478 <<
" \nrtC=" <<
toString(rightTurnConflicts)
479 <<
" \nhTL=" <<
toString(hasTurnLane)
485 const std::string vehicleState = state;
486 greenPhases.push_back((
int)logic->
getPhases().size());
489 const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
491 if (chosen.first->getPermissions() ==
SVC_TRAM && (chosen.second ==
nullptr || chosen.second->getPermissions() ==
SVC_TRAM)) {
494 bool tramExclusive =
true;
495 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
496 if (state[i1] ==
'G') {
497 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
499 tramExclusive =
false;
510 state =
addPedestrianPhases(logic, greenTime, minDur, maxDur, state, crossings, fromEdges, toEdges);
512 for (
int i1 = pos; i1 < pos + (int)crossings.size(); ++i1) {
515 if (brakingTime > 0) {
517 for (
int i1 = 0; i1 < pos; ++i1) {
518 if (state[i1] !=
'G' && state[i1] !=
'g') {
521 if ((vehicleState[i1] >=
'a' && vehicleState[i1] <=
'z')
522 && buildLeftGreenPhase
523 && !rightTurnConflicts[i1]
530 logic->
addStep(brakingTime, state);
536 if (buildLeftGreenPhase) {
538 for (
int i1 = 0; i1 < pos; ++i1) {
539 if (state[i1] ==
'Y' || state[i1] ==
'y') {
547 state =
allowCompatible(state, fromEdges, toEdges, fromLanes, toLanes);
548 state =
correctConflicting(state, fromEdges, toEdges, isTurnaround, fromLanes, hadGreenMajor, haveForbiddenLeftMover, rightTurnConflicts);
551 logic->
addStep(leftTurnTime, state, minDur, maxDur);
554 if (brakingTime > 0) {
555 for (
int i1 = 0; i1 < pos; ++i1) {
556 if (state[i1] !=
'G' && state[i1] !=
'g') {
562 logic->
addStep(brakingTime, state);
569 if (crossings.size() > 0) {
573 if (logic->
getPhases().size() == 2 && brakingTime > 0
576 logic->
addStep(redTime, std::string(noLinksAll,
'r'));
579 if (crossings.size() > 0 && !onlyConts) {
589 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
591 greenPhaseTime += dur;
592 minGreenDuration =
MIN2(minGreenDuration, dur);
594 const int patchSeconds = (int)(
STEPS2TIME(cycleTime - totalDuration) / greenPhases.size());
595 const int patchSecondsRest = (int)(
STEPS2TIME(cycleTime - totalDuration)) - patchSeconds * (
int)greenPhases.size();
599 || greenPhases.size() == 0) {
605 for (std::vector<int>::const_iterator it = greenPhases.begin(); it != greenPhases.end(); ++it) {
608 if (greenPhases.size() > 0) {
618 if (totalDuration > 0) {
619 if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) {
634 for (
auto c : crossings) {
638 for (EdgeVector::const_iterator it_e = cross.
edges.begin(); it_e != cross.
edges.end(); ++it_e) {
639 const NBEdge* edge = *it_e;
640 if (edge == from || edge == to) {
653 std::string state,
const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
658 const std::string orig = state;
662 logic->
addStep(greenTime, state, minDur, maxDur);
664 const SUMOTime pedTime = greenTime - pedClearingTime;
665 if (pedTime >= minPedTime) {
667 const int pedStates = (int)crossings.size();
668 logic->
addStep(pedTime, state, minDur, maxDur);
669 state = state.substr(0, state.size() - pedStates) + std::string(pedStates,
'r');
670 logic->
addStep(pedClearingTime, state);
674 logic->
addStep(greenTime, state, minDur, maxDur);
683 std::string result = state;
684 const int pos = (int)(state.size() - crossings.size());
685 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
686 const int i1 = pos + ic;
691 if (fromEdges[i2] != 0 && toEdges[i2] != 0 && fromEdges[i2]->getToNode() == cross.
node) {
692 for (EdgeVector::const_iterator it = cross.
edges.begin(); it != cross.
edges.end(); ++it) {
695 if (state[i2] !=
'r' && state[i2] !=
's' && (edge == fromEdges[i2] ||
711 for (
int i1 = 0; i1 < pos; ++i1) {
712 if (result[i1] ==
'G') {
713 for (
int ic = 0; ic < (int)crossings.size(); ++ic) {
715 if (fromEdges[i1] != 0 && toEdges[i1] != 0 && fromEdges[i1]->getToNode() == crossing.
node) {
716 const int i2 = pos + ic;
769 (*i)->removeTrafficLight(&dummy);
780 for (EdgeVector::iterator it = result.begin(); it != result.end();) {
781 if ((*it)->getConnections().size() == 0 || (*it)->isInsideTLS()) {
782 it = result.erase(it);
793 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
804 const int size = (int)fromEdges.size();
805 NBEdge* greenEdge =
nullptr;
806 for (
int i1 = 0; i1 < size; ++i1) {
807 if (state[i1] ==
'G') {
808 if (greenEdge ==
nullptr) {
809 greenEdge = fromEdges[i1];
810 }
else if (greenEdge != fromEdges[i1]) {
815 if (greenEdge !=
nullptr) {
816 for (
int i1 = 0; i1 < size; ++i1) {
817 if (fromEdges[i1] == greenEdge) {
832 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
833 if (state[i1] ==
'G') {
839 bool followsChosen =
false;
840 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
841 if (state[i2] ==
'G' && fromEdges[i1] == toEdges[i2]) {
842 followsChosen =
true;
858 const std::vector<int>& fromLanes,
const std::vector<int>& toLanes) {
864 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
865 if (state[i1] ==
'G') {
868 if (
forbidden(state, i1, fromEdges, toEdges)) {
871 bool preceedsChosen =
false;
872 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
873 if (state[i2] ==
'G' && fromEdges[i2] == toEdges[i1]
874 && fromLanes[i2] == toLanes[i1]) {
875 preceedsChosen =
true;
879 if (preceedsChosen) {
891 const std::vector<bool>& isTurnaround,
892 const std::vector<NBNode::Crossing*>& crossings) {
893 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
894 if (state[i1] ==
'G') {
898 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
899 if (state[i2] ==
'G' && !isTurnaround[i2] &&
900 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
915 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
916 SVCPermissions linkPerm = (fromEdges[i1]->getPermissions() & toEdges[i1]->getPermissions());
917 if ((linkPerm & ~perm) == 0) {
927 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
928 if (state[i2] ==
'G' &&
foes(fromEdges[i2], toEdges[i2], fromEdges[index], toEdges[index])) {
938 const std::vector<bool>& isTurnaround,
939 const std::vector<int>& fromLanes,
940 const std::vector<bool>& hadGreenMajor,
941 bool& haveForbiddenLeftMover,
942 std::vector<bool>& rightTurnConflicts) {
944 for (
int i1 = 0; i1 < (int)fromEdges.size(); ++i1) {
945 if (state[i1] ==
'G') {
946 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
947 if ((state[i2] ==
'G' || state[i2] ==
'g')) {
949 fromEdges[i1], toEdges[i1], fromLanes[i1], fromEdges[i2], toEdges[i2], fromLanes[i2])) {
950 rightTurnConflicts[i1] =
true;
952 if (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true, controlledWithin) || rightTurnConflicts[i1]) {
955 if (!isTurnaround[i1] && !hadGreenMajor[i1] && !rightTurnConflicts[i1]) {
956 haveForbiddenLeftMover =
true;
962 if (state[i1] ==
'r') {
964 fromEdges[i1]->getToNode()->getDirection(fromEdges[i1], toEdges[i1]) ==
LINKDIR_RIGHT) {
967 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
968 if (state[i2] ==
'G' && !isTurnaround[i2] &&
969 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
970 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
971 const LinkDirection foeDir = fromEdges[i2]->getToNode()->getDirection(fromEdges[i2], toEdges[i2]);
978 if (state[i1] ==
's') {
980 for (
int i2 = 0; i2 < (int)fromEdges.size(); ++i2) {
981 if (state[i2] ==
'G' && !isTurnaround[i2] &&
982 (
forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1],
true) ||
983 forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2],
true))) {
997 const std::vector<NBNode::Crossing*>& crossings,
const EdgeVector& fromEdges,
const EdgeVector& toEdges) {
998 const int vehLinks = noLinksAll - (int)crossings.size();
999 std::vector<bool> foundGreen(crossings.size(),
false);
1000 const std::vector<NBTrafficLightLogic::PhaseDefinition>& phases = logic->
getPhases();
1001 for (
int i = 0; i < (int)phases.size(); ++i) {
1002 const std::string state = phases[i].state;
1003 for (
int j = 0; j < (int)crossings.size(); ++j) {
1006 foundGreen[j] =
true;
1010 for (
int j = 0; j < (int)foundGreen.size(); ++j) {
1011 if (!foundGreen[j]) {
1014 if (phases.size() > 0) {
1015 bool needYellowPhase =
false;
1016 std::string state = phases.back().state;
1017 for (
int i1 = 0; i1 < vehLinks; ++i1) {
1018 if (state[i1] ==
'G' || state[i1] ==
'g') {
1020 needYellowPhase =
true;
1024 if (needYellowPhase && brakingTime > 0) {
1025 logic->
addStep(brakingTime, state);
1039 if (allRedTime > 0) {
1041 std::string allRedState = state;
1042 for (
int i1 = 0; i1 < (int)state.size(); ++i1) {
1043 if (allRedState[i1] ==
'Y' || allRedState[i1] ==
'y') {
1044 allRedState[i1] =
'r';
1047 logic->
addStep(allRedTime, allRedState);
1053 int minCustomIndex = -1;
1054 int maxCustomIndex = -1;
1057 const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
1058 for (
auto crossing : c) {
1059 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex);
1060 minCustomIndex =
MIN2(minCustomIndex, crossing->customTLIndex2);
1061 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex);
1062 maxCustomIndex =
MAX2(maxCustomIndex, crossing->customTLIndex2);
1079 if (logic !=
nullptr) {
1095 dummy.setParticipantsInformation();
1097 int greenPhases = 0;
1098 for (
const auto& phase : tllDummy->
getPhases()) {
1099 if (phase.state.find_first_of(
"gG") != std::string::npos) {
1105 (*i)->removeTrafficLight(&dummy);
1107 return greenPhases <= 2;