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 
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:752
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
static double gLateralResolution
Definition: MSGlobals.h:91
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2256
double getLength() const
Returns the vehicle&#39;s length.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
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.
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:628
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:564
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:249
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
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
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
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:497
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:439
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:901
const std::string & getID() const
Returns the id.
Definition: Named.h:65
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
#define TS
Definition: SUMOTime.h:51
This is an uncontrolled, all-way stop link.
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:513
This is an uncontrolled, zipper-merge link.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3674
#define SIMTIME
Definition: SUMOTime.h:71
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:3202
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
bool isInternal() const
Definition: MSLane.cpp:1774
#define SUMOTime_MIN
Definition: SUMOTime.h:44
A road/street connecting two junctions.
Definition: MSEdge.h:80
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
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:882
int getIndex() const
Returns the lane&#39;s index.
Definition: MSLane.h:520
MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else 0.
Definition: MSLane.cpp:1902
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
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
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 interpolateGeometryPosToLanePos(double geometryPos) const
Definition: MSLane.h:467
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:176
#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.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
T MIN2(T a, T b)
Definition: StdDefs.h:67
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:403
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:398
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 bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:75
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:211
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:229
const SUMOVTypeParameter & getParameter() const
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:439
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
virtual Position getPosition() const
Return the Network coordinate of the transportable.
const MSJunction * getFromJunction() const
Definition: MSEdge.h:348
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1797
virtual double getLateralPositionOnLane() const =0
Get the vehicle&#39;s lateral position on the lane.
double getLength() const
Get vehicle&#39;s length [m].
static SUMOTime gIgnoreJunctionBlocker
Definition: MSGlobals.h:79
const MSVehicleType & getVehicleType() const
#define DEBUG_COND
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:3120
The parent class for traffic light logics.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
bool closeTag()
Closes the most recently opened tag.
static const double SAFETY_GAP
Definition: MSPModel.h:113
long long int SUMOTime
Definition: TraCIDefs.h:51
#define NUMERICAL_EPS
Definition: config.h:151
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1332
const double INVALID_DOUBLE
Definition: StdDefs.h:59
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1874
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:482
const std::string & getID() const
Returns the name of the vehicle.
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.
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:224
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.