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 
48 // ===========================================================================
49 // static value definitions
50 // ===========================================================================
52 
53 
54 // ===========================================================================
55 // member method definitions
56 // ===========================================================================
57 /* -------------------------------------------------------------------------
58  * member method definitions
59  * ----------------------------------------------------------------------- */
61  MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch)
62  : myTLControl(tlcontrol), myTLLogic(tlLogic),
63  myAssumedNextSwitch(nextSwitch), myAmValid(true) {}
64 
65 
67 
68 
69 
72  // check whether this command has been descheduled
73  if (!myAmValid) {
74  return 0;
75  }
76  //
77  const bool isActive = myTLControl.isActive(myTLLogic);
78  int step1 = myTLLogic->getCurrentPhaseIndex();
79  SUMOTime next = myTLLogic->trySwitch();
80  int step2 = myTLLogic->getCurrentPhaseIndex();
81  if (step1 != step2) {
82  if (isActive) {
83  // execute any action connected to this tls
85  // set link priorities
87  // execute switch actions
89  }
90  }
91  myAssumedNextSwitch += next;
92  return next;
93 }
94 
95 
96 void
98  if (tlLogic == myTLLogic) {
99  myAmValid = false;
100  myAssumedNextSwitch = -1;
101  }
102 }
103 
104 
105 /* -------------------------------------------------------------------------
106  * member method definitions
107  * ----------------------------------------------------------------------- */
109  const std::string& programID, SUMOTime delay, const std::map<std::string, std::string>& parameters) :
110  Named(id), Parameterised(parameters),
111  myProgramID(programID),
113  myDefaultCycleTime(0) {
114  mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
116 }
117 
118 
119 void
121  const Phases& phases = getPhases();
122  if (phases.size() > 0 && MSGlobals::gMesoTLSPenalty > 0) {
124  }
125  if (phases.size() > 1) {
126  bool haveWarnedAboutUnusedStates = false;
127  std::vector<bool> foundGreen(phases.front()->getState().size(), false);
128  for (int i = 0; i < (int)phases.size(); ++i) {
129  // warn about unused stats
130  const int iNext = (i + 1) % phases.size();
131  const std::string& state1 = phases[i]->getState();
132  const std::string& state2 = phases[iNext]->getState();
133  assert(state1.size() == state2.size());
134  if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size()) {
135  WRITE_WARNING("Unused states in tlLogic '" + getID()
136  + "', program '" + getProgramID() + "' in phase " + toString(i)
137  + " after tl-index " + toString((int)myLanes.size() - 1));
138  haveWarnedAboutUnusedStates = true;
139  }
140  // warn about transitions from green to red without intermediate yellow
141  for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()); ++j) {
142  if ((LinkState)state2[j] == LINKSTATE_TL_RED
143  && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
144  || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
145  for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
146  if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
147  WRITE_WARNING("Missing yellow phase in tlLogic '" + getID()
148  + "', program '" + getProgramID() + "' for tl-index " + toString(j)
149  + " when switching to phase " + toString(iNext));
150  return; // one warning per program is enough
151  }
152  }
153  }
154  }
155  // warn about links that never get the green light
156  for (int j = 0; j < (int)state1.size(); ++j) {
157  LinkState ls = (LinkState)state1[j];
159  foundGreen[j] = true;
160  }
161  }
162  }
163  for (int j = 0; j < (int)foundGreen.size(); ++j) {
164  if (!foundGreen[j]) {
165  WRITE_WARNING("Missing green phase in tlLogic '" + getID()
166  + "', program '" + getProgramID() + "' for tl-index " + toString(j));
167  break;
168  }
169  }
170  }
171 }
172 
173 
175  // no need to do something about mySwitchCommand here,
176  // it is handled by the event control
177 }
178 
179 
180 // ----------- Handling of controlled links
181 void
183  // !!! should be done within the loader (checking necessary)
184  myLinks.reserve(pos + 1);
185  while ((int)myLinks.size() <= pos) {
186  myLinks.push_back(LinkVector());
187  }
188  myLinks[pos].push_back(link);
189  //
190  myLanes.reserve(pos + 1);
191  while ((int)myLanes.size() <= pos) {
192  myLanes.push_back(LaneVector());
193  }
194  myLanes[pos].push_back(lane);
195  link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
196 }
197 
198 
199 void
201  myLinks = logic.myLinks;
202  myLanes = logic.myLanes;
203 }
204 
205 
206 std::map<MSLink*, LinkState>
208  std::map<MSLink*, LinkState> ret;
209  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
210  const LinkVector& l = (*i1);
211  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
212  ret[*i2] = (*i2)->getState();
213  }
214  }
215  return ret;
216 }
217 
218 
219 bool
221  // get the current traffic light signal combination
222  const std::string& state = getCurrentPhaseDef().getState();
223  // go through the links
224  for (int i = 0; i < (int)myLinks.size(); i++) {
225  const LinkVector& currGroup = myLinks[i];
226  LinkState ls = (LinkState) state[i];
227  for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
228  (*j)->setTLState(ls, t);
229  }
230  }
231  return true;
232 }
233 
234 
235 void
236 MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
237  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
238  const LinkVector& l = (*i1);
239  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
240  assert(vals.find(*i2) != vals.end());
241  (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
242  }
243  }
244 }
245 
246 
247 // ----------- Static Information Retrieval
248 int
249 MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
250  int index = 0;
251  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
252  const LinkVector& l = (*i1);
253  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
254  if ((*i2) == link) {
255  return index;
256  }
257  }
258  }
259  return -1;
260 }
261 
262 
263 
264 // ----------- Dynamic Information Retrieval
265 SUMOTime
267  return mySwitchCommand != 0 ? mySwitchCommand->getNextSwitchTime() : -1;
268 }
269 
270 
271 // ----------- Changing phases and phase durations
272 void
274  myOverridingTimes.push_back(duration);
275 }
276 
277 
278 void
281 }
282 
283 
285  // set mesoscopic time penalties
286  const Phases& phases = getPhases();
287  const int numLinks = (int)myLinks.size();
288  // warning already given if not all states are used
289  assert(numLinks <= (int)phases.front()->getState().size());
290  SUMOTime duration = 0;
291  std::vector<double> redDuration(numLinks, 0);
292  std::vector<double> totalRedDuration(numLinks, 0);
293  std::vector<double> penalty(numLinks, 0);
294  for (int i = 0; i < (int)phases.size(); ++i) {
295  const std::string& state = phases[i]->getState();
296  duration += phases[i]->duration;
297  // warn about transitions from green to red without intermediate yellow
298  for (int j = 0; j < numLinks; ++j) {
299  if ((LinkState)state[j] == LINKSTATE_TL_RED
300  || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
301  redDuration[j] += STEPS2TIME(phases[i]->duration);
302  totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
303  } else if (redDuration[j] > 0) {
304  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
305  redDuration[j] = 0;
306  }
307  }
308  }
310  for (int j = 0; j < numLinks; ++j) {
311  if (redDuration[j] > 0) {
312  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
313  redDuration[j] = 0;
314  }
315  }
316  const double durationSeconds = STEPS2TIME(duration);
317  std::set<const MSJunction*> controlledJunctions;
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  myLinks[j][k]->setGreenFraction(MAX2((durationSeconds - MSGlobals::gMesoTLSPenalty * totalRedDuration[j]) / durationSeconds, NUMERICAL_EPS)); // avoid zero capacity (warning issued before)
322  controlledJunctions.insert(myLinks[j][k]->getLane()->getEdge().getFromJunction()); // MSLink::myJunction is not yet initialized
323  //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";
324  }
325  }
326  // initialize empty-net travel times
327  // XXX refactor after merging sharps (links know their incoming edge)
328  for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
329  const ConstMSEdgeVector incoming = (*it)->getIncoming();
330  for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
331  const_cast<MSEdge*>(*it_e)->recalcCache();
332  }
333  }
334 
335 }
336 
337 /****************************************************************************/
338 
SUMOTime myCurrentDurationIncrement
A value for enlarge the current duration.
The link has green light, may pass.
virtual const MSPhaseDefinition & getCurrentPhaseDef() const =0
Returns the definition of the current phase.
const std::string & getState() const
Returns the state within this phase.
Builds detectors for microsim.
void initMesoTLSPenalties()
initialize optional meso penalties
is a pedestrian
Storage for all programs of a single tls.
MSTLLogicControl & myTLControl
The responsible traffic lights control.
static double gMesoTLSPenalty
Definition: MSGlobals.h:107
std::vector< SUMOTime > myOverridingTimes
A list of duration overrides.
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:128
static const LaneVector myEmptyLaneVector
An empty lane vector.
bool isActive(const MSTrafficLightLogic *tl) const
Returns whether the given tls program is the currently active for his tls.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:158
T MAX2(T a, T b)
Definition: StdDefs.h:70
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.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
const std::string & getID() const
Returns the id.
Definition: Named.h:66
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
void resetLinkStates(const std::map< MSLink *, LinkState > &vals) const
Resets the states of controlled links.
int getLinkIndex(const MSLink *const link) const
Returns the index of the given link.
#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.
A class that stores and controls tls and switching of their programs.
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:56
SUMOTime myDefaultCycleTime
The cycle time (without changes)
const std::string & getProgramID() const
Returns this tl-logic&#39;s id.
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:403
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
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.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:257
std::map< MSLink *, LinkState > collectLinkStates() const
Returns the (uncontrolled) states of the controlled links.
An upper class for objects with additional parameters.
Definition: Parameterised.h:51
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.
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 arrival lanes subjected to this tls.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
The link has red light (must brake)
virtual void addLink(MSLink *link, MSLane *lane, int pos)
Adds a link on building.
SwitchCommand * mySwitchCommand
The current switch command.
The parent class for traffic light logics.
T MIN3(T a, T b, T c)
Definition: StdDefs.h:77
long long int SUMOTime
Definition: TraCIDefs.h:52
#define NUMERICAL_EPS
Definition: config.h:151
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
bool myAmValid
Information whether this switch command is still valid.
virtual SUMOTime trySwitch()=0
Switches to the next phase.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
The link has red light (must brake) but indicates upcoming green.
SUMOTime execute(SUMOTime currentTime)
Executes the regarded junction&#39;s "trySwitch"- method.