SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NBLoadedSUMOTLDef.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A complete traffic light logic loaded from a sumo-net. (opted to reimplement
10 // since NBLoadedTLDef is quite vissim specific)
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2011-2014 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 // 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 <set>
35 #include <cassert>
36 #include <iterator>
38 #include <utils/common/ToString.h>
40 #include "NBTrafficLightLogic.h"
41 #include "NBOwnTLDef.h"
43 #include "NBLoadedSUMOTLDef.h"
44 #include "NBNode.h"
45 
46 #ifdef CHECK_MEMORY_LEAKS
47 #include <foreign/nvwa/debug_new.h>
48 #endif // CHECK_MEMORY_LEAKS
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 
54 NBLoadedSUMOTLDef::NBLoadedSUMOTLDef(const std::string& id, const std::string& programID,
55  SUMOTime offset, TrafficLightType type) :
56  NBTrafficLightDefinition(id, programID, offset, type),
57  myTLLogic(0) {
58  myTLLogic = new NBTrafficLightLogic(id, programID, 0, offset, type);
59 }
60 
61 
63  NBTrafficLightDefinition(def->getID(), def->getProgramID(), def->getOffset(), def->getType()),
64  myTLLogic(new NBTrafficLightLogic(logic)),
65  myOriginalNodes(def->getNodes().begin(), def->getNodes().end()) {
66  assert(def->getOffset() == logic->getOffset());
67  assert(def->getType() == logic->getType());
69 }
70 
71 
73  delete myTLLogic;
74 }
75 
76 
78 NBLoadedSUMOTLDef::myCompute(const NBEdgeCont& ec, unsigned int brakingTime) {
79  // @todo what to do with those parameters?
80  UNUSED_PARAMETER(ec);
81  UNUSED_PARAMETER(brakingTime);
84  return new NBTrafficLightLogic(myTLLogic);
85 }
86 
87 
88 void
89 NBLoadedSUMOTLDef::addConnection(NBEdge* from, NBEdge* to, int fromLane, int toLane, int linkIndex) {
90  assert(myTLLogic->getNumLinks() > 0); // logic should be loaded by now
91  if (linkIndex >= (int)myTLLogic->getNumLinks()) {
92  WRITE_ERROR("Invalid linkIndex " + toString(linkIndex) + " for traffic light '" + getID() +
93  "' with " + toString(myTLLogic->getNumLinks()) + " links.");
94  return;
95  }
96  NBConnection conn(from, fromLane, to, toLane, linkIndex);
97  // avoid duplicates
98  remove_if(myControlledLinks.begin(), myControlledLinks.end(), connection_equal(conn));
99  myControlledLinks.push_back(conn);
100  addNode(from->getToNode());
101  addNode(to->getFromNode());
102  myOriginalNodes.insert(from->getToNode());
103  myOriginalNodes.insert(to->getFromNode());
104  // added connections are definitely controlled. make sure none are removed because they lie within the tl
105  // myControlledInnerEdges.insert(from->getID()); // @todo recheck: this appears to be obsolete
106  // set this information now so that it can be used while loading diffs
107  from->setControllingTLInformation(conn, getID());
108 }
109 
110 
111 void
114 }
115 
116 
117 void
119  // if nodes have been removed our links may have been invalidated as well
120  // since no logic will be built anyway there is no reason to inform any edges
121  if (amInvalid()) {
122  return;
123  }
124  // set the information about the link's positions within the tl into the
125  // edges the links are starting at, respectively
126  for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
127  const NBConnection& c = *it;
128  assert(c.getTLIndex() < (int)myTLLogic->getNumLinks());
129  NBEdge* edge = c.getFrom();
131  }
132 }
133 
134 
135 void
137 
138 
139 void
141 
142 
143 void
144 NBLoadedSUMOTLDef::addPhase(SUMOTime duration, const std::string& state) {
145  myTLLogic->addStep(duration, state);
146 }
147 
148 
149 bool
151  if (myControlledLinks.size() == 0) {
152  return true;
153  }
154  // make sure that myControlledNodes are the original nodes
155  if (myControlledNodes.size() != myOriginalNodes.size()) {
156  return true;
157  }
158  for (std::vector<NBNode*>::const_iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
159  if (myOriginalNodes.count(*i) != 1) {
160  return true;
161  }
162  }
163  return false;
164 }
165 
166 
167 void
168 NBLoadedSUMOTLDef::removeConnection(const NBConnection& conn, bool reconstruct) {
169  NBConnectionVector::iterator it = myControlledLinks.begin();
170  // find the connection but ignore its TLIndex since it might have been
171  // invalidated by an earlier removal
172  for (; it != myControlledLinks.end(); ++it) {
173  if (it->getFrom() == conn.getFrom() &&
174  it->getTo() == conn.getTo() &&
175  it->getFromLane() == conn.getFromLane() &&
176  it->getToLane() == conn.getToLane()) {
177  break;
178  }
179  }
180  if (it == myControlledLinks.end()) {
181  // a traffic light doesn't always controll all connections at a junction
182  // especially when using the option --tls.join
183  return;
184  }
185  const int removed = it->getTLIndex();
186  // remove the connection
187  myControlledLinks.erase(it);
188  if (reconstruct) {
189  // updating the edge is only needed for immediate use in NETEDIT.
190  // It may conflict with loading diffs
191  conn.getFrom()->setControllingTLInformation(conn, "");
192  // shift link numbers down so there is no gap
193  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
194  NBConnection& c = *it;
195  if (c.getTLIndex() > removed) {
196  c.setTLIndex(c.getTLIndex() - 1);
197  }
198  }
199  // update controlling information with new link numbers
201  // rebuild the logic
202  const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases();
204  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
205  std::string newState = it->state;
206  newState.erase(newState.begin() + removed);
207  newLogic->addStep(it->duration, newState);
208  }
209  delete myTLLogic;
210  myTLLogic = newLogic;
211  }
212 }
213 
214 
215 void
217  myOffset = offset;
218  myTLLogic->setOffset(offset);
219 }
220 
221 
222 void
224  if (myControlledLinks.size() == 0) {
225  // maybe we only loaded a different program for a default traffic light.
226  // Try to build links now.
227  myOriginalNodes.insert(myControlledNodes.begin(), myControlledNodes.end());
228  collectAllLinks();
229  }
230 }
231 
232 
234 void
236  // avoid shifting twice if the edge is incoming and outgoing to a joined TLS
237  if (myShifted.count(edge) == 0) {
239  myShifted.insert(edge);
240  for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
241  (*it).shiftLaneIndex(edge, offset);
242  }
243  }
244 }
245 
246 void
248  // XXX what to do if crossings are removed during network building?
249  const unsigned int size = myTLLogic->getNumLinks();
250  unsigned int noLinksAll = size;
251  // collect crossings
252  std::vector<NBNode::Crossing> crossings;
253  for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) {
254  const std::vector<NBNode::Crossing>& c = (*i)->getCrossings();
255  // set tl indices for crossings
256  (*i)->setCrossingTLIndices(noLinksAll);
257  copy(c.begin(), c.end(), std::back_inserter(crossings));
258  noLinksAll += (unsigned int)c.size();
259  }
260  if (crossings.size() > 0) {
261  // collect edges
262  assert(size > 0);
263  EdgeVector fromEdges(size, 0);
264  EdgeVector toEdges(size, 0);
265  for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) {
266  const NBConnection& c = *it;
268  assert(c.getTLIndex() < (int)size);
269  fromEdges[c.getTLIndex()] = c.getFrom();
270  toEdges[c.getTLIndex()] = c.getTo();
271  }
272  }
274  const std::string crossingDefaultState(crossings.size(), 'r');
275 
276  // rebuild the logic (see NBOwnTLDef.cpp::myCompute)
277  const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases();
279  //std::cout << "patchIfCrossingsAdded for " << getID() << " numPhases=" << phases.size() << "\n";
280  for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) {
281  NBOwnTLDef::addPedestrianPhases(newLogic, it->duration, it->state + crossingDefaultState, crossings, fromEdges, toEdges);
282  }
283  delete myTLLogic;
284  myTLLogic = newLogic;
285  }
286 }
287 
288 
289 /****************************************************************************/
290