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//#define DEBUG_COORDINATION
40#define DEBUG_COND (getID()=="C")
41
42
43// ===========================================================================
44// member method definitions
45// ===========================================================================
47 const std::string& id, const std::string& programID, const SUMOTime offset, const TrafficLightType logicType, const Phases& phases,
48 int step, SUMOTime delay,
49 const Parameterised::Map& parameters) :
50 MSTrafficLightLogic(tlcontrol, id, programID, offset, logicType, delay, parameters),
51 myPhases(phases),
52 myStep(step) {
53 for (const MSPhaseDefinition* phase : myPhases) {
54 myDefaultCycleTime += phase->duration;
55 }
56 if (myStep < (int)myPhases.size()) {
57 myPhases[myStep]->myLastSwitch = SIMSTEP;
58 }
59 // the following initializations are only used by 'actuated' and 'delay_based' but do not affect 'static'
62 }
64 if (myPhases.size() > 0) {
65 SUMOTime earliest = SIMSTEP + getEarliest(-1);
66 if (earliest > getNextSwitchTime()) {
68 mySwitchCommand = new SwitchCommand(tlcontrol, this, earliest);
70 }
71 }
72}
73
74
77}
78
79
80// ------------ Switching and setting current rows
83 // check whether the current duration shall be increased
87 return delay;
88 }
89
90 // increment the index
91 if (myPhases[myStep]->nextPhases.size() > 0 && myPhases[myStep]->nextPhases.front() >= 0) {
92 myStep = myPhases[myStep]->nextPhases.front();
93 } else {
94 myStep++;
95 }
96 // if the last phase was reached ...
97 if (myStep >= (int)myPhases.size()) {
98 // ... set the index to the first phase
99 myStep = 0;
100 }
101 assert((int)myPhases.size() > myStep);
102 //stores the time the phase started
104 // check whether the next duration was overridden
105 if (myOverridingTimes.size() > 0) {
106 SUMOTime nextDuration = myOverridingTimes[0];
108 return nextDuration;
109 }
110 // return offset to the next switch
111 return myPhases[myStep]->duration;
112}
113
114
115// ------------ Static Information Retrieval
116int
118 return (int) myPhases.size();
119}
120
121
124 return myPhases;
125}
126
127
130 return myPhases;
131}
132
133
136 assert((int)myPhases.size() > givenStep);
137 return *myPhases[givenStep];
138}
139
140
141// ------------ Dynamic Information Retrieval
142int
144 return myStep;
145}
146
147
150 return *myPhases[myStep];
151}
152
153
154// ------------ Conversion between time and phase
157 SUMOTime position = 0;
158 if (myStep > 0) {
159 for (int i = 0; i < myStep; i++) {
160 position = position + getPhase(i).duration;
161 }
162 }
163 position = position + simStep - getPhase(myStep).myLastSwitch;
164 position = position % myDefaultCycleTime;
165 assert(position <= myDefaultCycleTime);
166 return position;
167}
168
169
172 assert(index < (int)myPhases.size());
173 if (index == 0) {
174 return 0;
175 }
176 SUMOTime pos = 0;
177 for (int i = 0; i < index; i++) {
178 pos += getPhase(i).duration;
179 }
180 return pos;
181}
182
183
184int
186 offset = offset % myDefaultCycleTime;
187 if (offset == myDefaultCycleTime) {
188 return 0;
189 }
190 SUMOTime testPos = 0;
191 for (int i = 0; i < (int)myPhases.size(); i++) {
192 testPos = testPos + getPhase(i).duration;
193 if (testPos > offset) {
194 return i;
195 }
196 if (testPos == offset) {
197 assert((int)myPhases.size() > (i + 1));
198 return (i + 1);
199 }
200 }
201 return 0;
202}
203
204
207 return (myCoordinated
209 : (t - myPhases[0]->myLastSwitch) % myDefaultCycleTime);
210}
211
212
213
214
217 SUMOTime earliest = getEarliestEnd();
219 return 0;
220 } else {
221 if (prevStart >= SIMSTEP - getTimeInCycle() && prevStart < getCurrentPhaseDef().myLastEnd) {
222 // phase was started and ended once already in the current cycle
223 // it should not end a second time in the same cycle
224 earliest += myDefaultCycleTime;
225#ifdef DEBUG_COORDINATION
226 if (DEBUG_COND) {
227 std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep
228 << " prevStart= " << STEPS2TIME(prevStart)
229 << " prevEnd= " << STEPS2TIME(getCurrentPhaseDef().myLastEnd)
230 << " cycleStart=" << STEPS2TIME(SIMSTEP - getTimeInCycle()) << " started Twice - move into next cycle\n";
231 }
232#endif
233 } else {
234 SUMOTime latest = getLatestEnd();
236 const SUMOTime minRemaining = getMinDur() - (SIMSTEP - getCurrentPhaseDef().myLastSwitch);
237 const SUMOTime minEnd = getTimeInCycle() + minRemaining;
238 if (latest > earliest && latest < minEnd) {
239 // cannot terminate phase between earliest and latest -> move end into next cycle
240 earliest += myDefaultCycleTime;
241 } else if (latest < earliest && latest >= minEnd) {
242 // can ignore earliest since it counts from the previous cycle
243 earliest -= myDefaultCycleTime;
244 }
245#ifdef DEBUG_COORDINATION
246 if (DEBUG_COND) {
247 std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep << " latest=" << STEPS2TIME(latest) << " minEnd="
248 << STEPS2TIME(minEnd) << " earliest=" << STEPS2TIME(earliest) << "\n";
249 }
250#endif
251 }
252 }
253 const SUMOTime maxRemaining = getMaxDur() - (SIMSTEP - getCurrentPhaseDef().myLastSwitch);
254 return MIN2(earliest - getTimeInCycle(), maxRemaining);
255 }
256}
257
258
261 const SUMOTime latest = getLatestEnd();
263 return SUMOTime_MAX; // no restriction
264 } else {
265 if (latest < getEarliestEnd()) {
267 if (running < getTimeInCycle()) {
268 // phase was started in the current cycle so the restriction does not apply yet
269 return SUMOTime_MAX;
270 }
271 }
272#ifdef DEBUG_COORDINATION
273 if (DEBUG_COND) {
274 std::cout << SIMTIME << " tl=" << getID() << " getLatest phase=" << myStep << " latest=" << STEPS2TIME(latest)
275 << " cycTime=" << STEPS2TIME(getTimeInCycle()) << " res=" << STEPS2TIME(latest - getTimeInCycle()) << "\n";
276 }
277#endif
278 if (latest == myDefaultCycleTime && getTimeInCycle() == 0) {
279 // special case: end on cylce time wrap-around
280 return 0;
281 }
282 return MAX2(SUMOTime(0), latest - getTimeInCycle());
283 }
284}
285
286
287
288// ------------ Changing phases and phase durations
289void
291 SUMOTime simStep, int step, SUMOTime stepDuration) {
293 mySwitchCommand = new SwitchCommand(tlcontrol, this, stepDuration + simStep);
294 if (step >= 0 && step != myStep) {
295 myStep = step;
297 setTrafficLightSignals(simStep);
298 tlcontrol.get(getID()).executeOnSwitchActions();
299 }
301 mySwitchCommand, stepDuration + simStep);
302}
303
304
305void
307 assert(step < (int)phases.size());
308 deletePhases();
309 myPhases = phases;
310 myStep = step;
311}
312
313
314void
316 for (int i = 0; i < (int)myPhases.size(); i++) {
317 delete myPhases[i];
318 }
319}
320
321void
328 out.closeTag();
329}
330
331const std::string
332MSSimpleTrafficLightLogic::getParameter(const std::string& key, const std::string defaultValue) const {
333 if (key == "cycleTime") {
335 } else if (key == "offset") {
337 } else if (key == "coordinated") {
338 return toString(myCoordinated);
339 } else if (key == "cycleSecond") {
341 }
342 return Parameterised::getParameter(key, defaultValue);
343}
344
345void
346MSSimpleTrafficLightLogic::setParameter(const std::string& key, const std::string& value) {
347 if (key == "cycleTime") {
349 Parameterised::setParameter(key, value);
350 } else if (key == "cycleSecond") {
351 throw InvalidArgument(key + " cannot be changed dynamically for traffic light '" + getID() + "'");
352 } else if (key == "offset") {
353 myOffset = string2time(value);
354 } else if (key == "coordinated") {
356 Parameterised::setParameter(key, value);
357 } else {
358 Parameterised::setParameter(key, value);
359 }
360}
361
362/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define DEBUG_COND
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define SIMSTEP
Definition: SUMOTime.h:60
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define SIMTIME
Definition: SUMOTime.h:61
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
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:71
T MAX2(T a, T b)
Definition: StdDefs.h:77
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:183
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:472
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:321
The definition of a single phase of a tls logic.
static const SUMOTime UNSPECIFIED_DURATION
SUMOTime myLastSwitch
Stores the timestep of the last on-switched of the phase.
SUMOTime duration
The duration of the phase.
SUMOTime getLatest() const
the maximum duration for keeping the current phase when considering 'latestEnd'
int getIndexFromOffset(SUMOTime offset) const override
Returns the step (the phasenumber) of a given position of the cycle.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration) override
Changes the current phase and her duration.
Phases myPhases
The list of phases this logic uses.
virtual void saveState(OutputDevice &out) const override
Saves the current tls states into the given stream.
const MSPhaseDefinition & getPhase(int givenstep) const override
Returns the definition of the phase from the given position within the plan.
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const override
Returns the index of the logic at the given simulation step.
SUMOTime getOffsetFromIndex(int index) const override
Returns the position (start of a phase during a cycle) from of a given step.
int getPhaseNumber() const override
Returns the number of phases.
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.
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 Parameterised::Map &parameters)
Constructor.
virtual SUMOTime mapTimeInCycle(SUMOTime t) const override
map the given time into the current cycle
bool myCoordinated
whether coordination parameters earliestEnd, latestEnd are
int getCurrentPhaseIndex() const override
Returns the current index within the program.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const override
gets a parameter
void deletePhases()
frees memory responsibilities
const Phases & getPhases() const override
Returns the phases of this tls program.
virtual void setParameter(const std::string &key, const std::string &value) override
Sets a parameter and updates internal constants.
virtual SUMOTime trySwitch() override
Switches to the next phase.
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current 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
virtual SUMOTime getLatestEnd(int step=-1) const
std::vector< SUMOTime > myOverridingTimes
A list of duration overrides.
virtual SUMOTime getMinDur(int step=-1) const
SUMOTime myDefaultCycleTime
The cycle time (without changes)
SUMOTime getTimeInCycle() const
return time within the current cycle
const std::string & getProgramID() const
Returns this tl-logic's id.
virtual SUMOTime getEarliestEnd(int step=-1) const
SwitchCommand * mySwitchCommand
The current switch command.
SUMOTime myCurrentDurationIncrement
A value for enlarge the current duration.
virtual SUMOTime getMaxDur(int step=-1) const
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 & 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 & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:251
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
std::map< std::string, std::string > Map
parameters map
Definition: Parameterised.h:45
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
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