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