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.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // Builder of microsim-junctions and tls
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <map>
34 #include <string>
35 #include <vector>
36 #include <list>
37 #include <algorithm>
58 #include <microsim/MSGlobals.h>
59 #include <microsim/MSNet.h>
64 #include <utils/common/ToString.h>
65 #include <netbuild/NBNode.h>
66 #include "NLBuilder.h"
68 
69 
70 // ===========================================================================
71 // static members
72 // ===========================================================================
74 
75 // ===========================================================================
76 // method definitions
77 // ===========================================================================
79  myNet(net),
80  myDetectorBuilder(db),
81  myOffset(0),
82  myJunctions(0),
83  myNetIsLoaded(false) {
86 }
87 
88 
90  delete myLogicControl;
91  delete myJunctions;
92 }
93 
94 
95 void
97  const std::string& key,
98  const SumoXMLNodeType type,
99  const Position pos,
100  const PositionVector& shape,
101  const std::vector<MSLane*>& incomingLanes,
102  const std::vector<MSLane*>& internalLanes) {
103  myActiveInternalLanes = internalLanes;
104  myActiveIncomingLanes = incomingLanes;
105  myActiveID = id;
106  myActiveKey = key;
107  myType = type;
108  myPosition.set(pos);
109  myShape = shape;
110  myAdditionalParameter.clear();
111 }
112 
113 
114 void
115 NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
116  if (myJunctions == 0) {
117  throw ProcessError("Information about the number of nodes was missing.");
118  }
119  MSJunction* junction = 0;
120  switch (myType) {
121  case NODETYPE_NOJUNCTION:
122  case NODETYPE_DEAD_END:
124  case NODETYPE_DISTRICT:
126  junction = buildNoLogicJunction();
127  break;
131  case NODETYPE_PRIORITY:
134  case NODETYPE_ZIPPER:
135  junction = buildLogicJunction();
136  break;
137  case NODETYPE_INTERNAL:
139  junction = buildInternalJunction();
140  }
141  break;
144  myOffset = 0;
146  myActiveProgram = "0";
148  closeTrafficLightLogic(basePath);
149  junction = buildLogicJunction();
150  break;
151  default:
152  throw InvalidArgument("False junction logic type.");
153  }
154  if (junction != 0) {
155  if (!myJunctions->add(myActiveID, junction)) {
156  throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
157  }
158  }
160 }
161 
162 
166  myJunctions = 0;
167  return js;
168 }
169 
170 
171 MSJunction*
175 }
176 
177 
178 MSJunction*
181  // build the junction
184  jtype);
185 }
186 
187 
188 MSJunction*
190  // build the junction
193 }
194 
195 
198  // get and check the junction logic
199  if (myLogics.find(myActiveID) == myLogics.end()) {
200  throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
201  }
202  return myLogics[myActiveID];
203 }
204 
205 
207 NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
208  return getTLLogicControlToUse().get(id);
209 }
210 
211 
212 void
214  if (myActiveProgram == "off") {
215  if (myAbsDuration > 0) {
216  throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
217  }
220  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
221  }
222  return;
223  }
224  SUMOTime firstEventOffset = 0;
225  int step = 0;
226  MSTrafficLightLogic* existing = 0;
227  MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
228  if (myLogicType != TLTYPE_RAIL) {
229  if (myAbsDuration == 0) {
231  if (existing == 0) {
232  throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
233  } else {
234  // only modify the offset of an existing logic
235  myAbsDuration = existing->getDefaultCycleTime();
236  i = existing->getPhases().begin();
237  }
238  }
239  // compute the initial step and first switch time of the tls-logic
240  // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
241  // @note The implementation of % for negative values is implementation defined in ISO1998
242  SUMOTime offset; // the time to run the traffic light in advance
243  if (myOffset >= 0) {
245  } else {
247  }
248  while (offset >= (*i)->duration) {
249  step++;
250  offset -= (*i)->duration;
251  ++i;
252  }
253  firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
254  if (existing != 0) {
256  myNet.getCurrentTimeStep(), step, (*i)->duration - offset);
257  return;
258  }
259  }
260 
261  if (myActiveProgram == "") {
262  myActiveProgram = "default";
263  }
264  MSTrafficLightLogic* tlLogic = 0;
265  // build the tls-logic in dependance to its type
266  switch (myLogicType) {
267  case TLTYPE_SWARM_BASED:
268  firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
270  break;
273  break;
274  case TLTYPE_SOTL_REQUEST:
276  break;
277  case TLTYPE_SOTL_PLATOON:
279  break;
280  case TLTYPE_SOTL_WAVE:
282  break;
283  case TLTYPE_SOTL_PHASE:
285  break;
288  break;
289  case TLTYPE_ACTUATED:
290  // @note it is unclear how to apply the given offset in the context
291  // of variable-length phases
294  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
295  myAdditionalParameter, basePath);
296  break;
297  case TLTYPE_DELAYBASED:
300  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
301  myAdditionalParameter, basePath);
302  break;
303  case TLTYPE_STATIC:
304  tlLogic =
307  myActivePhases, step, firstEventOffset,
309  break;
310  case TLTYPE_RAIL:
311  if (myType == NODETYPE_RAIL_SIGNAL) {
312  tlLogic = new MSRailSignal(getTLLogicControlToUse(),
315  } else if (myType == NODETYPE_RAIL_CROSSING) {
316  tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
319  } else {
320  throw ProcessError("Invalid node type '" + toString(myType)
321  + "' for traffic light type '" + toString(myLogicType) + "'");
322  }
323  break;
324  case TLTYPE_INVALID:
325  throw ProcessError("Invalid traffic light type '" + toString(myLogicType) + "'");
326  }
327  myActivePhases.clear();
328  if (tlLogic != 0) {
329  if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
330  if (myNetIsLoaded) {
331  tlLogic->init(myDetectorBuilder);
332  } else {
333  myLogics2PostLoadInit.push_back(tlLogic);
334  }
335  } else {
336  WRITE_ERROR("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
337  delete tlLogic;
338  }
339  }
340 }
341 
342 
343 void
345  myActiveKey = id;
346  myActiveProgram = "";
347  myActiveLogic.clear();
348  myActiveFoes.clear();
349  myActiveConts.reset();
350  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
352  myCurrentHasError = false;
353 }
354 
355 
356 void
358  const std::string& response,
359  const std::string& foes,
360  bool cont) {
361  if (myCurrentHasError) {
362  // had an error
363  return;
364  }
365  if (request >= SUMO_MAX_CONNECTIONS) {
366  // bad request
367  myCurrentHasError = true;
368  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
369  }
371  // initialize
372  myRequestSize = (int)response.size();
373  }
374  if (static_cast<int>(response.size()) != myRequestSize) {
375  myCurrentHasError = true;
376  throw InvalidArgument("Invalid response size " + toString(response.size()) +
377  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
378  }
379  if (static_cast<int>(foes.size()) != myRequestSize) {
380  myCurrentHasError = true;
381  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
382  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
383  }
384  // assert that the logicitems come ordered by their request index
385  assert((int)myActiveLogic.size() == request);
386  assert((int)myActiveFoes.size() == request);
387  // add the read response for the given request index
388  myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
389  // add the read junction-internal foes for the given request index
390  myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
391  // add whether the vehicle may drive a little bit further
392  myActiveConts.set(request, cont);
393  // increse number of set information
395 }
396 
397 
398 void
399 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
400  TrafficLightType type, SUMOTime offset) {
401  myActiveKey = id;
402  myActiveProgram = programID;
403  myActivePhases.clear();
404  myAbsDuration = 0;
406  myLogicType = type;
407  myOffset = offset;
408  myAdditionalParameter.clear();
409 }
410 
411 
412 void
413 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state, SUMOTime minDuration, SUMOTime maxDuration, bool transient_notdecisional, bool commit) throw() {
414  // build and add the phase definition to the list
415  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state, transient_notdecisional, commit));
416  // add phase duration to the absolute duration
417  myAbsDuration += duration;
418 }
419 
420 void
421 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state, SUMOTime minDuration, SUMOTime maxDuration, bool transient_notdecisional, bool commit, MSPhaseDefinition::LaneIdVector& targetLanes) throw() {
422  // build and add the phase definition to the list
423  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state, transient_notdecisional, commit, targetLanes));
424  // add phase duration to the absolute duration
425  myAbsDuration += duration;
426 }
427 
428 
429 void
430 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state,
431  SUMOTime minDuration, SUMOTime maxDuration) {
432  // build and add the phase definition to the list
433  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
434  // add phase duration to the absolute duration
435  myAbsDuration += duration;
436 }
437 
438 
439 void
442  // We have a legacy network. junction element did not contain logicitems; read the logic later
443  return;
444  }
445  if (myCurrentHasError) {
446  // had an error before...
447  return;
448  }
450  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
451  }
452  if (myLogics.count(myActiveKey) > 0) {
453  throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
454  }
458  myActiveConts);
459  myLogics[myActiveKey] = logic;
460 }
461 
462 
465  postLoadInitialization(); // must happen after edgeBuilder is finished
467  throw ProcessError("Traffic lights could not be built.");
468  }
470  myLogicControl = 0;
471  return ret;
472 }
473 
474 
475 void
476 NLJunctionControlBuilder::addParam(const std::string& key,
477  const std::string& value) {
478  myAdditionalParameter[key] = value;
479 }
480 
481 
484  if (myLogicControl != 0) {
485  return *myLogicControl;
486  }
487  return myNet.getTLSControl();
488 }
489 
490 
491 const std::string&
493  return myActiveKey;
494 }
495 
496 
497 const std::string&
499  return myActiveProgram;
500 }
501 
502 
503 void
505  for (std::vector<MSTrafficLightLogic*>::const_iterator it = myLogics2PostLoadInit.begin();
506  it != myLogics2PostLoadInit.end(); ++it) {
507  (*it)->init(myDetectorBuilder);
508  }
509  myNetIsLoaded = true;
510 }
511 
512 
513 MSJunction*
514 NLJunctionControlBuilder::retrieve(const std::string id) {
515  if (myJunctions != 0) {
516  return myJunctions->get(id);
517  } else {
518  return 0;
519  }
520 }
521 
522 /****************************************************************************/
void postLoadInitialization()
initialize junctions after all connections have been loaded
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.
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.
LaneVector myActiveInternalLanes
The list of the internal lanes of the currently chosen junction.
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)
Begins the processing of the named junction.
Class for low-level platoon policy.
A signal for rails.
Definition: MSRailSignal.h:53
MSBitSetLogic< SUMO_MAX_CONNECTIONS > MSBitsetLogic
std::string myActiveKey
The key of the currently chosen junction.
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.
T get(const std::string &id) const
Retrieves an item.
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)
virtual MSJunction * buildInternalJunction()
Builds an internal junction.
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:42
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
const std::string & getActiveSubKey() const
Returns the active sub key.
void set(double x, double y)
set positions x and y
Definition: Position.h:92
Position myPosition
The position of the junction.
PositionVector myShape
The shape of the current junction.
The simulated network and simulation perfomer.
Definition: MSNet.h:90
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.
MSTLLogicControl::TLSLogicVariants & getTLLogic(const std::string &id) const
Returns a previously build tls logic.
bool add(const std::string &id, T item)
Adds an item.
An actuated (adaptive) traffic light logic.
A class that stores and controls tls and switching of their programs.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
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
void updateParameter(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
MSJunctionControl * myJunctions
The junctions controls.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:379
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:62
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
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:75
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 & getTLLogicControlToUse() const
Returns the used tls control.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
virtual MSJunction * buildNoLogicJunction()
Builds a junction that does not use a logic.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
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:58
Class for low-level phase policy.
std::vector< MSTrafficLightLogic * > myLogics2PostLoadInit
The container for information which junctions shall be initialised using which values.
MSTLLogicControl * myLogicControl
The tls control to use (0 if net&#39;s tls control shall be used)
A junction with right-of-way - rules.
The parent class for traffic light logics.
long long int SUMOTime
Definition: TraCIDefs.h:51
MSJunctionLogic * getJunctionLogicSecure()
Returns the current junction logic.
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
MSTLLogicControl * buildTLLogics()
Returns the built tls-logic control.
The definition of a single phase of a tls logic.
const std::string & getActiveKey() const
Returns the active key.
TrafficLightType
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.