SUMO - Simulation of Urban MObility
NLJunctionControlBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Builder of microsim-junctions and tls
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <map>
35 #include <string>
36 #include <vector>
37 #include <list>
38 #include <algorithm>
59 #include <microsim/MSGlobals.h>
60 #include <microsim/MSNet.h>
65 #include <utils/common/ToString.h>
66 #include <netbuild/NBNode.h>
67 #include "NLBuilder.h"
69 
70 #ifdef CHECK_MEMORY_LEAKS
71 #include <foreign/nvwa/debug_new.h>
72 #endif // CHECK_MEMORY_LEAKS
73 
74 
75 // ===========================================================================
76 // static members
77 // ===========================================================================
79 
80 // ===========================================================================
81 // method definitions
82 // ===========================================================================
84  myNet(net),
85  myDetectorBuilder(db),
86  myOffset(0),
87  myJunctions(0),
88  myNetIsLoaded(false) {
91 }
92 
93 
95  delete myLogicControl;
96  delete myJunctions;
97 }
98 
99 
100 void
102  const std::string& key,
103  const SumoXMLNodeType type,
104  SUMOReal x, SUMOReal y,
105  const PositionVector& shape,
106  const std::vector<MSLane*>& incomingLanes,
107  const std::vector<MSLane*>& internalLanes) {
108 #ifdef HAVE_INTERNAL_LANES
109  myActiveInternalLanes = internalLanes;
110 #else
111  UNUSED_PARAMETER(internalLanes);
112 #endif
113  myActiveIncomingLanes = incomingLanes;
114  myActiveID = id;
115  myActiveKey = key;
116  myType = type;
117  myPosition.set(x, y);
118  myShape = shape;
119 }
120 
121 
122 void
123 NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
124  if (myJunctions == 0) {
125  throw ProcessError("Information about the number of nodes was missing.");
126  }
127  MSJunction* junction = 0;
128  switch (myType) {
129  case NODETYPE_NOJUNCTION:
130  case NODETYPE_DEAD_END:
132  case NODETYPE_DISTRICT:
134  junction = buildNoLogicJunction();
135  break;
139  case NODETYPE_PRIORITY:
142  case NODETYPE_ZIPPER:
143  junction = buildLogicJunction();
144  break;
145  case NODETYPE_INTERNAL:
146 #ifdef HAVE_INTERNAL_LANES
148  junction = buildInternalJunction();
149  }
150 #endif
151  break;
154  myOffset = 0;
156  myActiveProgram = "0";
158  closeTrafficLightLogic(basePath);
159  junction = buildLogicJunction();
160  break;
161  default:
162  throw InvalidArgument("False junction logic type.");
163  }
164  if (junction != 0) {
165  if (!myJunctions->add(myActiveID, junction)) {
166  throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
167  }
168  }
169 }
170 
171 
175  myJunctions = 0;
176  return js;
177 }
178 
179 
180 MSJunction*
183 #ifdef HAVE_INTERNAL_LANES
184  , myActiveInternalLanes
185 #endif
186  );
187 }
188 
189 
190 MSJunction*
193  // build the junction
195 #ifdef HAVE_INTERNAL_LANES
196  myActiveInternalLanes,
197 #endif
198  jtype);
199 }
200 
201 
202 #ifdef HAVE_INTERNAL_LANES
203 MSJunction*
204 NLJunctionControlBuilder::buildInternalJunction() {
205  // build the junction
207  myActiveInternalLanes);
208 }
209 #endif
210 
211 
214  // get and check the junction logic
215  if (myLogics.find(myActiveID) == myLogics.end()) {
216  throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
217  }
218  return myLogics[myActiveID];
219 }
220 
221 
223 NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
224  return getTLLogicControlToUse().get(id);
225 }
226 
227 
228 void
230  if (myActiveProgram == "off") {
231  if (myAbsDuration > 0) {
232  throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
233  }
236  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
237  }
238  return;
239  }
240  SUMOTime firstEventOffset = 0;
241  int step = 0;
242  MSTrafficLightLogic* existing = 0;
243  MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
244  if (myLogicType != TLTYPE_RAIL) {
245  if (myAbsDuration == 0) {
247  if (existing == 0) {
248  throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
249  } else {
250  // only modify the offset of an existing logic
251  myAbsDuration = existing->getDefaultCycleTime();
252  i = existing->getPhases().begin();
253  }
254  }
255  // compute the initial step and first switch time of the tls-logic
256  // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
257  // @note The implementation of % for negative values is implementation defined in ISO1998
258  SUMOTime offset; // the time to run the traffic light in advance
259  if (myOffset >= 0) {
261  } else {
263  }
264  while (offset >= (*i)->duration) {
265  step++;
266  offset -= (*i)->duration;
267  ++i;
268  }
269  firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
270  if (existing != 0) {
272  myNet.getCurrentTimeStep(), step, (*i)->duration - offset);
273  return;
274  }
275  }
276 
277  if (myActiveProgram == "") {
278  myActiveProgram = "default";
279  }
280  MSTrafficLightLogic* tlLogic = 0;
281  // build the tls-logic in dependance to its type
282  switch (myLogicType) {
283  case TLTYPE_SWARM_BASED:
284  firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
286  break;
289  break;
290  case TLTYPE_SOTL_REQUEST:
292  break;
293  case TLTYPE_SOTL_PLATOON:
295  break;
296  case TLTYPE_SOTL_WAVE:
298  break;
299  case TLTYPE_SOTL_PHASE:
301  break;
304  break;
305  case TLTYPE_ACTUATED:
306  // @note it is unclear how to apply the given offset in the context
307  // of variable-length phases
310  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
311  myAdditionalParameter, basePath);
312  break;
313  case TLTYPE_DELAYBASED:
316  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
317  myAdditionalParameter, basePath);
318  break;
319  case TLTYPE_STATIC:
320  tlLogic =
323  myActivePhases, step, firstEventOffset,
325  break;
326  case TLTYPE_RAIL:
327  if (myType == NODETYPE_RAIL_SIGNAL) {
328  tlLogic = new MSRailSignal(getTLLogicControlToUse(),
331  } else if (myType == NODETYPE_RAIL_CROSSING) {
332  tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
335  } else {
336  throw ProcessError("Invalid node type '" + toString(myType)
337  + "' for traffic light type '" + toString(myLogicType) + "'");
338  }
339  break;
340  case TLTYPE_INVALID:
341  throw ProcessError("Invalid traffic light type '" + toString(myLogicType) + "'");
342  }
343  myActivePhases.clear();
344  if (tlLogic != 0) {
345  if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
346  if (myNetIsLoaded) {
347  tlLogic->init(myDetectorBuilder);
348  } else {
349  myLogics2PostLoadInit.push_back(tlLogic);
350  }
351  } else {
352  WRITE_ERROR("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
353  delete tlLogic;
354  }
355  }
356 }
357 
358 
359 void
361  myActiveKey = id;
362  myActiveProgram = "";
363  myActiveLogic.clear();
364  myActiveFoes.clear();
365  myActiveConts.reset();
366  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
368  myCurrentHasError = false;
369 }
370 
371 
372 void
374  const std::string& response,
375  const std::string& foes,
376  bool cont) {
377  if (myCurrentHasError) {
378  // had an error
379  return;
380  }
381  if (request >= SUMO_MAX_CONNECTIONS) {
382  // bad request
383  myCurrentHasError = true;
384  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
385  }
387  // initialize
388  myRequestSize = (int)response.size();
389  }
390  if (static_cast<int>(response.size()) != myRequestSize) {
391  myCurrentHasError = true;
392  throw InvalidArgument("Invalid response size " + toString(response.size()) +
393  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
394  }
395  if (static_cast<int>(foes.size()) != myRequestSize) {
396  myCurrentHasError = true;
397  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
398  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
399  }
400  // assert that the logicitems come ordered by their request index
401  assert((int)myActiveLogic.size() == request);
402  assert((int)myActiveFoes.size() == request);
403  // add the read response for the given request index
404  myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
405  // add the read junction-internal foes for the given request index
406  myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
407  // add whether the vehicle may drive a little bit further
408  myActiveConts.set(request, cont);
409  // increse number of set information
411 }
412 
413 
414 void
415 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
416  TrafficLightType type, SUMOTime offset) {
417  myActiveKey = id;
418  myActiveProgram = programID;
419  myActivePhases.clear();
420  myAbsDuration = 0;
422  myLogicType = type;
423  myOffset = offset;
424  myAdditionalParameter.clear();
425 }
426 
427 
428 void
429 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state, SUMOTime minDuration, SUMOTime maxDuration, bool transient_notdecisional, bool commit) throw() {
430  // build and add the phase definition to the list
431  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state, transient_notdecisional, commit));
432  // add phase duration to the absolute duration
433  myAbsDuration += duration;
434 }
435 
436 void
437 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state, SUMOTime minDuration, SUMOTime maxDuration, bool transient_notdecisional, bool commit, MSPhaseDefinition::LaneIdVector& targetLanes) throw() {
438  // build and add the phase definition to the list
439  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state, transient_notdecisional, commit, targetLanes));
440  // add phase duration to the absolute duration
441  myAbsDuration += duration;
442 }
443 
444 
445 void
446 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state,
447  SUMOTime minDuration, SUMOTime maxDuration) {
448  // build and add the phase definition to the list
449  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
450  // add phase duration to the absolute duration
451  myAbsDuration += duration;
452 }
453 
454 
455 void
458  // We have a legacy network. junction element did not contain logicitems; read the logic later
459  return;
460  }
461  if (myCurrentHasError) {
462  // had an error before...
463  return;
464  }
466  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
467  }
468  if (myLogics.count(myActiveKey) > 0) {
469  throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
470  }
474  myActiveConts);
475  myLogics[myActiveKey] = logic;
476 }
477 
478 
481  postLoadInitialization(); // must happen after edgeBuilder is finished
483  throw ProcessError("Traffic lights could not be built.");
484  }
486  myLogicControl = 0;
487  return ret;
488 }
489 
490 
491 void
492 NLJunctionControlBuilder::addParam(const std::string& key,
493  const std::string& value) {
494  myAdditionalParameter[key] = value;
495 }
496 
497 
500  if (myLogicControl != 0) {
501  return *myLogicControl;
502  }
503  return myNet.getTLSControl();
504 }
505 
506 
507 const std::string&
509  return myActiveKey;
510 }
511 
512 
513 const std::string&
515  return myActiveProgram;
516 }
517 
518 
519 void
521  for (std::vector<MSTrafficLightLogic*>::const_iterator it = myLogics2PostLoadInit.begin();
522  it != myLogics2PostLoadInit.end(); ++it) {
523  (*it)->init(myDetectorBuilder);
524  }
525  myNetIsLoaded = true;
526 }
527 
528 
529 MSJunction*
530 NLJunctionControlBuilder::retrieve(const std::string id) {
531  if (myJunctions != 0) {
532  return myJunctions->get(id);
533  } else {
534  return 0;
535  }
536 }
537 
538 /****************************************************************************/
void postLoadInitialization()
initialize junctions after all connections have been loaded
const std::string & getActiveKey() const
Returns the active key.
void initTrafficLightLogic(const std::string &id, const std::string &programID, TrafficLightType type, SUMOTime offset)
Begins the reading of a traffic lights logic.
Builds detectors for microsim.
virtual ~NLJunctionControlBuilder()
Destructor.
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
long long int SUMOTime
Definition: SUMOTime.h:43
An actuated traffic light logic based on time delay of approaching vehicles.
std::bitset< SUMO_MAX_CONNECTIONS > myActiveConts
The description about which lanes have an internal follower.
Storage for all programs of a single tls.
virtual bool add(const std::string &id, T item)
Adds an item.
Class for low-level platoon policy.
A signal for rails.
Definition: MSRailSignal.h:54
MSBitSetLogic< SUMO_MAX_CONNECTIONS > MSBitsetLogic
std::string myActiveKey
The key of the currently chosen junction.
const std::string & getActiveSubKey() const
Returns the active sub key.
The base class for an intersection.
Definition: MSJunction.h:64
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
MSNet & myNet
The net to use.
MSBitsetLogic::Logic myActiveLogic
The right-of-way-logic of the currently chosen bitset-logic.
void closeJunctionLogic()
Ends the building of a junction logic (row-logic)
SUMOTime myAbsDuration
The absolute duration of a tls-control loop.
Class for low-level request policy.
Class for low-level marching policy.
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition: StdDefs.h:41
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
Position myPosition
The position of the junction.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
PositionVector myShape
The shape of the current junction.
The simulated network and simulation perfomer.
Definition: MSNet.h:94
A fixed traffic light logic.
Container for junctions; performs operations on all stored junctions.
SUMOTime myOffset
The switch offset within the tls.
A traffic lights logic which represents a tls in an off-mode.
void closeJunction(const std::string &basePath)
Closes (ends) the processing of the current junction.
T get(const std::string &id) const
Retrieves an item.
An actuated (adaptive) traffic light logic.
A class that stores and controls tls and switching of their programs.
void addPhase(SUMOTime duration, const std::string &state, SUMOTime min, SUMOTime max)
Adds a phase to the currently built traffic lights logic.
A self-organizing traffic light logic based on a particular policy.
MSSimpleTrafficLightLogic::Phases myActivePhases
The current phase definitions for a simple traffic light.
TrafficLightType myLogicType
The current logic type.
std::string myActiveID
The id of the currently chosen junction.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
MSJunctionControl * myJunctions
The junctions controls.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:381
A list of positions.
virtual MSJunction * buildLogicJunction()
Builds a junction with a logic.
virtual void closeTrafficLightLogic(const std::string &basePath)
Ends the building of a traffic lights logic.
std::map< std::string, MSJunctionLogic * > myLogics
Map of loaded junction logics.
int myRequestSize
The size of the request.
std::vector< std::bitset< N > > Foes
Container holding the information which internal lanes prohibt which links Build the same way as Logi...
Definition: MSBitSetLogic.h:63
bool myNetIsLoaded
whether the network has been loaded
MSJunction * retrieve(const std::string id)
try to retrieve junction by id
A signal for rails.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:73
void openJunction(const std::string &id, const std::string &key, const SumoXMLNodeType type, SUMOReal x, SUMOReal y, const PositionVector &shape, const std::vector< MSLane * > &incomingLanes, const std::vector< MSLane * > &internalLanes)
Begins the processing of the named junction.
MSTLLogicControl & getTLLogicControlToUse() const
Returns the used tls control.
NLJunctionControlBuilder(MSNet &net, NLDetectorBuilder &db)
Constructor.
void addParam(const std::string &key, const std::string &value)
Adds a parameter.
int myRequestItemNumber
Counter for the inserted items.
bool myCurrentHasError
Information whether the current logic had an error.
MSBitsetLogic::Foes myActiveFoes
The description about which lanes disallow other passing the junction simultaneously.
MSTLLogicControl::TLSLogicVariants & getTLLogic(const std::string &id) const
Returns a previously build tls logic.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
virtual MSJunction * buildNoLogicJunction()
Builds a junction that does not use a logic.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
StringParameterMap myAdditionalParameter
Parameter map (key->value)
std::vector< std::string > LaneIdVector
SumoXMLNodeType myType
The type of the currently chosen junction.
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
void initJunctionLogic(const std::string &id)
Initialises a junction logic.
LaneVector myActiveIncomingLanes
The list of the incoming lanes of the currently chosen junction.
std::vector< std::bitset< N > > Logic
Container that holds the right of way bitsets. Each link has it&#39;s own bitset. The bits in the bitsets...
Definition: MSBitSetLogic.h:59
Class for low-level phase policy.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
std::vector< MSTrafficLightLogic * > myLogics2PostLoadInit
The container for information which junctions shall be initialised using which values.
#define HAVE_INTERNAL_LANES
Definition: config.h:53
void set(SUMOReal x, SUMOReal y)
set positions x and y
Definition: Position.h:93
MSTLLogicControl * myLogicControl
The tls control to use (0 if net&#39;s tls control shall be used)
A junction with right-of-way - rules.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
The parent class for traffic light logics.
#define SUMOReal
Definition: config.h:208
MSJunctionLogic * getJunctionLogicSecure()
Returns the current junction logic.
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
MSTLLogicControl * buildTLLogics()
Returns the built tls-logic control.
The definition of a single phase of a tls logic.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
TrafficLightType
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.