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-sim.org/
13 // Copyright (C) 2001-2013 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:
249  myActivePhases, step, firstEventOffset,
251  break;
252  case TLTYPE_AGENT:
255  myActivePhases, step, firstEventOffset,
257  break;
258  case TLTYPE_STATIC:
259  tlLogic =
262  myActivePhases, step, firstEventOffset,
264  break;
265  }
266  myActivePhases.clear();
267  if (tlLogic != 0) {
268  if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
269  if (myNetIsLoaded) {
270  tlLogic->init(myDetectorBuilder);
271  } else {
272  myLogics2PostLoadInit.push_back(tlLogic);
273  }
274  } else {
275  WRITE_ERROR("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
276  delete tlLogic;
277  }
278  }
279 }
280 
281 
282 void
284  myActiveKey = id;
285  myActiveProgram = "";
286  myActiveLogic.clear();
287  myActiveFoes.clear();
288  myActiveConts.reset();
289  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
291  myCurrentHasError = false;
292 }
293 
294 
295 void
297  const std::string& response,
298  const std::string& foes,
299  bool cont) {
300  if (myCurrentHasError) {
301  // had an error
302  return;
303  }
304  if (request > 63) {
305  // bad request
306  myCurrentHasError = true;
307  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
308  }
310  // initialize
311  myRequestSize = (int)response.size();
312  }
313  if (static_cast<int>(response.size()) != myRequestSize) {
314  myCurrentHasError = true;
315  throw InvalidArgument("Invalid response size " + toString(response.size()) +
316  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
317  }
318  if (static_cast<int>(foes.size()) != myRequestSize) {
319  myCurrentHasError = true;
320  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
321  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
322  }
323  // assert that the logicitems come ordered by their request index
324  assert(myActiveLogic.size() == (size_t) request);
325  assert(myActiveFoes.size() == (size_t) request);
326  // add the read response for the given request index
327  myActiveLogic.push_back(std::bitset<64>(response));
328  // add the read junction-internal foes for the given request index
329  myActiveFoes.push_back(std::bitset<64>(foes));
330  // add whether the vehicle may drive a little bit further
331  myActiveConts.set(request, cont);
332  // increse number of set information
334 }
335 
336 
337 void
338 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
339  TrafficLightType type, SUMOTime offset) {
340  myActiveKey = id;
341  myActiveProgram = programID;
342  myActivePhases.clear();
343  myAbsDuration = 0;
345  myLogicType = type;
346  myOffset = offset;
347  myAdditionalParameter.clear();
348 }
349 
350 
351 void
352 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state,
353  int minDuration, int maxDuration) {
354  // build and add the phase definition to the list
355  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
356  // add phase duration to the absolute duration
357  myAbsDuration += duration;
358 }
359 
360 
361 void
364  // We have a legacy network. junction element did not contain logicitems; read the logic later
365  return;
366  }
367  if (myCurrentHasError) {
368  // had an error before...
369  return;
370  }
372  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
373  }
374  if (myLogics.count(myActiveKey) > 0) {
375  throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
376  }
380  myActiveConts);
381  myLogics[myActiveKey] = logic;
382 }
383 
384 
388  throw ProcessError("Traffic lights could not be built.");
389  }
391  myLogicControl = 0;
392  return ret;
393 }
394 
395 
396 void
397 NLJunctionControlBuilder::addParam(const std::string& key,
398  const std::string& value) {
399  myAdditionalParameter[key] = value;
400 }
401 
402 
405  if (myLogicControl != 0) {
406  return *myLogicControl;
407  }
408  return myNet.getTLSControl();
409 }
410 
411 
412 const std::string&
414  return myActiveKey;
415 }
416 
417 
418 const std::string&
420  return myActiveProgram;
421 }
422 
423 
424 void
426  for (std::vector<MSTrafficLightLogic*>::const_iterator it = myLogics2PostLoadInit.begin();
427  it != myLogics2PostLoadInit.end(); ++it) {
428  (*it)->init(myDetectorBuilder);
429  }
430  myNetIsLoaded = true;
431 }
432 
433 /****************************************************************************/
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:57
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 (in s)
Definition: MSNet.cpp:502
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:36
PositionVector myShape
The shape of the current junction.
The simulated network and simulation perfomer.
Definition: MSNet.h:89
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.
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:304
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
void closeJunction()
Closes (ends) the processing of the current junction.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:70
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:51
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:201
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:47
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.
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:215
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.