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-2014 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  NBTrafficLightLogic* ret = myCompute(ec, brakingTime);
125  ret->addParameter(getMap());
126  return ret;
127 }
128 
129 
130 bool
132  return myControlledLinks.size() == 0;
133 }
134 
135 
136 unsigned int
139  return (unsigned int)(vmax / minDecel);
140 }
141 
142 
143 void
145  // collect the information about participating edges and links
146  collectEdges();
147  collectLinks();
148 }
149 
150 
151 void
153  myIncomingEdges.clear();
154  EdgeVector myOutgoing;
155  // collect the edges from the participating nodes
156  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
157  const EdgeVector& incoming = (*i)->getIncomingEdges();
158  copy(incoming.begin(), incoming.end(), back_inserter(myIncomingEdges));
159  const EdgeVector& outgoing = (*i)->getOutgoingEdges();
160  copy(outgoing.begin(), outgoing.end(), back_inserter(myOutgoing));
161  }
162  // check which of the edges are completely within the junction
163  // remove these edges from the list of incoming edges
164  // add them to the list of edges lying within the node
165  for (EdgeVector::iterator j = myIncomingEdges.begin(); j != myIncomingEdges.end();) {
166  NBEdge* edge = *j;
167  // an edge lies within the logic if it is outgoing as well as incoming
168  EdgeVector::iterator k = find(myOutgoing.begin(), myOutgoing.end(), edge);
169  if (k != myOutgoing.end()) {
170  if (myControlledInnerEdges.count(edge->getID()) == 0) {
171  myEdgesWithin.push_back(edge);
172  (*j)->setIsInnerEdge();
173  j = myIncomingEdges.erase(j);
174  continue;
175  }
176  }
177  ++j;
178  }
179 }
180 
181 
182 bool
183 NBTrafficLightDefinition::isLeftMover(const NBEdge* const from, const NBEdge* const to) const {
184  // the destination edge may be unused
185  if (to == 0) {
186  return false;
187  }
188  // get the node which is holding this connection
189  std::vector<NBNode*>::const_iterator i =
190  find_if(myControlledNodes.begin(), myControlledNodes.end(),
192  assert(i != myControlledNodes.end());
193  NBNode* node = *i;
194  return node->isLeftMover(from, to);
195 }
196 
197 
198 bool
199 NBTrafficLightDefinition::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
200  std::vector<NBNode*>::const_iterator i =
201  find_if(myControlledNodes.begin(), myControlledNodes.end(),
203  assert(i != myControlledNodes.end());
204  NBNode* node = *i;
205  if (!node->hasOutgoing(to)) {
206  return true; // !!!
207  }
208  return node->mustBrake(from, to, -1);
209 }
210 
211 
212 bool
213 NBTrafficLightDefinition::mustBrake(const NBEdge* const possProhibitedFrom,
214  const NBEdge* const possProhibitedTo,
215  const NBEdge* const possProhibitorFrom,
216  const NBEdge* const possProhibitorTo,
217  bool regardNonSignalisedLowerPriority) const {
218  return forbids(possProhibitorFrom, possProhibitorTo,
219  possProhibitedFrom, possProhibitedTo,
220  regardNonSignalisedLowerPriority);
221 }
222 
223 
224 bool
226  const NBConnection& possProhibitor,
227  bool regardNonSignalisedLowerPriority) const {
228  return forbids(possProhibitor.getFrom(), possProhibitor.getTo(),
229  possProhibited.getFrom(), possProhibited.getTo(),
230  regardNonSignalisedLowerPriority);
231 }
232 
233 
234 bool
235 NBTrafficLightDefinition::forbids(const NBEdge* const possProhibitorFrom,
236  const NBEdge* const possProhibitorTo,
237  const NBEdge* const possProhibitedFrom,
238  const NBEdge* const possProhibitedTo,
239  bool regardNonSignalisedLowerPriority) const {
240  if (possProhibitorFrom == 0 || possProhibitorTo == 0 || possProhibitedFrom == 0 || possProhibitedTo == 0) {
241  return false;
242  }
243  // retrieve both nodes
244  std::vector<NBNode*>::const_iterator incoming =
245  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorFrom));
246  std::vector<NBNode*>::const_iterator outgoing =
247  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_outgoing_finder(possProhibitedTo));
248  assert(incoming != myControlledNodes.end());
249  NBNode* incnode = *incoming;
250  NBNode* outnode = *outgoing;
251  EdgeVector::const_iterator i;
252  if (incnode != outnode) {
253  // the links are located at different nodes
254  const EdgeVector& ev1 = possProhibitedTo->getConnectedEdges();
255  // go through the following edge,
256  // check whether one of these connections is prohibited
257  for (i = ev1.begin(); i != ev1.end(); ++i) {
258  std::vector<NBNode*>::const_iterator outgoing2 =
260  if (outgoing2 == myControlledNodes.end()) {
261  continue;
262  }
263  NBNode* outnode2 = *outgoing2;
264  if (incnode != outnode2) {
265  continue;
266  }
267  bool ret1 = incnode->foes(possProhibitorTo, *i,
268  possProhibitedFrom, possProhibitedTo);
269  bool ret2 = incnode->forbids(possProhibitorFrom, possProhibitorTo,
270  possProhibitedTo, *i,
271  regardNonSignalisedLowerPriority);
272  bool ret = ret1 || ret2;
273  if (ret) {
274  return true;
275  }
276  }
277 
278  const EdgeVector& ev2 = possProhibitorTo->getConnectedEdges();
279  // go through the following edge,
280  // check whether one of these connections is prohibited
281  for (i = ev2.begin(); i != ev2.end(); ++i) {
282  std::vector<NBNode*>::const_iterator incoming2 =
283  find_if(myControlledNodes.begin(), myControlledNodes.end(), NBContHelper::node_with_incoming_finder(possProhibitorTo));
284  if (incoming2 == myControlledNodes.end()) {
285  continue;
286  }
287  NBNode* incnode2 = *incoming2;
288  if (incnode2 != outnode) {
289  continue;
290  }
291  bool ret1 = incnode2->foes(possProhibitorTo, *i,
292  possProhibitedFrom, possProhibitedTo);
293  bool ret2 = incnode2->forbids(possProhibitorTo, *i,
294  possProhibitedFrom, possProhibitedTo,
295  regardNonSignalisedLowerPriority);
296  bool ret = ret1 || ret2;
297  if (ret) {
298  return true;
299  }
300  }
301  return false;
302  }
303  // both links are located at the same node
304  // check using this node's information
305  return incnode->forbids(possProhibitorFrom, possProhibitorTo,
306  possProhibitedFrom, possProhibitedTo,
307  regardNonSignalisedLowerPriority);
308 }
309 
310 
311 bool
312 NBTrafficLightDefinition::foes(const NBEdge* const from1, const NBEdge* const to1,
313  const NBEdge* const from2, const NBEdge* const to2) const {
314  if (to1 == 0 || to2 == 0) {
315  return false;
316  }
317  // retrieve both nodes (it is possible that a connection
318  std::vector<NBNode*>::const_iterator incoming =
319  find_if(myControlledNodes.begin(), myControlledNodes.end(),
321  std::vector<NBNode*>::const_iterator outgoing =
322  find_if(myControlledNodes.begin(), myControlledNodes.end(),
324  assert(incoming != myControlledNodes.end());
325  NBNode* incnode = *incoming;
326  NBNode* outnode = *outgoing;
327  if (incnode != outnode) {
328  return false;
329  }
330  return incnode->foes(from1, to1, from2, to2);
331 }
332 
333 
334 void
336  if (std::find(myControlledNodes.begin(), myControlledNodes.end(), node) == myControlledNodes.end()) {
337  myControlledNodes.push_back(node);
339  node->addTrafficLight(this);
340  }
341 }
342 
343 
344 void
346  std::vector<NBNode*>::iterator i = std::find(myControlledNodes.begin(), myControlledNodes.end(), node);
347  if (i != myControlledNodes.end()) {
348  myControlledNodes.erase(i);
349  }
350  // !!! remove in node?
351 }
352 
353 
354 void
355 NBTrafficLightDefinition::addControlledInnerEdges(const std::vector<std::string>& edges) {
356  myControlledInnerEdges.insert(edges.begin(), edges.end());
357 }
358 
359 
360 std::vector<std::string>
362  return std::vector<std::string>(myControlledInnerEdges.begin(), myControlledInnerEdges.end());
363 }
364 
365 
366 const EdgeVector&
368  return myIncomingEdges;
369 }
370 
371 
372 void
374  myControlledLinks.clear();
375  // build the list of links which are controled by the traffic light
376  for (EdgeVector::iterator i = myIncomingEdges.begin(); i != myIncomingEdges.end(); i++) {
377  NBEdge* incoming = *i;
378  unsigned int noLanes = incoming->getNumLanes();
379  for (unsigned int j = 0; j < noLanes; j++) {
380  std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j);
381  for (std::vector<NBEdge::Connection>::iterator k = connected.begin(); k != connected.end(); k++) {
382  const NBEdge::Connection& el = *k;
383  if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) {
384  if (el.toEdge != 0 && el.toLane >= (int) el.toEdge->getNumLanes()) {
385  throw ProcessError("Connection '" + incoming->getID() + "_" + toString(j) + "->" + el.toEdge->getID() + "_" + toString(el.toLane) + "' yields in a not existing lane.");
386  }
387  int tlIndex = (int)myControlledLinks.size();
388  myControlledLinks.push_back(NBConnection(incoming, el.fromLane, el.toEdge, el.toLane, tlIndex));
389  }
390  }
391  }
392  }
393 }
394 
395 /****************************************************************************/
396 
virtual void setParticipantsInformation()
Builds the list of participating nodes/edges/links.
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:148
int toLane
The lane the connections yields in.
Definition: NBEdge.h:166
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
void collectAllLinks()
helper method for use in NBOwnTLDef and NBLoadedSUMOTLDef
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:164
std::vector< std::string > getControlledInnerEdges() const
Retrieve the ids of edges explicitly controlled by the tls.
A SUMO-compliant built logic for a traffic light.
EdgeVector myIncomingEdges
The list of incoming edges.
virtual ~NBTrafficLightDefinition()
Destructor.
The representation of a single edge during network building.
Definition: NBEdge.h:71
bool mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const
Definition: NBEdge.cpp:1725
bool mustBrake(const NBEdge *const from, const NBEdge *const to, int toLane) const
Returns the information whether the described flow must let any other flow pass.
Definition: NBNode.cpp:1101
Used for sorting the cells by the begin time they describe.
Definition: NBNode.h:594
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
const std::map< std::string, std::string > & getMap() const
Returns the inner key/value map.
const EdgeVector & getIncomingEdges() const
Returns the list of incoming edges (must be build first)
std::vector< Connection > getConnectionsFromLane(unsigned int lane) const
Returns connections from a given lane.
Definition: NBEdge.cpp:726
NBEdge * getFrom() const
returns the from-edge (start of the connection)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
virtual void collectLinks()=0
Collects the links participating in this traffic light If a link could not be found.
EdgeVector getConnectedEdges() const
Returns the list of outgoing edges unsorted.
Definition: NBEdge.cpp:785
const std::string & getID() const
Returns the id.
Definition: Named.h:60
void collectEdges()
Build the list of participating edges.
std::set< std::string > myControlledInnerEdges
Set of inner edges that shall be controlled, though.
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:162
NBTrafficLightLogic * compute(const NBEdgeCont &ec, OptionsCont &oc)
Computes the traffic light logic.
static SUMOReal maxSpeed(const EdgeVector &ev)
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:344
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
static const std::string DefaultProgramID
unsigned int computeBrakingTime(SUMOReal minDecel) const
Computes the time vehicles may need to brake.
void addControlledInnerEdges(const std::vector< std::string > &edges)
Adds the given ids into the list of inner edges controlled by the tls.
bool mustBrake(const NBEdge *const from, const NBEdge *const to) const
Returns the information whether the described flow must let any other flow pass.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
virtual void removeNode(NBNode *node)
Removes the given node from the list of controlled nodes.
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
Computes whether the given connection is a left mover across the junction.
Definition: NBNode.cpp:1130
Base class for objects which have an id.
Definition: Named.h:45
void addParameter(const std::string &key, const std::string &value)
Adds a parameter.
void addTrafficLight(NBTrafficLightDefinition *tlDef)
Adds a traffic light to the list of traffic lights that control this node.
Definition: NBNode.cpp:289
std::vector< NBEdge * > EdgeVector
Definition: NBCont.h:38
A storage for options typed value containers)
Definition: OptionsCont.h:108
NBEdge * getTo() const
returns the to-edge (end of the connection)
Represents a single node (junction) during network building.
Definition: NBNode.h:75
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
virtual NBTrafficLightLogic * myCompute(const NBEdgeCont &ec, unsigned int brakingTime)=0
Computes the traffic light logic finally in dependence to the type.
#define SUMOReal
Definition: config.h:215
bool isLeftMover(const NBEdge *const from, const NBEdge *const to) const
returns the information whether the given link is a left-mover
std::vector< NBNode * > myControlledNodes
The container with participating nodes.
NBTrafficLightDefinition(const std::string &id, const std::vector< NBNode * > &junctions, const std::string &programID, SUMOTime offset, TrafficLightType type)
Constructor.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.
Definition: NBNode.cpp:1159
NBConnectionVector myControlledLinks
The list of controlled links.
EdgeVector myEdgesWithin
The list of edges within the area controlled by the tls.
TrafficLightType
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
bool forbids(const NBEdge *const possProhibitorFrom, const NBEdge *const possProhibitorTo, const NBEdge *const possProhibitedFrom, const NBEdge *const possProhibitedTo, bool regardNonSignalisedLowerPriority) const
Returns the information whether "prohibited" flow must let "prohibitor" flow pass.
Definition: NBNode.cpp:1149
bool foes(const NBEdge *const from1, const NBEdge *const to1, const NBEdge *const from2, const NBEdge *const to2) const
Returns the information whether the given flows cross.