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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // The parent class for traffic light logics
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <cassert>
33 #include <string>
34 #include <iostream>
35 #include <map>
36 #include <microsim/MSLink.h>
37 #include <microsim/MSLane.h>
40 #include <microsim/MSNet.h>
41 #include <microsim/MSEdge.h>
42 #include <microsim/MSGlobals.h>
43 #include "MSTLLogicControl.h"
44 #include "MSTrafficLightLogic.h"
45 
46 
47 // ===========================================================================
48 // static value definitions
49 // ===========================================================================
51 
52 
53 // ===========================================================================
54 // member method definitions
55 // ===========================================================================
56 /* -------------------------------------------------------------------------
57  * member method definitions
58  * ----------------------------------------------------------------------- */
60  MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch)
61  : myTLControl(tlcontrol), myTLLogic(tlLogic),
62  myAssumedNextSwitch(nextSwitch), myAmValid(true) {}
63 
64 
66 
67 
68 
71  // check whether this command has been descheduled
72  if (!myAmValid) {
73  return 0;
74  }
75  //
76  const bool isActive = myTLControl.isActive(myTLLogic);
77  int step1 = myTLLogic->getCurrentPhaseIndex();
78  SUMOTime next = myTLLogic->trySwitch();
79  int step2 = myTLLogic->getCurrentPhaseIndex();
80  if (step1 != step2) {
81  if (isActive) {
82  // execute any action connected to this tls
84  // set link priorities
86  // execute switch actions
88  }
89  }
90  myAssumedNextSwitch += next;
91  return next;
92 }
93 
94 
95 void
97  if (tlLogic == myTLLogic) {
98  myAmValid = false;
100  }
101 }
102 
103 
104 /* -------------------------------------------------------------------------
105  * member method definitions
106  * ----------------------------------------------------------------------- */
108  const std::string& programID, SUMOTime delay, const std::map<std::string, std::string>& parameters) :
109  Named(id), Parameterised(parameters),
110  myProgramID(programID),
112  myDefaultCycleTime(0) {
113  mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
115 }
116 
117 
118 void
120  const Phases& phases = getPhases();
121  if (phases.size() > 0 && MSGlobals::gMesoTLSPenalty > 0) {
123  }
124  if (phases.size() > 1) {
125  bool haveWarnedAboutUnusedStates = false;
126  std::vector<bool> foundGreen(phases.front()->getState().size(), false);
127  for (int i = 0; i < (int)phases.size(); ++i) {
128  // warn about unused stats
129  const int iNext = (i + 1) % phases.size();
130  const std::string& state1 = phases[i]->getState();
131  const std::string& state2 = phases[iNext]->getState();
132  assert(state1.size() == state2.size());
133  if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size()) {
134  WRITE_WARNING("Unused states in tlLogic '" + getID()
135  + "', program '" + getProgramID() + "' in phase " + toString(i)
136  + " after tl-index " + toString((int)myLanes.size() - 1));
137  haveWarnedAboutUnusedStates = true;
138  }
139  // warn about transitions from green to red without intermediate yellow
140  for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()); ++j) {
141  if ((LinkState)state2[j] == LINKSTATE_TL_RED
142  && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
143  || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
144  for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
145  if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
146  WRITE_WARNING("Missing yellow phase in tlLogic '" + getID()
147  + "', program '" + getProgramID() + "' for tl-index " + toString(j)
148  + " when switching to phase " + toString(iNext));
149  return; // one warning per program is enough
150  }
151  }
152  }
153  }
154  // warn about links that never get the green light
155  for (int j = 0; j < (int)state1.size(); ++j) {
156  LinkState ls = (LinkState)state1[j];
158  foundGreen[j] = true;
159  }
160  }
161  }
162  for (int j = 0; j < (int)foundGreen.size(); ++j) {
163  if (!foundGreen[j]) {
164  WRITE_WARNING("Missing green phase in tlLogic '" + getID()
165  + "', program '" + getProgramID() + "' for tl-index " + toString(j));
166  break;
167  }
168  }
169  }
170 }
171 
172 
174  // no need to do something about mySwitchCommand here,
175  // it is handled by the event control
176 }
177 
178 
179 // ----------- Handling of controlled links
180 void
182  // !!! should be done within the loader (checking necessary)
183  myLinks.reserve(pos + 1);
184  while ((int)myLinks.size() <= pos) {
185  myLinks.push_back(LinkVector());
186  }
187  myLinks[pos].push_back(link);
188  //
189  myLanes.reserve(pos + 1);
190  while ((int)myLanes.size() <= pos) {
191  myLanes.push_back(LaneVector());
192  }
193  myLanes[pos].push_back(lane);
194  link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
195 }
196 
197 
198 void
200  myLinks = logic.myLinks;
201  myLanes = logic.myLanes;
202 }
203 
204 
205 std::map<MSLink*, LinkState>
207  std::map<MSLink*, LinkState> ret;
208  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
209  const LinkVector& l = (*i1);
210  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
211  ret[*i2] = (*i2)->getState();
212  }
213  }
214  return ret;
215 }
216 
217 
218 bool
220  // get the current traffic light signal combination
221  const std::string& state = getCurrentPhaseDef().getState();
222  // go through the links
223  for (int i = 0; i < (int)myLinks.size(); i++) {
224  const LinkVector& currGroup = myLinks[i];
225  LinkState ls = (LinkState) state[i];
226  for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
227  (*j)->setTLState(ls, t);
228  }
229  }
230  return true;
231 }
232 
233 
234 void
235 MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
236  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
237  const LinkVector& l = (*i1);
238  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
239  assert(vals.find(*i2) != vals.end());
240  (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
241  }
242  }
243 }
244 
245 
246 // ----------- Static Information Retrieval
247 int
248 MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
249  int index = 0;
250  for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
251  const LinkVector& l = (*i1);
252  for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
253  if ((*i2) == link) {
254  return index;
255  }
256  }
257  }
258  return -1;
259 }
260 
261 
262 
263 // ----------- Dynamic Information Retrieval
264 SUMOTime
266  return mySwitchCommand != 0 ? mySwitchCommand->getNextSwitchTime() : -1;
267 }
268 
269 
270 SUMOTime
272  const SUMOTime nextSwitch = getNextSwitchTime();
273  if (nextSwitch == -1) {
274  return -1;
275  } else {
276  const SUMOTime remaining = nextSwitch - MSNet::getInstance()->getCurrentTimeStep();
277  return getCurrentPhaseDef().duration - remaining;
278  }
279 }
280 
281 
282 // ----------- Changing phases and phase durations
283 void
285  myOverridingTimes.push_back(duration);
286 }
287 
288 
289 void
292 }
293 
294 
296  // set mesoscopic time penalties
297  const Phases& phases = getPhases();
298  const int numLinks = (int)myLinks.size();
299  // warning already given if not all states are used
300  assert(numLinks <= (int)phases.front()->getState().size());
301  SUMOTime duration = 0;
302  std::vector<double> redDuration(numLinks, 0);
303  std::vector<double> totalRedDuration(numLinks, 0);
304  std::vector<double> penalty(numLinks, 0);
305  for (int i = 0; i < (int)phases.size(); ++i) {
306  const std::string& state = phases[i]->getState();
307  duration += phases[i]->duration;
308  // warn about transitions from green to red without intermediate yellow
309  for (int j = 0; j < numLinks; ++j) {
310  if ((LinkState)state[j] == LINKSTATE_TL_RED
311  || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
312  redDuration[j] += STEPS2TIME(phases[i]->duration);
313  totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
314  } else if (redDuration[j] > 0) {
315  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
316  redDuration[j] = 0;
317  }
318  }
319  }
321  for (int j = 0; j < numLinks; ++j) {
322  if (redDuration[j] > 0) {
323  penalty[j] += 0.5 * (redDuration[j] * redDuration[j] + redDuration[j]);
324  redDuration[j] = 0;
325  }
326  }
327  const double durationSeconds = STEPS2TIME(duration);
328  std::set<const MSJunction*> controlledJunctions;
329  for (int j = 0; j < numLinks; ++j) {
330  for (int k = 0; k < (int)myLinks[j].size(); ++k) {
331  myLinks[j][k]->setMesoTLSPenalty(TIME2STEPS(MSGlobals::gMesoTLSPenalty * penalty[j] / durationSeconds));
332  myLinks[j][k]->setGreenFraction(MAX2((durationSeconds - MSGlobals::gMesoTLSPenalty * totalRedDuration[j]) / durationSeconds, NUMERICAL_EPS)); // avoid zero capacity (warning issued before)
333  controlledJunctions.insert(myLinks[j][k]->getLane()->getEdge().getFromJunction()); // MSLink::myJunction is not yet initialized
334  //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";
335  }
336  }
337  // initialize empty-net travel times
338  // XXX refactor after merging sharps (links know their incoming edge)
339  for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
340  const ConstMSEdgeVector incoming = (*it)->getIncoming();
341  for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
342  const_cast<MSEdge*>(*it_e)->recalcCache();
343  }
344  }
345 
346 }
347 
348 /****************************************************************************/
349 
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:106
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:167
T MAX2(T a, T b)
Definition: StdDefs.h:73
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:74
#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:199
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
SUMOTime duration
The duration of the phase.
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)
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:399
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:64
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:253
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:50
void setCurrentDurationIncrement(SUMOTime delay)
Delays current phase by the given delay.
Base class for objects which have an id.
Definition: Named.h:54
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:80
long long int SUMOTime
Definition: TraCIDefs.h:51
#define NUMERICAL_EPS
Definition: config.h:151
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
SUMOTime getSpentDuration() const
Returns the duration spent in the current phase.
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:77
The link has red light (must brake) but indicates upcoming green.
SUMOTime execute(SUMOTime currentTime)
Executes the regarded junction&#39;s "trySwitch"- method.