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.dev/sumo
3 // Copyright (C) 2001-2024 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"
35 #include <utils/options/Option.h>
36 #include <utils/common/ToString.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()) {
65 }
66 
67 
69 
70 
71 void
72 NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const std::vector<int>& next, const std::string& name, const int index) {
73  addStep(duration, state,
81  name, next, index);
82 }
83 
84 
85 void
86 NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd,
87  const SUMOTime latestEnd, const SUMOTime vehExt, const SUMOTime yellow, const SUMOTime red,
88  const std::string& name,
89  const std::vector<int>& next,
90  int index) {
91  // check state size
92  if (myNumLinks == 0) {
93  // initialize
94  myNumLinks = (int)state.size();
95  } else if ((int)state.size() != myNumLinks) {
96  throw ProcessError("When adding phase to tlLogic '" + getID() + "': state length of " + toString(state.size()) +
97  " does not match declared number of links " + toString(myNumLinks));
98  }
99  // check state contents
100  const std::string::size_type illegal = state.find_first_not_of(SUMOXMLDefinitions::ALLOWED_TLS_LINKSTATES);
101  if (std::string::npos != illegal) {
102  throw ProcessError(TLF("When adding phase: illegal character '%' in state", toString(state[illegal])));
103  }
104  // interpret index
105  if (index < 0 || index >= (int)myPhases.size()) {
106  // insert at the end
107  index = (int)myPhases.size();
108  }
109  myPhases.insert(myPhases.begin() + index, PhaseDefinition(duration, state, minDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red, next, name));
110 }
111 
112 
113 void
115  if (index >= (int)myPhases.size()) {
116  throw InvalidArgument("Index " + toString(index) + " out of range for logic with "
117  + toString(myPhases.size()) + " phases.");
118  }
119  myPhases.erase(myPhases.begin() + index);
120 }
121 
122 
123 void
124 NBTrafficLightLogic::swapPhase(int indexPhaseA, int indexPhaseB) {
125  if (indexPhaseA >= (int)myPhases.size()) {
126  throw InvalidArgument("Index " + toString(indexPhaseA) + " out of range for logic with "
127  + toString(myPhases.size()) + " phases.");
128  }
129  if (indexPhaseB >= (int)myPhases.size()) {
130  throw InvalidArgument("Index " + toString(indexPhaseB) + " out of range for logic with "
131  + toString(myPhases.size()) + " phases.");
132  }
133  // declare auxiliar PhaseDefinition and swap
134  const auto auxPhase = myPhases.at(indexPhaseA);
135  myPhases.at(indexPhaseA) = myPhases.at(indexPhaseB);
136  myPhases.at(indexPhaseB) = auxPhase;
137 }
138 
139 
140 void
142  const auto firstPhase = myPhases.front();
143  myPhases.erase(myPhases.begin());
144  myPhases.push_back(firstPhase);
145 }
146 
147 
148 void
150  const auto lastPhase = myPhases.back();
151  myPhases.pop_back();
152  myPhases.insert(myPhases.begin(), lastPhase);
153 }
154 
155 void
157  if (myNumLinks > numLinks) {
158  for (PhaseDefinition& p : myPhases) {
159  p.state = p.state.substr(0, numLinks);
160  }
161  } else {
162  std::string add(numLinks - myNumLinks, (char)fill);
163  for (PhaseDefinition& p : myPhases) {
164  p.state = p.state + add;
165  }
166  }
167  myNumLinks = numLinks;
168 }
169 
170 
171 void
173  assert(index >= 0);
174  assert(index < myNumLinks);
175  for (PhaseDefinition& p : myPhases) {
176  p.state.erase(index, 1);
177  }
178  myNumLinks--;
179 }
180 
181 
182 void
184  myNumLinks = 0;
185  myPhases.clear();
186 }
187 
188 
189 SUMOTime
191  SUMOTime duration = 0;
192  for (PhaseDefinitionVector::const_iterator i = myPhases.begin(); i != myPhases.end(); ++i) {
193  duration += (*i).duration;
194  }
195  return duration;
196 }
197 
198 
199 void
200 NBTrafficLightLogic::closeBuilding(bool checkVarDurations) {
201  for (int i = 0; i < (int)myPhases.size() - 1;) {
202  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) {
203  ++i;
204  continue;
205  }
206  myPhases[i].duration += myPhases[i + 1].duration;
209  myPhases[i].minDur += myPhases[i + 1].minDur;
210  } else {
211  myPhases[i].minDur = myPhases[i + 1].minDur;
212  }
213  }
216  myPhases[i].maxDur += myPhases[i + 1].maxDur;
217  } else {
218  myPhases[i].maxDur = myPhases[i + 1].maxDur;
219  }
220  }
221  myPhases.erase(myPhases.begin() + i + 1);
222  }
223  // check if actuated lights are defined correctly
224  if (checkVarDurations) {
226  bool found = false;
227  for (auto p : myPhases) {
230  found = true;
231  break;
232  }
233  }
234  if (!found) {
235  WRITE_WARNINGF(TL("Non-static traffic light '%' does not define variable phase length."), getID());
236  }
237  }
238  }
239 }
240 
241 
242 void
243 NBTrafficLightLogic::setPhaseState(int phaseIndex, int tlIndex, LinkState linkState) {
244  assert(phaseIndex < (int)myPhases.size());
245  std::string& phaseState = myPhases[phaseIndex].state;
246  assert(tlIndex < (int)phaseState.size());
247  phaseState[tlIndex] = (char)linkState;
248 }
249 
250 
251 void
253  assert(phaseIndex < (int)myPhases.size());
254  myPhases[phaseIndex].duration = duration;
255 }
256 
257 
258 void
260  assert(phaseIndex < (int)myPhases.size());
261  myPhases[phaseIndex].minDur = duration;
262 }
263 
264 
265 void
267  assert(phaseIndex < (int)myPhases.size());
268  myPhases[phaseIndex].maxDur = duration;
269 }
270 
271 
272 void
274  assert(phaseIndex < (int)myPhases.size());
275  myPhases[phaseIndex].earliestEnd = duration;
276 }
277 
278 
279 void
281  assert(phaseIndex < (int)myPhases.size());
282  myPhases[phaseIndex].latestEnd = duration;
283 }
284 
285 
286 void
288  assert(phaseIndex < (int)myPhases.size());
289  myPhases[phaseIndex].vehExt = duration;
290 }
291 
292 
293 void
295  assert(phaseIndex < (int)myPhases.size());
296  myPhases[phaseIndex].yellow = duration;
297 }
298 
299 
300 void
301 NBTrafficLightLogic::setPhaseRed(int phaseIndex, SUMOTime duration) {
302  assert(phaseIndex < (int)myPhases.size());
303  myPhases[phaseIndex].red = duration;
304 }
305 
306 
307 void
308 NBTrafficLightLogic::setPhaseNext(int phaseIndex, const std::vector<int>& next) {
309  assert(phaseIndex < (int)myPhases.size());
310  myPhases[phaseIndex].next = next;
311 }
312 
313 
314 void
315 NBTrafficLightLogic::setPhaseName(int phaseIndex, const std::string& name) {
316  assert(phaseIndex < (int)myPhases.size());
317  myPhases[phaseIndex].name = name;
318 }
319 
320 
321 void
322 NBTrafficLightLogic::overrideState(int phaseIndex, const char c) {
323  assert(phaseIndex < (int)myPhases.size());
324  for (int i = 0; i < (int)myPhases[phaseIndex].state.size(); i++) {
325  myPhases[phaseIndex].state[i] = c;
326  }
327 }
328 
329 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
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
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
static const std::string ALLOWED_TLS_LINKSTATES
all allowed characters for phase state