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.sourceforge.net/
13 // Copyright (C) 2001-2012 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), myDetectorBuilder(db), myOffset(0), myJunctions(0) {
75 }
76 
77 
79  delete myLogicControl;
80  delete myJunctions;
81 }
82 
83 
84 void
86  const std::string& key,
87  const std::string& type,
88  SUMOReal x, SUMOReal y,
89  const PositionVector& shape,
90  const std::vector<MSLane*> &incomingLanes,
91  const std::vector<MSLane*> &internalLanes) throw(InvalidArgument) {
92 #ifdef HAVE_INTERNAL_LANES
93  myActiveInternalLanes = internalLanes;
94 #endif
95  myActiveIncomingLanes = incomingLanes;
96  myActiveID = id;
97  myActiveKey = key;
98  if (!SUMOXMLDefinitions::NodeTypes.hasString(type)) {
99  throw InvalidArgument("An unknown or invalid junction type '" + type + "' occured in junction '" + id + "'.");
100  }
101 
102  myType = SUMOXMLDefinitions::NodeTypes.get(type);
103  myPosition.set(x, y);
104  myShape = shape;
105 }
106 
107 
108 void
110  if (myJunctions == 0) {
111  throw ProcessError("Information about the number of nodes was missing.");
112  }
113  MSJunction* junction = 0;
114  switch (myType) {
115  case NODETYPE_NOJUNCTION:
116  case NODETYPE_DEAD_END:
118  case NODETYPE_DISTRICT:
119  junction = buildNoLogicJunction();
120  break;
124  junction = buildLogicJunction();
125  break;
126  case NODETYPE_INTERNAL:
127 #ifdef HAVE_INTERNAL_LANES
129  junction = buildInternalJunction();
130  }
131 #endif
132  break;
133  default:
134  throw InvalidArgument("False junction logic type.");
135  }
136  if (junction != 0) {
137  if (!myJunctions->add(myActiveID, junction)) {
138  throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
139  }
140  }
141 }
142 
143 
147  myJunctions = 0;
148  return js;
149 }
150 
151 
152 MSJunction*
155 #ifdef HAVE_INTERNAL_LANES
156  , myActiveInternalLanes
157 #endif
158  );
159 }
160 
161 
162 MSJunction*
165  // build the junction
167 #ifdef HAVE_INTERNAL_LANES
168  myActiveInternalLanes,
169 #endif
170  jtype);
171 }
172 
173 
174 #ifdef HAVE_INTERNAL_LANES
175 MSJunction*
176 NLJunctionControlBuilder::buildInternalJunction() {
177  // build the junction
179  myActiveInternalLanes);
180 }
181 #endif
182 
183 
186  // get and check the junction logic
187  if (myLogics.find(myActiveID) == myLogics.end()) {
188  throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
189  }
190  return myLogics[myActiveID];
191 }
192 
193 
195 NLJunctionControlBuilder::getTLLogic(const std::string& id) const throw(InvalidArgument) {
196  return getTLLogicControlToUse().get(id);
197 }
198 
199 
200 void
202  if (myActiveProgram == "off") {
203  if (myAbsDuration > 0) {
204  throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
205  }
208  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
209  }
210  return;
211  }
212  if (myAbsDuration == 0) {
213  throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
214  }
215  // compute the initial step and first switch time of the tls-logic
216  // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
217  // @note The implementation of % for negative values is implementation defined in ISO1998
218  SUMOTime offset; // the time to run the traffic light in advance
219  if (myOffset >= 0) {
221  } else {
223  }
224  unsigned int step = 0;
225  SUMOTime firstEventOffset = 0;
226  MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
227  while (offset >= (*i)->duration) {
228  step++;
229  offset -= (*i)->duration;
230  ++i;
231  }
232  firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
233 
234  //
235  if (myActiveProgram == "") {
236  myActiveProgram = "default";
237  }
238  MSTrafficLightLogic* tlLogic = 0;
239  // build the tls-logic in dependance to its type
240  switch (myLogicType) {
241  case TLTYPE_ACTUATED:
244  myActivePhases, step, firstEventOffset, myAdditionalParameter);
245  break;
246  case TLTYPE_AGENT:
249  myActivePhases, step, firstEventOffset, myAdditionalParameter);
250  break;
251  case TLTYPE_STATIC:
252  tlLogic =
255  myActivePhases, step, firstEventOffset);
257  }
258  TLInitInfo ii;
259  ii.logic = tlLogic;
261  myJunctions2PostLoadInit.push_back(ii);
262  myActivePhases.clear();
263  if (tlLogic != 0) {
264  try {
265  if (!getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
266  throw InvalidArgument("Another logic with id '" + myActiveKey + "' and subid '" + myActiveProgram + "' exists.");
267  }
269  tlLogic->init(myDetectorBuilder);
270  } catch (InvalidArgument&) {
271  delete tlLogic;
272  throw;
273  }
274  }
275 }
276 
277 
278 void
280  myActiveKey = id;
281  myActiveProgram = "";
282  myActiveLogic.clear();
283  myActiveFoes.clear();
284  myActiveConts.reset();
285  myRequestSize = NO_REQUEST_SIZE; // seems not to be used
287  myCurrentHasError = false;
288 }
289 
290 
291 void
293  const std::string& response,
294  const std::string& foes,
295  bool cont) throw(InvalidArgument) {
296  if (myCurrentHasError) {
297  // had an error
298  return;
299  }
300  if (request > 63) {
301  // bad request
302  myCurrentHasError = true;
303  throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
304  }
305  if (myRequestSize == NO_REQUEST_SIZE) {
306  // initialize
307  myRequestSize = (int)response.size();
308  }
309  if (response.size() != myRequestSize) {
310  myCurrentHasError = true;
311  throw InvalidArgument("Invalid response size " + toString(response.size()) +
312  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
313  }
314  if (foes.size() != myRequestSize) {
315  myCurrentHasError = true;
316  throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
317  " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
318  }
319  // assert that the logicitems come ordered by their request index
320  assert(myActiveLogic.size() == (size_t) request);
321  assert(myActiveFoes.size() == (size_t) request);
322  // add the read response for the given request index
323  myActiveLogic.push_back(std::bitset<64>(response));
324  // add the read junction-internal foes for the given request index
325  myActiveFoes.push_back(std::bitset<64>(foes));
326  // add whether the vehicle may drive a little bit further
327  myActiveConts.set(request, cont);
328  // increse number of set information
329  myRequestItemNumber++;
330 }
331 
332 
333 void
334 NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
335  TrafficLightType type, SUMOTime offset) {
336  myActiveKey = id;
337  myActiveProgram = programID;
338  myActivePhases.clear();
339  myAbsDuration = 0;
341  myLogicType = type;
342  myOffset = offset;
343  myAdditionalParameter.clear();
344 }
345 
346 
347 void
348 NLJunctionControlBuilder::addPhase(SUMOTime duration, const std::string& state,
349  int minDuration, int maxDuration) {
350  // build and add the phase definition to the list
351  myActivePhases.push_back(new MSPhaseDefinition(duration, minDuration, maxDuration, state));
352  // add phase duration to the absolute duration
353  myAbsDuration += duration;
354 }
355 
356 
357 void
360  // We have a legacy network. junction element did not contain logicitems; read the logic later
361  return;
362  }
363  if (myCurrentHasError) {
364  // had an error before...
365  return;
366  }
368  throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
369  }
370  if (myLogics.count(myActiveKey) > 0) {
371  throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
372  }
376  myActiveConts);
377  myLogics[myActiveKey] = logic;
378 }
379 
380 
384  throw ProcessError("Traffic lights could not be built.");
385  }
387  myLogicControl = 0;
388  return ret;
389 }
390 
391 
392 void
393 NLJunctionControlBuilder::addParam(const std::string& key,
394  const std::string& value) {
395  myAdditionalParameter[key] = value;
396 }
397 
398 
401  if (myLogicControl != 0) {
402  return *myLogicControl;
403  }
404  return myNet.getTLSControl();
405 }
406 
407 
408 const std::string&
410  return myActiveKey;
411 }
412 
413 
414 const std::string&
416  return myActiveProgram;
417 }
418 
419 
420 /****************************************************************************/