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.sourceforge.net/
12 // Copyright (C) 2001-2012 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>
44 #include "NBTrafficLightLogic.h"
45 #include "NBContHelper.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 // ===========================================================================
52 // static members
53 // ===========================================================================
54 const std::string NBTrafficLightDefinition::DefaultProgramID = "0";
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
60  const std::vector<NBNode*> &junctions,
61  const std::string& programID)
62  : Named(id), myControlledNodes(junctions), mySubID(programID) {
63  std::vector<NBNode*>::iterator i = myControlledNodes.begin();
64  while (i != myControlledNodes.end()) {
65  for (std::vector<NBNode*>::iterator j = i + 1; j != myControlledNodes.end();) {
66  if (*i == *j) {
67  j = myControlledNodes.erase(j);
68  } else {
69  j++;
70  }
71  }
72  i++;
73  }
75  for (std::vector<NBNode*>::const_iterator i = junctions.begin(); i != junctions.end(); i++) {
76  (*i)->addTrafficLight(this);
77  }
78 }
79 
80 
82  NBNode* junction,
83  const std::string& programID)
84  : Named(id), mySubID(programID) {
85  addNode(junction);
86  junction->addTrafficLight(this);
87 }
88 
89 
90 NBTrafficLightDefinition::NBTrafficLightDefinition(const std::string& id, const std::string& programID)
91  : Named(id), mySubID(programID) {}
92 
93 
95 
96 
99  // it is not really a traffic light if no incoming edge exists
100  if (amInvalid()) {
101  // make a copy of myControlledNodes because it will be modified;
102  std::vector<NBNode*> nodes = myControlledNodes;
103  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
104  (*it)->removeTrafficLight(this);
105  }
106  WRITE_WARNING("The traffic light '" + getID() + "' does not control any links; it will not be build.");
107  return 0;
108  }
109  // compute the time needed to brake
110  unsigned int brakingTime = computeBrakingTime(oc.getFloat("tls.yellow.min-decel"));
111  // perform the computation depending on whether the traffic light
112  // definition was loaded or shall be computed new completely
113  if (oc.isSet("tls.yellow.time")) {
114  brakingTime = oc.getInt("tls.yellow.time");
115  }
116  return myCompute(ec, brakingTime);
117 }
118 
119 
120 bool
122  return myControlledLinks.size() == 0;
123 }
124 
125 
126 unsigned int
129  return (unsigned int)(vmax / minDecel);
130 }
131 
132 
133 void
135  // collect the information about participating edges and links
136  collectEdges();
137  collectLinks();
138 }
139 
140 
141 void
143  myIncomingEdges.clear();
144  EdgeVector myOutgoing;
145  // collect the edges from the participating nodes
146  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
147  const EdgeVector& incoming = (*i)->getIncomingEdges();
148  copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
149  const EdgeVector& outgoing = (*i)->getOutgoingEdges();
150  copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
151  }
152  // check which of the edges are completely within the junction
153  // remove these edges from the list of incoming edges
154  // add them to the list of edges lying within the node
155  for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) {
156  NBEdge* edge = *j;
157  // an edge lies within the logic if it is outgoing as well as incoming
158  EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge);
159  if (k != myOutgoing.end()) {
160  if (myControlledInnerEdges.count(edge->getID()) == 0) {
161  myEdgesWithin.push_back(edge);
162  (*j)->setIsInnerEdge();
163  j = myIncomingEdges.erase(j);
164  continue;
165  }
166  }
167  ++j;
168  }
169 }
170 
171 
172 bool
173 NBTrafficLightDefinition::isLeftMover(const NBEdge* const from, const NBEdge* const to) const {
174  // the destination edge may be unused
175  if (to == 0) {
176  return false;
177  }
178  // get the node which is holding this connection
179  std::vector<NBNode*>::const_iterator i =
180  find_if(myControlledNodes.begin(), myControlledNodes.end(),
182  assert(i != myControlledNodes.end());
183  NBNode* node = *i;
184  return node->isLeftMover(from, to);
185 }
186 
187 
188 bool
189 NBTrafficLightDefinition::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
190  std::vector<NBNode*>::const_iterator i =
191  find_if(myControlledNodes.begin(), myControlledNodes.end(),
193  assert(i != myControlledNodes.end());
194  NBNode* node = *i;
195  if (!node->hasOutgoing(to)) {
196  return true; // !!!
197  }
198  return node->mustBrake(from, to, -1);
199 }
200 
201 
202 bool
203 NBTrafficLightDefinition::mustBrake(const NBEdge* const possProhibitedFrom,
204  const NBEdge* const possProhibitedTo,
205  const NBEdge* const possProhibitorFrom,
206  const NBEdge* const possProhibitorTo,
207  bool regardNonSignalisedLowerPriority) const {
208  return forbids(possProhibitorFrom, possProhibitorTo,
209  possProhibitedFrom, possProhibitedTo,
210  regardNonSignalisedLowerPriority);
211 }
212 
213 
214 bool
216  const NBConnection& possProhibitor,
217  bool regardNonSignalisedLowerPriority) const {
218  return forbids(possProhibitor.getFrom(), possProhibitor.getTo(),
219  possProhibited.getFrom(), possProhibited.getTo(),
220  regardNonSignalisedLowerPriority);
221 }
222 
223 
224 bool
225 NBTrafficLightDefinition::forbids(const NBEdge* const possProhibitorFrom,
226  const NBEdge* const possProhibitorTo,
227  const NBEdge* const possProhibitedFrom,
228  const NBEdge* const possProhibitedTo,
229  bool regardNonSignalisedLowerPriority) const {
230  if (possProhibitorFrom == 0 || possProhibitorTo == 0 || possProhibitedFrom == 0 || possProhibitedTo == 0) {
231  return false;
232  }
233  // retrieve both nodes
234  std::vector<NBNode*>::const_iterator incoming =
235  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorFrom));
236  std::vector<NBNode*>::const_iterator outgoing =
237  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(possProhibitedTo));
238  assert(incoming != myControlledNodes.end());
239  NBNode* incnode = *incoming;
240  NBNode* outnode = *outgoing;
241  EdgeVector::const_iterator i;
242  if (incnode != outnode) {
243  // the links are located at different nodes
244  const EdgeVector& ev1 = possProhibitedTo->getConnectedEdges();
245  // go through the following edge,
246  // check whether one of these connections is prohibited
247  for (i = ev1.begin(); i != ev1.end(); ++i) {
248  std::vector<NBNode*>::const_iterator outgoing2 =
250  if (outgoing2 == myControlledNodes.end()) {
251  continue;
252  }
253  NBNode* outnode2 = *outgoing2;
254  if (incnode != outnode2) {
255  continue;
256  }
257  bool ret1 = incnode->foes(possProhibitorTo, *i,
258  possProhibitedFrom, possProhibitedTo);
259  bool ret2 = incnode->forbids(possProhibitorFrom, possProhibitorTo,
260  possProhibitedTo, *i,
261  regardNonSignalisedLowerPriority);
262  bool ret = ret1 || ret2;
263  if (ret) {
264  return true;
265  }
266  }
267 
268  const EdgeVector& ev2 = possProhibitorTo->getConnectedEdges();
269  // go through the following edge,
270  // check whether one of these connections is prohibited
271  for (i = ev2.begin(); i != ev2.end(); ++i) {
272  std::vector<NBNode*>::const_iterator incoming2 =
273  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorTo));
274  if (incoming2 == myControlledNodes.end()) {
275  continue;
276  }
277  NBNode* incnode2 = *incoming2;
278  if (incnode2 != outnode) {
279  continue;
280  }
281  bool ret1 = incnode2->foes(possProhibitorTo, *i,
282  possProhibitedFrom, possProhibitedTo);
283  bool ret2 = incnode2->forbids(possProhibitorTo, *i,
284  possProhibitedFrom, possProhibitedTo,
285  regardNonSignalisedLowerPriority);
286  bool ret = ret1 || ret2;
287  if (ret) {
288  return true;
289  }
290  }
291  return false;
292  }
293  // both links are located at the same node
294  // check using this node's information
295  return incnode->forbids(possProhibitorFrom, possProhibitorTo,
296  possProhibitedFrom, possProhibitedTo,
297  regardNonSignalisedLowerPriority);
298 }
299 
300 
301 bool
302 NBTrafficLightDefinition::foes(const NBEdge* const from1, const NBEdge* const to1,
303  const NBEdge* const from2, const NBEdge* const to2) const {
304  if (to1 == 0 || to2 == 0) {
305  return false;
306  }
307  // retrieve both nodes (it is possible that a connection
308  std::vector<NBNode*>::const_iterator incoming =
309  find_if(myControlledNodes.begin(), myControlledNodes.end(),
311  std::vector<NBNode*>::const_iterator outgoing =
312  find_if(myControlledNodes.begin(), myControlledNodes.end(),
314  assert(incoming != myControlledNodes.end());
315  NBNode* incnode = *incoming;
316  NBNode* outnode = *outgoing;
317  if (incnode != outnode) {
318  return false;
319  }
320  return incnode->foes(from1, to1, from2, to2);
321 }
322 
323 
324 void
326  if (std::find(myControlledNodes.begin(), myControlledNodes.end(), node) == myControlledNodes.end()) {
327  myControlledNodes.push_back(node);
329  node->addTrafficLight(this);
330  }
331 }
332 
333 
334 void
336  std::vector<NBNode*>::iterator i = std::find(myControlledNodes.begin(), myControlledNodes.end(), node);
337  if (i != myControlledNodes.end()) {
338  myControlledNodes.erase(i);
339  }
340  // !!! remove in node?
341 }
342 
343 
344 void
345 NBTrafficLightDefinition::addControlledInnerEdges(const std::vector<std::string> &edges) {
346  myControlledInnerEdges.insert(edges.begin(), edges.end());
347 }
348 
349 
350 const EdgeVector&
352  return myIncomingEdges;
353 }
354 
355 
356 /****************************************************************************/
357