Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSSimpleTrafficLightLogic.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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) {
54 if (myStep < (int)myPhases.size()) {
55 myPhases[myStep]->myLastSwitch = SIMSTEP;
56 }
57 // the following initializations are only used by 'actuated' and 'delay_based' but do not affect 'static'
60 }
62 if (myPhases.size() > 0) {
63 SUMOTime earliest = SIMSTEP + getEarliest(-1);
64 if (earliest > getNextSwitchTime()) {
66 mySwitchCommand = new SwitchCommand(tlcontrol, this, earliest);
68 }
69 }
70}
71
72
76
77
78// ------------ Switching and setting current rows
81 // check whether the current duration shall be increased
85 return delay;
86 }
87
88 // increment the index
89 if (myPhases[myStep]->nextPhases.size() > 0 && myPhases[myStep]->nextPhases.front() >= 0) {
90 myStep = myPhases[myStep]->nextPhases.front();
91 } else {
92 myStep++;
93 }
94 // if the last phase was reached ...
95 if (myStep >= (int)myPhases.size()) {
96 // ... set the index to the first phase
97 myStep = 0;
98 }
99 assert((int)myPhases.size() > myStep);
100 //stores the time the phase started
102 // check whether the next duration was overridden
103 if (myOverridingTimes.size() > 0) {
104 SUMOTime nextDuration = myOverridingTimes[0];
106 return nextDuration;
107 }
108 // return offset to the next switch
109 return myPhases[myStep]->duration;
110}
111
112
113// ------------ Static Information Retrieval
114int
116 return (int) myPhases.size();
117}
118
119
124
125
130
131
134 assert((int)myPhases.size() > givenStep);
135 return *myPhases[givenStep];
136}
137
138
139// ------------ Dynamic Information Retrieval
140int
144
145
150
151
152void
156
157
158// ------------ Conversion between time and phase
161 SUMOTime position = 0;
162 if (myStep > 0) {
163 for (int i = 0; i < myStep; i++) {
164 position = position + getPhase(i).duration;
165 }
166 }
167 position = position + simStep - getPhase(myStep).myLastSwitch;
168 position = position % myDefaultCycleTime;
169 assert(position <= myDefaultCycleTime);
170 return position;
171}
172
173
176 assert(index < (int)myPhases.size());
177 if (index == 0) {
178 return 0;
179 }
180 SUMOTime pos = 0;
181 for (int i = 0; i < index; i++) {
182 pos += getPhase(i).duration;
183 }
184 return pos;
185}
186
187
188int
190 offset = offset % myDefaultCycleTime;
191 if (offset == myDefaultCycleTime) {
192 return 0;
193 }
194 SUMOTime testPos = 0;
195 for (int i = 0; i < (int)myPhases.size(); i++) {
196 testPos = testPos + getPhase(i).duration;
197 if (testPos > offset) {
198 return i;
199 }
200 if (testPos == offset) {
201 assert((int)myPhases.size() > (i + 1));
202 return (i + 1);
203 }
204 }
205 return 0;
206}
207
208
211 return (myCoordinated
213 : (t - myPhases[0]->myLastSwitch) % myDefaultCycleTime);
214}
215
216
217
218
221 SUMOTime earliest = getEarliestEnd();
223 return 0;
224 } else {
225 if (prevStart >= SIMSTEP - getTimeInCycle() && prevStart < getCurrentPhaseDef().myLastEnd) {
226 // phase was started and ended once already in the current cycle
227 // it should not end a second time in the same cycle
228 earliest += myDefaultCycleTime;
229#ifdef DEBUG_COORDINATION
230 if (DEBUG_COND) {
231 std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep
232 << " prevStart= " << STEPS2TIME(prevStart)
233 << " prevEnd= " << STEPS2TIME(getCurrentPhaseDef().myLastEnd)
234 << " cycleStart=" << STEPS2TIME(SIMSTEP - getTimeInCycle()) << " started Twice - move into next cycle\n";
235 }
236#endif
237 } else {
238 SUMOTime latest = getLatestEnd();
240 const SUMOTime minRemaining = getMinDur() - (SIMSTEP - getCurrentPhaseDef().myLastSwitch);
241 const SUMOTime minEnd = getTimeInCycle() + minRemaining;
242 if (latest > earliest && latest < minEnd) {
243 // cannot terminate phase between earliest and latest -> move end into next cycle
244 earliest += myDefaultCycleTime;
245 } else if (latest < earliest && latest >= minEnd) {
246 // can ignore earliest since it counts from the previous cycle
247 earliest -= myDefaultCycleTime;
248 }
249#ifdef DEBUG_COORDINATION
250 if (DEBUG_COND) {
251 std::cout << SIMTIME << " tl=" << getID() << " getEarliest phase=" << myStep << " latest=" << STEPS2TIME(latest) << " minEnd="
252 << STEPS2TIME(minEnd) << " earliest=" << STEPS2TIME(earliest) << "\n";
253 }
254#endif
255 }
256 }
257 const SUMOTime maxRemaining = getMaxDur() - (SIMSTEP - getCurrentPhaseDef().myLastSwitch);
258 return MIN2(earliest - getTimeInCycle(), maxRemaining);
259 }
260}
261
262
265 const SUMOTime latest = getLatestEnd();
267 return SUMOTime_MAX; // no restriction
268 } else {
269 if (latest < getEarliestEnd()) {
271 if (running < getTimeInCycle()) {
272 // phase was started in the current cycle so the restriction does not apply yet
273 return SUMOTime_MAX;
274 }
275 }
276#ifdef DEBUG_COORDINATION
277 if (DEBUG_COND) {
278 std::cout << SIMTIME << " tl=" << getID() << " getLatest phase=" << myStep << " latest=" << STEPS2TIME(latest)
279 << " cycTime=" << STEPS2TIME(getTimeInCycle()) << " res=" << STEPS2TIME(latest - getTimeInCycle()) << "\n";
280 }
281#endif
282 if (latest == myDefaultCycleTime && getTimeInCycle() == 0) {
283 // special case: end on cylce time wrap-around
284 return 0;
285 }
286 return MAX2(SUMOTime(0), latest - getTimeInCycle());
287 }
288}
289
290
291
292// ------------ Changing phases and phase durations
293void
295 SUMOTime simStep, int step, SUMOTime stepDuration) {
297 mySwitchCommand = new SwitchCommand(tlcontrol, this, stepDuration + simStep);
298 if (step >= 0 && step != myStep) {
299 myStep = step;
301 if (myAmActive) {
302 // when loading from state, the last loaded program isn't always the active one
303 setTrafficLightSignals(simStep);
304 }
305 tlcontrol.get(getID()).executeOnSwitchActions();
306 }
308 mySwitchCommand, stepDuration + simStep);
309}
310
311
312void
314 assert(step < (int)phases.size());
315 SUMOTime lastSwitch = myPhases[myStep]->getState() == phases[step]->getState() ? myPhases[myStep]->myLastSwitch : SIMSTEP;
316 deletePhases();
317 myPhases = phases;
318 myStep = step;
320 myPhases[myStep]->myLastSwitch = lastSwitch;
321}
322
323
324void
326 for (int i = 0; i < (int)myPhases.size(); i++) {
327 delete myPhases[i];
328 }
329}
330
331void
341
342const std::string
343MSSimpleTrafficLightLogic::getParameter(const std::string& key, const std::string defaultValue) const {
344 if (key == "cycleTime") {
346 } else if (key == "offset") {
348 } else if (key == "coordinated") {
349 return toString(myCoordinated);
350 } else if (key == "cycleSecond") {
352 } else if (key == "typeName") {
353 return toString(this->getLogicType());
354 }
355 return Parameterised::getParameter(key, defaultValue);
356}
357
358void
359MSSimpleTrafficLightLogic::setParameter(const std::string& key, const std::string& value) {
360 if (key == "cycleTime") {
362 Parameterised::setParameter(key, value);
363 } else if (key == "cycleSecond" || key == "typeName") {
364 throw InvalidArgument(key + " cannot be changed dynamically for traffic light '" + getID() + "'");
365 } else if (key == "offset") {
366 myOffset = string2time(value);
367 } else if (key == "coordinated") {
369 Parameterised::setParameter(key, value);
370 } else {
371 Parameterised::setParameter(key, value);
372 }
373}
374
375/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SIMSTEP
Definition SUMOTime.h:64
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:65
#define TIME2STEPS(x)
Definition SUMOTime.h:60
@ SUMO_TAG_TLLOGIC
a traffic light logic
@ SUMO_ATTR_PHASE
@ SUMO_ATTR_ID
@ SUMO_ATTR_PROGRAMID
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_CYCLETIME
@ SUMO_ATTR_ACTIVE
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
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:187
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:485
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
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
SUMOTime computeCycleTime(const Phases &phases)
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.
TrafficLightType getLogicType() const
Returns the type of the logic.
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
bool myAmActive
whether the current program is active
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.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
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.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
std::map< std::string, std::string > Map
parameters map
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.
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
#define DEBUG_COND