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