Eclipse SUMO - Simulation of Urban MObility
NBLoadedSUMOTLDef.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2011-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // A complete traffic light logic loaded from a sumo-net. (opted to reimplement
17 // since NBLoadedTLDef is quite vissim specific)
18 /****************************************************************************/
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <vector>
26 #include <set>
27 #include <cassert>
28 #include <iterator>
30 #include <utils/common/ToString.h>
32 #include "NBTrafficLightLogic.h"
33 #include "NBOwnTLDef.h"
35 #include "NBLoadedSUMOTLDef.h"
36 #include "NBNetBuilder.h"
37 #include "NBOwnTLDef.h"
38 #include "NBNode.h"
39 
40 //#define DEBUG_RECONSTRUCTION
41 
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
45 
46 NBLoadedSUMOTLDef::NBLoadedSUMOTLDef(const std::string& id, const std::string& programID,
47  SUMOTime offset, TrafficLightType type) :
48  NBTrafficLightDefinition(id, programID, offset, type),
49  myTLLogic(nullptr),
50  myReconstructAddedConnections(false),
51  myReconstructRemovedConnections(false),
52  myPhasesLoaded(false) {
53  myTLLogic = new NBTrafficLightLogic(id, programID, 0, offset, type);
54 }
55 
56 
58  // allow for adding a new program for the same def: take the offset and programID from the new logic
59  NBTrafficLightDefinition(def->getID(), logic->getProgramID(), logic->getOffset(), def->getType()),
60  myTLLogic(new NBTrafficLightLogic(logic)),
61  myOriginalNodes(def->getNodes().begin(), def->getNodes().end()),
62  myReconstructAddedConnections(false),
63  myReconstructRemovedConnections(false),
64  myPhasesLoaded(false) {
65  assert(def->getType() == logic->getType());
67  myControlledNodes = def->getNodes();
68  NBLoadedSUMOTLDef* sumoDef = dynamic_cast<NBLoadedSUMOTLDef*>(def);
70  if (sumoDef != nullptr) {
73  }
74 }
75 
76 
78  delete myTLLogic;
79 }
80 
81 
83 NBLoadedSUMOTLDef::myCompute(int brakingTimeSeconds) {
84  // @todo what to do with those parameters?
85  UNUSED_PARAMETER(brakingTimeSeconds);
87  myTLLogic->closeBuilding(false);
90  return new NBTrafficLightLogic(myTLLogic);
91 }
92 
93 
94 void
95 NBLoadedSUMOTLDef::addConnection(NBEdge* from, NBEdge* to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct) {
96  assert(myTLLogic->getNumLinks() > 0); // logic should be loaded by now
97  if (linkIndex >= (int)myTLLogic->getNumLinks()) {
98  throw ProcessError("Invalid linkIndex " + toString(linkIndex) + " for traffic light '" + getID() +
99  "' with " + toString(myTLLogic->getNumLinks()) + " links.");
100  }
101  if (linkIndex2 >= (int)myTLLogic->getNumLinks()) {
102  throw ProcessError("Invalid linkIndex2 " + toString(linkIndex2) + " for traffic light '" + getID() +
103  "' with " + toString(myTLLogic->getNumLinks()) + " links.");
104  }
105  NBConnection conn(from, fromLane, to, toLane, linkIndex, linkIndex2);
106  // avoid duplicates
107  auto newEnd = remove_if(myControlledLinks.begin(), myControlledLinks.end(), connection_equal(conn));
108  // remove_if does not remove, only re-order
109  myControlledLinks.erase(newEnd, myControlledLinks.end());
110  myControlledLinks.push_back(conn);
111  addNode(from->getToNode());
112  addNode(to->getFromNode());
113  myOriginalNodes.insert(from->getToNode());
114  myOriginalNodes.insert(to->getFromNode());
115  // added connections are definitely controlled. make sure none are removed because they lie within the tl
116  // myControlledInnerEdges.insert(from->getID()); // @todo recheck: this appears to be obsolete
117  // set this information now so that it can be used while loading diffs
118  from->setControllingTLInformation(conn, getID());
119  myReconstructAddedConnections |= reconstruct;
120 }
121 
122 
123 void
129  for (std::vector<NBNode*>::const_iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
130  (*i)->removeTrafficLight(&dummy);
131  }
132  }
134  return; // will be called again in reconstructLogic()
135  }
136  // if nodes have been removed our links may have been invalidated as well
137  // since no logic will be built anyway there is no reason to inform any edges
138  if (amInvalid()) {
139  return;
140  }
141  // set the information about the link's positions within the tl into the
142  // edges the links are starting at, respectively
143  for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
144  const NBConnection& c = *it;
145  if (c.getTLIndex() >= (int)myTLLogic->getNumLinks()) {
146  throw ProcessError("Invalid linkIndex " + toString(c.getTLIndex()) + " for traffic light '" + getID() +
147  "' with " + toString(myTLLogic->getNumLinks()) + " links.");
148  }
149  NBEdge* edge = c.getFrom();
150  if (edge != nullptr && edge->getNumLanes() > c.getFromLane()) {
151  // logic may have yet to be reconstructed
153  }
154  }
155 }
156 
157 
158 void
160 
161 
162 void
163 NBLoadedSUMOTLDef::replaceRemoved(NBEdge* removed, int removedLane, NBEdge* by, int byLane) {
164  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); ++it) {
165  (*it).replaceFrom(removed, removedLane, by, byLane);
166  (*it).replaceTo(removed, removedLane, by, byLane);
167  }
168 }
169 
170 
171 void
172 NBLoadedSUMOTLDef::addPhase(SUMOTime duration, const std::string& state, SUMOTime minDur, SUMOTime maxDur, const std::vector<int>& next, const std::string& name) {
173  myTLLogic->addStep(duration, state, minDur, maxDur, next, name);
174 }
175 
176 
177 bool
179  if (myControlledLinks.size() == 0) {
180  return true;
181  }
182  // make sure that myControlledNodes are the original nodes
183  if (myControlledNodes.size() != myOriginalNodes.size()) {
184  //std::cout << " myControlledNodes=" << myControlledNodes.size() << " myOriginalNodes=" << myOriginalNodes.size() << "\n";
185  return true;
186  }
187  if (myIncomingEdges.size() == 0) {
188  return true;
189  }
190  for (std::vector<NBNode*>::const_iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
191  if (myOriginalNodes.count(*i) != 1) {
192  //std::cout << " node " << (*i)->getID() << " missing from myOriginalNodes\n";
193  return true;
194  }
195  }
196  return false;
197 }
198 
199 
200 void
201 NBLoadedSUMOTLDef::removeConnection(const NBConnection& conn, bool reconstruct) {
202  NBConnectionVector::iterator it = myControlledLinks.begin();
203  // find the connection but ignore its TLIndex since it might have been
204  // invalidated by an earlier removal
205  for (; it != myControlledLinks.end(); ++it) {
206  if (it->getFrom() == conn.getFrom() &&
207  it->getTo() == conn.getTo() &&
208  it->getFromLane() == conn.getFromLane() &&
209  it->getToLane() == conn.getToLane()) {
210  break;
211  }
212  }
213  if (it == myControlledLinks.end()) {
214  // a traffic light doesn't always controll all connections at a junction
215  // especially when using the option --tls.join
216  return;
217  }
218  myReconstructRemovedConnections |= reconstruct;
219 }
220 
221 
222 void
224  myOffset = offset;
225  myTLLogic->setOffset(offset);
226 }
227 
228 
229 void
231  myType = type;
232  myTLLogic->setType(type);
233 }
234 
235 
236 void
238  if (myControlledLinks.size() == 0) {
240  }
241  myIncomingEdges.clear();
242  EdgeVector myOutgoing;
243  // collect the edges from the participating nodes
244  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
245  const EdgeVector& incoming = (*i)->getIncomingEdges();
246  copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
247  const EdgeVector& outgoing = (*i)->getOutgoingEdges();
248  copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
249  }
250  // check which of the edges are completely within the junction
251  // and which are uncontrolled as well (we already know myControlledLinks)
252  for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) {
253  NBEdge* edge = *j;
254  // an edge lies within the logic if it is outgoing as well as incoming
255  EdgeVector::iterator k = std::find(myOutgoing.begin(), myOutgoing.end(), edge);
256  if (k != myOutgoing.end()) {
257  if (myControlledInnerEdges.count(edge->getID()) == 0) {
258  bool controlled = false;
259  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
260  if ((*it).getFrom() == edge) {
261  controlled = true;
262  break;
263  }
264  }
265  if (controlled) {
266  myControlledInnerEdges.insert(edge->getID());
267  } else {
268  myEdgesWithin.push_back(edge);
269  (*j)->setInsideTLS();
270  ++j; //j = myIncomingEdges.erase(j);
271  continue;
272  }
273  }
274  }
275  ++j;
276  }
277 }
278 
279 
280 void
282  if (myControlledLinks.size() == 0) {
283  // maybe we only loaded a different program for a default traffic light.
284  // Try to build links now.
285  myOriginalNodes.insert(myControlledNodes.begin(), myControlledNodes.end());
286  collectAllLinks();
287  }
288 }
289 
290 
292 void
293 NBLoadedSUMOTLDef::shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold) {
294  // avoid shifting twice if the edge is incoming and outgoing to a joined TLS
295  if (myShifted.count(edge) == 0) {
297  myShifted.insert(edge);
298  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
299  (*it).shiftLaneIndex(edge, offset, threshold);
300  }
301  }
302 }
303 
304 void
306  const int size = myTLLogic->getNumLinks();
307  int noLinksAll = 0;
308  for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
309  const NBConnection& c = *it;
311  noLinksAll = MAX2(noLinksAll, (int)c.getTLIndex() + 1);
312  }
313  }
314  const int numNormalLinks = noLinksAll;
315  int oldCrossings = 0;
316  // collect crossings
317  bool customIndex = false;
318  std::vector<NBNode::Crossing*> crossings;
319  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
320  const std::vector<NBNode::Crossing*>& c = (*i)->getCrossings();
321  // set tl indices for crossings
322  customIndex |= (*i)->setCrossingTLIndices(getID(), noLinksAll);
323  copy(c.begin(), c.end(), std::back_inserter(crossings));
324  noLinksAll += (int)c.size();
325  oldCrossings += (*i)->numCrossingsFromSumoNet();
326  }
327  if ((int)crossings.size() != oldCrossings) {
328  std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases();
329  // do not rebuilt crossing states there are custom indices and the state string is long enough
330  if (phases.size() > 0 && (
331  (int)(phases.front().state.size()) < noLinksAll ||
332  ((int)(phases.front().state.size()) > noLinksAll && !customIndex))) {
333  // collect edges
334  EdgeVector fromEdges(size, (NBEdge*)nullptr);
335  EdgeVector toEdges(size, (NBEdge*)nullptr);
336  std::vector<int> fromLanes(size, 0);
337  collectEdgeVectors(fromEdges, toEdges, fromLanes);
338  const std::string crossingDefaultState(crossings.size(), 'r');
339 
340  // rebuild the logic (see NBOwnTLDef.cpp::myCompute)
342  SUMOTime brakingTime = TIME2STEPS(computeBrakingTime(OptionsCont::getOptions().getFloat("tls.yellow.min-decel")));
343  //std::cout << "patchIfCrossingsAdded for " << getID() << " numPhases=" << phases.size() << "\n";
344  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
345  const std::string state = it->state.substr(0, numNormalLinks) + crossingDefaultState;
346  NBOwnTLDef::addPedestrianPhases(newLogic, it->duration, it->minDur, it->maxDur, state, crossings, fromEdges, toEdges);
347  }
348  NBOwnTLDef::addPedestrianScramble(newLogic, noLinksAll, TIME2STEPS(10), brakingTime, crossings, fromEdges, toEdges);
349 
350  delete myTLLogic;
351  myTLLogic = newLogic;
352  } else if (phases.size() == 0) {
353  WRITE_WARNING("Could not patch tlLogic '" + getID() + "' for changed crossings");
354  }
355  }
356 }
357 
358 
359 void
360 NBLoadedSUMOTLDef::collectEdgeVectors(EdgeVector& fromEdges, EdgeVector& toEdges, std::vector<int>& fromLanes) const {
361  assert(fromEdges.size() > 0);
362  assert(fromEdges.size() == toEdges.size());
363  const int size = (int)fromEdges.size();
364 
365  for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
366  const NBConnection& c = *it;
368  if (c.getTLIndex() >= size) {
369  throw ProcessError("Invalid linkIndex " + toString(c.getTLIndex()) + " for traffic light '" + getID() +
370  "' with " + toString(size) + " links.");
371  }
372  fromEdges[c.getTLIndex()] = c.getFrom();
373  toEdges[c.getTLIndex()] = c.getTo();
374  fromLanes[c.getTLIndex()] = c.getFromLane();
375  }
376  }
377 }
378 
379 
380 void
382  if (!amInvalid() && !myNeedsContRelationReady) {
383  myNeedsContRelation.clear();
384  myRightOnRedConflicts.clear();
385  const bool controlledWithin = !OptionsCont::getOptions().getBool("tls.uncontrolled-within");
386  const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases();
387  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
388  const std::string state = (*it).state;
389  for (NBConnectionVector::const_iterator it1 = myControlledLinks.begin(); it1 != myControlledLinks.end(); it1++) {
390  const NBConnection& c1 = *it1;
391  const int i1 = c1.getTLIndex();
392  if (i1 == NBConnection::InvalidTlIndex || (state[i1] != 'g' && state[i1] != 's') || c1.getFrom() == nullptr || c1.getTo() == nullptr) {
393  continue;
394  }
395  for (NBConnectionVector::const_iterator it2 = myControlledLinks.begin(); it2 != myControlledLinks.end(); it2++) {
396  const NBConnection& c2 = *it2;
397  const int i2 = c2.getTLIndex();
399  && i2 != i1
400  && (state[i2] == 'G' || state[i2] == 'g')
401  && c2.getFrom() != nullptr && c2.getTo() != nullptr) {
402  const bool rightTurnConflict = NBNode::rightTurnConflict(
403  c1.getFrom(), c1.getTo(), c1.getFromLane(), c2.getFrom(), c2.getTo(), c2.getFromLane());
404  const bool forbidden = forbids(c2.getFrom(), c2.getTo(), c1.getFrom(), c1.getTo(), true, controlledWithin);
405  const bool isFoes = foes(c2.getFrom(), c2.getTo(), c1.getFrom(), c1.getTo()) && !c2.getFrom()->isTurningDirectionAt(c2.getTo());
406  if (forbidden || rightTurnConflict) {
407  myNeedsContRelation.insert(StreamPair(c1.getFrom(), c1.getTo(), c2.getFrom(), c2.getTo()));
408  }
409  if (isFoes) {
410  myRightOnRedConflicts.insert(std::make_pair(i1, i2));
411  }
412  //std::cout << getID() << " i1=" << i1 << " i2=" << i2 << " rightTurnConflict=" << rightTurnConflict << " forbidden=" << forbidden << " isFoes=" << isFoes << "\n";
413  }
414  }
415  }
416  }
417  }
420 }
421 
422 
423 bool
424 NBLoadedSUMOTLDef::rightOnRedConflict(int index, int foeIndex) const {
425  if (amInvalid()) {
426  return false;
427  }
431  }
432  return std::find(myRightOnRedConflicts.begin(), myRightOnRedConflicts.end(), std::make_pair(index, foeIndex)) != myRightOnRedConflicts.end();
433 }
434 
435 
436 void
437 NBLoadedSUMOTLDef::registerModifications(bool addedConnections, bool removedConnections) {
438  myReconstructAddedConnections |= addedConnections;
439  myReconstructRemovedConnections |= removedConnections;
440 }
441 
442 void
444  const bool netedit = NBNetBuilder::runningNetedit();
445 #ifdef DEBUG_RECONSTRUCTION
447  std::cout << " reconstructLogic added=" << myReconstructAddedConnections << " removed=" << myReconstructRemovedConnections << " valid=" << hasValidIndices() << " oldLinks:\n";
448  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); ++it) {
449  std::cout << " " << *it << "\n";
450  }
451 #endif
454  // do not rebuild the logic when running netedit and all links are already covered by the program
455  if (!myPhasesLoaded && !(netedit && hasValidIndices())) {
456  // rebuild the logic from scratch
457  // XXX if a connection with the same from- and to-edge already exisits, its states could be copied instead
460  dummy.setProgramID(getProgramID());
465  for (std::vector<NBNode*>::const_iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
466  (*i)->removeTrafficLight(&dummy);
467  }
468  delete myTLLogic;
469  myTLLogic = newLogic;
470  if (newLogic != nullptr) {
471  newLogic->setID(getID());
472  newLogic->setType(getType());
473  newLogic->setOffset(getOffset());
475  // reset crossing custom indices
476  for (NBNode* n : myControlledNodes) {
477  for (NBNode::Crossing* c : n->getCrossings()) {
478  c->customTLIndex = NBConnection::InvalidTlIndex;
479  }
480  }
481 
482  }
483  } else {
485  }
486  }
489  // for each connection, check whether it is still valid
490  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end();) {
491  const NBConnection con = (*it);
492  if (// edge still exists
493  std::find(myIncomingEdges.begin(), myIncomingEdges.end(), con.getFrom()) != myIncomingEdges.end()
494  // connection still exists
495  && con.getFrom()->hasConnectionTo(con.getTo(), con.getToLane(), con.getFromLane())
496  // connection is still set to be controlled
497  && con.getFrom()->mayBeTLSControlled(con.getFromLane(), con.getTo(), con.getToLane())) {
498  it++;
499  } else {
500  // remove connection
501  const int removed = con.getTLIndex();
502  it = myControlledLinks.erase(it);
503  // no automatic modificaions when running netedit
504  if (!myPhasesLoaded && !(netedit && hasValidIndices())) {
505  // shift index off successive connections and remove entry from all phases if the tlIndex was only used by this connection
506  bool exclusive = true;
507  for (NBConnection& other : myControlledLinks) {
508  if (other != con && other.getTLIndex() == removed) {
509  exclusive = false;
510  break;
511  }
512  }
513  if (exclusive) {
514  // shift indices above the removed index downward
515  for (NBConnection& other : myControlledLinks) {
516  if (other.getTLIndex() > removed) {
517  other.setTLIndex(other.getTLIndex() - 1);
518  }
519  }
520  // shift crossing custom indices above the removed index downward
521  for (NBNode* n : myControlledNodes) {
522  for (NBNode::Crossing* c : n->getCrossings()) {
523  if (c->customTLIndex > removed) {
524  c->customTLIndex--;
525  }
526  }
527  }
528  // rebuild the logic
529  const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases();
531  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
532  std::string newState = it->state;
533  newState.erase(newState.begin() + removed);
534  newLogic->addStep(it->duration, newState);
535  }
536  delete myTLLogic;
537  myTLLogic = newLogic;
538  }
539  }
540  }
541  }
543  }
544 #ifdef DEBUG_RECONSTRUCTION
545  if (debugPrintModified) {
546  std::cout << " newLinks:\n";
547  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); ++it) {
548  std::cout << " " << *it << "\n";
549  }
550  }
551 #endif
552 }
553 
554 
555 int
557  int maxIndex = -1;
558  for (const NBConnection& c : myControlledLinks) {
559  maxIndex = MAX2(maxIndex, c.getTLIndex());
560  }
561  for (NBNode* n : myControlledNodes) {
562  for (NBNode::Crossing* c : n->getCrossings()) {
563  maxIndex = MAX2(maxIndex, c->tlLinkIndex);
564  maxIndex = MAX2(maxIndex, c->tlLinkIndex2);
565  }
566  }
567  return maxIndex;
568 }
569 
570 
571 int
573  return myTLLogic->getNumLinks() - 1;
574 }
575 
576 
577 bool
579  for (const NBConnection& c : myControlledLinks) {
580  if (c.getTLIndex() == NBConnection::InvalidTlIndex) {
581  return false;
582  }
583  }
584  for (NBNode* n : myControlledNodes) {
585  for (NBNode::Crossing* c : n->getCrossings()) {
586  if (c->tlLinkIndex == NBConnection::InvalidTlIndex) {
587  return false;
588  }
589  }
590  }
591  // method getMaxIndex() is const but cannot be declare as such due to inheritance
592  return const_cast<NBLoadedSUMOTLDef*>(this)->getMaxIndex() < myTLLogic->getNumLinks();
593 }
594 
595 
596 bool
598  const int maxIndex = getMaxIndex();
599  if (maxIndex >= 0 && maxIndex + 1 < myTLLogic->getNumLinks()) {
600  myTLLogic->setStateLength(maxIndex + 1);
601  return true;
602  }
603  return false;
604 }
605 
606 void
610  const int maxIndex = MAX2(getMaxIndex(), def->getMaxIndex());
611  myTLLogic->setStateLength(maxIndex + 1);
612  myControlledLinks.insert(myControlledLinks.end(), def->getControlledLinks().begin(), def->getControlledLinks().end());
613  myOriginalNodes.insert(def->getNodes().begin(), def->getNodes().end());
614 }
615 
616 bool
618  // count how often each index is used
619  std::map<int, int> indexUsage;
620  for (const NBConnection& c : myControlledLinks) {
621  indexUsage[c.getTLIndex()]++;
622  }
623  for (NBNode* n : myControlledNodes) {
624  for (NBNode::Crossing* c : n->getCrossings()) {
625  indexUsage[c->tlLinkIndex]++;
626  indexUsage[c->tlLinkIndex2]++;
627  }
628  }
629  for (auto it : indexUsage) {
630  if (it.first >= 0 && it.second > 1) {
631  return true;
632  }
633  }
634  return false;
635 }
636 
637 void
639  bool hasMinMaxDur = false;
640  for (auto phase : myTLLogic->getPhases()) {
641  if (phase.maxDur != UNSPECIFIED_DURATION) {
642  std::cout << " phase=" << phase.state << " maxDur=" << phase.maxDur << "\n";
643  hasMinMaxDur = true;
644  }
645  }
646  if (!hasMinMaxDur) {
647  const SUMOTime minMinDur = TIME2STEPS(OptionsCont::getOptions().getInt("tls.min-dur"));
648  const SUMOTime maxDur = TIME2STEPS(OptionsCont::getOptions().getInt("tls.max-dur"));
649  std::set<int> yellowIndices;
650  for (auto phase : myTLLogic->getPhases()) {
651  for (int i = 0; i < (int)phase.state.size(); i++) {
652  if (phase.state[i] == 'y' || phase.state[i] == 'Y') {
653  yellowIndices.insert(i);
654  }
655  }
656  }
657  for (int ip = 0; ip < (int)myTLLogic->getPhases().size(); ip++) {
658  bool needMinMaxDur = false;
659  auto phase = myTLLogic->getPhases()[ip];
660  std::set<int> greenIndices;
661  if (phase.state.find_first_of("yY") != std::string::npos) {
662  continue;
663  }
664  for (int i = 0; i < (int)phase.state.size(); i++) {
665  if (yellowIndices.count(i) != 0 && phase.state[i] == 'G') {
666  needMinMaxDur = true;
667  greenIndices.insert(i);
668  }
669  }
670  if (needMinMaxDur) {
671  double maxSpeed = 0;
672  for (NBConnection& c : myControlledLinks) {
673  if (greenIndices.count(c.getTLIndex()) != 0) {
674  maxSpeed = MAX2(maxSpeed, c.getFrom()->getLaneSpeed(c.getFromLane()));
675  }
676  }
677  // 5s at 50km/h, 10s at 80km/h, rounded to full seconds
678  const double minDurBySpeed = maxSpeed * 3.6 / 6 - 3.3;
679  SUMOTime minDur = MAX2(minMinDur, TIME2STEPS(floor(minDurBySpeed + 0.5)));
680  myTLLogic->setPhaseMinDuration(ip, minDur);
681  myTLLogic->setPhaseMaxDuration(ip, maxDur);
682  }
683  }
684  }
685 }
686 /****************************************************************************/
687 
NBLoadedSUMOTLDef::reconstructLogic
void reconstructLogic()
adapt to removal or addition of connections
Definition: NBLoadedSUMOTLDef.cpp:443
NBTrafficLightDefinition::StreamPair
data structure for caching needsCont information
Definition: NBTrafficLightDefinition.h:430
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:31
ToString.h
NBTrafficLightDefinition::compute
NBTrafficLightLogic * compute(OptionsCont &oc)
Computes the traffic light logic.
Definition: NBTrafficLightDefinition.cpp:106
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
NBLoadedSUMOTLDef::myTLLogic
NBTrafficLightLogic * myTLLogic
phases are added directly to myTLLogic which is then returned in myCompute()
Definition: NBLoadedSUMOTLDef.h:183
NBConnection::getTLIndex
int getTLIndex() const
returns the index within the controlling tls or InvalidTLIndex if this link is unontrolled
Definition: NBConnection.h:93
NBLoadedSUMOTLDef::collectEdgeVectors
void collectEdgeVectors(EdgeVector &fromEdges, EdgeVector &toEdges, std::vector< int > &fromLanes) const
Collects the edges for each tlIndex.
Definition: NBLoadedSUMOTLDef.cpp:360
OptionsCont.h
NBLoadedSUMOTLDef::removeConnection
void removeConnection(const NBConnection &conn, bool reconstruct=true)
removes the given connection from the traffic light if recontruct=true, reconstructs the logic and in...
Definition: NBLoadedSUMOTLDef.cpp:201
NBTrafficLightDefinition::myControlledNodes
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
Definition: NBTrafficLightDefinition.h:406
NBTrafficLightLogic.h
NBOwnTLDef::addPedestrianPhases
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
Definition: NBOwnTLDef.cpp:650
MsgHandler.h
NBLoadedSUMOTLDef::hasValidIndices
bool hasValidIndices() const
return whether all tls link indices are valid
Definition: NBLoadedSUMOTLDef.cpp:578
EdgeVector
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:34
NBLoadedSUMOTLDef::~NBLoadedSUMOTLDef
~NBLoadedSUMOTLDef()
Destructor.
Definition: NBLoadedSUMOTLDef.cpp:77
NBTrafficLightDefinition::myControlledLinks
NBConnectionVector myControlledLinks
The list of controlled links.
Definition: NBTrafficLightDefinition.h:415
NBEdge::isTurningDirectionAt
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:2756
NBTrafficLightLogic::closeBuilding
void closeBuilding(bool checkVarDurations=true)
closes the building process
Definition: NBTrafficLightLogic.cpp:144
TrafficLightType
TrafficLightType
Definition: SUMOXMLDefinitions.h:1197
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
NBConnection::getFrom
NBEdge * getFrom() const
returns the from-edge (start of the connection)
Definition: NBConnection.cpp:89
NBLoadedSUMOTLDef::guessMinMaxDuration
void guessMinMaxDuration()
heuristically add minDur and maxDur when switching from tlType fixed to actuated
Definition: NBLoadedSUMOTLDef.cpp:638
NBTrafficLightDefinition::myOffset
SUMOTime myOffset
The offset in the program.
Definition: NBTrafficLightDefinition.h:424
NBOwnTLDef::addPedestrianScramble
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
Definition: NBOwnTLDef.cpp:995
NBEdge::setControllingTLInformation
bool setControllingTLInformation(const NBConnection &c, const std::string &tlID)
Returns if the link could be set as to be controlled.
Definition: NBEdge.cpp:2820
NBConnection::InvalidTlIndex
static const int InvalidTlIndex
Definition: NBConnection.h:125
NBConnection::getTo
NBEdge * getTo() const
returns the to-edge (end of the connection)
Definition: NBConnection.cpp:95
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:222
NBLoadedSUMOTLDef::addPhase
void addPhase(SUMOTime duration, const std::string &state, SUMOTime minDur, SUMOTime maxDur, const std::vector< int > &next, const std::string &name)
Adds a phase to the logic the new phase is inserted at the end of the list of already added phases.
Definition: NBLoadedSUMOTLDef.cpp:172
NBOwnTLDef
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:46
NBLoadedSUMOTLDef::connection_equal
class for identifying connections
Definition: NBLoadedSUMOTLDef.h:214
NBTrafficLightDefinition.h
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
NBLoadedSUMOTLDef::setOffset
void setOffset(SUMOTime offset)
Sets the offset of this tls.
Definition: NBLoadedSUMOTLDef.cpp:223
NBTrafficLightDefinition::DummyID
static const std::string DummyID
id for temporary definitions
Definition: NBTrafficLightDefinition.h:378
NBTrafficLightDefinition::getOffset
SUMOTime getOffset()
Returns the offset.
Definition: NBTrafficLightDefinition.h:324
NBTrafficLightDefinition::myType
TrafficLightType myType
The algorithm type for the traffic light.
Definition: NBTrafficLightDefinition.h:427
NBLoadedSUMOTLDef::getMaxIndex
int getMaxIndex()
return the highest known tls link index used by any controlled connection or crossing
Definition: NBLoadedSUMOTLDef.cpp:556
NBLoadedSUMOTLDef::initNeedsContRelation
void initNeedsContRelation() const
Definition: NBLoadedSUMOTLDef.cpp:381
NBTrafficLightLogic::getType
TrafficLightType getType() const
get the algorithm type (static etc..)
Definition: NBTrafficLightLogic.h:226
NBTrafficLightLogic::setOffset
void setOffset(SUMOTime offset)
Sets the offset of this tls.
Definition: NBTrafficLightLogic.h:190
NBLoadedSUMOTLDef::addConnection
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex, int linkIndex2, bool reconstruct=true)
Adds a connection and immediately informs the edges.
Definition: NBLoadedSUMOTLDef.cpp:95
NBLoadedSUMOTLDef::registerModifications
void registerModifications(bool addedConnections, bool removedConnections)
register changes that necessitate recomputation
Definition: NBLoadedSUMOTLDef.cpp:437
NBTrafficLightDefinition::collectEdges
virtual void collectEdges()
Build the list of participating edges.
Definition: NBTrafficLightDefinition.cpp:185
NBTrafficLightDefinition::setProgramID
void setProgramID(const std::string &programID)
Sets the programID.
Definition: NBTrafficLightDefinition.h:316
NBEdge
The representation of a single edge during network building.
Definition: NBEdge.h:91
NBTrafficLightLogic::addStep
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.
Definition: NBTrafficLightLogic.cpp:69
NBTrafficLightDefinition::getMaxIndex
virtual int getMaxIndex()=0
Returns the maximum index controlled by this traffic light and assigned to a connection.
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
NBTrafficLightDefinition::myRightOnRedConflicts
RightOnRedConflicts myRightOnRedConflicts
Definition: NBTrafficLightDefinition.h:465
Parameterised::getParametersMap
const std::map< std::string, std::string > & getParametersMap() const
Returns the inner key/value map.
Definition: Parameterised.cpp:106
NBLoadedSUMOTLDef::myOriginalNodes
std::set< NBNode * > myOriginalNodes
The original nodes for which the loaded logic is valid.
Definition: NBLoadedSUMOTLDef.h:186
NBEdge::getToNode
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:498
Parameterised::updateParameters
void updateParameters(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
Definition: Parameterised.cpp:58
NBTrafficLightDefinition::getType
TrafficLightType getType() const
get the algorithm type (static etc..)
Definition: NBTrafficLightDefinition.h:330
NBTrafficLightLogic::setPhaseMinDuration
void setPhaseMinDuration(int phaseIndex, SUMOTime duration)
Definition: NBTrafficLightLogic.cpp:202
TIME2STEPS
#define TIME2STEPS(x)
Definition: SUMOTime.h:58
NBTrafficLightDefinition::UNSPECIFIED_DURATION
static const SUMOTime UNSPECIFIED_DURATION
Definition: NBTrafficLightDefinition.h:70
NBTrafficLightLogic::setStateLength
void setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
Definition: NBTrafficLightLogic.cpp:111
NBLoadedSUMOTLDef::rightOnRedConflict
bool rightOnRedConflict(int index, int foeIndex) const
whether the given index must yield to the foeIndex while turing right on a red light
Definition: NBLoadedSUMOTLDef.cpp:424
NBLoadedSUMOTLDef::collectLinks
void collectLinks()
Collects the links participating in this traffic light (only if not previously loaded)
Definition: NBLoadedSUMOTLDef.cpp:281
NBTrafficLightDefinition::getControlledLinks
const NBConnectionVector & getControlledLinks() const
returns the controlled links (depends on previous call to collectLinks)
Definition: NBTrafficLightDefinition.h:294
NBLoadedSUMOTLDef::myReconstructAddedConnections
bool myReconstructAddedConnections
whether the logic must be reconstructed
Definition: NBLoadedSUMOTLDef.h:195
NBTrafficLightLogic::getPhases
const std::vector< PhaseDefinition > & getPhases() const
Returns the phases.
Definition: NBTrafficLightLogic.h:206
NBTrafficLightDefinition::myRightOnRedConflictsReady
bool myRightOnRedConflictsReady
Definition: NBTrafficLightDefinition.h:466
NBTrafficLightLogic::getNumLinks
int getNumLinks()
Returns the number of participating links.
Definition: NBTrafficLightLogic.h:221
NBConnection::getToLane
int getToLane() const
returns the to-lane
Definition: NBConnection.cpp:240
NBEdge::getNumLanes
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:477
NBNetBuilder.h
NBTrafficLightDefinition::computeBrakingTime
int computeBrakingTime(double minDecel) const
Computes the time vehicles may need to brake.
Definition: NBTrafficLightDefinition.cpp:137
ProcessError
Definition: UtilExceptions.h:39
NBTrafficLightDefinition::getIncomingEdges
const EdgeVector & getIncomingEdges() const
Returns the list of incoming edges (must be build first)
Definition: NBTrafficLightDefinition.cpp:446
NBTrafficLightDefinition::getNodes
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
Definition: NBTrafficLightDefinition.h:172
NBNode::rightTurnConflict
static bool rightTurnConflict(const NBEdge *from, const NBEdge *to, int fromLane, const NBEdge *prohibitorFrom, const NBEdge *prohibitorTo, int prohibitorFromLane, bool lefthand=false)
return whether the given laneToLane connection is a right turn which must yield to a bicycle crossing...
Definition: NBNode.cpp:1698
NBTrafficLightDefinition::myNeedsContRelation
NeedsContRelation myNeedsContRelation
Definition: NBTrafficLightDefinition.h:461
NBEdge::mayBeTLSControlled
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
return true if certain connection must be controlled by TLS
Definition: NBEdge.cpp:2809
NBLoadedSUMOTLDef::myShifted
std::set< NBEdge * > myShifted
set of edges with shifted lane indices (to avoid shifting twice)
Definition: NBLoadedSUMOTLDef.h:192
NBConnection
Definition: NBConnection.h:43
NBLoadedSUMOTLDef::cleanupStates
bool cleanupStates()
Definition: NBLoadedSUMOTLDef.cpp:597
NBTrafficLightDefinition::myNeedsContRelationReady
bool myNeedsContRelationReady
Definition: NBTrafficLightDefinition.h:462
NBTrafficLightDefinition::myEdgesWithin
EdgeVector myEdgesWithin
The list of edges within the area controlled by the tls.
Definition: NBTrafficLightDefinition.h:412
NBLoadedSUMOTLDef::replaceRemoved
void replaceRemoved(NBEdge *removed, int removedLane, NBEdge *by, int byLane)
Replaces a removed edge/lane.
Definition: NBLoadedSUMOTLDef.cpp:163
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
NBLoadedSUMOTLDef::getMaxValidIndex
int getMaxValidIndex()
Returns the maximum index controlled by this traffic light.
Definition: NBLoadedSUMOTLDef.cpp:572
NBLoadedSUMOTLDef::myCompute
NBTrafficLightLogic * myCompute(int brakingTimeSeconds)
Computes the traffic light logic finally in dependence to the type.
Definition: NBLoadedSUMOTLDef.cpp:83
NBTrafficLightDefinition::myControlledInnerEdges
std::set< std::string > myControlledInnerEdges
Set of inner edges that shall be controlled, though.
Definition: NBTrafficLightDefinition.h:418
NBLoadedSUMOTLDef::myReconstructRemovedConnections
bool myReconstructRemovedConnections
Definition: NBLoadedSUMOTLDef.h:196
NBTrafficLightDefinition::foes
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.
Definition: NBTrafficLightDefinition.cpp:391
NBLoadedSUMOTLDef::remapRemoved
void remapRemoved(NBEdge *removed, const EdgeVector &incoming, const EdgeVector &outgoing)
Replaces occurences of the removed edge in incoming/outgoing edges of all definitions.
Definition: NBLoadedSUMOTLDef.cpp:159
NBTrafficLightLogic::setType
void setType(TrafficLightType type)
set the algorithm type (static etc..)
Definition: NBTrafficLightLogic.h:231
NBTrafficLightDefinition::setParticipantsInformation
virtual void setParticipantsInformation()
Builds the list of participating nodes/edges/links.
Definition: NBTrafficLightDefinition.cpp:157
NBLoadedSUMOTLDef::NBLoadedSUMOTLDef
NBLoadedSUMOTLDef(const std::string &id, const std::string &programID, SUMOTime offset, TrafficLightType type)
Constructor.
Definition: NBLoadedSUMOTLDef.cpp:46
NBTrafficLightDefinition::getProgramID
const std::string & getProgramID() const
Returns the ProgramID.
Definition: NBTrafficLightDefinition.h:308
NBTrafficLightDefinition::addNode
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
Definition: NBTrafficLightDefinition.cpp:414
NBLoadedSUMOTLDef::patchIfCrossingsAdded
void patchIfCrossingsAdded()
repair the plan if controlled nodes received pedestrian crossings
Definition: NBLoadedSUMOTLDef.cpp:305
config.h
NBNetBuilder::runningNetedit
static bool runningNetedit()
whether netbuilding takes place in the context of NETEDIT
Definition: NBNetBuilder.cpp:700
NBTrafficLightLogic
A SUMO-compliant built logic for a traffic light.
Definition: NBTrafficLightLogic.h:51
NBNode
Represents a single node (junction) during network building.
Definition: NBNode.h:67
NBLoadedSUMOTLDef::amInvalid
bool amInvalid() const
Definition: NBLoadedSUMOTLDef.cpp:178
NBTrafficLightDefinition::myIncomingEdges
EdgeVector myIncomingEdges
The list of incoming edges.
Definition: NBTrafficLightDefinition.h:409
NBOwnTLDef.h
NBLoadedSUMOTLDef::myPhasesLoaded
bool myPhasesLoaded
Definition: NBLoadedSUMOTLDef.h:197
NBLoadedSUMOTLDef.h
NBOwnTLDef::setTLControllingInformation
void setTLControllingInformation() const
Informs edges about being controlled by a tls.
Definition: NBOwnTLDef.cpp:735
NBEdge::hasConnectionTo
bool hasConnectionTo(NBEdge *destEdge, int destLane, int fromLane=-1) const
Retrieves info about a connection to a certain lane of a certain edge.
Definition: NBEdge.cpp:1143
NBNode::Crossing
A definition of a pedestrian crossing.
Definition: NBNode.h:131
NBTrafficLightDefinition::collectAllLinks
void collectAllLinks()
helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
Definition: NBTrafficLightDefinition.cpp:452
NBNode.h
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
NBEdge::getFromNode
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:491
NBConnection::getFromLane
int getFromLane() const
returns the from-lane
Definition: NBConnection.cpp:234
NBTrafficLightDefinition::forbids
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.
Definition: NBTrafficLightDefinition.cpp:272
NBLoadedSUMOTLDef::joinLogic
void joinLogic(NBTrafficLightDefinition *def)
join nodes and states from the given logic (append red state)
Definition: NBLoadedSUMOTLDef.cpp:607
NBLoadedSUMOTLDef::setTLControllingInformation
void setTLControllingInformation() const
Informs edges about being controlled by a tls.
Definition: NBLoadedSUMOTLDef.cpp:124
NBTrafficLightDefinition
The base class for traffic light logic definitions.
Definition: NBTrafficLightDefinition.h:67
NBLoadedSUMOTLDef::collectEdges
void collectEdges()
Build the list of participating edges.
Definition: NBLoadedSUMOTLDef.cpp:237
Named::setID
void setID(const std::string &newID)
resets the id
Definition: Named.h:84
NBLoadedSUMOTLDef::usingSignalGroups
bool usingSignalGroups() const
whether this definition uses signal group (multiple connections with the same link index)
Definition: NBLoadedSUMOTLDef.cpp:617
NBTrafficLightLogic::setPhaseMaxDuration
void setPhaseMaxDuration(int phaseIndex, SUMOTime duration)
Definition: NBTrafficLightLogic.cpp:208
NBLoadedSUMOTLDef::setType
void setType(TrafficLightType type)
Sets the algorithm type of this tls.
Definition: NBLoadedSUMOTLDef.cpp:230
NBLoadedSUMOTLDef::shiftTLConnectionLaneIndex
void shiftTLConnectionLaneIndex(NBEdge *edge, int offset, int threshold=-1)
patches signal plans by modifying lane indices with the given offset, only indices with a value above...
Definition: NBLoadedSUMOTLDef.cpp:293
NBEdge::getID
const std::string & getID() const
Definition: NBEdge.h:1380
NBLoadedSUMOTLDef
A loaded (complete) traffic light logic.
Definition: NBLoadedSUMOTLDef.h:44