Eclipse SUMO - Simulation of Urban MObility
NBTrafficLightLogic.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/****************************************************************************/
20// A SUMO-compliant built logic for a traffic light
21/****************************************************************************/
22#include <config.h>
23
24#include <vector>
25#include <bitset>
26#include <utility>
27#include <string>
28#include <sstream>
29#include <cassert>
30#include "NBEdge.h"
31#include "NBEdgeCont.h"
32#include "NBTrafficLightLogic.h"
40
41
42// ===========================================================================
43// static members
44// ===========================================================================
45
46// ===========================================================================
47// member method definitions
48// ===========================================================================
50 const std::string& subid, int noLinks,
51 SUMOTime offset, TrafficLightType type) :
52 Named(id), myNumLinks(noLinks), mySubID(subid),
53 myOffset(offset),
54 myType(type) {}
55
56
58 Named(logic->getID()),
59 myNumLinks(logic->myNumLinks),
60 mySubID(logic->getProgramID()),
61 myOffset(logic->getOffset()),
62 myPhases(logic->myPhases.begin(), logic->myPhases.end()),
63 myType(logic->getType()) {}
64
65
67
68
69void
70NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const std::vector<int>& next, const std::string& name, const int index) {
71 addStep(duration, state,
79 name, next, index);
80}
81
82
83void
84NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd,
85 const SUMOTime latestEnd, const SUMOTime vehExt, const SUMOTime yellow, const SUMOTime red,
86 const std::string& name,
87 const std::vector<int>& next,
88 int index) {
89 // check state size
90 if (myNumLinks == 0) {
91 // initialize
92 myNumLinks = (int)state.size();
93 } else if ((int)state.size() != myNumLinks) {
94 throw ProcessError("When adding phase to tlLogic '" + getID() + "': state length of " + toString(state.size()) +
95 " does not match declared number of links " + toString(myNumLinks));
96 }
97 // check state contents
98 const std::string::size_type illegal = state.find_first_not_of(SUMOXMLDefinitions::ALLOWED_TLS_LINKSTATES);
99 if (std::string::npos != illegal) {
100 throw ProcessError("When adding phase: illegal character '" + toString(state[illegal]) + "' in state");
101 }
102 // interpret index
103 if (index < 0 || index >= (int)myPhases.size()) {
104 // insert at the end
105 index = (int)myPhases.size();
106 }
107 myPhases.insert(myPhases.begin() + index, PhaseDefinition(duration, state, minDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red, next, name));
108}
109
110
111void
113 if (index >= (int)myPhases.size()) {
114 throw InvalidArgument("Index " + toString(index) + " out of range for logic with "
115 + toString(myPhases.size()) + " phases.");
116 }
117 myPhases.erase(myPhases.begin() + index);
118}
119
120
121void
122NBTrafficLightLogic::swapPhase(int indexPhaseA, int indexPhaseB) {
123 if (indexPhaseA >= (int)myPhases.size()) {
124 throw InvalidArgument("Index " + toString(indexPhaseA) + " out of range for logic with "
125 + toString(myPhases.size()) + " phases.");
126 }
127 if (indexPhaseB >= (int)myPhases.size()) {
128 throw InvalidArgument("Index " + toString(indexPhaseB) + " out of range for logic with "
129 + toString(myPhases.size()) + " phases.");
130 }
131 // declare auxiliar PhaseDefinition and swap
132 const auto auxPhase = myPhases.at(indexPhaseA);
133 myPhases.at(indexPhaseA) = myPhases.at(indexPhaseB);
134 myPhases.at(indexPhaseB) = auxPhase;
135}
136
137
138void
140 const auto firstPhase = myPhases.front();
141 myPhases.erase(myPhases.begin());
142 myPhases.push_back(firstPhase);
143}
144
145
146void
148 const auto lastPhase = myPhases.back();
149 myPhases.pop_back();
150 myPhases.insert(myPhases.begin(), lastPhase);
151}
152
153void
155 if (myNumLinks > numLinks) {
156 for (PhaseDefinition& p : myPhases) {
157 p.state = p.state.substr(0, numLinks);
158 }
159 } else {
160 std::string add(numLinks - myNumLinks, (char)fill);
161 for (PhaseDefinition& p : myPhases) {
162 p.state = p.state + add;
163 }
164 }
165 myNumLinks = numLinks;
166}
167
168
169void
171 assert(index >= 0);
172 assert(index < myNumLinks);
173 for (PhaseDefinition& p : myPhases) {
174 p.state.erase(index, 1);
175 }
176 myNumLinks--;
177}
178
179
180void
182 myNumLinks = 0;
183 myPhases.clear();
184}
185
186
189 SUMOTime duration = 0;
190 for (PhaseDefinitionVector::const_iterator i = myPhases.begin(); i != myPhases.end(); ++i) {
191 duration += (*i).duration;
192 }
193 return duration;
194}
195
196
197void
198NBTrafficLightLogic::closeBuilding(bool checkVarDurations) {
199 for (int i = 0; i < (int)myPhases.size() - 1;) {
200 if (myPhases[i].state != myPhases[i + 1].state || myPhases[i].next.size() > 0 || myPhases[i + 1].next.size() > 0 || myPhases[i].name != myPhases[i + 1].name) {
201 ++i;
202 continue;
203 }
204 myPhases[i].duration += myPhases[i + 1].duration;
207 myPhases[i].minDur += myPhases[i + 1].minDur;
208 } else {
209 myPhases[i].minDur = myPhases[i + 1].minDur;
210 }
211 }
214 myPhases[i].maxDur += myPhases[i + 1].maxDur;
215 } else {
216 myPhases[i].maxDur = myPhases[i + 1].maxDur;
217 }
218 }
219 myPhases.erase(myPhases.begin() + i + 1);
220 }
221 // check if actuated lights are defined correctly
222 if (checkVarDurations) {
224 bool found = false;
225 for (auto p : myPhases) {
228 found = true;
229 break;
230 }
231 }
232 if (!found) {
233 WRITE_WARNING("Non-static traffic light '" + getID() + "' does not define variable phase length.");
234 }
235 }
236 }
237}
238
239
240void
241NBTrafficLightLogic::setPhaseState(int phaseIndex, int tlIndex, LinkState linkState) {
242 assert(phaseIndex < (int)myPhases.size());
243 std::string& phaseState = myPhases[phaseIndex].state;
244 assert(tlIndex < (int)phaseState.size());
245 phaseState[tlIndex] = (char)linkState;
246}
247
248
249void
251 assert(phaseIndex < (int)myPhases.size());
252 myPhases[phaseIndex].duration = duration;
253}
254
255
256void
258 assert(phaseIndex < (int)myPhases.size());
259 myPhases[phaseIndex].minDur = duration;
260}
261
262
263void
265 assert(phaseIndex < (int)myPhases.size());
266 myPhases[phaseIndex].maxDur = duration;
267}
268
269
270void
272 assert(phaseIndex < (int)myPhases.size());
273 myPhases[phaseIndex].earliestEnd = duration;
274}
275
276
277void
279 assert(phaseIndex < (int)myPhases.size());
280 myPhases[phaseIndex].latestEnd = duration;
281}
282
283
284void
286 assert(phaseIndex < (int)myPhases.size());
287 myPhases[phaseIndex].vehExt = duration;
288}
289
290
291void
293 assert(phaseIndex < (int)myPhases.size());
294 myPhases[phaseIndex].yellow = duration;
295}
296
297
298void
300 assert(phaseIndex < (int)myPhases.size());
301 myPhases[phaseIndex].red = duration;
302}
303
304
305void
306NBTrafficLightLogic::setPhaseNext(int phaseIndex, const std::vector<int>& next) {
307 assert(phaseIndex < (int)myPhases.size());
308 myPhases[phaseIndex].next = next;
309}
310
311
312void
313NBTrafficLightLogic::setPhaseName(int phaseIndex, const std::string& name) {
314 assert(phaseIndex < (int)myPhases.size());
315 myPhases[phaseIndex].name = name;
316}
317
318
319void
320NBTrafficLightLogic::overrideState(int phaseIndex, const char c) {
321 assert(phaseIndex < (int)myPhases.size());
322 for (int i = 0; i < (int)myPhases[phaseIndex].state.size(); i++) {
323 myPhases[phaseIndex].state[i] = c;
324 }
325}
326
327/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
TrafficLightType
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static const SUMOTime UNSPECIFIED_DURATION
The definition of a single phase of the logic.
A SUMO-compliant built logic for a traffic light.
SUMOTime getDuration() const
Returns the duration of the complete cycle.
void setPhaseVehExt(int phaseIndex, SUMOTime duration)
Modifies the veh ex for an existing phase (used by NETEDIT)
void deleteStateIndex(int index)
remove the index from all phase states
void resetPhases()
deletes all phases and reset the expect number of links
void setPhaseEarliestEnd(int phaseIndex, SUMOTime duration)
Modifies the min duration for an existing phase (used by NETEDIT)
void setPhaseRed(int phaseIndex, SUMOTime duration)
Modifies the veh ex for an existing phase (used by NETEDIT)
int myNumLinks
The number of participating links.
void setPhaseMinDuration(int phaseIndex, SUMOTime duration)
Modifies the min duration for an existing phase (used by NETEDIT)
void swaplastPhase()
swap first phase
NBTrafficLightLogic(const std::string &id, const std::string &subid, int noLinks, SUMOTime offset=0, TrafficLightType type=TrafficLightType::STATIC)
Constructor.
void closeBuilding(bool checkVarDurations=true)
closes the building process
void swapPhase(int indexPhaseA, int indexPhaseB)
void overrideState(int phaseIndex, const char c)
override state with the given character(used by NETEDIT)
PhaseDefinitionVector myPhases
The junction logic's storage for traffic light phase list.
void setPhaseName(int phaseIndex, const std::string &name)
Modifies the phase name (used by NETEDIT)
void setPhaseDuration(int phaseIndex, SUMOTime duration)
Modifies the duration for an existing phase (used by NETEDIT)
void setPhaseState(int phaseIndex, int tlIndex, LinkState linkState)
Modifies the state for an existing phase (used by NETEDIT)
void setPhaseMaxDuration(int phaseIndex, SUMOTime duration)
Modifies the max duration for an existing phase (used by NETEDIT)
void setPhaseYellow(int phaseIndex, SUMOTime duration)
Modifies the veh ex for an existing phase (used by NETEDIT)
void setPhaseLatestEnd(int phaseIndex, SUMOTime duration)
Modifies the max duration for an existing phase (used by NETEDIT)
void setPhaseNext(int phaseIndex, const std::vector< int > &next)
Modifies the next phase (used by NETEDIT)
~NBTrafficLightLogic()
Destructor.
void setStateLength(int numLinks, LinkState fill=LINKSTATE_TL_RED)
void swapfirstPhase()
swap first phase
TrafficLightType myType
The algorithm type for the traffic light.
void addStep(const SUMOTime duration, const std::string &state, const std::vector< int > &next=std::vector< int >(), const std::string &name="", const int index=-1)
Adds a phase to the logic (static)
Base class for objects which have an id.
Definition: Named.h:54
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static const std::string ALLOWED_TLS_LINKSTATES
all allowed characters for phase state