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-2013 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 "MSNet.h"
35 #include "MSLink.h"
36 #include "MSLane.h"
37 #include "MSGlobals.h"
38 #include "MSVehicle.h"
39 
40 #ifdef CHECK_MEMORY_LEAKS
41 #include <foreign/nvwa/debug_new.h>
42 #endif // CHECK_MEMORY_LEAKS
43 
44 
45 // ===========================================================================
46 // static member variables
47 // ===========================================================================
49 
50 
51 // ===========================================================================
52 // member method definitions
53 // ===========================================================================
54 #ifndef HAVE_INTERNAL_LANES
56  LinkDirection dir, LinkState state,
57  SUMOReal length)
58  :
59  myLane(succLane),
60  myRequestIdx(0), myRespondIdx(0),
61  myState(state), myDirection(dir), myLength(length) {}
62 #else
63 MSLink::MSLink(MSLane* succLane, MSLane* via,
64  LinkDirection dir, LinkState state, SUMOReal length)
65  :
66  myLane(succLane),
67  myRequestIdx(0), myRespondIdx(0),
68  myState(state), myDirection(dir), myLength(length),
69  myJunctionInlane(via) {}
70 #endif
71 
72 
74 
75 
76 void
77 MSLink::setRequestInformation(unsigned int requestIdx, unsigned int respondIdx, bool isCrossing, bool isCont,
78  const std::vector<MSLink*>& foeLinks,
79  const std::vector<MSLane*>& foeLanes) {
80  myRequestIdx = requestIdx;
81  myRespondIdx = respondIdx;
83  myAmCont = isCont;
84  myFoeLinks = foeLinks;
85  myFoeLanes = foeLanes;
86 }
87 
88 
89 void
90 MSLink::setApproaching(SUMOVehicle* approaching, SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, bool setRequest) {
91  removeApproaching(approaching);
92  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, approaching->getVehicleType().getLengthWithGap());
93  ApproachingVehicleInformation approachInfo(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, approaching, setRequest);
94  myApproachingVehicles.push_back(approachInfo);
95 }
96 
97 
98 void
100  myBlockedFoeLinks.insert(link);
101 }
102 
103 
104 
105 bool
107  for (std::set<MSLink*>::const_iterator i = myBlockedFoeLinks.begin(); i != myBlockedFoeLinks.end(); ++i) {
108  if ((*i)->isBlockingAnyone()) {
109  return true;
110  }
111  }
112  return false;
113 }
114 
115 
116 void
118  LinkApproachingVehicles::iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), vehicle_in_request_finder(veh));
119  if (i != myApproachingVehicles.end()) {
120  myApproachingVehicles.erase(i);
121  }
122 }
123 
124 
127  LinkApproachingVehicles::const_iterator i = find_if(myApproachingVehicles.begin(), myApproachingVehicles.end(), vehicle_in_request_finder(veh));
128  if (i != myApproachingVehicles.end()) {
129  return *i;
130  } else {
131  return ApproachingVehicleInformation(-1000, -1000, 0, 0, 0, false);
132  }
133 }
134 
135 
136 SUMOTime
137 MSLink::getLeaveTime(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength) const {
138  return arrivalTime + TIME2STEPS((getLength() + vehicleLength) / (0.5 * (arrivalSpeed + leaveSpeed)));
139 }
140 
141 
142 bool
143 MSLink::opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength) const {
144  if (myState == LINKSTATE_TL_RED) {
145  return false;
146  }
148  return true;
149  }
150  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, vehicleLength);
151  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
152 #ifdef HAVE_INTERNAL
154  if ((*i)->getState() == LINKSTATE_TL_RED) {
155  continue;
156  }
157  }
158 #endif
159  if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, myLane == (*i)->getLane())) {
160  return false;
161  }
162  }
163  return true;
164 }
165 
166 
167 bool
168 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed,
169  bool sameTargetLane) const {
170  for (LinkApproachingVehicles::const_iterator i = myApproachingVehicles.begin(); i != myApproachingVehicles.end(); ++i) {
171  if (!(*i).willPass) {
172  continue;
173  }
174  if ((*i).leavingTime < arrivalTime) {
175  // ego wants to be follower
176  if (sameTargetLane && unsafeHeadwayTime(arrivalTime - (*i).leavingTime, (*i).leaveSpeed, arrivalSpeed)) {
177  return true;
178  }
179  } else if ((*i).arrivalTime > leaveTime) {
180  // ego wants to be leader
181  if (sameTargetLane && unsafeHeadwayTime((*i).arrivalTime - leaveTime, leaveSpeed, (*i).arrivalSpeed)) {
182  return true;
183  }
184  } else {
185  // even without considering safeHeadwayTime there is already a conflict
186  return true;
187  }
188  }
189  return false;
190 }
191 
192 
193 SUMOTime
194 MSLink::unsafeHeadwayTime(SUMOTime headwayTime, SUMOReal leaderSpeed, SUMOReal followerSpeed) {
195  if (headwayTime < myLookaheadTime) {
196  return true;
197  }
198  // headwayTime is the expected time difference between the leaders rear and the followers front + safeGap
199  if (leaderSpeed < DEFAULT_VEH_DECEL) {
200  // leader may break in one timestep
201  leaderSpeed = 0;
202  }
203  // this formula is conservative since the headway time increases as soon as
204  // the follower starts to break
205  // on the other hand, vehicles turning onto a higher-priority road usually
206  // don't want to make other people break
207  return ((followerSpeed - leaderSpeed) / DEFAULT_VEH_DECEL) > STEPS2TIME(headwayTime);
208 }
209 
210 
211 bool
213  MSVehicle* veh = lane->getLastVehicle();
214  SUMOReal distLeft = 0;
215  if (veh == 0) {
216  veh = lane->getPartialOccupator();
217  distLeft = lane->getLength() - lane->getPartialOccupatorEnd();
218  } else {
219  distLeft = lane->getLength() - veh->getPositionOnLane() + veh->getVehicleType().getLength();
220  }
221  if (veh == 0) {
222  return false;
223  } else {
224  assert(distLeft > 0);
225  // can we be sure that the vehicle leaves this lane in the next step?
226  bool result = distLeft > (veh->getSpeed() - veh->getCarFollowModel().getMaxDecel());
227  return result;
228  }
229 }
230 
231 
232 bool
233 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed) const {
234  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
235  if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed, myLane == (*i)->getLane())) {
236  return true;
237  }
238  }
239  for (std::vector<MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
240  if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
241  return true;
242  }
243  }
244  return false;
245 }
246 
247 
250  return myDirection;
251 }
252 
253 
254 void
256  myState = state;
257 }
258 
259 
260 MSLane*
262  return myLane;
263 }
264 
265 
266 #ifdef HAVE_INTERNAL_LANES
267 MSLane*
268 MSLink::getViaLane() const {
269  return myJunctionInlane;
270 }
271 
272 
273 std::pair<MSVehicle*, SUMOReal>
274 MSLink::getLeaderInfo(const std::map<const MSLink*, std::string>& previousLeaders, SUMOReal dist) const {
275  if (MSGlobals::gUsingInternalLanes && myJunctionInlane == 0) {
276  // this is an exit link
277 
278  // there might have been a link leader from previous steps who still qualifies
279  // but is not the last vehicle on the foe lane anymore
280  std::map<const MSLink*, std::string>::const_iterator it = previousLeaders.find(this);
281  if (it != previousLeaders.end()) {
282  MSVehicle* leader = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(it->second));
283  if (leader != 0 && std::find(myFoeLanes.begin(), myFoeLanes.end(), leader->getLane()) != myFoeLanes.end()) {
284  return std::make_pair(leader,
285  dist - (leader->getLane()->getLength() - leader->getPositionOnLane()) - leader->getVehicleType().getLength());
286  }
287  }
288  // now check for last vehicle on foe lane
289  for (std::vector<MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
290  assert((*i)->getLinkCont().size() == 1);
291  MSLink* exitLink = (*i)->getLinkCont()[0];
292  if (myLane == exitLink->getLane()) {
293  MSVehicle* leader = (*i)->getLastVehicle();
294  if (leader != 0) {
295  return std::make_pair(leader,
296  dist - ((*i)->getLength() - leader->getPositionOnLane()) - leader->getVehicleType().getLength());
297  }
298  }
299  }
300  }
301  return std::make_pair<MSVehicle*, SUMOReal>(0, 0);
302 }
303 #endif
304 
305 
306 MSLane*
308 #ifdef HAVE_INTERNAL_LANES
309  if (myJunctionInlane != 0) {
310  return myJunctionInlane;
311  } else {
312  return myLane;
313  }
314 #else
315  return myLane;
316 #endif
317 }
318 
319 
320 unsigned int
322  return myRespondIdx;
323 }
324 
325 
326 
327 /****************************************************************************/
328