Eclipse SUMO - Simulation of Urban MObility
NLJunctionControlBuilder.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 /****************************************************************************/
21 // Builder of microsim-junctions and tls
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <map>
26 #include <string>
27 #include <vector>
28 #include <list>
29 #include <algorithm>
32 #include <utils/common/ToString.h>
33 #include <microsim/MSGlobals.h>
34 #include <microsim/MSNet.h>
56 #include "NLBuilder.h"
59 
60 
61 // ===========================================================================
62 // static members
63 // ===========================================================================
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
70  myNet(net),
71  myDetectorBuilder(db),
72  myOffset(0),
73  myJunctions(new MSJunctionControl()),
74  myNetIsLoaded(false) {
76 }
77 
78 
80  delete myLogicControl;
81  delete myJunctions;
82 }
83 
84 
85 void
87  const std::string& key,
88  const SumoXMLNodeType type,
89  const Position pos,
90  const PositionVector& shape,
91  const std::vector<MSLane*>& incomingLanes,
92  const std::vector<MSLane*>& internalLanes,
93  const std::string& name) {
94  myActiveInternalLanes = internalLanes;
95  myActiveIncomingLanes = incomingLanes;
96  myActiveID = id;
97  myActiveKey = key;
98  myType = type;
99  myPosition.set(pos);
100  myShape = shape;
101  myActiveName = name;
102  myAdditionalParameter.clear();
103 }
104 
105 
106 void
107 NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
108  if (myCurrentHasError) {
109  // had an error before...
110  return;
111  }
113  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
114  }
115  if (myJunctions == nullptr) {
116  throw ProcessError(TL("Information about the number of nodes was missing."));
117  }
118  MSJunction* junction = nullptr;
119  switch (myType) {
125  if (!myActiveLogic.empty()) {
126  WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
127  }
128  junction = buildNoLogicJunction();
129  break;
139  break;
142  if (!myActiveLogic.empty()) {
143  WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
144  }
145  junction = buildInternalJunction();
146  }
147  break;
150  myOffset = 0;
152  myActiveProgram = "0";
154  closeTrafficLightLogic(basePath);
156  break;
157  default:
158  throw InvalidArgument("False junction logic type.");
159  }
160  if (junction != nullptr) {
161  if (!myJunctions->add(myActiveID, junction)) {
162  throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
163  }
165  }
166 }
167 
168 
172  myJunctions = nullptr;
173  return js;
174 }
175 
176 
177 MSJunction*
181 }
182 
183 
184 MSJunction*
188 }
189 
190 
191 MSJunction*
193  // build the junction
196 }
197 
198 
200 NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
201  return getTLLogicControlToUse().get(id);
202 }
203 
204 
205 void
207  if (myActiveProgram == "off") {
208  if (myAbsDuration > 0) {
209  throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
210  }
213  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
214  }
215  return;
216  }
217  SUMOTime firstEventOffset = 0;
218  int step = 0;
219  MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
221  if (existing != nullptr && (existing->getLogicType() == TrafficLightType::RAIL_SIGNAL || existing->getLogicType() == TrafficLightType::RAIL_CROSSING)) {
223  return;
224  } else {
226  if (myAbsDuration == 0) {
227  if (existing == nullptr) {
228  throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
229  } else {
230  // only modify the offset of an existing logic
231  myAbsDuration = existing->getDefaultCycleTime();
232  i = existing->getPhases().begin();
233  }
234  } else if (existing != nullptr) {
235  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
236  }
237  // compute the initial step and first switch time of the tls-logic
238  // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
239  // @note The implementation of % for negative values is implementation defined in ISO1998
240  SUMOTime offset; // the time to run the traffic light in advance
241  if (myOffset >= 0) {
243  } else {
245  }
246  while (offset >= (*i)->duration) {
247  step++;
248  offset -= (*i)->duration;
249  ++i;
250  }
251  firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
252  if (existing != nullptr) {
254  myNet.getCurrentTimeStep(), step, (*i)->duration - offset);
255  // parameters that are used when initializing a logic will not take
256  // effect but parameters that are checked at runtime can be used
257  // here (i.e. device.glosa.range)
259  return;
260  }
261  }
262  }
263 
264  if (myActiveProgram == "") {
265  myActiveProgram = "default";
266  }
267  MSTrafficLightLogic* tlLogic = nullptr;
268  // build the tls-logic in dependence to its type
269  switch (myLogicType) {
271  firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
273  break;
276  break;
279  break;
282  break;
285  break;
288  break;
291  break;
293  // @note it is unclear how to apply the given offset in the context
294  // of variable-length phases
297  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
299  break;
301  tlLogic = new NEMALogic(getTLLogicControlToUse(),
303  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
304  myAdditionalParameter, basePath);
305  break;
309  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
310  myAdditionalParameter, basePath);
311  break;
316  myActivePhases, step, firstEventOffset,
318  break;
320  tlLogic = new MSRailSignal(getTLLogicControlToUse(),
323  break;
325  tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
328  break;
331  break;
333  throw ProcessError(TLF("Invalid traffic light type '%'", toString(myLogicType)));
334  }
335  myActivePhases.clear();
336  if (tlLogic != nullptr) {
337  if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
338  if (myNetIsLoaded) {
339  myAdditionalLogics.push_back(tlLogic);
341  // special case: intialize earlier because signals are already used when
342  // loading train routes in additional files
343  myRailSignals.push_back(tlLogic);
344  } else {
345  myNetworkLogics.push_back(tlLogic);
346  }
347  } else {
348  WRITE_ERRORF(TL("Another logic with id '%' and programID '%' exists."), myActiveKey, myActiveProgram);
349  }
350  }
351 }
352 
353 
354 void
356  myActiveKey = id;
357  myActiveProgram = "";
358  myActiveLogic.clear();
359  myActiveFoes.clear();
360  myActiveConts.reset();
361  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
363  myCurrentHasError = false;
364 }
365 
366 
367 void
369  const std::string& response,
370  const std::string& foes,
371  bool cont) {
372  if (myCurrentHasError) {
373  // had an error
374  return;
375  }
376  if (request >= SUMO_MAX_CONNECTIONS) {
377  // bad request
378  myCurrentHasError = true;
379  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
380  }
382  // initialize
383  myRequestSize = (int)response.size();
384  }
385  if (static_cast<int>(response.size()) != myRequestSize) {
386  myCurrentHasError = true;
387  throw InvalidArgument("Invalid response size " + toString(response.size()) +
388  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
389  }
390  if (static_cast<int>(foes.size()) != myRequestSize) {
391  myCurrentHasError = true;
392  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
393  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
394  }
395  // assert that the logicitems come ordered by their request index
396  assert((int)myActiveLogic.size() == request);
397  assert((int)myActiveFoes.size() == request);
398  // add the read response for the given request index
399  myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
400  // add the read junction-internal foes for the given request index
401  myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
402  // add whether the vehicle may drive a little bit further
403  myActiveConts.set(request, cont);
404  // increse number of set information
406 }
407 
408 
409 void
410 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
411  TrafficLightType type, SUMOTime offset) {
412  myActiveKey = id;
413  myActiveProgram = programID;
414  myActivePhases.clear();
415  myActiveConditions.clear();
416  myActiveAssignments.clear();
417  myActiveFunctions.clear();
418  myAbsDuration = 0;
420  myLogicType = type;
421  myOffset = offset;
422  myAdditionalParameter.clear();
423 }
424 
425 
426 void
428  // build and add the phase definition to the list
429  myActivePhases.push_back(phase);
430  // add phase duration to the absolute duration
431  myAbsDuration += phase->duration;
432 }
433 
434 
435 bool
436 NLJunctionControlBuilder::addCondition(const std::string& id, const std::string& value) {
437  if (myActiveConditions.count(id) == 0) {
438  myActiveConditions[id] = value;
439  return true;
440  } else {
441  return false;
442  }
443 }
444 
445 
446 void
447 NLJunctionControlBuilder::addAssignment(const std::string& id, const std::string& check, const std::string& value) {
448  if (myActiveFunction.id == "") {
449  myActiveAssignments.push_back(std::make_tuple(id, check, value));
450  } else {
451  myActiveFunction.assignments.push_back(std::make_tuple(id, check, value));
452  }
453 }
454 
455 
456 void
457 NLJunctionControlBuilder::addFunction(const std::string& id, int nArgs) {
458  myActiveFunction.id = id;
459  myActiveFunction.nArgs = nArgs;
460 }
461 
462 
463 void
466  myActiveFunction.id = "";
468 }
469 
470 
474  throw ProcessError(TL("Traffic lights could not be built."));
475  }
476  for (MSTrafficLightLogic* const logic : myRailSignals) {
477  logic->init(myDetectorBuilder);
478  }
480  myNetIsLoaded = true;
481  myLogicControl = nullptr;
482  return ret;
483 }
484 
485 
486 void
487 NLJunctionControlBuilder::addParam(const std::string& key,
488  const std::string& value) {
489  myAdditionalParameter[key] = value;
490 }
491 
492 
495  if (myLogicControl != nullptr) {
496  return *myLogicControl;
497  }
498  return myNet.getTLSControl();
499 }
500 
501 
502 const std::string&
504  return myActiveKey;
505 }
506 
507 
508 const std::string&
510  return myActiveProgram;
511 }
512 
513 
514 void
516  for (MSTrafficLightLogic* const logic : myNetworkLogics) {
517  logic->init(myDetectorBuilder);
518  }
519  for (MSTrafficLightLogic* const logic : myAdditionalLogics) {
520  logic->init(myDetectorBuilder);
521  }
522  // delay parameter loading until initialization
523  for (auto item : myLogicParams) {
524  item.first->updateParameters(item.second);
525  }
526 }
527 
528 
529 MSJunction*
530 NLJunctionControlBuilder::retrieve(const std::string id) {
531  if (myJunctions != nullptr) {
532  return myJunctions->get(id);
533  } else {
534  return nullptr;
535  }
536 }
537 
538 
539 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
MSBitSetLogic< SUMO_MAX_CONNECTIONS > MSBitsetLogic
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
TrafficLightType
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition: StdDefs.h:41
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
An actuated (adaptive) traffic light logic.
An actuated traffic light logic based on time delay of approaching vehicles.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
Container for junctions; performs operations on all stored junctions.
The base class for an intersection.
Definition: MSJunction.h:58
The simulated network and simulation perfomer.
Definition: MSNet.h:89
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:451
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
A traffic lights logic which represents a tls in an off-mode.
The definition of a single phase of a tls logic.
SUMOTime duration
The duration of the phase.
A signal for rails.
A signal for rails.
Definition: MSRailSignal.h:46
A junction with right-of-way - rules.
Class for low-level marching policy.
Class for low-level phase policy.
Class for low-level platoon policy.
A self-organizing traffic light logic based on a particular policy.
Class for low-level request policy.
A fixed traffic light logic.
Storage for all programs of a single tls.
A class that stores and controls tls and switching of their programs.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
The parent class for traffic light logics.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
TrafficLightType getLogicType() const
Returns the type of the logic.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
A NEMA (adaptive) traffic light logic based on E2Detector.
Builds detectors for microsim.
PositionVector myShape
The shape of the current junction.
NLJunctionControlBuilder(MSNet &net, NLDetectorBuilder &db)
Constructor.
int myRequestItemNumber
Counter for the inserted items.
SumoXMLNodeType myType
The type of the currently chosen junction.
std::vector< MSTrafficLightLogic * > myNetworkLogics
The container for information which junctions shall be initialised using which values.
MSTLLogicControl::TLSLogicVariants & getTLLogic(const std::string &id) const
Returns a previously build tls logic.
std::string myActiveName
the name of the current junction
virtual ~NLJunctionControlBuilder()
Destructor.
void closeFunction()
closes a switching condition function to the traffic lights logic currently build
MSJunction * retrieve(const std::string id)
try to retrieve junction by id
MSActuatedTrafficLightLogic::AssignmentMap myActiveAssignments
The current assignments for an actuated traffic light.
MSBitsetLogic::Foes myActiveFoes
The description about which lanes disallow other passing the junction simultaneously.
std::string myActiveID
The id of the currently chosen junction.
MSActuatedTrafficLightLogic::ConditionMap myActiveConditions
The current switching conditions for an actuated traffic light.
SUMOTime myOffset
The switch offset within the tls.
MSTLLogicControl * myLogicControl
The tls control to use (0 if net's tls control shall be used)
std::string myActiveKey
The key of the currently chosen junction.
TrafficLightType myLogicType
The current logic type.
bool myCurrentHasError
Information whether the current logic had an error.
MSTLLogicControl * buildTLLogics()
Returns the built tls-logic control.
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
int myRequestSize
The size of the request.
void addPhase(MSPhaseDefinition *phase)
Adds a phase to the currently built traffic lights logic.
MSTLLogicControl & getTLLogicControlToUse() const
Returns the used tls control.
void addFunction(const std::string &id, int nArgs)
adds a switching condition function to the traffic lights logic currently build
LaneVector myActiveIncomingLanes
The list of the incoming lanes of the currently chosen junction.
const std::string & getActiveSubKey() const
Returns the active sub key.
bool addCondition(const std::string &id, const std::string &value)
Adds a condition to the currently built traffic lights logic.
StringParameterMap myAdditionalParameter
Parameter map (key->value)
void openJunction(const std::string &id, const std::string &key, const SumoXMLNodeType type, const Position pos, const PositionVector &shape, const std::vector< MSLane * > &incomingLanes, const std::vector< MSLane * > &internalLanes, const std::string &name)
Begins the processing of the named junction.
void addParam(const std::string &key, const std::string &value)
Adds a parameter.
LaneVector myActiveInternalLanes
The list of the internal lanes of the currently chosen junction.
void initJunctionLogic(const std::string &id)
Initialises a junction logic.
void initTrafficLightLogic(const std::string &id, const std::string &programID, TrafficLightType type, SUMOTime offset)
Begins the reading of a traffic lights logic.
MSActuatedTrafficLightLogic::FunctionMap myActiveFunctions
The current functions for an actuated traffic light.
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
virtual MSJunction * buildNoLogicJunction()
Builds a junction that does not use a logic.
virtual MSJunction * buildInternalJunction()
Builds an internal junction.
MSJunctionControl * myJunctions
The junctions controls.
std::vector< MSTrafficLightLogic * > myAdditionalLogics
const std::string & getActiveKey() const
Returns the active key.
Position myPosition
The position of the junction.
void addAssignment(const std::string &id, const std::string &check, const std::string &value)
Adds an assignment to the currently built traffic lights logic.
void postLoadInitialization()
initialize junctions after all connections have been loaded
std::map< MSTrafficLightLogic *, StringParameterMap > myLogicParams
std::vector< MSTrafficLightLogic * > myRailSignals
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.
MSActuatedTrafficLightLogic::Function myActiveFunction
The current function for an actuated traffic light.
MSBitsetLogic::Logic myActiveLogic
The right-of-way-logic of the currently chosen bitset-logic.
virtual MSJunction * buildLogicJunction(MSJunctionLogic *const logic)
Builds a junction with a logic.
SUMOTime myAbsDuration
The absolute duration of a tls-control loop.
void closeJunction(const std::string &basePath)
Closes (ends) the processing of the current junction.
MSSimpleTrafficLightLogic::Phases myActivePhases
The current phase definitions for a simple traffic light.
bool myNetIsLoaded
whether the network has been loaded
virtual void closeTrafficLightLogic(const std::string &basePath)
Ends the building of a traffic lights logic.
std::bitset< SUMO_MAX_CONNECTIONS > myActiveConts
The description about which lanes have an internal follower.
T get(const std::string &id) const
Retrieves an item.
bool add(const std::string &id, T item)
Adds an item.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void set(double x, double y)
set positions x and y
Definition: Position.h:85
A list of positions.