SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSLink.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A connnection between lanes
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2012 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 <iostream>
34 #include "MSLink.h"
35 #include "MSLane.h"
36 #include "MSGlobals.h"
37 #include "MSVehicle.h"
38 
39 #ifdef CHECK_MEMORY_LEAKS
40 #include <foreign/nvwa/debug_new.h>
41 #endif // CHECK_MEMORY_LEAKS
42 
43 
44 // ===========================================================================
45 // static member variables
46 // ===========================================================================
48 
49 
50 // ===========================================================================
51 // member method definitions
52 // ===========================================================================
53 #ifndef HAVE_INTERNAL_LANES
55  LinkDirection dir, LinkState state,
56  SUMOReal length)
57  :
58  myLane(succLane),
59  myRequestIdx(0), myRespondIdx(0),
60  myState(state), myDirection(dir), myLength(length) {}
61 #else
62 MSLink::MSLink(MSLane* succLane, MSLane* via,
63  LinkDirection dir, LinkState state, SUMOReal length)
64  :
65  myLane(succLane),
66  myRequestIdx(0), myRespondIdx(0),
67  myState(state), myDirection(dir), myLength(length),
68  myJunctionInlane(via) {}
69 #endif
70 
71 
73 
74 
75 void
76 MSLink::setRequestInformation(unsigned int requestIdx, unsigned int respondIdx, bool isCrossing, bool isCont,
77  const std::vector<MSLink*>& foeLinks,
78  const std::vector<MSLane*>& foeLanes) {
79  myRequestIdx = requestIdx;
80  myRespondIdx = respondIdx;
82  myAmCont = isCont;
83  myFoeLinks = foeLinks;
84  myFoeLanes = foeLanes;
85 }
86 
87 
88 void
89 MSLink::setApproaching(SUMOVehicle* approaching, SUMOTime arrivalTime, SUMOReal speed, bool setRequest) {
90  LinkApproachingVehicles::iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), vehicle_in_request_finder(approaching));
91  if (i != myApproachingVehicles.end()) {
92  myApproachingVehicles.erase(i);
93  }
94  const SUMOTime leaveTime = arrivalTime + TIME2STEPS((approaching->getVehicleType().getLengthWithGap() + getLength()) / speed);
95  ApproachingVehicleInformation approachInfo(arrivalTime, leaveTime, approaching, setRequest);
96  myApproachingVehicles.push_back(approachInfo);
97 }
98 
99 
100 void
102  myBlockedFoeLinks.insert(link);
103 }
104 
105 
106 
107 bool
109  for (std::set<MSLink*>::const_iterator i = myBlockedFoeLinks.begin(); i != myBlockedFoeLinks.end(); ++i) {
110  if ((*i)->isBlockingAnyone()) {
111  return true;
112  }
113  }
114  return false;
115 }
116 
117 
118 void
120  LinkApproachingVehicles::iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), vehicle_in_request_finder(veh));
121  if (i != myApproachingVehicles.end()) {
122  myApproachingVehicles.erase(i);
123  }
124 }
125 
126 
127 bool
128 MSLink::opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength) const {
129  if (myState == LINKSTATE_TL_RED) {
130  return false;
131  }
132  if (myAmCont) {
133  return true;
134  }
135  const SUMOTime leaveTime = arrivalTime + TIME2STEPS((getLength() + vehicleLength) / (0.5 * (arrivalSpeed + leaveSpeed)));
136  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
137 #ifdef HAVE_INTERNAL
139  if ((*i)->getState() == LINKSTATE_TL_RED) {
140  continue;
141  }
142  }
143 #endif
144  if ((*i)->blockedAtTime(arrivalTime, leaveTime, leaveSpeed)) {
145  return false;
146  }
147  }
148  for (std::vector<MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
149  if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
150  return false;
151  }
152  }
153  return true;
154 }
155 
156 
157 bool
158 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed) const {
159  for (LinkApproachingVehicles::const_iterator i = myApproachingVehicles.begin(); i != myApproachingVehicles.end(); ++i) {
160  if (!(*i).willPass) {
161  continue;
162  }
163  if ((*i).leavingTime < arrivalTime) {
164  // ego wants to be follower
165  if ((*i).leavingTime + safeHeadwayTime(i->vehicle->getSpeed(), speed) >= arrivalTime) {
166  return true;
167  }
168  } else if ((*i).arrivalTime > leaveTime) {
169  // ego wants to be leader
170  if ((*i).arrivalTime - safeHeadwayTime(speed, i->vehicle->getSpeed()) <= leaveTime) {
171  return true;
172  }
173  } else {
174  // even without considering safeHeadwayTime there is already a conflict
175  return true;
176  }
177  }
178  return false;
179 }
180 
181 
182 SUMOTime
183 MSLink::safeHeadwayTime(SUMOReal leaderSpeed, SUMOReal followerSpeed) {
184  // v: leader speed
185  // u: follower speed
186  // a: leader decel
187  // b: follower decel
188  // g: follower min gap
189  // h: save headway time (result)
190  const SUMOReal v = leaderSpeed;
191  const SUMOReal u = followerSpeed;
192  // XXX use cfmodel values of possible
193  const SUMOReal a = DEFAULT_VEH_DECEL;
194  const SUMOReal b = DEFAULT_VEH_DECEL;
195  const SUMOReal g = DEFAULT_VEH_MINGAP;
196  // breaking distance ~ (v^2 - a*v)/(2*a)
197  if (v < a) {
198  // leader may break in one timestep (need different formula)
199  // u*h > g + (u^2 - b*u)/(2*b) + 0.5
200  return TIME2STEPS((g + 0.5) / u + (u / b - 1.0) * 0.5);
201  } else {
202  // u*h + (v^2 - a*v)/(2*a) > g + (u^2 - b*u)/(2*b) + 0.5
203  return TIME2STEPS((g + (1.0 + v - v * v / a) * 0.5) / u + (u / b - 1.0) * 0.5);
204  }
205 }
206 
207 
208 bool
209 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed) const {
210  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
211  if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed)) {
212  return true;
213  }
214  }
215  for (std::vector<MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
216  if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
217  return true;
218  }
219  }
220  return false;
221 }
222 
223 
226  return myDirection;
227 }
228 
229 
230 void
232  myState = state;
233 }
234 
235 
236 MSLane*
238  return myLane;
239 }
240 
241 
242 #ifdef HAVE_INTERNAL_LANES
243 MSLane*
244 MSLink::getViaLane() const {
245  return myJunctionInlane;
246 }
247 #endif
248 
249 
250 MSLane*
252 #ifdef HAVE_INTERNAL_LANES
253  if (myJunctionInlane != 0) {
254  return myJunctionInlane;
255  } else {
256  return myLane;
257  }
258 #else
259  return myLane;
260 #endif
261 }
262 
263 
264 unsigned int
266  return myRespondIdx;
267 }
268 
269 
270 
271 /****************************************************************************/
272