SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NBTrafficLightDefinition.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // The base class for traffic light logic definitions
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
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 <vector>
34 #include <string>
35 #include <algorithm>
36 #include <cassert>
37 #include <iterator>
39 #include <utils/common/ToString.h>
43 #include "NBTrafficLightLogic.h"
44 #include "NBContHelper.h"
45 
46 #ifdef CHECK_MEMORY_LEAKS
47 #include <foreign/nvwa/debug_new.h>
48 #endif // CHECK_MEMORY_LEAKS
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
53 const std::string NBTrafficLightDefinition::DefaultProgramID = "0";
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
59  const std::vector<NBNode*>& junctions, const std::string& programID,
60  SUMOTime offset, TrafficLightType type) :
61  Named(id),
62  myControlledNodes(junctions),
63  mySubID(programID), myOffset(offset),
64  myType(type) {
65  std::vector<NBNode*>::iterator i = myControlledNodes.begin();
66  while (i != myControlledNodes.end()) {
67  for (std::vector<NBNode*>::iterator j = i + 1; j != myControlledNodes.end();) {
68  if (*i == *j) {
69  j = myControlledNodes.erase(j);
70  } else {
71  j++;
72  }
73  }
74  i++;
75  }
77  for (std::vector<NBNode*>::const_iterator i = junctions.begin(); i != junctions.end(); i++) {
78  (*i)->addTrafficLight(this);
79  }
80 }
81 
82 
84  NBNode* junction, const std::string& programID, SUMOTime offset, TrafficLightType type) :
85  Named(id),
86  mySubID(programID),
87  myOffset(offset),
88  myType(type) {
89  addNode(junction);
90  junction->addTrafficLight(this);
91 }
92 
93 
94 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string& id, const std::string& programID,
95  SUMOTime offset, TrafficLightType type) :
96  Named(id),
97  mySubID(programID),
98  myOffset(offset),
99  myType(type) {}
100 
101 
103 
104 
107  // it is not really a traffic light if no incoming edge exists
108  if (amInvalid()) {
109  // make a copy of myControlledNodes because it will be modified;
110  std::vector<NBNode*> nodes = myControlledNodes;
111  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
112  (*it)->removeTrafficLight(this);
113  }
114  WRITE_WARNING("The traffic light '" + getID() + "' does not control any links; it will not be build.");
115  return 0;
116  }
117  // compute the time needed to brake
118  unsigned int brakingTime = computeBrakingTime(oc.getFloat("tls.yellow.min-decel"));
119  // perform the computation depending on whether the traffic light
120  // definition was loaded or shall be computed new completely
121  if (oc.isSet("tls.yellow.time")) {
122  brakingTime = oc.getInt("tls.yellow.time");
123  }
124  return myCompute(ec, brakingTime);
125 }
126 
127 
128 bool
130  return myControlledLinks.size() == 0;
131 }
132 
133 
134 unsigned int
137  return (unsigned int)(vmax / minDecel);
138 }
139 
140 
141 void
143  // collect the information about participating edges and links
144  collectEdges();
145  collectLinks();
146 }
147 
148 
149 void
151  myIncomingEdges.clear();
152  EdgeVector myOutgoing;
153  // collect the edges from the participating nodes
154  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
155  const EdgeVector& incoming = (*i)->getIncomingEdges();
156  copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
157  const EdgeVector& outgoing = (*i)->getOutgoingEdges();
158  copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
159  }
160  // check which of the edges are completely within the junction
161  // remove these edges from the list of incoming edges
162  // add them to the list of edges lying within the node
163  for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) {
164  NBEdge* edge = *j;
165  // an edge lies within the logic if it is outgoing as well as incoming
166  EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge);
167  if (k != myOutgoing.end()) {
168  if (myControlledInnerEdges.count(edge->getID()) == 0) {
169  myEdgesWithin.push_back(edge);
170  (*j)->setIsInnerEdge();
171  j = myIncomingEdges.erase(j);
172  continue;
173  }
174  }
175  ++j;
176  }
177 }
178 
179 
180 bool
181 NBTrafficLightDefinition::isLeftMover(const NBEdge* const from, const NBEdge* const to) const {
182  // the destination edge may be unused
183  if (to == 0) {
184  return false;
185  }
186  // get the node which is holding this connection
187  std::vector<NBNode*>::const_iterator i =
188  find_if(myControlledNodes.begin(), myControlledNodes.end(),
190  assert(i != myControlledNodes.end());
191  NBNode* node = *i;
192  return node->isLeftMover(from, to);
193 }
194 
195 
196 bool
197 NBTrafficLightDefinition::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
198  std::vector<NBNode*>::const_iterator i =
199  find_if(myControlledNodes.begin(), myControlledNodes.end(),
201  assert(i != myControlledNodes.end());
202  NBNode* node = *i;
203  if (!node->hasOutgoing(to)) {
204  return true; // !!!
205  }
206  return node->mustBrake(from, to, -1);
207 }
208 
209 
210 bool
211 NBTrafficLightDefinition::mustBrake(const NBEdge* const possProhibitedFrom,
212  const NBEdge* const possProhibitedTo,
213  const NBEdge* const possProhibitorFrom,
214  const NBEdge* const possProhibitorTo,
215  bool regardNonSignalisedLowerPriority) const {
216  return forbids(possProhibitorFrom, possProhibitorTo,
217  possProhibitedFrom, possProhibitedTo,
218  regardNonSignalisedLowerPriority);
219 }
220 
221 
222 bool
224  const NBConnection& possProhibitor,
225  bool regardNonSignalisedLowerPriority) const {
226  return forbids(possProhibitor.getFrom(), possProhibitor.getTo(),
227  possProhibited.getFrom(), possProhibited.getTo(),
228  regardNonSignalisedLowerPriority);
229 }
230 
231 
232 bool
233 NBTrafficLightDefinition::forbids(const NBEdge* const possProhibitorFrom,
234  const NBEdge* const possProhibitorTo,
235  const NBEdge* const possProhibitedFrom,
236  const NBEdge* const possProhibitedTo,
237  bool regardNonSignalisedLowerPriority) const {
238  if (possProhibitorFrom == 0 || possProhibitorTo == 0 || possProhibitedFrom == 0 || possProhibitedTo == 0) {
239  return false;
240  }
241  // retrieve both nodes
242  std::vector<NBNode*>::const_iterator incoming =
243  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorFrom));
244  std::vector<NBNode*>::const_iterator outgoing =
245  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(possProhibitedTo));
246  assert(incoming != myControlledNodes.end());
247  NBNode* incnode = *incoming;
248  NBNode* outnode = *outgoing;
249  EdgeVector::const_iterator i;
250  if (incnode != outnode) {
251  // the links are located at different nodes
252  const EdgeVector& ev1 = possProhibitedTo->getConnectedEdges();
253  // go through the following edge,
254  // check whether one of these connections is prohibited
255  for (i = ev1.begin(); i != ev1.end(); ++i) {
256  std::vector<NBNode*>::const_iterator outgoing2 =
258  if (outgoing2 == myControlledNodes.end()) {
259  continue;
260  }
261  NBNode* outnode2 = *outgoing2;
262  if (incnode != outnode2) {
263  continue;
264  }
265  bool ret1 = incnode->foes(possProhibitorTo, *i,
266  possProhibitedFrom, possProhibitedTo);
267  bool ret2 = incnode->forbids(possProhibitorFrom, possProhibitorTo,
268  possProhibitedTo, *i,
269  regardNonSignalisedLowerPriority);
270  bool ret = ret1 || ret2;
271  if (ret) {
272  return true;
273  }
274  }
275 
276  const EdgeVector& ev2 = possProhibitorTo->getConnectedEdges();
277  // go through the following edge,
278  // check whether one of these connections is prohibited
279  for (i = ev2.begin(); i != ev2.end(); ++i) {
280  std::vector<NBNode*>::const_iterator incoming2 =
281  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorTo));
282  if (incoming2 == myControlledNodes.end()) {
283  continue;
284  }
285  NBNode* incnode2 = *incoming2;
286  if (incnode2 != outnode) {
287  continue;
288  }
289  bool ret1 = incnode2->foes(possProhibitorTo, *i,
290  possProhibitedFrom, possProhibitedTo);
291  bool ret2 = incnode2->forbids(possProhibitorTo, *i,
292  possProhibitedFrom, possProhibitedTo,
293  regardNonSignalisedLowerPriority);
294  bool ret = ret1 || ret2;
295  if (ret) {
296  return true;
297  }
298  }
299  return false;
300  }
301  // both links are located at the same node
302  // check using this node's information
303  return incnode->forbids(possProhibitorFrom, possProhibitorTo,
304  possProhibitedFrom, possProhibitedTo,
305  regardNonSignalisedLowerPriority);
306 }
307 
308 
309 bool
310 NBTrafficLightDefinition::foes(const NBEdge* const from1, const NBEdge* const to1,
311  const NBEdge* const from2, const NBEdge* const to2) const {
312  if (to1 == 0 || to2 == 0) {
313  return false;
314  }
315  // retrieve both nodes (it is possible that a connection
316  std::vector<NBNode*>::const_iterator incoming =
317  find_if(myControlledNodes.begin(), myControlledNodes.end(),
319  std::vector<NBNode*>::const_iterator outgoing =
320  find_if(myControlledNodes.begin(), myControlledNodes.end(),
322  assert(incoming != myControlledNodes.end());
323  NBNode* incnode = *incoming;
324  NBNode* outnode = *outgoing;
325  if (incnode != outnode) {
326  return false;
327  }
328  return incnode->foes(from1, to1, from2, to2);
329 }
330 
331 
332 void
334  if (std::find(myControlledNodes.begin(), myControlledNodes.end(), node) == myControlledNodes.end()) {
335  myControlledNodes.push_back(node);
337  node->addTrafficLight(this);
338  }
339 }
340 
341 
342 void
344  std::vector<NBNode*>::iterator i = std::find(myControlledNodes.begin(), myControlledNodes.end(), node);
345  if (i != myControlledNodes.end()) {
346  myControlledNodes.erase(i);
347  }
348  // !!! remove in node?
349 }
350 
351 
352 void
353 NBTrafficLightDefinition::addControlledInnerEdges(const std::vector<std::string>& edges) {
354  myControlledInnerEdges.insert(edges.begin(), edges.end());
355 }
356 
357 
358 const EdgeVector&
360  return myIncomingEdges;
361 }
362 
363 
364 void
366  myControlledLinks.clear();
367  // build the list of links which are controled by the traffic light
368  for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) {
369  NBEdge* incoming = *i;
370  unsigned int noLanes = incoming->getNumLanes();
371  for (unsigned int j = 0; j < noLanes; j++) {
372  std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j);
373  for (std::vector<NBEdge::Connection>::iterator k = connected.begin(); k != connected.end(); k++) {
374  const NBEdge::Connection& el = *k;
375  if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) {
376  if (el.toEdge != 0 && el.toLane >= (int) el.toEdge->getNumLanes()) {
377  throw ProcessError("Connection '" + incoming->getID() + "_" + toString(j) + "->" + el.toEdge->getID() + "_" + toString(el.toLane) + "' yields in a not existing lane.");
378  }
379  int tlIndex = (int)myControlledLinks.size();
380  myControlledLinks.push_back(NBConnection(incoming, el.fromLane, el.toEdge, el.toLane, tlIndex));
381  }
382  }
383  }
384  }
385 }
386 
387 /****************************************************************************/
388