Eclipse SUMO - Simulation of Urban MObility
MSTrafficLightLogic.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // The parent class for traffic light logics
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <cassert>
25 #include <string>
26 #include <iostream>
27 #include <map>
28 #include <microsim/MSLink.h>
29 #include <microsim/MSLane.h>
32 #include <microsim/MSNet.h>
33 #include <microsim/MSEdge.h>
34 #include <microsim/MSGlobals.h>
35 #include "MSTLLogicControl.h"
36 #include "MSTrafficLightLogic.h"
37 
38 
39 // ===========================================================================
40 // static value definitions
41 // ===========================================================================
43 
44 
45 // ===========================================================================
46 // member method definitions
47 // ===========================================================================
48 /* -------------------------------------------------------------------------
49  * member method definitions
50  * ----------------------------------------------------------------------- */
52  MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch)
53  : myTLControl(tlcontrol), myTLLogic(tlLogic),
54  myAssumedNextSwitch(nextSwitch), myAmValid(true) {}
55 
56 
58 
59 
60 
63  // check whether this command has been descheduled
64  if (!myAmValid) {
65  return 0;
66  }
67  int step1 = myTLLogic->getCurrentPhaseIndex();
68  SUMOTime next = myTLLogic->trySwitch();
69  int step2 = myTLLogic->getCurrentPhaseIndex();
70  if (step1 != step2) {
71  if (myTLLogic->isActive()) {
72  // execute any action connected to this tls
73  const MSTLLogicControl::TLSLogicVariants& vars = myTLControl.get(myTLLogic->getID());
74  // set link priorities
75  myTLLogic->setTrafficLightSignals(t);
76  // execute switch actions
78  }
79  }
80  myAssumedNextSwitch += next;
81  return next;
82 }
83 
84 
85 void
87  if (tlLogic == myTLLogic) {
88  myAmValid = false;
89  myAssumedNextSwitch = -1;
90  }
91 }
92 
95  if (myTLLogic->getDefaultCycleTime() == DELTA_T) {
96  // MSRailSignal
97  return newTime;
98  } else {
99  UNUSED_PARAMETER(currentTime);
100  UNUSED_PARAMETER(execTime);
101  // XXX changeStepAndDuration (computed as in NLJunctionControlBuilder::closeTrafficLightLogic
102  return newTime;
103  }
104 }
105 
106 /* -------------------------------------------------------------------------
107  * member method definitions
108  * ----------------------------------------------------------------------- */
110  const std::string& programID, const TrafficLightType logicType, const SUMOTime delay,
111  const std::map<std::string, std::string>& parameters) :
112  Named(id), Parameterised(parameters),
113  myProgramID(programID),
114  myLogicType(logicType),
117  myAmActive(true) {
118  mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
120 }
121 
122 
123 void
125  const Phases& phases = getPhases();
126  if (phases.size() > 0 && MSGlobals::gUseMesoSim) {
128  }
129  if (phases.size() > 1) {
130  bool haveWarnedAboutUnusedStates = false;
131  std::vector<bool> foundGreen(phases.front()->getState().size(), false);
132  for (int i = 0; i < (int)phases.size(); ++i) {
133  // warn about unused states
134  std::vector<int> nextPhases;
135  nextPhases.push_back((i + 1) % phases.size());
136  bool iNextDefault = true;
137  if (phases[i]->nextPhases.size() > 0) {
138  nextPhases = phases[i]->nextPhases;
139  iNextDefault = false;
140  }
141  for (int iNext : nextPhases) {
142  if (iNext < 0 || iNext >= (int)phases.size()) {
143  throw ProcessError("Invalid nextPhase " + toString(iNext) + " in tlLogic '" + getID()
144  + "', program '" + getProgramID() + "' with " + toString(phases.size()) + " phases");
145  }
146  const std::string optionalFrom = iNextDefault ? "" : " from phase " + toString(i);
147  const std::string& state1 = phases[i]->getState();
148  const std::string& state2 = phases[iNext]->getState();
149  assert(state1.size() == state2.size());
150  if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size() + myIgnoredIndices.size()) {
151  WRITE_WARNING("Unused states in tlLogic '" + getID()
152  + "', program '" + getProgramID() + "' in phase " + toString(i)
153  + " after tl-index " + toString((int)myLanes.size() - 1));
154  haveWarnedAboutUnusedStates = true;
155  }
156  // detect illegal states
157  const std::string::size_type illegal = state1.find_first_not_of(SUMOXMLDefinitions::ALLOWED_TLS_LINKSTATES);
158  if (std::string::npos != illegal) {
159  throw ProcessError("Illegal character '" + toString(state1[illegal]) + "' in tlLogic '" + getID()
160  + "', program '" + getProgramID() + "' in phase " + toString(i));
161  }
162  // warn about transitions from green to red without intermediate yellow
163  bool haveWarned = false;
164  for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()) && !haveWarned; ++j) {
165  if ((LinkState)state2[j] == LINKSTATE_TL_RED
166  && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
167  || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
168  for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
169  if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
170  WRITE_WARNING("Missing yellow phase in tlLogic '" + getID()
171  + "', program '" + getProgramID() + "' for tl-index " + toString(j)
172  + " when switching" + optionalFrom + " to phase " + toString(iNext));
173  // one warning per program is enough
174  haveWarned = true;
175  break;
176  }
177  }
178  }
179  }
180  // warn about links that never get the green light
181  for (int j = 0; j < (int)state1.size(); ++j) {
182  LinkState ls = (LinkState)state1[j];
184  foundGreen[j] = true;
185  }
186  }
187  }
188  }
189  for (int j = 0; j < (int)foundGreen.size(); ++j) {
190  if (!foundGreen[j]) {
191  WRITE_WARNING("Missing green phase in tlLogic '" + getID()
192  + "', program '" + getProgramID() + "' for tl-index " + toString(j));
193  break;
194  }
195  }
196  }
197  // check incompatible junction logic
198  // this can happen if the network was built with a very different signal
199  // plan from the one currently being used.
200  // Cconnections that never had a common green phase during network building may
201  // have a symmetric response relation to avoid certain kinds of jam but this
202  // can lead to deadlock if a different program gives minor green to both
203  // connections at the same time
204  // Note: mutual conflict between 'g' and 'G' is expected for traffic_light_right_on_red
205 
206  const bool mustCheck = MSNet::getInstance()->hasInternalLinks();
207  // The checks only runs for definitions from additional file and this is sufficient.
208  // The distinction is implicit because original logics are loaded earlier and at that time hasInternalLinks is alwas false
209  // Also, when the network has no internal links, mutual conflicts are not built by netconvert
210  //std::cout << "init tlLogic=" << getID() << " prog=" << getProgramID() << " links=" << myLinks.size() << " internal=" << MSNet::getInstance()->hasInternalLinks() << "\n";
211  if (mustCheck && phases.size() > 0) {
212  // see NBNode::tlsConflict
213  std::set<const MSJunction*> controlledJunctions;
214  const int numLinks = (int)myLinks.size();
215  for (int j = 0; j < numLinks; ++j) {
216  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
217  MSLink* link = myLinks[j][k];
218  assert(link->getJunction() != nullptr);
219  controlledJunctions.insert(link->getJunction());
220  }
221  }
222  const std::string minor = "gos";
223  for (const MSJunction* junction : controlledJunctions) {
224  const MSJunctionLogic* logic = junction->getLogic();
225  if (logic != nullptr) {
226  // find symmetrical response
227  const int logicSize = logic->getLogicSize();
228  std::vector<int> tlIndex;
229  for (int u = 0; u < logicSize; u++) {
230  const MSLogicJunction::LinkBits& response = logic->getResponseFor(u);
231  for (int v = 0; v < logicSize; v++) {
232  if (response.test(v)) {
233  if (logic->getResponseFor(v).test(u)) {
234  // get tls link index for links u and v
235  if (tlIndex.size() == 0) {
236  // init tlindex for all links once
237  tlIndex.resize(logicSize, -1);
238  for (int j = 0; j < numLinks; ++j) {
239  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
240  MSLink* link = myLinks[j][k];
241  if (link->getJunction() == junction) {
242  tlIndex[link->getIndex()] = link->getTLIndex();
243  }
244  }
245  }
246  }
247  const int tlu = tlIndex[u];
248  const int tlv = tlIndex[v];
249  if (tlu >= 0 && tlv >= 0) {
250  int phaseIndex = 0;
251  for (MSPhaseDefinition* p : phases) {
252  if (minor.find(p->getState()[tlu]) != std::string::npos
253  && minor.find(p->getState()[tlv]) != std::string::npos) {
254  WRITE_ERROR("Program '" + getProgramID() + "' at tlLogic '" + getID() + "' is incompatible with logic at junction '" + junction->getID() + "'"
255  + " (mututal conflict between link indices " + toString(u) + "," + toString(v)
256  + " tl indices " + toString(tlu) + "," + toString(tlv) + " phase " + toString(phaseIndex) + ")."
257  + "\n Rebuild the network with option '--tls.ignore-internal-junction-jam or include the program when building.");
258  return;
259  }
260  phaseIndex++;
261  }
262  }
263  }
264  }
265  }
266  }
267  }
268  }
269  }
270  myNumLinks = (int)myLinks.size();
271 }
272 
273 
275  // no need to do something about mySwitchCommand here,
276  // it is handled by the event control
277 }
278 
279 
280 // ----------- Handling of controlled links
281 void
283  // !!! should be done within the loader (checking necessary)
284  myLinks.reserve(pos + 1);
285  while ((int)myLinks.size() <= pos) {
286  myLinks.push_back(LinkVector());
287  }
288  myLinks[pos].push_back(link);
289  //
290  myLanes.reserve(pos + 1);
291  while ((int)myLanes.size() <= pos) {
292  myLanes.push_back(LaneVector());
293  }
294  myLanes[pos].push_back(lane);
295  link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
296 }
297 
298 
299 void
301  myLinks = logic.myLinks;
302  myLanes = logic.myLanes;
304 }
305 
306 
307 std::map<MSLink*, LinkState>
309  std::map<MSLink*, LinkState> ret;
310  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
311  const LinkVector& l = (*i1);
312  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
313  ret[*i2] = (*i2)->getState();
314  }
315  }
316  return ret;
317 }
318 
319 
320 bool
322  // get the current traffic light signal combination
323  const std::string& state = getCurrentPhaseDef().getState();
324  // go through the links
325  for (int i = 0; i < (int)myLinks.size(); i++) {
326  const LinkVector& currGroup = myLinks[i];
327  LinkState ls = (LinkState) state[i];
328  for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
329  (*j)->setTLState(ls, t);
330  }
331  }
332  return true;
333 }
334 
335 
336 void
337 MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
338  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
339  const LinkVector& l = (*i1);
340  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
341  assert(vals.find(*i2) != vals.end());
342  (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
343  }
344  }
345 }
346 
347 
348 // ----------- Static Information Retrieval
349 int
350 MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
351  int index = 0;
352  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
353  const LinkVector& l = (*i1);
354  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
355  if ((*i2) == link) {
356  return index;
357  }
358  }
359  }
360  return -1;
361 }
362 
363 
364 
365 // ----------- Dynamic Information Retrieval
366 SUMOTime
368  return mySwitchCommand != nullptr ? mySwitchCommand->getNextSwitchTime() : -1;
369 }
370 
371 
372 SUMOTime
374  if (simStep == -1) {
375  simStep = SIMSTEP;
376  }
377  const SUMOTime nextSwitch = getNextSwitchTime();
378  if (nextSwitch == -1) {
379  return -1;
380  } else {
381  const SUMOTime remaining = nextSwitch - simStep;
382  return getCurrentPhaseDef().duration - remaining;
383  }
384 }
385 
386 
387 // ----------- Changing phases and phase durations
388 void
390  myOverridingTimes.push_back(duration);
391 }
392 
393 
394 void
397 }
398 
399 
401  // set mesoscopic time penalties
402  const Phases& phases = getPhases();
403  const int numLinks = (int)myLinks.size();
404  // warning already given if not all states are used
405  assert(numLinks <= (int)phases.front()->getState().size());
406  SUMOTime duration = 0;
407  std::vector<double> redDuration(numLinks, 0);
408  std::vector<double> totalRedDuration(numLinks, 0);
409  std::vector<double> penalty(numLinks, 0);
410  for (int i = 0; i < (int)phases.size(); ++i) {
411  const std::string& state = phases[i]->getState();
412  duration += phases[i]->duration;
413  // warn about transitions from green to red without intermediate yellow
414  for (int j = 0; j < numLinks; ++j) {
415  if ((LinkState)state[j] == LINKSTATE_TL_RED
416  || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
417  redDuration[j] += STEPS2TIME(phases[i]->duration);
418  totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
419  } else if (redDuration[j] > 0) {
420  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
421  redDuration[j] = 0;
422  }
423  }
424  }
426  for (int j = 0; j < numLinks; ++j) {
427  if (redDuration[j] > 0) {
428  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
429  redDuration[j] = 0;
430  }
431  }
432  const double durationSeconds = STEPS2TIME(duration);
433  std::set<const MSJunction*> controlledJunctions;
434  for (int j = 0; j < numLinks; ++j) {
435  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
436  MSLink* link = myLinks[j][k];
437  MSEdge& edge = link->getLaneBefore()->getEdge();
438  const MSNet::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(edge.getEdgeType());
439  double greenFraction = (durationSeconds - totalRedDuration[j]) / durationSeconds;
440  if (edgeType.tlsFlowPenalty == 0) {
441  greenFraction = 1;
442  } else {
443  greenFraction = MAX2(MIN2(greenFraction / edgeType.tlsFlowPenalty, 1.0), 0.01);
444  }
445  if (greenFraction == 0.01) {
446  WRITE_WARNINGF("Green fraction is only 1% for link % in tlLogic '%', program '%'.", "%", j, getID(), getProgramID());
447  }
448  link->setMesoTLSPenalty(TIME2STEPS(edgeType.tlsPenalty * penalty[j] / durationSeconds));
449  link->setGreenFraction(greenFraction);
450  controlledJunctions.insert(link->getLane()->getEdge().getFromJunction()); // MSLink::myJunction is not yet initialized
451  //std::cout << " tls=" << getID() << " i=" << j << " link=" << link->getViaLaneOrLane()->getID() << " penalty=" << penalty[j] / durationSeconds << " durSecs=" << durationSeconds << " greenTime=" << " gF=" << myLinks[j][k]->getGreenFraction() << "\n";
452  }
453  }
454  // initialize empty-net travel times
455  // XXX refactor after merging sharps (links know their incoming edge)
456  for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
457  const ConstMSEdgeVector incoming = (*it)->getIncoming();
458  for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
459  const_cast<MSEdge*>(*it_e)->recalcCache();
460  }
461  }
462 
463 }
464 
465 
466 void
468  myIgnoredIndices.insert(pos);
469 }
470 
471 
472 bool
474  return MSNet::getInstance()->isSelected(this);
475 }
476 
477 
478 void
480  myAmActive = true;
481 }
482 
483 
484 void
486  myAmActive = false;
487 }
488 
489 
490 /****************************************************************************/
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:277
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SIMSTEP
Definition: SUMOTime.h:59
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
@ SVC_PEDESTRIAN
pedestrian
TrafficLightType
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_TL_REDYELLOW
The link has red light (must brake) but indicates upcoming green.
@ LINKSTATE_TL_GREEN_MAJOR
The link has green light, may pass.
@ LINKSTATE_TL_RED
The link has red light (must brake)
@ LINKSTATE_TL_GREEN_MINOR
The link has green light, has to brake.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:29
T MIN3(T a, T b, T c)
Definition: StdDefs.h:86
T MIN2(T a, T b)
Definition: StdDefs.h:73
T MAX2(T a, T b)
Definition: StdDefs.h:79
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A road/street connecting two junctions.
Definition: MSEdge.h:77
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:111
const MSJunction * getFromJunction() const
Definition: MSEdge.h:388
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:307
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition: MSGlobals.h:88
The base class for an intersection.
Definition: MSJunction.h:58
virtual const MSLogicJunction::LinkBits & getResponseFor(int linkIndex) const
Returns the response for the given link.
int getLogicSize() const
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
std::bitset< SUMO_MAX_CONNECTIONS > LinkBits
Container for link response and foes.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
virtual bool isSelected(const MSTrafficLightLogic *) const
return wheter the given logic (or rather it's wrapper) is selected in the GUI
Definition: MSNet.h:579
const MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition: MSNet.cpp:347
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:464
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:695
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
SUMOTime duration
The duration of the phase.
Storage for all programs of a single tls.
A class that stores and controls tls and switching of their programs.
Class realising the switch between the traffic light phases.
void deschedule(MSTrafficLightLogic *tlLogic)
Marks this swicth as invalid (if the phase duration has changed, f.e.)
SUMOTime shiftTime(SUMOTime currentTime, SUMOTime execTime, SUMOTime newTime)
Reschedule or deschedule the command when quick-loading state.
SwitchCommand(MSTLLogicControl &tlcontrol, MSTrafficLightLogic *tlLogic, SUMOTime nextSwitch)
Constructor.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
SUMOTime execute(SUMOTime currentTime)
Executes the regarded junction's "trySwitch"- method.
The parent class for traffic light logics.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
int getLinkIndex(const MSLink *const link) const
Returns the index of the given link.
void setCurrentDurationIncrement(SUMOTime delay)
Delays current phase by the given delay.
MSTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const TrafficLightType logicType, const SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor.
std::map< MSLink *, LinkState > collectLinkStates() const
Returns the (uncontrolled) states of the controlled links.
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
virtual ~MSTrafficLightLogic()
Destructor.
virtual void deactivateProgram()
std::vector< SUMOTime > myOverridingTimes
A list of duration overrides.
void ignoreLinkIndex(int pos)
ignore pedestrian crossing index in mesosim
static const LaneVector myEmptyLaneVector
An empty lane vector.
const TrafficLightType myLogicType
The type of the logic.
bool isSelected() const
whether this logic is selected in the GUI
SUMOTime myDefaultCycleTime
The cycle time (without changes)
const std::string myProgramID
The id of the logic.
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index.
SwitchCommand * mySwitchCommand
The current switch command.
int myNumLinks
number of controlled links
SUMOTime myCurrentDurationIncrement
A value for enlarge the current duration.
void resetLinkStates(const std::map< MSLink *, LinkState > &vals) const
Resets the states of controlled links.
virtual void activateProgram()
called when switching programs
void addOverridingDuration(SUMOTime duration)
Changes the duration of the next phase.
bool myAmActive
whether the current program is active
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
std::set< int > myIgnoredIndices
list of indices that are ignored in mesoscopic simulatino
SUMOTime getSpentDuration(SUMOTime simStep=-1) const
Returns the duration spent in the current phase.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index.
void initMesoTLSPenalties()
initialize optional meso penalties
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
const std::string & getProgramID() const
Returns this tl-logic's id.
Builds detectors for microsim.
Base class for objects which have an id.
Definition: Named.h:53
const std::string & getID() const
Returns the id.
Definition: Named.h:73
An upper class for objects with additional parameters.
Definition: Parameterised.h:39
static const std::string ALLOWED_TLS_LINKSTATES
all allowed characters for phase state
edge type specific meso parameters
Definition: MSNet.h:117
double tlsPenalty
Definition: MSNet.h:124
double tlsFlowPenalty
Definition: MSNet.h:125