SUMO - Simulation of Urban MObility
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-2017 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 "MSJunction.h"
39 #include "MSLink.h"
40 #include "MSLane.h"
42 #include "MSEdge.h"
43 #include "MSGlobals.h"
44 #include "MSVehicle.h"
47 
48 //#define MSLink_DEBUG_CROSSING_POINTS
49 //#define MSLink_DEBUG_OPENED
50 
51 // ===========================================================================
52 // static member variables
53 // ===========================================================================
55 // additional caution is needed when approaching a zipper link
57 
58 const double MSLink::ZIPPER_ADAPT_DIST(100);
59 
60 // time to link in seconds below which adaptation should take place
61 #define ZIPPER_ADAPT_TIME 10
62 // the default safety gap when passing before oncoming pedestrians
63 #define JM_CROSSING_GAP_DEFAULT 10
64 
65 // ===========================================================================
66 // member method definitions
67 // ===========================================================================
68 MSLink::MSLink(MSLane* predLane, MSLane* succLane, MSLane* via, LinkDirection dir, LinkState state, double length, double foeVisibilityDistance, bool keepClear, MSTrafficLightLogic* logic, int tlIndex) :
69  myLane(succLane),
70  myLaneBefore(predLane),
71  myIndex(-1),
72  myTLIndex(tlIndex),
73  myLogic(logic),
74  myState(state),
75  myLastStateChange(SUMOTime_MIN),
76  myDirection(dir),
77  myLength(length),
78  myFoeVisibilityDistance(foeVisibilityDistance),
79  myHasFoes(false),
80  myAmCont(false),
81  myKeepClear(keepClear),
82  myInternalLane(via),
83  myInternalLaneBefore(0),
84  myMesoTLSPenalty(0),
85  myGreenFraction(1),
86  myWalkingAreaFoe(0),
87  myParallelRight(0),
88  myParallelLeft(0),
89  myJunction(0) {
90 }
91 
92 
94 
95 
96 void
98  const std::vector<MSLink*>& foeLinks,
99  const std::vector<MSLane*>& foeLanes,
100  MSLane* internalLaneBefore) {
101 //#ifdef MSLink_DEBUG_CROSSING_POINTS
102 // std::cout << " setRequestInformation() for junction " << getViaLaneOrLane()->getEdge().getFromJunction()->getID()
103 // << "\nInternalLanes = " << toString(getViaLaneOrLane()->getEdge().getFromJunction()->getInternalLanes())
104 // << std::endl;
105 //#endif
106  myIndex = index;
107  myHasFoes = hasFoes;
108  myAmCont = isCont;
109  myFoeLinks = foeLinks;
110  for (std::vector<MSLane*>::const_iterator it_lane = foeLanes.begin(); it_lane != foeLanes.end(); ++it_lane) {
111  // cannot assign vector due to const-ness
112  myFoeLanes.push_back(*it_lane);
113  }
114  myJunction = const_cast<MSJunction*>(myLane->getEdge().getFromJunction()); // junctionGraph is initialized after the whole network is loaded
115  myInternalLaneBefore = internalLaneBefore;
116  MSLane* lane = 0;
117  if (internalLaneBefore != 0) {
118  // this is an exit link. compute crossing points with all foeLanes
119  lane = internalLaneBefore;
120  //} else if (myLane->getEdge().isCrossing()) {
121  // // this is the link to a pedestrian crossing. compute crossing points with all foeLanes
122  // // @note not currently used by pedestrians
123  // lane = myLane;
124  }
125 #ifdef MSLink_DEBUG_CROSSING_POINTS
126  std::cout << " link " << myIndex << " to " << getViaLaneOrLane()->getID() << " internalLaneBefore=" << (lane == 0 ? "NULL" : lane->getID()) << " has foes: " << toString(foeLanes) << "\n";
127 #endif
128  if (lane != 0) {
129  const bool beforeInternalJunction = lane->getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal();
130  assert(lane->getIncomingLanes().size() == 1);
131  // compute crossing points
132  for (std::vector<const MSLane*>::const_iterator it_lane = myFoeLanes.begin(); it_lane != myFoeLanes.end(); ++it_lane) {
133  const bool sameTarget = myLane == (*it_lane)->getLinkCont()[0]->getLane();
134  if (sameTarget && !beforeInternalJunction) {
135  //if (myLane == (*it_lane)->getLinkCont()[0]->getLane()) {
136  // this foeLane has the same target and merges at the end (lane exits the junction)
137  myLengthsBehindCrossing.push_back(std::make_pair(0, 0)); // dummy value, never used
138 #ifdef MSLink_DEBUG_CROSSING_POINTS
139  std::cout
140  << " " << lane->getID()
141  << " merges with " << (*it_lane)->getID()
142  << " nextLane " << lane->getLinkCont()[0]->getViaLaneOrLane()->getID()
143  << " dist1=" << myLengthsBehindCrossing.back().first
144  << " dist2=" << myLengthsBehindCrossing.back().second
145  << "\n";
146 #endif
147  } else {
148  std::vector<double> intersections1 = lane->getShape().intersectsAtLengths2D((*it_lane)->getShape());
149 #ifdef MSLink_DEBUG_CROSSING_POINTS
150 // std::cout << " intersections1=" << toString(intersections1) << "\n";
151 #endif
152  bool haveIntersection = true;
153  if (intersections1.size() == 0) {
154  intersections1.push_back(-10000.0); // disregard this foe (using maxdouble leads to nasty problems down the line)
155  haveIntersection = false;
156  } else if (intersections1.size() > 1) {
157  std::sort(intersections1.begin(), intersections1.end());
158  }
159  std::vector<double> intersections2 = (*it_lane)->getShape().intersectsAtLengths2D(lane->getShape());
160 #ifdef MSLink_DEBUG_CROSSING_POINTS
161  //std::cout << " intersections2=" << toString(intersections2) << "\n";
162 #endif
163  if (intersections2.size() == 0) {
164  intersections2.push_back(0);
165  } else if (intersections2.size() > 1) {
166  std::sort(intersections2.begin(), intersections2.end());
167  }
168  if (haveIntersection) {
169  // lane width affects the crossing point
170  intersections1.back() -= (*it_lane)->getWidth() / 2;
171  intersections2.back() -= lane->getWidth() / 2;
172  // also length/geometry factor. (XXX: Why subtract width/2 *before* converting geometric position to lane pos? refs #3031)
173  intersections1.back() = lane->interpolateGeometryPosToLanePos(intersections1.back());
174  intersections2.back() = (*it_lane)->interpolateGeometryPosToLanePos(intersections2.back());
175 
176  if (internalLaneBefore->getLogicalPredecessorLane()->getEdge().isInternal() && !(*it_lane)->getEdge().isCrossing()) {
177  // wait at the internal junction
178  // (except for foes that are crossings since there is no internal junction)
179  intersections1.back() = 0;
180  }
181  }
182 
183  myLengthsBehindCrossing.push_back(std::make_pair(
184  lane->getLength() - intersections1.back(),
185  (*it_lane)->getLength() - intersections2.back()));
186 
187 #ifdef MSLink_DEBUG_CROSSING_POINTS
188  std::cout
189  << " intersection of " << lane->getID()
190  << " totalLength=" << lane->getLength()
191  << " with " << (*it_lane)->getID()
192  << " totalLength=" << (*it_lane)->getLength()
193  << " dist1=" << myLengthsBehindCrossing.back().first
194  << " dist2=" << myLengthsBehindCrossing.back().second
195  << "\n";
196 #endif
197  }
198  }
199  // check for overlap with internal lanes from the same source lane
200  const MSLane* pred = lane->getLogicalPredecessorLane();
201  // to avoid overlap with vehicles that came from pred (especially when pred has endOffset > 0)
202  // we add all other internal lanes from pred as foeLanes
203  const MSLinkCont& predLinks = pred->getLinkCont();
204  for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
205  const MSLane* sibling = (*it)->getViaLane();
206  if (sibling != lane && sibling != 0) {
207  std::vector<double> intersections1 = lane->getShape().intersectsAtLengths2D(sibling->getShape());
208 #ifdef MSLink_DEBUG_CROSSING_POINTS
209  //std::cout << " intersections1=" << toString(intersections1) << "\n";
210 #endif
211  if (intersections1.size() > 0) {
212  std::sort(intersections1.begin(), intersections1.end());
213  if (intersections1.back() > NUMERICAL_EPS) {
214  // siblings share a common shape up to the last crossing point so intersections are identical and only need to be computed once
215  myLengthsBehindCrossing.push_back(std::make_pair(
216  lane->getLength() - intersections1.back(),
217  sibling->getLength() - intersections1.back()));
218  myFoeLanes.push_back(sibling);
219 #ifdef MSLink_DEBUG_CROSSING_POINTS
220  std::cout << " adding same-origin foe" << sibling->getID()
221  << " dist1=" << myLengthsBehindCrossing.back().first
222  << " dist2=" << myLengthsBehindCrossing.back().second
223  << "\n";
224 #endif
225  }
226  }
227  }
228  }
229  }
231  // check for links with the same origin lane and the same destination edge
232  const MSEdge* myTarget = &myLane->getEdge();
233  // save foes for entry links
234  const MSLinkCont& predLinks = myLaneBefore->getLinkCont();
235  for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
236  const MSEdge* target = &((*it)->getLane()->getEdge());
237  if (*it != this && target == myTarget) {
238  mySublaneFoeLinks.push_back(*it);
239  }
240  }
241  // save foes for exit links
242  if (fromInternalLane()) {
243  //std::cout << " setRequestInformation link=" << getViaLaneOrLane()->getID() << " before=" << myLaneBefore->getID() << " before2=" << myLaneBefore->getIncomingLanes().front().lane->getID() << "\n";
244  const MSLinkCont& predLinks2 = myLaneBefore->getIncomingLanes().front().lane->getLinkCont();
245  for (MSLinkCont::const_iterator it = predLinks2.begin(); it != predLinks2.end(); ++it) {
246  const MSEdge* target = &((*it)->getLane()->getEdge());
247  if ((*it)->getViaLane() != myInternalLaneBefore && target == myTarget) {
248  //std::cout << " add sublaneFoe=" << (*it)->getViaLane()->getID() << "\n";
249  mySublaneFoeLanes.push_back((*it)->getViaLane());
250  }
251  }
252  }
253  }
254 }
255 
256 
257 std::pair<double, double>
258 getLastIntersections(const MSLane* lane, const MSLane* foe);
259 
260 void
261 MSLink::setApproaching(const SUMOVehicle* approaching, const SUMOTime arrivalTime, const double arrivalSpeed, const double leaveSpeed,
262  const bool setRequest, const SUMOTime arrivalTimeBraking, const double arrivalSpeedBraking, const SUMOTime waitingTime, double dist) {
263  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, approaching->getVehicleType().getLength());
264  myApproachingVehicles.insert(std::make_pair(approaching,
265  ApproachingVehicleInformation(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, setRequest,
266  arrivalTimeBraking, arrivalSpeedBraking, waitingTime, dist)));
267 }
268 
269 
270 void
272  myBlockedFoeLinks.insert(link);
273 }
274 
275 
276 
277 bool
279  for (std::set<MSLink*>::const_iterator i = myBlockedFoeLinks.begin(); i != myBlockedFoeLinks.end(); ++i) {
280  if ((*i)->isBlockingAnyone()) {
281  return true;
282  }
283  }
284  return false;
285 }
286 
287 
288 void
290  myApproachingVehicles.erase(veh);
291 }
292 
293 
296  std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.find(veh);
297  if (i != myApproachingVehicles.end()) {
298  return i->second;
299  } else {
300  return ApproachingVehicleInformation(-1000, -1000, 0, 0, false, -1000, 0, 0, 0);
301  }
302 }
303 
304 
305 SUMOTime
306 MSLink::getLeaveTime(const SUMOTime arrivalTime, const double arrivalSpeed,
307  const double leaveSpeed, const double vehicleLength) const {
308  return arrivalTime + TIME2STEPS((getLength() + vehicleLength) / MAX2(0.5 * (arrivalSpeed + leaveSpeed), NUMERICAL_EPS));
309 }
310 
311 
312 bool
313 MSLink::opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength,
314  double impatience, double decel, SUMOTime waitingTime, double posLat,
315  std::vector<const SUMOVehicle*>* collectFoes, bool ignoreRed, const SUMOVehicle* ego) const {
316  if (haveRed() && !ignoreRed) {
317  return false;
318  }
320  return true;
321  }
322  const SUMOTime leaveTime = getLeaveTime(arrivalTime, arrivalSpeed, leaveSpeed, vehicleLength);
324  // check for foes on the same lane
325  for (std::vector<MSLink*>::const_iterator it = mySublaneFoeLinks.begin(); it != mySublaneFoeLinks.end(); ++it) {
326  const MSLink* foeLink = *it;
327  assert(myLane != foeLink->getLane());
328  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = foeLink->myApproachingVehicles.begin(); i != foeLink->myApproachingVehicles.end(); ++i) {
329  const SUMOVehicle* foe = i->first;
330  if (
331  // there only is a conflict if the paths cross
332  ((posLat < foe->getLateralPositionOnLane() && myLane->getIndex() > foeLink->myLane->getIndex())
333  || (posLat > foe->getLateralPositionOnLane() && myLane->getIndex() < foeLink->myLane->getIndex()))
334  // the vehicle that arrives later must yield
335  && (arrivalTime > i->second.arrivalTime
336  // if both vehicles arrive at the same time, the one
337  // to the left must yield
338  || (arrivalTime == i->second.arrivalTime && posLat > foe->getLateralPositionOnLane()))) {
339  if (blockedByFoe(i->first, i->second, arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, false,
340  impatience, decel, waitingTime)) {
341 #ifdef MSLink_DEBUG_OPENED
342  if (gDebugFlag1) {
343  std::cout << SIMTIME << " blocked by " << foe->getID() << " arrival=" << arrivalTime << " foeArrival=" << i->second.arrivalTime << "\n";
344  }
345 #endif
346  if (collectFoes == 0) {
347 #ifdef MSLink_DEBUG_OPENED
348  if (gDebugFlag1) {
349  std::cout << " link=" << getViaLaneOrLane()->getID() << " blocked by sublaneFoe=" << foe->getID() << " foeLink=" << foeLink->getViaLaneOrLane()->getID() << " posLat=" << posLat << "\n";
350  }
351 #endif
352  return false;
353  } else {
354  collectFoes->push_back(i->first);
355  }
356  }
357  }
358  }
359  }
360  }
361  if (havePriority() && myState != LINKSTATE_ZIPPER) {
362  // priority usually means the link is open but there are exceptions:
363  // zipper still needs to collect foes
364  // sublane model could have detected a conflict
365  return collectFoes == 0 || collectFoes->size() == 0;
366  }
367  if ((myState == LINKSTATE_STOP || myState == LINKSTATE_ALLWAY_STOP) && waitingTime == 0) {
368  return false;
369  }
370 
371 #ifdef MSLink_DEBUG_OPENED
372  if (gDebugFlag1) {
373  std::cout << SIMTIME << " opened link=" << getViaLaneOrLane()->getID() << " foeLinks=" << myFoeLinks.size() << "\n";
374  }
375 #endif
376 
377  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
379  if ((*i)->haveRed()) {
380  continue;
381  }
382  }
383  if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, myLane == (*i)->getLane(),
384  impatience, decel, waitingTime, collectFoes, ego)) {
385  return false;
386  }
387  }
388  if (collectFoes != 0 && collectFoes->size() > 0) {
389  return false;
390  }
391  return true;
392 }
393 
394 
395 bool
396 MSLink::blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
397  bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime,
398  std::vector<const SUMOVehicle*>* collectFoes, const SUMOVehicle* ego) const {
399  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i = myApproachingVehicles.begin(); i != myApproachingVehicles.end(); ++i) {
400  if (i->first != ego && blockedByFoe(i->first, i->second, arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, sameTargetLane,
401  impatience, decel, waitingTime)) {
402  if (collectFoes == 0) {
403  return true;
404  } else {
405  collectFoes->push_back(i->first);
406  }
407  }
408  }
409  return false;
410 }
411 
412 
413 bool
414 MSLink::blockedByFoe(const SUMOVehicle* veh, const ApproachingVehicleInformation& avi, SUMOTime arrivalTime, SUMOTime leaveTime, double arrivalSpeed, double leaveSpeed,
415  bool sameTargetLane, double impatience, double decel, SUMOTime waitingTime) const {
416 #ifdef MSLink_DEBUG_OPENED
417  if (gDebugFlag1) {
418  std::cout << " foe link=" << getViaLaneOrLane()->getID()
419  << " foeVeh=" << veh->getID()
420  << " req=" << avi.willPass
421  << " aT=" << avi.arrivalTime
422  << " lT=" << avi.leavingTime
423  << "\n";
424  }
425 #endif
426  if (!avi.willPass) {
427  return false;
428  }
430  assert(waitingTime > 0);
431  if (waitingTime > avi.waitingTime) {
432  return false;
433  }
434  if (waitingTime == avi.waitingTime && arrivalTime < avi.arrivalTime) {
435  return false;
436  }
437  }
438  const SUMOTime foeArrivalTime = (SUMOTime)((1.0 - impatience) * avi.arrivalTime + impatience * avi.arrivalTimeBraking);
440  if (avi.leavingTime < arrivalTime) {
441  // ego wants to be follower
442  if (sameTargetLane && (arrivalTime - avi.leavingTime < lookAhead
443  || unsafeMergeSpeeds(avi.leaveSpeed, arrivalSpeed,
444  veh->getVehicleType().getCarFollowModel().getMaxDecel(), decel))) {
445 #ifdef MSLink_DEBUG_OPENED
446  if (gDebugFlag1) {
447  std::cout << " blocked (cannot follow)\n";
448  }
449 #endif
450  return true;
451  }
452  } else if (foeArrivalTime > leaveTime) {
453  // ego wants to be leader.
454  if (sameTargetLane && (foeArrivalTime - leaveTime < lookAhead
455  || unsafeMergeSpeeds(leaveSpeed, avi.arrivalSpeedBraking,
456  decel, veh->getVehicleType().getCarFollowModel().getMaxDecel()))) {
457 #ifdef MSLink_DEBUG_OPENED
458  if (gDebugFlag1) {
459  std::cout << " blocked (cannot lead)\n";
460  }
461 #endif
462  return true;
463  }
464  } else {
465  // even without considering safeHeadwayTime there is already a conflict
466 #ifdef MSLink_DEBUG_OPENED
467  if (gDebugFlag1) {
468  std::cout << " blocked (hard conflict)\n";
469  }
470 #endif
471  return true;
472  }
473  return false;
474 }
475 
476 
477 bool
479  MSVehicle* veh = lane->getLastAnyVehicle();
480  double distLeft = 0;
481  if (veh == 0) {
482  return false;
483  } else {
484  distLeft = lane->getLength() - veh->getBackPositionOnLane(lane);
485  assert(distLeft > 0);
486  // can we be sure that the vehicle leaves this lane in the next step?
487  bool result = distLeft > (veh->getSpeed() - veh->getCarFollowModel().getMaxDecel());
488  return result;
489  }
490 }
491 
492 
493 bool
494 MSLink::hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, double speed, double decel) const {
495  for (std::vector<MSLink*>::const_iterator i = myFoeLinks.begin(); i != myFoeLinks.end(); ++i) {
496  if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed, myLane == (*i)->getLane(), 0, decel, 0)) {
497  return true;
498  }
499  }
500  for (std::vector<const MSLane*>::const_iterator i = myFoeLanes.begin(); i != myFoeLanes.end(); ++i) {
501  if ((*i)->getVehicleNumberWithPartials() > 0) {
502  return true;
503  }
504  }
505  return false;
506 }
507 
508 
511  return myDirection;
512 }
513 
514 
515 void
517  if (myState != state) {
518  myLastStateChange = t;
519  }
520  myState = state;
521 }
522 
523 
524 MSLane*
526  return myLane;
527 }
528 
529 bool
531  if (myInternalLane == 0 || myAmCont) {
532  return false;
533  } else {
535  if (!pred->getEdge().isInternal()) {
536  return false;
537  } else {
538  MSLane* pred2 = pred->getLogicalPredecessorLane();
539  assert(pred2 != 0);
540  MSLink* predLink = MSLinkContHelper::getConnectingLink(*pred2, *pred);
541  assert(predLink != 0);
542  return predLink->havePriority();
543  }
544  }
545 }
546 
547 
548 void
549 MSLink::writeApproaching(OutputDevice& od, const std::string fromLaneID) const {
550  if (myApproachingVehicles.size() > 0) {
551  od.openTag("link");
552  od.writeAttr(SUMO_ATTR_FROM, fromLaneID);
553  const std::string via = getViaLane() == 0 ? "" : getViaLane()->getID();
554  od.writeAttr(SUMO_ATTR_VIA, via);
555  od.writeAttr(SUMO_ATTR_TO, getLane() == 0 ? "" : getLane()->getID());
556  std::vector<std::pair<SUMOTime, const SUMOVehicle*> > toSort; // stabilize output
557  for (std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator it = myApproachingVehicles.begin(); it != myApproachingVehicles.end(); ++it) {
558  toSort.push_back(std::make_pair(it->second.arrivalTime, it->first));
559  }
560  std::sort(toSort.begin(), toSort.end());
561  for (std::vector<std::pair<SUMOTime, const SUMOVehicle*> >::const_iterator it = toSort.begin(); it != toSort.end(); ++it) {
562  od.openTag("approaching");
563  const ApproachingVehicleInformation& avi = myApproachingVehicles.find(it->second)->second;
564  od.writeAttr(SUMO_ATTR_ID, it->second->getID());
565  od.writeAttr(SUMO_ATTR_IMPATIENCE, it->second->getImpatience());
566  od.writeAttr("arrivalTime", time2string(avi.arrivalTime));
567  od.writeAttr("arrivalTimeBraking", time2string(avi.arrivalTimeBraking));
568  od.writeAttr("leaveTime", time2string(avi.leavingTime));
569  od.writeAttr("arrivalSpeed", toString(avi.arrivalSpeed));
570  od.writeAttr("arrivalSpeedBraking", toString(avi.arrivalSpeedBraking));
571  od.writeAttr("leaveSpeed", toString(avi.leaveSpeed));
572  od.writeAttr("willPass", toString(avi.willPass));
573  od.closeTag();
574  }
575  od.closeTag();
576  }
577 }
578 
579 
580 double
582  double len = 0.;
583  MSLane* lane = myInternalLane;
584 
585  while (lane != 0 && lane->isInternal()) {
586  len += lane->getLength();
587  lane = lane->getLinkCont()[0]->getViaLane();
588  }
589  return len;
590 }
591 
592 double
594  double len = 0.;
595  const MSLane* lane = myInternalLane;
596 
597  while (lane != 0 && lane->isInternal()) {
598  len += lane->getLength();
599  if (lane->getIncomingLanes().size() == 1) {
600  lane = lane->getIncomingLanes()[0].lane;
601  } else {
602  break;
603  }
604  }
605  return len;
606 }
607 
608 
609 double
611  MSLane* via = myInternalLane;
612  double totalDist = 0.;
613  bool foundCrossing = false;
614  while (via != 0) {
615  MSLink* link = via->getLinkCont()[0];
616  double dist = link->getLengthBeforeCrossing(foeLane);
617  if (dist != INVALID_DOUBLE) {
618  // found conflicting lane
619  totalDist += dist;
620  foundCrossing = true;
621  break;
622  } else {
623  totalDist += via->getLength();
624  via = link->getViaLane();
625  }
626  }
627  if (foundCrossing) {
628  return totalDist;
629  } else {
630  return INVALID_DOUBLE;
631  }
632 }
633 
634 
635 double
637  int foe_ix;
638  for (foe_ix = 0; foe_ix != (int)myFoeLanes.size(); ++foe_ix) {
639  if (myFoeLanes[foe_ix] == foeLane) {
640  break;
641  }
642  }
643  if (foe_ix == (int)myFoeLanes.size()) {
644  // no conflict with the given lane, indicate by returning -1
645 #ifdef MSLink_DEBUG_CROSSING_POINTS
646  std::cout << "No crossing of lanes '" << foeLane->getID() << "' and '" << myInternalLaneBefore->getID() << "'" << std::endl;
647 #endif
648  return INVALID_DOUBLE;
649  } else {
650  // found conflicting lane index
651  double dist = myInternalLaneBefore->getLength() - myLengthsBehindCrossing[foe_ix].first;
652  if (dist == -10000.) {
653  // this is the value in myLengthsBehindCrossing, if the relation allows intersection but none is present for the actual geometry.
654  return INVALID_DOUBLE;
655  }
656 #ifdef MSLink_DEBUG_CROSSING_POINTS
657  std::cout << "Crossing of lanes '" << myInternalLaneBefore->getID() << "' and '" << foeLane->getID()
658  << "' at distance " << dist << " (approach along '"
659  << myInternalLaneBefore->getEntryLink()->getLaneBefore()->getID() << "')" << std::endl;
660 #endif
661  return dist;
662  }
663 }
664 
665 
666 MSLane*
668  return myInternalLane;
669 }
670 
671 
672 bool
676  } else {
677  return false;
678  }
679 }
680 
681 
682 MSLink*
684  MSLane* lane = myInternalLane;
685  MSLink* link = 0;
686  while (lane != 0) {
687  link = lane->getLinkCont()[0];
688  lane = link->getViaLane();
689  }
690  return link;
691 }
692 
693 
694 bool
696  return getInternalLaneBefore() != 0 && myInternalLane != 0;
697 }
698 
699 bool
701  return isExitLink() || isInternalJunctionLink();
702 }
703 
705 MSLink::getLeaderInfo(const MSVehicle* ego, double dist, std::vector<const MSPerson*>* collectBlockers, bool isShadowLink) const {
706  LinkLeaders result;
707  if (ego != 0 && ego->getLaneChangeModel().isOpposite()) {
708  // ignore link leaders
709  return result;
710  }
711  //gDebugFlag1 = true;
712  // this link needs to start at an internal lane (either an exit link or between two internal lanes)
713  // or it must be queried by the pedestrian model (ego == 0)
714  if (fromInternalLane() || ego == 0) {
715  if (gDebugFlag1) {
716  std::cout << SIMTIME << " getLeaderInfo link=" << getViaLaneOrLane()->getID() << "\n";
717  }
718  // this is an exit link
719  for (int i = 0; i < (int)myFoeLanes.size(); ++i) {
720  const MSLane* foeLane = myFoeLanes[i];
721  // distance from the querying vehicle to the crossing point with foeLane
722  double distToCrossing = dist - myLengthsBehindCrossing[i].first;
723  const bool sameTarget = (myLane == foeLane->getLinkCont()[0]->getLane());
724  const bool sameSource = (myInternalLaneBefore != 0 && myInternalLaneBefore->getLogicalPredecessorLane() == foeLane->getLogicalPredecessorLane());
725  const double crossingWidth = (sameTarget || sameSource) ? 0 : foeLane->getWidth();
726  const double foeCrossingWidth = (sameTarget || sameSource) ? 0 : myInternalLaneBefore->getWidth();
727  if (gDebugFlag1) {
728  std::cout << " distToCrossing=" << distToCrossing << " foeLane=" << foeLane->getID() << "\n";
729  }
730  if (distToCrossing + crossingWidth < 0) {
731  continue; // vehicle is behind the crossing point, continue with next foe lane
732  }
733  const double foeDistToCrossing = foeLane->getLength() - myLengthsBehindCrossing[i].second;
734  // it is not sufficient to return the last vehicle on the foeLane because ego might be its leader
735  // therefore we return all vehicles on the lane
736  //
737  // special care must be taken for continuation lanes. (next lane is also internal)
738  // vehicles on these lanes should always block (gap = -1)
739  const bool contLane = (foeLane->getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal());
740  // vehicles on cont. lanes or on internal lanes with the same target as this link can never be ignored
741  const bool cannotIgnore = (contLane || sameTarget || sameSource) && ego != 0;
743  for (MSLane::AnyVehicleIterator it_veh = foeLane->anyVehiclesBegin(); it_veh != end; ++it_veh) {
744  MSVehicle* leader = (MSVehicle*)*it_veh;
745  const bool isOpposite = leader->getLaneChangeModel().isOpposite();
746  if (gDebugFlag1) {
747  std::cout << " candiate leader=" << leader->getID()
748  << " cannotIgnore=" << cannotIgnore
749  << " willPass=" << foeLane->getLinkCont()[0]->getApproaching(leader).willPass
750  << " isFrontOnLane=" << leader->isFrontOnLane(foeLane)
751  << " isOpposite=" << isOpposite << "\n";
752  }
753  if (leader == ego) {
754  continue;
755  }
756  if (!cannotIgnore && !foeLane->getLinkCont()[0]->getApproaching(leader).willPass && leader->isFrontOnLane(foeLane) && !isOpposite && !leader->isStopped()) {
757  continue;
758  }
759  if (cannotIgnore || leader->getWaitingTime() < MSGlobals::gIgnoreJunctionBlocker) {
760  // compute distance between vehicles on the the superimposition of both lanes
761  // where the crossing point is the common point
762  double gap;
763  bool fromLeft = true;
764  if (ego == 0) {
765  // request from pedestrian model. return distance between leaderBack and crossing point
766  const double leaderBack = leader->getBackPositionOnLane(foeLane);
767  //std::cout << " foeLane=" << foeLane->getID() << " leaderBack=" << leaderBack << " foeDistToCrossing=" << foeDistToCrossing << " foeLength=" << foeLane->getLength() << " foebehind=" << myLengthsBehindCrossing[i].second << " dist=" << dist << " behind=" << myLengthsBehindCrossing[i].first << "\n";
768  gap = foeDistToCrossing - leaderBack;
769  // distToCrossing should not take into account the with of the foe lane
770  // (which was subtracted in setRequestInformation)
771  // Instead, the width of the foe vehicle is used directly by the caller.
772  distToCrossing += foeLane->getWidth() / 2;
773  if (gap + foeCrossingWidth < 0) {
774  // leader is completely past the crossing point
775  // or there is no crossing point
776  continue; // next vehicle
777  }
778  // we need to determine whether the vehicle passes the
779  // crossing from the left or the right (heuristic)
780  fromLeft = foeDistToCrossing > 0.5 * foeLane->getLength();
781  } else if ((contLane && !sameSource) || isOpposite) {
782  gap = -1; // always break for vehicles which are on a continuation lane or for opposite-direction vehicles
783  } else {
784  const double leaderBack = leader->getBackPositionOnLane(foeLane);
785  const double leaderBackDist = foeDistToCrossing - leaderBack;
786  if (gDebugFlag1) {
787  std::cout << " distToCrossing=" << distToCrossing << " leader back=" << leaderBack << " backDist=" << leaderBackDist << "\n";
788  }
789  if (leaderBackDist + foeCrossingWidth < 0) {
790  // leader is completely past the crossing point
791  // or there is no crossing point
792  continue; // next vehicle
793  }
794  gap = distToCrossing - leaderBackDist - (sameTarget ? ego->getVehicleType().getMinGap() : 0);
795  }
796  if (gDebugFlag1) {
797  std::cout << " leader=" << leader->getID() << " contLane=" << contLane << " cannotIgnore=" << cannotIgnore << "\n";
798  }
799  // if the foe is already moving off the intersection, we may
800  // advance up to the crossing point unless we have the same target
801  const bool stopAsap = leader->isFrontOnLane(foeLane) ? cannotIgnore : sameTarget;
802  result.push_back(LinkLeader(leader, gap, stopAsap ? -1 : distToCrossing, fromLeft));
803  }
804 
805  }
806  if (ego != 0) {
807  // check for crossing pedestrians (keep driving if already on top of the crossing
808  const double distToPeds = distToCrossing - MSPModel::SAFETY_GAP;
809  const double vehWidth = ego->getVehicleType().getWidth() + MSPModel::SAFETY_GAP; // + configurable safety gap
811  // @check lefthand?!
812  const bool wayIn = myLengthsBehindCrossing[i].first < myLaneBefore->getLength() * 0.5;
813  const double vehSideOffset = (foeDistToCrossing + myLaneBefore->getWidth() * 0.5 - vehWidth * 0.5
814  + ego->getLateralPositionOnLane() * (wayIn ? -1 : 1));
815  if (distToPeds >= -MSPModel::SAFETY_GAP && MSPModel::getModel()->blockedAtDist(foeLane, vehSideOffset, vehWidth,
817  collectBlockers)) {
818  result.push_back(LinkLeader((MSVehicle*)0, -1, distToPeds));
819  }
820  }
821  }
822 
823  //std::cout << SIMTIME << " ego=" << Named::getIDSecure(ego) << " link=" << getViaLaneOrLane()->getID() << " myWalkingAreaFoe=" << Named::getIDSecure(myWalkingAreaFoe) << "\n";
824  if (ego != 0 && myWalkingAreaFoe != 0 && myWalkingAreaFoe->getEdge().getPersons().size() > 0) {
825  // pedestrians may be on an arbitrary path across this
826  // walkingarea. make sure to keep enough distance.
827  // This is a simple but conservative solution that could be improved
828  // by ignoring pedestrians that are "obviously" not on a collision course
829  double distToPeds = std::numeric_limits<double>::max();
830  const std::set<MSTransportable*>& persons = myWalkingAreaFoe->getEdge().getPersons();
831  for (std::set<MSTransportable*>::const_iterator it = persons.begin(); it != persons.end(); ++it) {
832  MSPerson* p = dynamic_cast<MSPerson*>(*it);
833  distToPeds = MIN2(distToPeds, ego->getPosition().distanceTo2D(p->getPosition()) - p->getVehicleType().getLength() - MSPModel::SAFETY_GAP);
834  if (collectBlockers != 0) {
835  collectBlockers->push_back(p);
836  }
837  }
838  result.push_back(LinkLeader((MSVehicle*)0, -1, distToPeds));
839  }
840 
841  if (MSGlobals::gLateralResolution > 0 && ego != 0 && !isShadowLink) {
842  // check for foes on the same lane
843  for (std::vector<MSLane*>::const_iterator it = mySublaneFoeLanes.begin(); it != mySublaneFoeLanes.end(); ++it) {
844  const MSLane* foeLane = *it;
846  for (MSLane::AnyVehicleIterator it_veh = foeLane->anyVehiclesBegin(); it_veh != end; ++it_veh) {
847  MSVehicle* leader = (MSVehicle*)*it_veh;
848  if (leader == ego) {
849  continue;
850  }
851  const double maxLength = MAX2(myInternalLaneBefore->getLength(), foeLane->getLength());
852  const double gap = dist - maxLength - ego->getVehicleType().getMinGap() + leader->getBackPositionOnLane(foeLane);
853  if (gap < -(ego->getVehicleType().getMinGap() + leader->getLength())) {
854  // ego is ahead of leader
855  continue;
856  }
857 
858  const double posLat = ego->getLateralPositionOnLane();
859  const double posLatLeader = leader->getLateralPositionOnLane() + leader->getLatOffset(foeLane);
860  if (gDebugFlag1) {
861  std::cout << " sublaneFoe lane=" << myInternalLaneBefore->getID()
862  << " foeLane=" << foeLane->getID()
863  << " leader=" << leader->getID()
864  << " egoLane=" << ego->getLane()->getID()
865  << " leaderLane=" << leader->getLane()->getID()
866  << " egoLat=" << posLat
867  << " leaderLat=" << posLatLeader
868  << " leaderLatOffset=" << leader->getLatOffset(foeLane)
869  << " egoIndex=" << myInternalLaneBefore->getIndex()
870  << " foeIndex=" << foeLane->getIndex()
871  << " dist=" << dist
872  << " leaderBack=" << leader->getBackPositionOnLane(foeLane)
873  << "\n";
874  }
875  // there only is a conflict if the paths cross
876  if ((posLat < posLatLeader && myInternalLaneBefore->getIndex() > foeLane->getIndex())
877  || (posLat > posLatLeader && myInternalLaneBefore->getIndex() < foeLane->getIndex())) {
878  if (gDebugFlag1) {
879  std::cout << SIMTIME << " blocked by " << leader->getID() << " (sublane split) foeLane=" << foeLane->getID() << "\n";
880  }
881  result.push_back(LinkLeader(leader, gap, -1));
882  }
883  }
884  }
885  }
886  }
887  return result;
888 }
889 
890 
891 MSLane*
893  if (myInternalLane != 0) {
894  return myInternalLane;
895  }
896  return myLane;
897 }
898 
899 
900 const MSLane*
902  if (myInternalLaneBefore != 0) {
904  throw ProcessError("lane before mismatch!");
905  }
906  }
907  return myLaneBefore;
908 }
909 
910 
911 MSLink*
912 MSLink::getParallelLink(int direction) const {
913  if (direction == -1) {
914  return myParallelRight;
915  } else if (direction == 1) {
916  return myParallelLeft;
917  } else {
918  assert(false);
919  return 0;
920  }
921 }
922 
923 
924 MSLink*
926  MSLane* before = getLaneBefore()->getParallelLane(direction);
927  MSLane* after = getViaLaneOrLane()->getParallelLane(direction);
928  if (before != 0 && after != 0) {
929  return MSLinkContHelper::getConnectingLink(*before, *after);
930  } else {
931  return 0;
932  }
933 }
934 
935 void
937  if (myJunction != 0) {
938  myJunction->passedJunction(vehicle);
939  }
940 }
941 
942 
943 bool
944 MSLink::isLeader(const MSVehicle* ego, const MSVehicle* foe) const {
945  if (myJunction != 0) {
946  return myJunction->isLeader(ego, foe);
947  } else {
948  // unregulated junction
949  return false;
950  }
951 }
952 
953 const MSLane*
955  return myInternalLaneBefore;
956 }
957 
958 
959 double
960 MSLink::getZipperSpeed(const MSVehicle* ego, const double dist, double vSafe,
961  SUMOTime arrivalTime,
962  std::vector<const SUMOVehicle*>* collectFoes) const {
963  //gDebugFlag1 = ego->getID() == "left.7";
964  if (myFoeLinks.size() == 0) {
965  // link should have LINKSTATE_MAJOR in this case
966  assert(false);
967  return vSafe;
968  } else if (myFoeLinks.size() > 1) {
969  throw ProcessError("Zipper junctions with more than two conflicting lanes are not supported (at junction '"
970  + myJunction->getID() + "')");
971  }
973  const double secondsToArrival = STEPS2TIME(arrivalTime - now);
974  if (secondsToArrival > ZIPPER_ADAPT_TIME && dist > ZIPPER_ADAPT_DIST) {
975  //if (gDebugFlag1) std::cout << SIMTIME << " getZipperSpeed ego=" << ego->getID()
976  // << " dist=" << dist
977  // << " ignoring foes (arrival in " << STEPS2TIME(arrivalTime - now) << ")\n";
978  return vSafe;
979  }
980  //if (gDebugFlag1) std::cout << SIMTIME << " getZipperSpeed ego=" << ego->getID()
981  // << " egoAT=" << arrivalTime
982  // << " dist=" << dist
983  // << " vSafe=" << vSafe
984  // << " numFoes=" << collectFoes->size()
985  // << "\n";
986  MSLink* foeLink = myFoeLinks[0];
987  const double vSafeOrig = vSafe;
988  for (std::vector<const SUMOVehicle*>::const_iterator i = collectFoes->begin(); i != collectFoes->end(); ++i) {
989  const MSVehicle* foe = dynamic_cast<const MSVehicle*>(*i);
990  assert(foe != 0);
991  const ApproachingVehicleInformation& avi = foeLink->getApproaching(foe);
992  if ( // ignore vehicles that arrive after us (unless they are ahead and we could easily brake for them)
993  ((avi.arrivalTime > arrivalTime) && !couldBrakeForLeader(dist, avi.dist, ego, foe)) ||
994  // also ignore vehicles that are behind us and are able to brake for us
995  couldBrakeForLeader(avi.dist, dist, foe, ego) ||
996  // resolve ties by lane index
997  (avi.arrivalTime == arrivalTime && avi.dist == dist && ego->getLane()->getIndex() < foe->getLane()->getIndex())) {
998  //if (gDebugFlag1) std::cout
999  // << " ignoring foe=" << foe->getID()
1000  // << " foeAT=" << avi.arrivalTime
1001  // << " foeDist=" << avi.dist
1002  // << " foeSpeed=" << foe->getSpeed()
1003  // << " egoSpeed=" << ego->getSpeed()
1004  // << " deltaDist=" << avi.dist - dist
1005  // << " delteSpeed=" << foe->getSpeed() - foe->getCarFollowModel().getMaxDecel() - ego->getSpeed()
1006  // << "\n";
1007  continue;
1008  }
1009  const double gap = dist - foe->getVehicleType().getLength() - ego->getVehicleType().getMinGap() - avi.dist;
1010  const double follow = ego->getCarFollowModel().followSpeed(
1011  ego, ego->getSpeed(), gap, foe->getSpeed(), foe->getCarFollowModel().getMaxDecel());
1012  // speed adaption to follow the foe can be spread over secondsToArrival
1013  const double followInTime = vSafeOrig + (follow - vSafeOrig) / MAX2((double)1, secondsToArrival / TS);
1014  vSafe = MIN2(vSafe, followInTime);
1015  //if (gDebugFlag1) std::cout << " adapting to foe=" << foe->getID()
1016  // << " foeDist=" << avi.dist
1017  // << " follow=" << follow
1018  // << " followInTime=" << followInTime
1019  // << " gap=" << gap
1020  // << " foeSpeed=" << foe->getSpeed()
1021  // << " follow=" << follow
1022  // << " foeAT=" << avi.arrivalTime
1023  // << " foeLT=" << avi.leavingTime
1024  // << " foeAS=" << avi.arrivalSpeed
1025  // << " vSafe=" << vSafe
1026  // << "\n";
1027  }
1028  return vSafe;
1029 }
1030 
1031 
1032 bool
1033 MSLink::couldBrakeForLeader(double followDist, double leaderDist, const MSVehicle* follow, const MSVehicle* leader) {
1034  return (// leader is ahead of follower
1035  followDist > leaderDist &&
1036  // and follower could brake for 1 s to stay behind leader
1037  followDist - leaderDist > follow->getSpeed() - follow->getCarFollowModel().getMaxDecel() - leader->getSpeed());
1038 }
1039 
1040 
1041 void
1045 }
1046 
1047 /****************************************************************************/
1048 
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:33
double getMinGap() const
Get the free space in front of vehicles of this class.
static double gLateralResolution
Definition: MSGlobals.h:92
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:261
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:500
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1702
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:796
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
double getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:3862
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:547
This is an uncontrolled, minor link, has to stop.
The base class for an intersection.
Definition: MSJunction.h:64
std::vector< double > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:484
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
T MAX2(T a, T b)
Definition: StdDefs.h:74
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:806
bool isInternal() const
Definition: MSLane.cpp:1679
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
#define TS
Definition: SUMOTime.h:52
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:252
double getLength() const
Returns the vehicle&#39;s length.
This is an uncontrolled, all-way stop link.
This is an uncontrolled, zipper-merge link.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3144
#define SIMTIME
Definition: SUMOTime.h:70
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:225
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
#define SUMOTime_MIN
Definition: SUMOTime.h:45
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:81
const MSVehicleType & getVehicleType() const
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2161
#define max(a, b)
Definition: polyfonts.c:65
MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else 0.
Definition: MSLane.cpp:1807
const SUMOVTypeParameter & getParameter() const
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
void passedJunction(const MSVehicle *vehicle)
erase vehicle from myLinkLeaders
Definition: MSJunction.cpp:73
Representation of a vehicle.
Definition: SUMOVehicle.h:67
static MSPModel * getModel()
Definition: MSPModel.cpp:66
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:212
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:1867
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1240
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
T MIN2(T a, T b)
Definition: StdDefs.h:68
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2617
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:76
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
virtual double getLateralPositionOnLane() const =0
Get the vehicle&#39;s lateral position on the lane.
int getIndex() const
Returns the lane&#39;s index.
Definition: MSLane.h:507
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:230
double getJMParam(const SumoXMLAttr attr, const double defaultValue) const
Returns the named value from the map, or the default if it is not contained there.
double getLength() const
Get vehicle&#39;s length [m].
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2679
virtual Position getPosition() const
Return the Network coordinate of the transportable.
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:390
static SUMOTime gIgnoreJunctionBlocker
Definition: MSGlobals.h:80
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
The parent class for traffic light logics.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:177
bool closeTag()
Closes the most recently opened tag.
static const double SAFETY_GAP
Definition: MSPModel.h:114
const MSJunction * getFromJunction() const
Definition: MSEdge.h:349
long long int SUMOTime
Definition: TraCIDefs.h:52
#define NUMERICAL_EPS
Definition: config.h:152
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1779
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition: MSLane.h:454
const double INVALID_DOUBLE
Definition: StdDefs.h:60
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:499
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:727
virtual bool blockedAtDist(const MSLane *lane, double vehSide, double vehWidth, double oncomingGap, std::vector< const MSPerson * > *collectBlockers)
whether a pedestrian is blocking the crossing of lane for the given vehicle bondaries ...
Definition: MSPModel.h:80
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:385
static bool gUseMesoSim
Definition: MSGlobals.h:98
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
bool isLeader(const MSVehicle *ego, const MSVehicle *foe)
Definition: MSJunction.cpp:79
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
const std::string & getID() const
Returns the name of the vehicle.
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:443