SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2014 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>
47 #include <microsim/MSGlobals.h>
53 #include <utils/common/ToString.h>
54 #include <netbuild/NBNode.h>
55 #include "NLBuilder.h"
57 
58 #ifdef CHECK_MEMORY_LEAKS
59 #include <foreign/nvwa/debug_new.h>
60 #endif // CHECK_MEMORY_LEAKS
61 
62 
63 // ===========================================================================
64 // static members
65 // ===========================================================================
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
72  myNet(net),
73  myDetectorBuilder(db),
74  myOffset(0),
75  myJunctions(0),
76  myNetIsLoaded(false) {
79 }
80 
81 
83  delete myLogicControl;
84  delete myJunctions;
85 }
86 
87 
88 void
90  const std::string& key,
91  const SumoXMLNodeType type,
92  SUMOReal x, SUMOReal y,
93  const PositionVector& shape,
94  const std::vector<MSLane*>& incomingLanes,
95  const std::vector<MSLane*>& internalLanes) {
96 #ifdef HAVE_INTERNAL_LANES
97  myActiveInternalLanes = internalLanes;
98 #else
99  UNUSED_PARAMETER(internalLanes);
100 #endif
101  myActiveIncomingLanes = incomingLanes;
102  myActiveID = id;
103  myActiveKey = key;
104  myType = type;
105  myPosition.set(x, y);
106  myShape = shape;
107 }
108 
109 
110 void
112  if (myJunctions == 0) {
113  throw ProcessError("Information about the number of nodes was missing.");
114  }
115  MSJunction* junction = 0;
116  switch (myType) {
117  case NODETYPE_NOJUNCTION:
118  case NODETYPE_DEAD_END:
120  case NODETYPE_DISTRICT:
122  junction = buildNoLogicJunction();
123  break;
126  case NODETYPE_PRIORITY:
129  junction = buildLogicJunction();
130  break;
131  case NODETYPE_INTERNAL:
132 #ifdef HAVE_INTERNAL_LANES
134  junction = buildInternalJunction();
135  }
136 #endif
137  break;
138  default:
139  throw InvalidArgument("False junction logic type.");
140  }
141  if (junction != 0) {
142  if (!myJunctions->add(myActiveID, junction)) {
143  throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
144  }
145  }
146 }
147 
148 
152  myJunctions = 0;
153  return js;
154 }
155 
156 
157 MSJunction*
160 #ifdef HAVE_INTERNAL_LANES
161  , myActiveInternalLanes
162 #endif
163  );
164 }
165 
166 
167 MSJunction*
170  // build the junction
172 #ifdef HAVE_INTERNAL_LANES
173  myActiveInternalLanes,
174 #endif
175  jtype);
176 }
177 
178 
179 #ifdef HAVE_INTERNAL_LANES
180 MSJunction*
181 NLJunctionControlBuilder::buildInternalJunction() {
182  // build the junction
184  myActiveInternalLanes);
185 }
186 #endif
187 
188 
191  // get and check the junction logic
192  if (myLogics.find(myActiveID) == myLogics.end()) {
193  throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
194  }
195  return myLogics[myActiveID];
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 subid '" + myActiveProgram + "' exists.");
214  }
215  return;
216  }
217  if (myAbsDuration == 0) {
218  throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
219  }
220  // compute the initial step and first switch time of the tls-logic
221  // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
222  // @note The implementation of % for negative values is implementation defined in ISO1998
223  SUMOTime offset; // the time to run the traffic light in advance
224  if (myOffset >= 0) {
226  } else {
228  }
229  unsigned int step = 0;
230  SUMOTime firstEventOffset = 0;
231  MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
232  while (offset >= (*i)->duration) {
233  step++;
234  offset -= (*i)->duration;
235  ++i;
236  }
237  firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
238 
239  //
240  if (myActiveProgram == "") {
241  myActiveProgram = "default";
242  }
243  MSTrafficLightLogic* tlLogic = 0;
244  // build the tls-logic in dependance to its type
245  switch (myLogicType) {
246  case TLTYPE_ACTUATED:
247  // @note it is unclear how to apply the given offset in the context
248  // of variable-length phases
251  myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
253  break;
254  case TLTYPE_AGENT:
257  myActivePhases, step, firstEventOffset,
259  break;
260  case TLTYPE_STATIC:
261  tlLogic =
264  myActivePhases, step, firstEventOffset,
266  break;
267  }
268  myActivePhases.clear();
269  if (tlLogic != 0) {
270  if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
271  if (myNetIsLoaded) {
272  tlLogic->init(myDetectorBuilder);
273  } else {
274  myLogics2PostLoadInit.push_back(tlLogic);
275  }
276  } else {
277  WRITE_ERROR("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
278  delete tlLogic;
279  }
280  }
281 }
282 
283 
284 void
286  myActiveKey = id;
287  myActiveProgram = "";
288  myActiveLogic.clear();
289  myActiveFoes.clear();
290  myActiveConts.reset();
291  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
293  myCurrentHasError = false;
294 }
295 
296 
297 void
299  const std::string& response,
300  const std::string& foes,
301  bool cont) {
302  if (myCurrentHasError) {
303  // had an error
304  return;
305  }
306  if (request > 63) {
307  // bad request
308  myCurrentHasError = true;
309  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
310  }
312  // initialize
313  myRequestSize = (int)response.size();
314  }
315  if (static_cast<int>(response.size()) != myRequestSize) {
316  myCurrentHasError = true;
317  throw InvalidArgument("Invalid response size " + toString(response.size()) +
318  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
319  }
320  if (static_cast<int>(foes.size()) != myRequestSize) {
321  myCurrentHasError = true;
322  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
323  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
324  }
325  // assert that the logicitems come ordered by their request index
326  assert(myActiveLogic.size() == (size_t) request);
327  assert(myActiveFoes.size() == (size_t) request);
328  // add the read response for the given request index
329  myActiveLogic.push_back(std::bitset<64>(response));
330  // add the read junction-internal foes for the given request index
331  myActiveFoes.push_back(std::bitset<64>(foes));
332  // add whether the vehicle may drive a little bit further
333  myActiveConts.set(request, cont);
334  // increse number of set information
336 }
337 
338 
339 void
340 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
341  TrafficLightType type, SUMOTime offset) {
342  myActiveKey = id;
343  myActiveProgram = programID;
344  myActivePhases.clear();
345  myAbsDuration = 0;
347  myLogicType = type;
348  myOffset = offset;
349  myAdditionalParameter.clear();
350 }
351 
352 
353 void
354 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state,
355  int minDuration, int maxDuration) {
356  // build and add the phase definition to the list
357  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
358  // add phase duration to the absolute duration
359  myAbsDuration += duration;
360 }
361 
362 
363 void
366  // We have a legacy network. junction element did not contain logicitems; read the logic later
367  return;
368  }
369  if (myCurrentHasError) {
370  // had an error before...
371  return;
372  }
374  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
375  }
376  if (myLogics.count(myActiveKey) > 0) {
377  throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
378  }
382  myActiveConts);
383  myLogics[myActiveKey] = logic;
384 }
385 
386 
390  throw ProcessError("Traffic lights could not be built.");
391  }
393  myLogicControl = 0;
394  return ret;
395 }
396 
397 
398 void
399 NLJunctionControlBuilder::addParam(const std::string& key,
400  const std::string& value) {
401  myAdditionalParameter[key] = value;
402 }
403 
404 
407  if (myLogicControl != 0) {
408  return *myLogicControl;
409  }
410  return myNet.getTLSControl();
411 }
412 
413 
414 const std::string&
416  return myActiveKey;
417 }
418 
419 
420 const std::string&
422  return myActiveProgram;
423 }
424 
425 
426 void
428  for (std::vector<MSTrafficLightLogic*>::const_iterator it = myLogics2PostLoadInit.begin();
429  it != myLogics2PostLoadInit.end(); ++it) {
430  (*it)->init(myDetectorBuilder);
431  }
432  myNetIsLoaded = true;
433 }
434 
435 
436 MSJunction*
437 NLJunctionControlBuilder::retrieve(const std::string id) {
438  if (myJunctions != 0) {
439  return myJunctions->get(id);
440  } else {
441  return 0;
442  }
443 }
444 
445 /****************************************************************************/
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.
An agentbased traffic light logic.
Builds detectors for microsim.
virtual ~NLJunctionControlBuilder()
Destructor.
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
Storage for all programs of a single tls.
virtual bool add(const std::string &id, T item)
Adds an item.
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:59
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.
Position myPosition
The position of the junction.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:230
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
PositionVector myShape
The shape of the current junction.
The simulated network and simulation perfomer.
Definition: MSNet.h:91
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.
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, int min, int max)
Adds a phase to the currently built traffic lights logic.
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.
MSJunctionControl * myJunctions
The junctions controls.
std::bitset< 64 > myActiveConts
The description about which lanes have an internal follower.
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:334
A list of positions.
virtual MSJunction * buildLogicJunction()
Builds a junction with a 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
MSTLLogicControl * buildTLLogics() const
Returns the built tls-logic control.
bool myNetIsLoaded
whether the network has been loaded
MSJunction * retrieve(const std::string id)
try to retrieve junction by id
void closeJunction()
Closes (ends) the processing of the current junction.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:71
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.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
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:205
virtual MSJunction * buildNoLogicJunction()
Builds a junction that does not use a logic.
MSBitSetLogic< 64 > MSBitsetLogic
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
StringParameterMap myAdditionalParameter
Parameter map (key-&gt;value)
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
std::vector< MSTrafficLightLogic * > myLogics2PostLoadInit
The container for information which junctions shall be initialised using which values.
#define HAVE_INTERNAL_LANES
Definition: config.h:50
void set(SUMOReal x, SUMOReal y)
Definition: Position.h:78
MSTLLogicControl * myLogicControl
The tls control to use (0 if net&#39;s tls control shall be used)
A junction with right-of-way - rules.
int SUMOTime
Definition: SUMOTime.h:43
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
virtual void closeTrafficLightLogic()
Ends the building of a traffic lights logic.
The parent class for traffic light logics.
#define SUMOReal
Definition: config.h:218
MSJunctionLogic * getJunctionLogicSecure()
Returns the current junction logic.
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
The definition of a single phase of a tls logic.
TrafficLightType
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.