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-2016 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/MSGlobals.h>
43 #include "MSTLLogicControl.h"
44 #include "MSTrafficLightLogic.h"
45 
46 #ifdef CHECK_MEMORY_LEAKS
47 #include <foreign/nvwa/debug_new.h>
48 #endif // CHECK_MEMORY_LEAKS
49 
50 
51 // ===========================================================================
52 // static value definitions
53 // ===========================================================================
55 
56 
57 // ===========================================================================
58 // member method definitions
59 // ===========================================================================
60 /* -------------------------------------------------------------------------
61  * member method definitions
62  * ----------------------------------------------------------------------- */
64  MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch)
65  : myTLControl(tlcontrol), myTLLogic(tlLogic),
66  myAssumedNextSwitch(nextSwitch), myAmValid(true) {}
67 
68 
70 
71 
72 
75  // check whether this command has been descheduled
76  if (!myAmValid) {
77  return 0;
78  }
79  //
80  const bool isActive = myTLControl.isActive(myTLLogic);
81  int step1 = myTLLogic->getCurrentPhaseIndex();
82  SUMOTime next = myTLLogic->trySwitch();
83  int step2 = myTLLogic->getCurrentPhaseIndex();
84  if (step1 != step2) {
85  if (isActive) {
86  // execute any action connected to this tls
88  // set link priorities
90  // execute switch actions
92  }
93  }
94  myAssumedNextSwitch += next;
95  return next;
96 }
97 
98 
99 void
101  if (tlLogic == myTLLogic) {
102  myAmValid = false;
103  myAssumedNextSwitch = -1;
104  }
105 }
106 
107 
108 /* -------------------------------------------------------------------------
109  * member method definitions
110  * ----------------------------------------------------------------------- */
112  const std::string& programID, SUMOTime delay, const std::map<std::string, std::string>& parameters) :
113  Named(id), Parameterised(parameters),
114  myProgramID(programID),
116  myDefaultCycleTime(0) {
117  mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
120 }
121 
122 
123 void
125  const Phases& phases = getPhases();
126  if (phases.size() > 0 && MSGlobals::gMesoTLSPenalty > 0) {
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 stats
134  const int iNext = (i + 1) % phases.size();
135  const std::string& state1 = phases[i]->getState();
136  const std::string& state2 = phases[iNext]->getState();
137  assert(state1.size() == state2.size());
138  if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size()) {
139  WRITE_WARNING("Unused states in tlLogic '" + getID()
140  + "', program '" + getProgramID() + "' in phase " + toString(i)
141  + " after tl-index " + toString((int)myLanes.size() - 1));
142  haveWarnedAboutUnusedStates = true;
143  }
144  // warn about transitions from green to red without intermediate yellow
145  for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()); ++j) {
146  if ((LinkState)state2[j] == LINKSTATE_TL_RED
147  && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
148  || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
149  for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
150  if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
151  WRITE_WARNING("Missing yellow phase in tlLogic '" + getID()
152  + "', program '" + getProgramID() + "' for tl-index " + toString(j)
153  + " when switching to phase " + toString(iNext));
154  return; // one warning per program is enough
155  }
156  }
157  }
158  }
159  // warn about links that never get the green light
160  for (int j = 0; j < (int)state1.size(); ++j) {
161  LinkState ls = (LinkState)state1[j];
163  foundGreen[j] = true;
164  }
165  }
166  }
167  for (int j = 0; j < (int)foundGreen.size(); ++j) {
168  if (!foundGreen[j]) {
169  WRITE_WARNING("Missing green phase in tlLogic '" + getID()
170  + "', program '" + getProgramID() + "' for tl-index " + toString(j));
171  break;
172  }
173  }
174  }
175 }
176 
177 
179  // no need to do something about mySwitchCommand here,
180  // it is handled by the event control
181 }
182 
183 
184 // ----------- Handling of controlled links
185 void
187  // !!! should be done within the loader (checking necessary)
188  myLinks.reserve(pos + 1);
189  while ((int)myLinks.size() <= pos) {
190  myLinks.push_back(LinkVector());
191  }
192  myLinks[pos].push_back(link);
193  //
194  myLanes.reserve(pos + 1);
195  while ((int)myLanes.size() <= pos) {
196  myLanes.push_back(LaneVector());
197  }
198  myLanes[pos].push_back(lane);
199  link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
200 }
201 
202 
203 void
205  myLinks = logic.myLinks;
206  myLanes = logic.myLanes;
207 }
208 
209 
210 std::map<MSLink*, LinkState>
212  std::map<MSLink*, LinkState> ret;
213  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
214  const LinkVector& l = (*i1);
215  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
216  ret[*i2] = (*i2)->getState();
217  }
218  }
219  return ret;
220 }
221 
222 
223 bool
225  // get the current traffic light signal combination
226  const std::string& state = getCurrentPhaseDef().getState();
227  // go through the links
228  for (size_t i = 0; i < myLinks.size(); i++) {
229  const LinkVector& currGroup = myLinks[i];
230  LinkState ls = (LinkState) state[i];
231  for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
232  (*j)->setTLState(ls, t);
233  }
234  }
235  return true;
236 }
237 
238 
239 void
240 MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
241  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
242  const LinkVector& l = (*i1);
243  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
244  assert(vals.find(*i2) != vals.end());
245  (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
246  }
247  }
248 }
249 
250 
251 // ----------- Static Information Retrieval
252 int
253 MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
254  int index = 0;
255  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
256  const LinkVector& l = (*i1);
257  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
258  if ((*i2) == link) {
259  return index;
260  }
261  }
262  }
263  return -1;
264 }
265 
266 
267 
268 // ----------- Dynamic Information Retrieval
269 SUMOTime
271  return mySwitchCommand != 0 ? mySwitchCommand->getNextSwitchTime() : -1;
272 }
273 
274 
275 // ----------- Changing phases and phase durations
276 void
278  myOverridingTimes.push_back(duration);
279 }
280 
281 
282 void
285 }
286 
287 
289  // set mesoscopic time penalties
290  const Phases& phases = getPhases();
291  const int numLinks = (int)phases.front()->getState().size();
292  assert(myLinks.size() >= numLinks);
293  SUMOTime duration = 0;
294  std::vector<SUMOReal> redDuration(numLinks, 0);
295  std::vector<SUMOReal> penalty(numLinks, 0);
296  for (int i = 0; i < (int)phases.size(); ++i) {
297  const std::string& state = phases[i]->getState();
298  duration += phases[i]->duration;
299  // warn about transitions from green to red without intermediate yellow
300  for (int j = 0; j < numLinks; ++j) {
301  if ((LinkState)state[j] == LINKSTATE_TL_RED
302  || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
303  redDuration[j] += STEPS2TIME(phases[i]->duration);
304  } else if (redDuration[j] > 0) {
305  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
306  redDuration[j] = 0;
307  }
308  }
309  }
311  for (int j = 0; j < numLinks; ++j) {
312  if (redDuration[j] > 0) {
313  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
314  redDuration[j] = 0;
315  }
316  }
317  const SUMOReal durationSeconds = STEPS2TIME(duration);
318  for (int j = 0; j < numLinks; ++j) {
319  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
320  myLinks[j][k]->setMesoTLSPenalty(TIME2STEPS(MSGlobals::gMesoTLSPenalty * penalty[j] / durationSeconds));
321  //std::cout << " tls=" << getID() << " link=" << j << " penalty=" << penalty[j] / durationSeconds << " durSecs=" << durationSeconds << "\n";
322  }
323  }
324 }
325 
326 /****************************************************************************/
327 
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.
void resetLinkStates(const std::map< MSLink *, LinkState > &vals) const
Resets the states of controlled links.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
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.
static const LaneVector myEmptyLaneVector
An empty lane vector.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:160
virtual int getCurrentPhaseIndex() const =0
Returns the current index within the program.
MSTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor.
#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:65
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.
SUMOTime myDefaultCycleTime
The cycle time (without changes)
MSTrafficLightLogic * myTLLogic
The logic to be executed on a switch.
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:389
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.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:54
An upper class for objects with additional parameters.
Definition: Parameterised.h:47
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:45
std::vector< MSLink * > LinkVector
Definition of the list of links that participate in this tl-light.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
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 links that participate in this tl-light.
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:213
const std::string & getProgramID() const
Returns this tl-logic&#39;s id.
T MIN3(T a, T b, T c)
Definition: StdDefs.h:82
bool myAmValid
Information whether this switch command is still valid.
static SUMOReal gMesoTLSPenalty
Definition: MSGlobals.h:96
virtual SUMOTime trySwitch()=0
Switches to the next phase.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
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.