Eclipse SUMO - Simulation of Urban MObility
MSSimpleTrafficLightLogic.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-2022 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 /****************************************************************************/
22 // A fixed traffic light logic
23 /****************************************************************************/
24 #include <config.h>
25 
26 #include <cassert>
27 #include <utility>
28 #include <vector>
29 #include <bitset>
30 #include <sstream>
33 #include <microsim/MSNet.h>
35 #include "MSTLLogicControl.h"
36 #include "MSTrafficLightLogic.h"
38 
39 
40 // ===========================================================================
41 // member method definitions
42 // ===========================================================================
44  const std::string& id, const std::string& programID, const SUMOTime offset, const TrafficLightType logicType, const Phases& phases,
45  int step, SUMOTime delay,
46  const std::map<std::string, std::string>& parameters) :
47  MSTrafficLightLogic(tlcontrol, id, programID, offset, logicType, delay, parameters),
48  myPhases(phases),
49  myStep(step) {
50  for (const MSPhaseDefinition* phase : myPhases) {
51  myDefaultCycleTime += phase->duration;
52  }
53  if (myStep < (int)myPhases.size()) {
54  myPhases[myStep]->myLastSwitch = SIMSTEP;
55  }
56  // the following initializations are only used by 'actuated' and 'delay_based' but do not affect 'static'
59  }
60  myCoordinated = StringUtils::toBool(getParameter("coordinated", "false"));
61  if (myPhases.size() > 0) {
62  SUMOTime earliest = SIMSTEP + getEarliest(-1);
63  if (earliest > getNextSwitchTime()) {
65  mySwitchCommand = new SwitchCommand(tlcontrol, this, earliest);
67  }
68  }
69 }
70 
71 
73  deletePhases();
74 }
75 
76 
77 // ------------ Switching and setting current rows
80  // check whether the current duration shall be increased
84  return delay;
85  }
86 
87  // increment the index
88  if (myPhases[myStep]->nextPhases.size() > 0 && myPhases[myStep]->nextPhases.front() >= 0) {
89  myStep = myPhases[myStep]->nextPhases.front();
90  } else {
91  myStep++;
92  }
93  // if the last phase was reached ...
94  if (myStep >= (int)myPhases.size()) {
95  // ... set the index to the first phase
96  myStep = 0;
97  }
98  assert((int)myPhases.size() > myStep);
99  //stores the time the phase started
101  // check whether the next duration was overridden
102  if (myOverridingTimes.size() > 0) {
103  SUMOTime nextDuration = myOverridingTimes[0];
104  myOverridingTimes.erase(myOverridingTimes.begin());
105  return nextDuration;
106  }
107  // return offset to the next switch
108  return myPhases[myStep]->duration;
109 }
110 
111 
112 // ------------ Static Information Retrieval
113 int
115  return (int) myPhases.size();
116 }
117 
118 
121  return myPhases;
122 }
123 
124 
127  return myPhases;
128 }
129 
130 
131 const MSPhaseDefinition&
133  assert((int)myPhases.size() > givenStep);
134  return *myPhases[givenStep];
135 }
136 
137 
138 // ------------ Dynamic Information Retrieval
139 int
141  return myStep;
142 }
143 
144 
145 const MSPhaseDefinition&
147  return *myPhases[myStep];
148 }
149 
150 
151 // ------------ Conversion between time and phase
152 SUMOTime
154  SUMOTime position = 0;
155  if (myStep > 0) {
156  for (int i = 0; i < myStep; i++) {
157  position = position + getPhase(i).duration;
158  }
159  }
160  position = position + simStep - getPhase(myStep).myLastSwitch;
161  position = position % myDefaultCycleTime;
162  assert(position <= myDefaultCycleTime);
163  return position;
164 }
165 
166 
167 SUMOTime
169  assert(index < (int)myPhases.size());
170  if (index == 0) {
171  return 0;
172  }
173  SUMOTime pos = 0;
174  for (int i = 0; i < index; i++) {
175  pos += getPhase(i).duration;
176  }
177  return pos;
178 }
179 
180 
181 int
183  offset = offset % myDefaultCycleTime;
184  if (offset == myDefaultCycleTime) {
185  return 0;
186  }
187  SUMOTime testPos = 0;
188  for (int i = 0; i < (int)myPhases.size(); i++) {
189  testPos = testPos + getPhase(i).duration;
190  if (testPos > offset) {
191  return i;
192  }
193  if (testPos == offset) {
194  assert((int)myPhases.size() > (i + 1));
195  return (i + 1);
196  }
197  }
198  return 0;
199 }
200 
201 
202 SUMOTime
204  return (myCoordinated
205  ? (t - myOffset) % myDefaultCycleTime
206  : (t - myPhases[0]->myLastSwitch) % myDefaultCycleTime);
207 }
208 
209 
210 
211 
212 SUMOTime
215  if (earliest == MSPhaseDefinition::UNSPECIFIED_DURATION) {
216  return 0;
217  } else {
218  if (prevStart >= SIMSTEP - getTimeInCycle()) {
219  // phase was started and ended once already in the current cycle
220  // it should not end a second time in the same cycle
221  earliest += myDefaultCycleTime;
222  //std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep << " started Twice - move into next cycle\n";
223  } else {
227  if (latest > earliest && latest < minEnd) {
228  // cannot terminate phase between earliest and latest -> move end into next cycle
229  earliest += myDefaultCycleTime;
230  } else if (latest < earliest && latest >= minEnd) {
231  // can ignore earliest since it counts from the previous cycle
232  earliest -= myDefaultCycleTime;
233  }
234  //std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep << " latest=" << STEPS2TIME(latest) << " minEnd=" << STEPS2TIME(minEnd) << " earliest=" << STEPS2TIME(earliest) << "\n";
235  }
236  }
238  return MIN2(earliest - getTimeInCycle(), maxRemaining);
239  }
240 }
241 
242 
243 SUMOTime
245  const SUMOTime latest = getCurrentPhaseDef().latestEnd;
247  return SUMOTime_MAX; // no restriction
248  } else {
249  if (latest < myPhases[myStep]->earliestEnd) {
250  const SUMOTime running = SIMSTEP - getCurrentPhaseDef().myLastSwitch;
251  if (running < getTimeInCycle()) {
252  // phase was started in the current cycle so the restriction does not apply yet
253  return SUMOTime_MAX;
254  }
255  }
256  return MAX2(SUMOTime(0), latest - getTimeInCycle());
257  }
258 }
259 
260 
261 
262 // ------------ Changing phases and phase durations
263 void
265  SUMOTime simStep, int step, SUMOTime stepDuration) {
267  mySwitchCommand = new SwitchCommand(tlcontrol, this, stepDuration + simStep);
268  if (step >= 0 && step != myStep) {
269  myStep = step;
271  setTrafficLightSignals(simStep);
272  tlcontrol.get(getID()).executeOnSwitchActions();
273  }
275  mySwitchCommand, stepDuration + simStep);
276 }
277 
278 
279 void
281  assert(step < (int)phases.size());
282  deletePhases();
283  myPhases = phases;
284  myStep = step;
285 }
286 
287 
288 void
290  for (int i = 0; i < (int)myPhases.size(); i++) {
291  delete myPhases[i];
292  }
293 }
294 
295 void
298  out.writeAttr(SUMO_ATTR_ID, getID());
302  out.closeTag();
303 }
304 
305 
306 /****************************************************************************/
#define SIMSTEP
Definition: SUMOTime.h:59
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
TrafficLightType
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_ATTR_PHASE
@ SUMO_ATTR_ID
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_CYCLETIME
T MIN2(T a, T b)
Definition: StdDefs.h:74
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:318
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:469
The definition of a single phase of a tls logic.
SUMOTime maxDuration
The maximum duration of the phase.
static const SUMOTime UNSPECIFIED_DURATION
SUMOTime latestEnd
The maximum time within the cycle for switching (for coordinated actuation)
SUMOTime minDuration
The minimum duration of the phase.
SUMOTime myLastSwitch
Stores the timestep of the last on-switched of the phase.
SUMOTime duration
The duration of the phase.
SUMOTime earliestEnd
The minimum time within the cycle for switching (for coordinated actuation)
SUMOTime getLatest() const
the maximum duratin for keeping the current phase when considering 'latestEnd'
Phases myPhases
The list of phases this logic uses.
MSSimpleTrafficLightLogic(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &programID, const SUMOTime offset, const TrafficLightType logicType, const Phases &phases, int step, SUMOTime delay, const std::map< std::string, std::string > &parameters)
Constructor.
virtual void saveState(OutputDevice &) const
Saves the current tls states into the given stream.
virtual SUMOTime mapTimeInCycle(SUMOTime t) const
map the given time into the current cycle
SUMOTime getEarliest(SUMOTime prevStart) const
the minimum duration for keeping the current phase when considering 'earliestEnd'
void setPhases(const Phases &phases, int index)
Replaces the phases and set the phase index.
int getIndexFromOffset(SUMOTime offset) const
Returns the step (the phasenumber) of a given position of the cycle.
int getPhaseNumber() const
Returns the number of phases.
int getCurrentPhaseIndex() const
Returns the current index within the program.
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const
Returns the index of the logic at the given simulation step.
SUMOTime getOffsetFromIndex(int index) const
Returns the position (start of a phase during a cycle) from of a given step.
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
const MSPhaseDefinition & getPhase(int givenstep) const
Returns the definition of the phase from the given position within the plan.
const Phases & getPhases() const
Returns the phases of this tls program.
bool myCoordinated
whether coordination parameters earliestEnd, latestEnd are
void deletePhases()
frees memory responsibilities
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)
Changes the current phase and her duration.
virtual SUMOTime trySwitch()
Switches to the next phase.
A class that stores and controls tls and switching of their programs.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
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.)
The parent class for traffic light logics.
SUMOTime myOffset
the offset parameter of the current program
std::vector< SUMOTime > myOverridingTimes
A list of duration overrides.
SUMOTime myDefaultCycleTime
The cycle time (without changes)
SUMOTime getTimeInCycle() const
return time within the current cycle
SwitchCommand * mySwitchCommand
The current switch command.
SUMOTime myCurrentDurationIncrement
A value for enlarge the current duration.
SUMOTime getNextSwitchTime() const
Returns the assumed next switch time.
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.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
const std::string & getProgramID() const
Returns this tl-logic's id.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter