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.dlr.de/
13 // Copyright (C) 2001-2015 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 <algorithm>
35 #include <limits>
37 #include "MSNet.h"
38 #include "MSLink.h"
39 #include "MSLane.h"
41 #include "MSEdge.h"
42 #include "MSGlobals.h"
43 #include "MSVehicle.h"
45 
46 #ifdef CHECK_MEMORY_LEAKS
47 #include <foreign/nvwa/debug_new.h>
48 #endif // CHECK_MEMORY_LEAKS
49 
50 //#define MSLink_DEBUG_CROSSING_POINTS
51 
52 // ===========================================================================
53 // static member variables
54 // ===========================================================================
56 
57 
58 // ===========================================================================
59 // member method definitions
60 // ===========================================================================
61 #ifndef HAVE_INTERNAL_LANES
62 MSLink::MSLink(MSLane* succLane, LinkDirection dir, LinkState state, SUMOReal length, bool keepClear) :
63  myLane(succLane),
64  myIndex(-1),
65  myState(state),
66  myLastStateChange(-1),
67  myDirection(dir),
68  myLength(length),
69  myHasFoes(false),
70  myAmCont(false),
71  myKeepClear(keepClear),
72  myJunction(0)
73 #else
74 MSLink::MSLink(MSLane* succLane, MSLane* via, LinkDirection dir, LinkState state, SUMOReal length, bool keepClear) :
75  myLane(succLane),
76  myIndex(-1),
77  myState(state),
78  myLastStateChange(-1),
79  myDirection(dir),
80  myLength(length),
81  myHasFoes(false),
82  myAmCont(false),
83  myKeepClear(keepClear),
84  myJunctionInlane(via),
85  myInternalLaneBefore(0),
86  myJunction(0)
87 #endif
88 {}
89 
90 
92 
93 
94 void
95 MSLink::setRequestInformation(int index, bool hasFoes, bool isCont,
96  const std::vector<MSLink*>& foeLinks,
97  const std::vector<MSLane*>& foeLanes,
98  MSLane* internalLaneBefore) {
99  myIndex = index;
100  myHasFoes = hasFoes;
101  myAmCont = isCont;
102  myFoeLinks = foeLinks;
103  for (std::vector<MSLane*>::const_iterator it_lane = foeLanes.begin(); it_lane != foeLanes.end(); ++it_lane) {
104  // cannot assign vector due to const-ness
105  myFoeLanes.push_back(*it_lane);
106  }
107  myJunction = myLane->getEdge().getFromJunction(); // junctionGraph is initialized after the whole network is loaded
108 #ifdef HAVE_INTERNAL_LANES
109  myInternalLaneBefore = internalLaneBefore;
110  MSLane* lane = 0;
111  if (internalLaneBefore != 0) {
112  // this is an exit link. compute crossing points with all foeLanes
113  lane = internalLaneBefore;
114  //} else if (myLane->getEdge().isCrossing()) {
115  // // this is the link to a pedestrian crossing. compute crossing points with all foeLanes
116  // // @note not currently used by pedestrians
117  // lane = myLane;
118  }
119 #ifdef MSLink_DEBUG_CROSSING_POINTS
120  std::cout << " link " << myIndex << " to " << getViaLaneOrLane()->getID() << " internalLane=" << (lane == 0 ? "NULL" : lane->getID()) << " has foes: " << toString(foeLanes) << "\n";
121 #endif
122  if (lane != 0) {
123  const bool beforeInternalJunction = lane->getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal();
124  assert(lane->getIncomingLanes().size() == 1);
125  // compute crossing points
126  for (std::vector<const MSLane*>::const_iterator it_lane = myFoeLanes.begin(); it_lane != myFoeLanes.end(); ++it_lane) {
127  const bool sameTarget = myLane == (*it_lane)->getLinkCont()[0]->getLane();
128  if (sameTarget && !beforeInternalJunction) {
129  //if (myLane == (*it_lane)->getLinkCont()[0]->getLane()) {
130  // this foeLane has the same target and merges at the end (lane exits the junction)
131  myLengthsBehindCrossing.push_back(std::make_pair(0, 0)); // dummy value, never used
132 #ifdef MSLink_DEBUG_CROSSING_POINTS
133  std::cout
134  << " " << lane->getID()
135  << " merges with " << (*it_lane)->getID()
136  << " nextLane " << lane->getLinkCont()[0]->getViaLaneOrLane()->getID()
137  << " dist1=" << myLengthsBehindCrossing.back().first
138  << " dist2=" << myLengthsBehindCrossing.back().second
139  << "\n";
140 #endif
141  } else {
142  std::vector<SUMOReal> intersections1 = lane->getShape().intersectsAtLengths2D((*it_lane)->getShape());
143 #ifdef MSLink_DEBUG_CROSSING_POINTS
144  //std::cout << " intersections1=" << toString(intersections1) << "\n";
145 #endif
146  bool haveIntersection = true;
147  if (intersections1.size() == 0) {
148  intersections1.push_back(-10000.0); // disregard this foe (using maxdouble leads to nasty problems down the line)
149  haveIntersection = false;
150  } else if (intersections1.size() > 1) {
151  std::sort(intersections1.begin(), intersections1.end());
152  }
153  std::vector<SUMOReal> intersections2 = (*it_lane)->getShape().intersectsAtLengths2D(lane->getShape());
154 #ifdef MSLink_DEBUG_CROSSING_POINTS
155  //std::cout << " intersections2=" << toString(intersections2) << "\n";
156 #endif
157  if (intersections2.size() == 0) {
158  intersections2.push_back(0);
159  } else if (intersections2.size() > 1) {
160  std::sort(intersections2.begin(), intersections2.end());
161  }
162  if (haveIntersection) {
163  // lane width affects the crossing point
164  intersections1.back() -= (*it_lane)->getWidth() / 2;
165  intersections2.back() -= lane->getWidth() / 2;
166  // also length/geometry factor
167  intersections1.back() = lane->interpolateGeometryPosToLanePos(intersections1.back());
168  intersections2.back() = (*it_lane)->interpolateGeometryPosToLanePos(intersections2.back());
169 
170  if (internalLaneBefore->getLogicalPredecessorLane()->getEdge().isInternal() && !(*it_lane)->getEdge().isCrossing()) {
171  // wait at the internal junction
172  // (except for foes that are crossings since there is no internal junction)
173  intersections1.back() = 0;
174  }
175  }
176 
177  myLengthsBehindCrossing.push_back(std::make_pair(
178  lane->getLength() - intersections1.back(),
179  (*it_lane)->getLength() - intersections2.back()));
180 
181 #ifdef MSLink_DEBUG_CROSSING_POINTS
182  std::cout
183  << " intersection of " << lane->getID()
184  << " totalLength=" << lane->getLength()
185  << " with " << (*it_lane)->getID()
186  << " totalLength=" << (*it_lane)->getLength()
187  << " dist1=" << myLengthsBehindCrossing.back().first
188  << " dist2=" << myLengthsBehindCrossing.back().second
189  << "\n";
190 #endif
191  }
192  }
193  // check for overlap with internal lanes from the same source lane
194  const MSLane* pred = lane->getLogicalPredecessorLane();
195  // to avoid overlap with vehicles that came from pred (especially when pred has endOffset > 0)
196  // we add all other internal lanes from pred as foeLanes
197  const MSLinkCont& predLinks = pred->getLinkCont();
198  for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
199  const MSLane* sibling = (*it)->getViaLane();
200  if (sibling != lane && sibling != 0) {
201  std::vector<SUMOReal> intersections1 = lane->getShape().intersectsAtLengths2D(sibling->getShape());
202 #ifdef MSLink_DEBUG_CROSSING_POINTS
203  //std::cout << " intersections1=" << toString(intersections1) << "\n";
204 #endif
205  if (intersections1.size() > 0) {
206  std::sort(intersections1.begin(), intersections1.end());
207  if (intersections1.back() > NUMERICAL_EPS) {
208  // siblings share a common shape up to the last crossing point so intersections are identical and only need to be computed once
209  myLengthsBehindCrossing.push_back(std::make_pair(
210  lane->getLength() - intersections1.back(),
211  sibling->getLength() - intersections1.back()));
212  myFoeLanes.push_back(sibling);
213 #ifdef MSLink_DEBUG_CROSSING_POINTS
214  std::cout << " adding same-origin foe" << sibling->getID()
215  << " dist1=" << myLengthsBehindCrossing.back().first
216  << " dist2=" << myLengthsBehindCrossing.back().second
217  << "\n";
218 #endif
219  }
220  }
221  }
222  }
223  }
224 #else
225  UNUSED_PARAMETER(internalLaneBefore);
226 #endif
227 }
228 
229 
230 std::pair<SUMOReal, SUMOReal>
231 getLastIntersections(const MSLane* lane, const MSLane* foe);
232 
233 void
234 MSLink::setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed,
235  const bool setRequest, const SUMOTime arrivalTimeBraking, const SUMOReal arrivalSpeedBraking, const SUMOTime waitingTime) {
236  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, approaching->getVehicleType().getLength());
237  myApproachingVehicles.insert(std::make_pair(approaching,
238  ApproachingVehicleInformation(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, setRequest,
239  arrivalTimeBraking, arrivalSpeedBraking, waitingTime)));
240 }
241 
242 
243 void
245  myBlockedFoeLinks.insert(link);
246 }
247 
248 
249 
250 bool
252  for (std::set<MSLink*>::const_iterator i = myBlockedFoeLinks.begin(); i != myBlockedFoeLinks.end(); ++i) {
253  if ((*i)->isBlockingAnyone()) {
254  return true;
255  }
256  }
257  return false;
258 }
259 
260 
261 void
263  myApproachingVehicles.erase(veh);
264 }
265 
266 
269  std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.find(veh);
270  if (i != myApproachingVehicles.end()) {
271  return i->second;
272  } else {
273  return ApproachingVehicleInformation(-1000, -1000, 0, 0, false, -1000, 0, 0);
274  }
275 }
276 
277 
278 SUMOTime
279 MSLink::getLeaveTime(const SUMOTime arrivalTime, const SUMOReal arrivalSpeed,
280  const SUMOReal leaveSpeed, const SUMOReal vehicleLength) const {
281  return arrivalTime + TIME2STEPS((getLength() + vehicleLength) / MAX2((SUMOReal)0.5 * (arrivalSpeed + leaveSpeed), NUMERICAL_EPS));
282 }
283 
284 
285 bool
286 MSLink::opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength,
287  SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime,
288  std::vector<const SUMOVehicle*>* collectFoes) const {
289  if (haveRed()) {
290  return false;
291  }
293  return true;
294  }
295  if ((myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP) && waitingTime == 0) {
296  return false;
297  }
298  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, vehicleLength);
299  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
300 #ifdef HAVE_INTERNAL
302  if ((*i)->haveRed()) {
303  continue;
304  }
305  }
306 #endif
307  if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, myLane == (*i)->getLane(),
308  impatience, decel, waitingTime, collectFoes)) {
309  return false;
310  }
311  }
312  return true;
313 }
314 
315 
316 bool
317 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed,
318  bool sameTargetLane, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime,
319  std::vector<const SUMOVehicle*>* collectFoes) const {
320  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.begin(); i != myApproachingVehicles.end(); ++i) {
321  if (!i->second.willPass) {
322  continue;
323  }
325  assert(waitingTime > 0);
326  if (waitingTime > i->second.waitingTime) {
327  continue;
328  }
329  if (waitingTime == i->second.waitingTime && arrivalTime < i->second.arrivalTime) {
330  continue;
331  }
332  }
333  const SUMOTime foeArrivalTime = (SUMOTime)((1.0 - impatience) * i->second.arrivalTime + impatience * i->second.arrivalTimeBraking);
334  if (i->second.leavingTime < arrivalTime) {
335  // ego wants to be follower
336  if (sameTargetLane && (arrivalTime - i->second.leavingTime < myLookaheadTime
337  || unsafeMergeSpeeds(i->second.leaveSpeed, arrivalSpeed,
338  i->first->getVehicleType().getCarFollowModel().getMaxDecel(), decel))) {
339  if (collectFoes == 0) {
340  return true;
341  } else {
342  collectFoes->push_back(i->first);
343  }
344  }
345  } else if (foeArrivalTime > leaveTime) {
346  // ego wants to be leader.
347  if (sameTargetLane && (foeArrivalTime - leaveTime < myLookaheadTime
348  || unsafeMergeSpeeds(leaveSpeed, i->second.arrivalSpeedBraking,
349  decel, i->first->getVehicleType().getCarFollowModel().getMaxDecel()))) {
350  if (collectFoes == 0) {
351  return true;
352  } else {
353  collectFoes->push_back(i->first);
354  }
355  }
356  } else {
357  // even without considering safeHeadwayTime there is already a conflict
358  if (collectFoes == 0) {
359  return true;
360  } else {
361  collectFoes->push_back(i->first);
362  }
363  }
364  }
365  return false;
366 }
367 
368 
369 bool
371  MSVehicle* veh = lane->getLastVehicle();
372  SUMOReal distLeft = 0;
373  if (veh == 0) {
374  veh = lane->getPartialOccupator();
375  distLeft = lane->getLength() - lane->getPartialOccupatorEnd();
376  } else {
377  distLeft = lane->getLength() - veh->getPositionOnLane() + veh->getVehicleType().getLength();
378  }
379  if (veh == 0) {
380  return false;
381  } else {
382  assert(distLeft > 0);
383  // can we be sure that the vehicle leaves this lane in the next step?
384  bool result = distLeft > (veh->getSpeed() - veh->getCarFollowModel().getMaxDecel());
385  return result;
386  }
387 }
388 
389 
390 bool
391 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed, SUMOReal decel) const {
392  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
393  if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed, myLane == (*i)->getLane(), 0, decel, 0)) {
394  return true;
395  }
396  }
397  for (std::vector<const MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
398  if ((*i)->getVehicleNumber() > 0 || (*i)->getPartialOccupator() != 0) {
399  return true;
400  }
401  }
402  return false;
403 }
404 
405 
408  return myDirection;
409 }
410 
411 
412 void
414  if (myState != state) {
415  myLastStateChange = t;
416  }
417  myState = state;
418 }
419 
420 
421 MSLane*
423  return myLane;
424 }
425 
426 MSLane*
428  MSLane* approachedLane; //the lane approached by this link; this lane may be an internal lane
429 #ifdef HAVE_INTERNAL_LANES
430  if (myJunctionInlane != 0) { // if there is an internal lane
431  approachedLane = myJunctionInlane; //consider the internal lane as the approached lane
432  } else { //if ther is no internal lane
433  approachedLane = myLane;
434  }
435 #else
436  approachedLane = myLane;
437 #endif
438  const std::vector<MSLane::IncomingLaneInfo> possibleLanes = approachedLane->getIncomingLanes();
439  std::vector<MSLane::IncomingLaneInfo>::const_iterator i;
440  for (i = possibleLanes.begin(); i != possibleLanes.end(); i++) {
441  MSLane* lane = (*i).lane;
442  MSLinkCont outgoingLinks = lane->getLinkCont(); //the links outgoing from lane
443  for (MSLinkCont::const_iterator j = outgoingLinks.begin(); j != outgoingLinks.end(); j++) {
444  if ((*j) == this) {
445  return lane;
446  }
447  }
448  }
449  WRITE_WARNING("No approaching lane found for the link with the index " + toString(this->getIndex()) + ".");
450  return 0;
451 }
452 
453 
454 bool
456 #ifdef HAVE_INTERNAL_LANES
457  if (myJunctionInlane == 0 || myAmCont) {
458  return false;
459  } else {
460  MSLane* pred = myJunctionInlane->getLogicalPredecessorLane();
462  return false;
463  } else {
464  MSLane* pred2 = pred->getLogicalPredecessorLane();
465  assert(pred2 != 0);
466  MSLink* predLink = MSLinkContHelper::getConnectingLink(*pred2, *pred);
467  assert(predLink != 0);
468  return predLink->havePriority();
469  }
470  }
471 #else
472  return false;
473 #endif
474 }
475 
476 
477 void
478 MSLink::writeApproaching(OutputDevice& od, const std::string fromLaneID) const {
479  if (myApproachingVehicles.size() > 0) {
480  od.openTag("link");
481  od.writeAttr(SUMO_ATTR_FROM, fromLaneID);
482 #ifdef HAVE_INTERNAL_LANES
483  const std::string via = getViaLane() == 0 ? "" : getViaLane()->getID();
484 #else
485  const std::string via = "";
486 #endif
487  od.writeAttr(SUMO_ATTR_VIA, via);
488  od.writeAttr(SUMO_ATTR_TO, getLane() == 0 ? "" : getLane()->getID());
489  std::vector<std::pair<SUMOTime, const SUMOVehicle*> > toSort; // stabilize output
490  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator it = myApproachingVehicles.begin(); it != myApproachingVehicles.end(); ++it) {
491  toSort.push_back(std::make_pair(it->second.arrivalTime, it->first));
492  }
493  std::sort(toSort.begin(), toSort.end());
494  for (std::vector<std::pair<SUMOTime, const SUMOVehicle*> >::const_iterator it = toSort.begin(); it != toSort.end(); ++it) {
495  od.openTag("approaching");
496  const ApproachingVehicleInformation& avi = myApproachingVehicles.find(it->second)->second;
497  od.writeAttr(SUMO_ATTR_ID, it->second->getID());
498  od.writeAttr(SUMO_ATTR_IMPATIENCE, it->second->getImpatience());
499  od.writeAttr("arrivalTime", time2string(avi.arrivalTime));
500  od.writeAttr("arrivalTimeBraking", time2string(avi.arrivalTimeBraking));
501  od.writeAttr("leaveTime", time2string(avi.leavingTime));
502  od.writeAttr("arrivalSpeed", toString(avi.arrivalSpeed));
503  od.writeAttr("arrivalSpeedBraking", toString(avi.arrivalSpeedBraking));
504  od.writeAttr("leaveSpeed", toString(avi.leaveSpeed));
505  od.writeAttr("willPass", toString(avi.willPass));
506  od.closeTag();
507  }
508  od.closeTag();
509  }
510 }
511 
512 
513 #ifdef HAVE_INTERNAL_LANES
514 MSLane*
515 MSLink::getViaLane() const {
516  return myJunctionInlane;
517 }
518 
519 
521 MSLink::getLeaderInfo(SUMOReal dist, SUMOReal minGap, std::vector<const MSPerson*>* collectBlockers) const {
522  LinkLeaders result;
523  //gDebugFlag1 = true;
524  // this link needs to start at an internal lane (either an exit link or between two internal lanes)
526  (myJunctionInlane == 0 && getLane()->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_NORMAL)
527  || (myJunctionInlane != 0 && myJunctionInlane->getLogicalPredecessorLane()->getEdge().isInternal()))) {
528  //if (gDebugFlag1) std::cout << SIMTIME << " getLeaderInfo link=" << getViaLaneOrLane()->getID() << "\n";
529  // this is an exit link
530  for (size_t i = 0; i < myFoeLanes.size(); ++i) {
531  const MSLane* foeLane = myFoeLanes[i];
532  // distance from the querying vehicle to the crossing point with foeLane
533  const SUMOReal distToCrossing = dist - myLengthsBehindCrossing[i].first;
534  const bool sameTarget = (myLane == foeLane->getLinkCont()[0]->getLane());
535  const bool sameSource = (myInternalLaneBefore != 0 && myInternalLaneBefore->getLogicalPredecessorLane() == foeLane->getLogicalPredecessorLane());
536  const SUMOReal crossingWidth = (sameTarget || sameSource) ? 0 : foeLane->getWidth();
537  const SUMOReal foeCrossingWidth = (sameTarget || sameSource) ? 0 : myInternalLaneBefore->getWidth();
538  //if (gDebugFlag1) std::cout << " distToCrossing=" << distToCrossing << " foeLane=" << foeLane->getID() << "\n";
539  if (distToCrossing + crossingWidth < 0) {
540  continue; // vehicle is behind the crossing point, continue with next foe lane
541  }
542  const SUMOReal foeDistToCrossing = foeLane->getLength() - myLengthsBehindCrossing[i].second;
543  // it is not sufficient to return the last vehicle on the foeLane because ego might be its leader
544  // therefore we return all vehicles on the lane
545  //
546  // special care must be taken for continuation lanes. (next lane is also internal)
547  // vehicles on these lanes should always block (gap = -1)
548  const bool contLane = (foeLane->getLinkCont()[0]->getViaLaneOrLane()->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL);
549  // vehicles on cont. lanes or on internal lanes with the same target as this link can never be ignored
550  const bool cannotIgnore = contLane || sameTarget || sameSource;
551  const MSLane::VehCont& vehicles = foeLane->getVehiclesSecure();
552  foeLane->releaseVehicles();
553  for (MSLane::VehCont::const_iterator it_veh = vehicles.begin(); it_veh != vehicles.end(); ++it_veh) {
554  MSVehicle* leader = *it_veh;
555  if (!cannotIgnore && !foeLane->getLinkCont()[0]->getApproaching(leader).willPass) {
556  continue;
557  }
558  if (cannotIgnore || leader->getWaitingTime() < MSGlobals::gIgnoreJunctionBlocker) {
559  // compute distance between vehicles on the the superimposition of both lanes
560  // where the crossing point is the common point
561  SUMOReal gap;
562  if (contLane && !sameSource) {
563  gap = -1; // always break for vehicles which are on a continuation lane
564  } else {
565  const SUMOReal leaderBack = leader->getPositionOnLane() - leader->getVehicleType().getLength();
566  const SUMOReal leaderBackDist = foeDistToCrossing - leaderBack;
567  //if (gDebugFlag1) std::cout << " distToCrossing=" << distToCrossing << " leader back=" << leaderBack << " backDist=" << leaderBackDist << "\n";
568  if (leaderBackDist + foeCrossingWidth < 0) {
569  // leader is completely past the crossing point
570  // or there is no crossing point
571  continue; // next vehicle
572  }
573  gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
574  }
575  result.push_back(LinkLeader(leader, gap, cannotIgnore ? -1 : distToCrossing));
576  }
577 
578  }
579  MSVehicle* leader = foeLane->getPartialOccupator();
580  if (leader != 0) {
581  if (cannotIgnore || leader->getWaitingTime() < MSGlobals::gIgnoreJunctionBlocker) {
582  // compute distance between vehicles on the the superimposition of both lanes
583  // where the crossing point is the common point
584  SUMOReal gap;
585  if (contLane && !sameSource) {
586  gap = -1; // always break for vehicles which are on a continuation lane
587  } else {
588  const SUMOReal leaderBackDist = foeDistToCrossing - foeLane->getPartialOccupatorEnd();
589  //if (gDebugFlag1) std::cout << " distToCrossing=" << distToCrossing << " leader (partialOccupator) backDist=" << leaderBackDist << "\n";
590  if (leaderBackDist + foeCrossingWidth < 0) {
591  // leader is completely past the crossing point
592  // or there is no crossing point
593  continue; // next lane
594  }
595  gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
596  }
597  result.push_back(LinkLeader(leader, gap, sameTarget ? -1 : distToCrossing));
598  }
599  }
600  // check for crossing pedestrians (keep driving if already on top of the crossing
601  const SUMOReal distToPeds = distToCrossing - MSPModel::SAFETY_GAP;
602  if (distToPeds >= -MSPModel::SAFETY_GAP && MSPModel::getModel()->blockedAtDist(foeLane, foeDistToCrossing, collectBlockers)) {
603  result.push_back(LinkLeader((MSVehicle*)0, -1, distToPeds));
604  }
605  }
606  }
607  return result;
608 }
609 #endif
610 
611 
612 MSLane*
614 #ifdef HAVE_INTERNAL_LANES
615  if (myJunctionInlane != 0) {
616  return myJunctionInlane;
617  }
618 #endif
619  return myLane;
620 }
621 
622 
623 /****************************************************************************/
624 
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:461
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
long long int SUMOTime
Definition: SUMOTime.h:43
static const SUMOReal SAFETY_GAP
Definition: MSPModel.h:81
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:303
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:544
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:359
This is an uncontrolled, minor link, has to stop.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:376
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
SUMOReal getLength() const
Get vehicle&#39;s length [m].
SUMOReal getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:392
T MAX2(T a, T b)
Definition: StdDefs.h:74
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:286
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
This is an uncontrolled, all-way stop link.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:296
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:261
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
const std::string & getID() const
Returns the id.
Definition: Named.h:60
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1426
Representation of a vehicle.
Definition: SUMOVehicle.h:65
static MSPModel * getModel()
Definition: MSPModel.cpp:65
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:71
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:184
MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:998
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:240
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:235
The edge is a normal street.
Definition: MSEdge.h:94
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:90
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:294
static SUMOTime gIgnoreJunctionBlocker
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:74
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:323
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:253
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:215
static const bool gUseMesoSim
Definition: MSGlobals.h:102
const MSJunction * getFromJunction() const
Definition: MSEdge.h:345
#define NUMERICAL_EPS
Definition: config.h:162
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1065
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:590
The edge is an internal edge.
Definition: MSEdge.h:98
SUMOReal interpolateGeometryPosToLanePos(SUMOReal geometryPos) const
Definition: MSLane.h:346
std::vector< SUMOReal > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.