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