SUMO - Simulation of Urban MObility
MSTrafficLightLogic.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // The parent class for traffic light logics
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <cassert>
34 #include <string>
35 #include <iostream>
36 #include <map>
37 #include <microsim/MSLink.h>
38 #include <microsim/MSLane.h>
41 #include <microsim/MSNet.h>
42 #include <microsim/MSEdge.h>
43 #include <microsim/MSGlobals.h>
44 #include "MSTLLogicControl.h"
45 #include "MSTrafficLightLogic.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 
52 // ===========================================================================
53 // static value definitions
54 // ===========================================================================
56 
57 
58 // ===========================================================================
59 // member method definitions
60 // ===========================================================================
61 /* -------------------------------------------------------------------------
62  * member method definitions
63  * ----------------------------------------------------------------------- */
65  MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch)
66  : myTLControl(tlcontrol), myTLLogic(tlLogic),
67  myAssumedNextSwitch(nextSwitch), myAmValid(true) {}
68 
69 
71 
72 
73 
76  // check whether this command has been descheduled
77  if (!myAmValid) {
78  return 0;
79  }
80  //
81  const bool isActive = myTLControl.isActive(myTLLogic);
82  int step1 = myTLLogic->getCurrentPhaseIndex();
83  SUMOTime next = myTLLogic->trySwitch();
84  int step2 = myTLLogic->getCurrentPhaseIndex();
85  if (step1 != step2) {
86  if (isActive) {
87  // execute any action connected to this tls
89  // set link priorities
91  // execute switch actions
93  }
94  }
95  myAssumedNextSwitch += next;
96  return next;
97 }
98 
99 
100 void
102  if (tlLogic == myTLLogic) {
103  myAmValid = false;
104  myAssumedNextSwitch = -1;
105  }
106 }
107 
108 
109 /* -------------------------------------------------------------------------
110  * member method definitions
111  * ----------------------------------------------------------------------- */
113  const std::string& programID, SUMOTime delay, const std::map<std::string, std::string>& parameters) :
114  Named(id), Parameterised(parameters),
115  myProgramID(programID),
117  myDefaultCycleTime(0) {
118  mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
121 }
122 
123 
124 void
126  const Phases& phases = getPhases();
127  if (phases.size() > 0 && MSGlobals::gMesoTLSPenalty > 0) {
129  }
130  if (phases.size() > 1) {
131  bool haveWarnedAboutUnusedStates = false;
132  std::vector<bool> foundGreen(phases.front()->getState().size(), false);
133  for (int i = 0; i < (int)phases.size(); ++i) {
134  // warn about unused stats
135  const int iNext = (i + 1) % phases.size();
136  const std::string& state1 = phases[i]->getState();
137  const std::string& state2 = phases[iNext]->getState();
138  assert(state1.size() == state2.size());
139  if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size()) {
140  WRITE_WARNING("Unused states in tlLogic '" + getID()
141  + "', program '" + getProgramID() + "' in phase " + toString(i)
142  + " after tl-index " + toString((int)myLanes.size() - 1));
143  haveWarnedAboutUnusedStates = true;
144  }
145  // warn about transitions from green to red without intermediate yellow
146  for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()); ++j) {
147  if ((LinkState)state2[j] == LINKSTATE_TL_RED
148  && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
149  || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
150  for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
151  if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
152  WRITE_WARNING("Missing yellow phase in tlLogic '" + getID()
153  + "', program '" + getProgramID() + "' for tl-index " + toString(j)
154  + " when switching to phase " + toString(iNext));
155  return; // one warning per program is enough
156  }
157  }
158  }
159  }
160  // warn about links that never get the green light
161  for (int j = 0; j < (int)state1.size(); ++j) {
162  LinkState ls = (LinkState)state1[j];
164  foundGreen[j] = true;
165  }
166  }
167  }
168  for (int j = 0; j < (int)foundGreen.size(); ++j) {
169  if (!foundGreen[j]) {
170  WRITE_WARNING("Missing green phase in tlLogic '" + getID()
171  + "', program '" + getProgramID() + "' for tl-index " + toString(j));
172  break;
173  }
174  }
175  }
176 }
177 
178 
180  // no need to do something about mySwitchCommand here,
181  // it is handled by the event control
182 }
183 
184 
185 // ----------- Handling of controlled links
186 void
188  // !!! should be done within the loader (checking necessary)
189  myLinks.reserve(pos + 1);
190  while ((int)myLinks.size() <= pos) {
191  myLinks.push_back(LinkVector());
192  }
193  myLinks[pos].push_back(link);
194  //
195  myLanes.reserve(pos + 1);
196  while ((int)myLanes.size() <= pos) {
197  myLanes.push_back(LaneVector());
198  }
199  myLanes[pos].push_back(lane);
200  link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
201 }
202 
203 
204 void
206  myLinks = logic.myLinks;
207  myLanes = logic.myLanes;
208 }
209 
210 
211 std::map<MSLink*, LinkState>
213  std::map<MSLink*, LinkState> ret;
214  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
215  const LinkVector& l = (*i1);
216  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
217  ret[*i2] = (*i2)->getState();
218  }
219  }
220  return ret;
221 }
222 
223 
224 bool
226  // get the current traffic light signal combination
227  const std::string& state = getCurrentPhaseDef().getState();
228  // go through the links
229  for (int i = 0; i < (int)myLinks.size(); i++) {
230  const LinkVector& currGroup = myLinks[i];
231  LinkState ls = (LinkState) state[i];
232  for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
233  (*j)->setTLState(ls, t);
234  }
235  }
236  return true;
237 }
238 
239 
240 void
241 MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
242  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
243  const LinkVector& l = (*i1);
244  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
245  assert(vals.find(*i2) != vals.end());
246  (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
247  }
248  }
249 }
250 
251 
252 // ----------- Static Information Retrieval
253 int
254 MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
255  int index = 0;
256  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
257  const LinkVector& l = (*i1);
258  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
259  if ((*i2) == link) {
260  return index;
261  }
262  }
263  }
264  return -1;
265 }
266 
267 
268 
269 // ----------- Dynamic Information Retrieval
270 SUMOTime
272  return mySwitchCommand != 0 ? mySwitchCommand->getNextSwitchTime() : -1;
273 }
274 
275 
276 // ----------- Changing phases and phase durations
277 void
279  myOverridingTimes.push_back(duration);
280 }
281 
282 
283 void
286 }
287 
288 
290  // set mesoscopic time penalties
291  const Phases& phases = getPhases();
292  const int numLinks = (int)myLinks.size();
293  // warning already given if not all states are used
294  assert(numLinks <= (int)phases.front()->getState().size());
295  SUMOTime duration = 0;
296  std::vector<SUMOReal> redDuration(numLinks, 0);
297  std::vector<SUMOReal> totalRedDuration(numLinks, 0);
298  std::vector<SUMOReal> penalty(numLinks, 0);
299  for (int i = 0; i < (int)phases.size(); ++i) {
300  const std::string& state = phases[i]->getState();
301  duration += phases[i]->duration;
302  // warn about transitions from green to red without intermediate yellow
303  for (int j = 0; j < numLinks; ++j) {
304  if ((LinkState)state[j] == LINKSTATE_TL_RED
305  || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
306  redDuration[j] += STEPS2TIME(phases[i]->duration);
307  totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
308  } else if (redDuration[j] > 0) {
309  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
310  redDuration[j] = 0;
311  }
312  }
313  }
315  for (int j = 0; j < numLinks; ++j) {
316  if (redDuration[j] > 0) {
317  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
318  redDuration[j] = 0;
319  }
320  }
321  const SUMOReal durationSeconds = STEPS2TIME(duration);
322  std::set<const MSJunction*> controlledJunctions;
323  for (int j = 0; j < numLinks; ++j) {
324  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
325  myLinks[j][k]->setMesoTLSPenalty(TIME2STEPS(MSGlobals::gMesoTLSPenalty * penalty[j] / durationSeconds));
326  myLinks[j][k]->setGreenFraction(MAX2((durationSeconds - MSGlobals::gMesoTLSPenalty * totalRedDuration[j]) / durationSeconds, NUMERICAL_EPS)); // avoid zero capacity (warning issued before)
327  controlledJunctions.insert(myLinks[j][k]->getLane()->getEdge().getFromJunction()); // MSLink::myJunction is not yet initialized
328  //std::cout << " tls=" << getID() << " i=" << j << " link=" << myLinks[j][k]->getViaLaneOrLane()->getID() << " penalty=" << penalty[j] / durationSeconds << " durSecs=" << durationSeconds << " greenTime=" << " gF=" << myLinks[j][k]->getGreenFraction() << "\n";
329  }
330  }
331  // initialize empty-net travel times
332  // XXX refactor after merging sharps (links know their incoming edge)
333  for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
334  const ConstMSEdgeVector incoming = (*it)->getIncoming();
335  for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
336  const_cast<MSEdge*>(*it_e)->recalcCache();
337  }
338  }
339 
340 }
341 
342 /****************************************************************************/
343 
SUMOTime myCurrentDurationIncrement
A value for enlarge the current duration.
The link has green light, may pass.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
void resetLinkStates(const std::map< MSLink *, LinkState > &vals) const
Resets the states of controlled links.
Builds detectors for microsim.
void initMesoTLSPenalties()
initialize optional meso penalties
long long int SUMOTime
Definition: SUMOTime.h:43
const std::string & getState() const
Returns the state within this phase.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
is a pedestrian
Storage for all programs of a single tls.
MSTLLogicControl & myTLControl
The responsible traffic lights control.
std::vector< SUMOTime > myOverridingTimes
A list of duration overrides.
int getLinkIndex(const MSLink *const link) const
Returns the index of the given link.
SwitchCommand(MSTLLogicControl &tlcontrol, MSTrafficLightLogic *tlLogic, SUMOTime nextSwitch)
Constructor.
std::string myProgramID
The id of the logic.
SUMOTime myAssumedNextSwitch
Assumed switch time (may change in case of adaptive traffic lights)
The link has green light, has to brake.
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:133
static const LaneVector myEmptyLaneVector
An empty lane vector.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:70
MSTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index...
virtual ~MSTrafficLightLogic()
Destructor.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
A class that stores and controls tls and switching of their programs.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
void deschedule(MSTrafficLightLogic *tlLogic)
Marks this swicth as invalid (if the phase duration has changed, f.e.)
Class realising the switch between the traffic light phases.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
SUMOTime myDefaultCycleTime
The cycle time (without changes)
MSTrafficLightLogic * myTLLogic
The logic to be executed on a switch.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:401
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
An upper class for objects with additional parameters.
Definition: Parameterised.h:51
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
void setCurrentDurationIncrement(SUMOTime delay)
Delays current phase by the given delay.
Base class for objects which have an id.
Definition: Named.h:46
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
void addOverridingDuration(SUMOTime duration)
Changes the duration of the next phase.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index...
std::vector< MSLane * > LaneVector
Definition of the list of arrival lanes subjected to this tls.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
The link has red light (must brake)
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
SwitchCommand * mySwitchCommand
The current switch command.
The parent class for traffic light logics.
#define SUMOReal
Definition: config.h:208
const std::string & getProgramID() const
Returns this tl-logic&#39;s id.
T MIN3(T a, T b, T c)
Definition: StdDefs.h:77
#define NUMERICAL_EPS
Definition: config.h:158
bool myAmValid
Information whether this switch command is still valid.
static SUMOReal gMesoTLSPenalty
Definition: MSGlobals.h:104
virtual SUMOTime trySwitch()=0
Switches to the next phase.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
std::map< MSLink *, LinkState > collectLinkStates() const
Returns the (uncontrolled) states of the controlled links.
The link has red light (must brake) but indicates upcoming green.
SUMOTime execute(SUMOTime currentTime)
Executes the regarded junction&#39;s "trySwitch"- method.