SUMO - Simulation of Urban MObility
MSLane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
14 // Representation of a lane in the micro simulation
15 /****************************************************************************/
16 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
17 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
18 /****************************************************************************/
19 //
20 // This file is part of SUMO.
21 // SUMO is free software: you can redistribute it and/or modify
22 // it under the terms of the GNU General Public License as published by
23 // the Free Software Foundation, either version 3 of the License, or
24 // (at your option) any later version.
25 //
26 /****************************************************************************/
27 
28 
29 // ===========================================================================
30 // included modules
31 // ===========================================================================
32 #ifdef _MSC_VER
33 #include <windows_config.h>
34 #else
35 #include <config.h>
36 #endif
37 
38 #include <cmath>
39 #include <bitset>
40 #include <iostream>
41 #include <cassert>
42 #include <functional>
43 #include <algorithm>
44 #include <iterator>
45 #include <exception>
46 #include <climits>
47 #include <set>
49 #include <utils/common/StdDefs.h>
51 #include <utils/common/ToString.h>
54 #include <utils/geom/GeomHelper.h>
57 #include "MSNet.h"
58 #include "MSVehicleType.h"
59 #include "MSEdge.h"
60 #include "MSEdgeControl.h"
61 #include "MSJunction.h"
62 #include "MSLogicJunction.h"
63 #include "MSLink.h"
64 #include "MSLane.h"
65 #include "MSVehicleTransfer.h"
66 #include "MSGlobals.h"
67 #include "MSVehicleControl.h"
68 #include "MSInsertionControl.h"
69 #include "MSVehicleControl.h"
70 #include "MSLeaderInfo.h"
71 #include "MSVehicle.h"
72 
73 //#define DEBUG_INSERTION
74 //#define DEBUG_PLAN_MOVE
75 //#define DEBUG_CONTEXT
76 //#define DEBUG_OPPOSITE
77 //#define DEBUG_VEHICLE_CONTAINER
78 //#define DEBUG_COLLISIONS
79 //#define DEBUG_LANE_SORTER
80 
81 #define DEBUG_COND (getID() == "disabled")
82 #define DEBUG_COND2(obj) ((obj != 0 && (obj)->getID() == "disabled"))
83 
84 // ===========================================================================
85 // static member definitions
86 // ===========================================================================
91 
92 // ===========================================================================
93 // internal class method definitions
94 // ===========================================================================
95 
96 
99  if (nextIsMyVehicles()) {
100  if (myI1 != myI1End) {
101  myI1 += myDirection;
102  }
103  // else: already at end
104  } else {
105  myI2 += myDirection;
106  }
107  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::operator++ lane=" << myLane->getID() << " myI1=" << myI1 << " myI2=" << myI2 << "\n";
108  return *this;
109 }
110 
111 
112 const MSVehicle*
114  if (nextIsMyVehicles()) {
115  if (myI1 != myI1End) {
116  return myLane->myVehicles[myI1];
117  } else {
118  return 0;
119  }
120  } else {
121  return myLane->myPartialVehicles[myI2];
122  }
123 }
124 
125 
126 bool
128  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::nextIsMyVehicles lane=" << myLane->getID()
129  // << " myI1=" << myI1
130  // << " myI2=" << myI2
131  // << "\n";
132  if (myI1 == myI1End) {
133  if (myI2 != myI2End) {
134  return false;
135  } else {
136  return true; // @note. must be caught
137  }
138  } else {
139  if (myI2 == myI2End) {
140  return true;
141  } else {
142  //if (DEBUG_COND2(myLane)) std::cout << " "
143  // << " veh1=" << myLane->myVehicles[myI1]->getID()
144  // << " veh2=" << myLane->myPartialVehicles[myI2]->getID()
145  // << " pos1=" << myLane->myVehicles[myI1]->getPositionOnLane(myLane)
146  // << " pos2=" << myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)
147  // << "\n";
148  if (myLane->myVehicles[myI1]->getPositionOnLane(myLane) < myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)) {
149  return myDownstream;
150  } else {
151  return !myDownstream;
152  }
153  }
154  }
155 }
156 
157 
158 // ===========================================================================
159 // member method definitions
160 // ===========================================================================
161 MSLane::MSLane(const std::string& id, double maxSpeed, double length, MSEdge* const edge,
162  int numericalID, const PositionVector& shape, double width,
163  SVCPermissions permissions, int index, bool isRampAccel) :
164  Named(id),
165  myNumericalID(numericalID), myShape(shape), myIndex(index),
166  myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed),
167  myPermissions(permissions),
168  myOriginalPermissions(permissions),
173  myLeaderInfo(this, 0, 0),
174  myFollowerInfo(this, 0, 0),
175  myLeaderInfoTmp(this, 0, 0),
178  myLengthGeometryFactor(MAX2(POSITION_EPS, myShape.length()) / myLength), // factor should not be 0
179  myIsRampAccel(isRampAccel),
180  myRightSideOnEdge(0), // initialized in MSEdge::initialize
181  myRightmostSublane(0) {
182  // initialized in MSEdge::initialize
183  initRestrictions();// may be reloaded again from initialized in MSEdge::closeBuilding
184 }
185 
186 
188  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
189  delete *i;
190  }
191 }
192 
193 
194 void
197 }
198 
199 
200 void
202  myLinks.push_back(link);
203 }
204 
205 
206 void
207 MSLane::addNeigh(const std::string& id) {
208  myNeighs.push_back(id);
209 }
210 
211 
212 // ------ interaction with MSMoveReminder ------
213 void
215  myMoveReminders.push_back(rem);
216  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
217  (*veh)->addReminder(rem);
218  }
219 }
220 
221 
222 double
224 #ifdef DEBUG_CONTEXT
225  if (DEBUG_COND2(v)) {
226  std::cout << SIMTIME << " setPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
227  }
228 #endif
229  // XXX update occupancy here?
230  myPartialVehicles.push_back(v);
231  return myLength;
232 }
233 
234 
235 void
237 #ifdef DEBUG_CONTEXT
238  if (DEBUG_COND2(v)) {
239  std::cout << SIMTIME << " resetPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
240  }
241 #endif
242  for (VehCont::iterator i = myPartialVehicles.begin(); i != myPartialVehicles.end(); ++i) {
243  if (v == *i) {
244  myPartialVehicles.erase(i);
245  // XXX update occupancy here?
246  //std::cout << " removed from myPartialVehicles\n";
247  return;
248  }
249  }
250  assert(false);
251 }
252 
253 
254 // ------ Vehicle emission ------
255 void
256 MSLane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
257  assert(pos <= myLength);
258  bool wasInactive = myVehicles.size() == 0;
259  veh->enterLaneAtInsertion(this, pos, speed, posLat, notification);
260  if (at == myVehicles.end()) {
261  // vehicle will be the first on the lane
262  myVehicles.push_back(veh);
263  } else {
264  myVehicles.insert(at, veh);
265  }
268  myEdge->markDelayed();
269  if (wasInactive) {
271  }
272 }
273 
274 
275 bool
276 MSLane::lastInsertion(MSVehicle& veh, double mspeed, bool patchSpeed) {
277  // XXX interpret departPosLat value
278  const double posLat = 0;
279  double pos = getLength() - POSITION_EPS;
280  MSVehicle* leader = getLastAnyVehicle();
281  // back position of leader relative to this lane
282  double leaderBack;
283  if (leader == 0) {
285  veh.setTentativeLaneAndPosition(this, pos, posLat);
286  veh.updateBestLanes(false, this);
287  std::pair<MSVehicle* const, double> leaderInfo = getLeader(&veh, pos, veh.getBestLanesContinuation(), veh.getCarFollowModel().brakeGap(mspeed));
288  leader = leaderInfo.first;
289  leaderBack = pos + leaderInfo.second + veh.getVehicleType().getMinGap();
290  } else {
291  leaderBack = leader->getBackPositionOnLane(this);
292  //std::cout << " leaderPos=" << leader->getPositionOnLane(this) << " leaderBack=" << leader->getBackPositionOnLane(this) << " leaderLane=" << leader->getLane()->getID() << "\n";
293  }
294  if (leader == 0) {
295  // insert at the end of this lane
296  return isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
297  } else {
298  // try to insert behind the leader
299  const double frontGapNeeded = veh.getCarFollowModel().getSecureGap(mspeed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap() + POSITION_EPS;
300  if (leaderBack >= frontGapNeeded) {
301  pos = MIN2(pos, leaderBack - frontGapNeeded);
302  bool result = isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
303  //if (!result) std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
304  return result;
305  }
306  //std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
307  }
308  return false;
309 }
310 
311 
312 bool
313 MSLane::freeInsertion(MSVehicle& veh, double mspeed,
314  MSMoveReminder::Notification notification) {
315  bool adaptableSpeed = true;
316  // try to insert teleporting vehicles fully on this lane
317  const double minPos = (notification == MSMoveReminder::NOTIFICATION_TELEPORT ?
318  MIN2(myLength, veh.getVehicleType().getLength()) : 0);
319  veh.setTentativeLaneAndPosition(this, minPos, 0);
320  if (myVehicles.size() == 0) {
321  // ensure sufficient gap to followers on predecessor lanes
322  const double backOffset = minPos - veh.getVehicleType().getLength();
323  const double missingRearGap = getMissingRearGap(&veh, backOffset, mspeed);
324  if (missingRearGap > 0) {
325  if (minPos + missingRearGap <= myLength) {
326  // @note. The rear gap is tailored to mspeed. If it changes due
327  // to a leader vehicle (on subsequent lanes) insertion will
328  // still fail. Under the right combination of acceleration and
329  // deceleration values there might be another insertion
330  // positions that would be successful be we do not look for it.
331  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " unclear @(340)\n";
332  return isInsertionSuccess(&veh, mspeed, minPos + missingRearGap, 0, adaptableSpeed, notification);
333  } else {
334  return false;
335  }
336  } else {
337  return isInsertionSuccess(&veh, mspeed, minPos, 0, adaptableSpeed, notification);
338  }
339 
340  } else {
341  // check whether the vehicle can be put behind the last one if there is such
342  MSVehicle* leader = getFirstFullVehicle(); // @todo reproduction of bogus old behavior. see #1961
343  const double leaderPos = leader->getBackPositionOnLane(this);
344  const double speed = adaptableSpeed ? leader->getSpeed() : mspeed;
345  const double frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
346  if (leaderPos >= frontGapNeeded) {
347  const double tspeed = MIN2(veh.getCarFollowModel().insertionFollowSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
348  // check whether we can insert our vehicle behind the last vehicle on the lane
349  if (isInsertionSuccess(&veh, tspeed, minPos, 0, adaptableSpeed, notification)) {
350  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " pos=" << minPos<< " speed=" << speed << " tspeed=" << tspeed << " frontGapNeeded=" << frontGapNeeded << " lead=" << leader->getID() << " lPos=" << leaderPos << "\n vehsOnLane=" << toString(myVehicles) << " @(358)\n";
351  return true;
352  }
353  }
354  }
355  // go through the lane, look for free positions (starting after the last vehicle)
356  MSLane::VehCont::iterator predIt = myVehicles.begin();
357  while (predIt != myVehicles.end()) {
358  // get leader (may be zero) and follower
359  // @todo compute secure position in regard to sublane-model
360  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : 0;
361  if (leader == 0 && myPartialVehicles.size() > 0) {
362  leader = myPartialVehicles.front();
363  }
364  const MSVehicle* follower = *predIt;
365 
366  // patch speed if allowed
367  double speed = mspeed;
368  if (adaptableSpeed && leader != 0) {
369  speed = MIN2(leader->getSpeed(), mspeed);
370  }
371 
372  // compute the space needed to not collide with leader
373  double frontMax = getLength();
374  if (leader != 0) {
375  double leaderRearPos = leader->getBackPositionOnLane(this);
376  double frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
377  frontMax = leaderRearPos - frontGapNeeded;
378  }
379  // compute the space needed to not let the follower collide
380  const double followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
381  const double backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
382  const double backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
383 
384  // check whether there is enough room (given some extra space for rounding errors)
385  if (frontMax > minPos && backMin + POSITION_EPS < frontMax) {
386  // try to insert vehicle (should be always ok)
387  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, 0, adaptableSpeed, notification)) {
388  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " @(393)\n";
389  return true;
390  }
391  }
392  ++predIt;
393  }
394  // first check at lane's begin
395  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " fail final\n";
396  return false;
397 }
398 
399 
400 double
401 MSLane::getDepartSpeed(const MSVehicle& veh, bool& patchSpeed) {
402  double speed = 0;
403  const SUMOVehicleParameter& pars = veh.getParameter();
404  switch (pars.departSpeedProcedure) {
405  case DEPART_SPEED_GIVEN:
406  speed = pars.departSpeed;
407  patchSpeed = false;
408  break;
409  case DEPART_SPEED_RANDOM:
410  speed = RandHelper::rand(getVehicleMaxSpeed(&veh));
411  patchSpeed = true; // @todo check
412  break;
413  case DEPART_SPEED_MAX:
414  speed = getVehicleMaxSpeed(&veh);
415  patchSpeed = true; // @todo check
416  break;
418  default:
419  // speed = 0 was set before
420  patchSpeed = false; // @todo check
421  break;
422  }
423  return speed;
424 }
425 
426 
427 bool
429  double pos = 0;
430  double posLat = 0;
431  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
432  const SUMOVehicleParameter& pars = veh.getParameter();
433  double speed = getDepartSpeed(veh, patchSpeed);
434 
435  // determine the position
436  switch (pars.departPosProcedure) {
437  case DEPART_POS_GIVEN:
438  pos = pars.departPos;
439  if (pos < 0.) {
440  pos += myLength;
441  }
442  break;
443  case DEPART_POS_RANDOM:
444  pos = RandHelper::rand(getLength());
445  break;
446  case DEPART_POS_RANDOM_FREE: {
447  for (int i = 0; i < 10; i++) {
448  // we will try some random positions ...
449  pos = RandHelper::rand(getLength());
452  posLat = RandHelper::rand(getWidth() - veh.getVehicleType().getWidth()) - getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
453  }
454  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
455  return true;
456  }
457  }
458  // ... and if that doesn't work, we put the vehicle to the free position
459  return freeInsertion(veh, speed);
460  }
461  break;
462  case DEPART_POS_FREE:
463  return freeInsertion(veh, speed);
464  case DEPART_POS_LAST:
465  return lastInsertion(veh, speed, patchSpeed);
466  case DEPART_POS_BASE:
467  case DEPART_POS_DEFAULT:
468  default:
469  pos = basePos(veh);
470  break;
471  }
472  // determine the lateral position
473  switch (pars.departPosLatProcedure) {
474  case DEPART_POSLAT_GIVEN:
475  posLat = pars.departPosLat;
476  break;
478  posLat = RandHelper::rand(getWidth() - veh.getVehicleType().getWidth()) - getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
479  break;
481  for (int i = 0; i < 10; i++) {
482  // we will try some random positions ...
483  posLat = RandHelper::rand(getWidth()) - getWidth() * 0.5;
484  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
485  return true;
486  }
487  }
488  // ... and if that doesn't work, we put the vehicle to the free position
489  return freeInsertion(veh, speed);
490  }
491  break;
492  case DEPART_POSLAT_FREE:
493  return freeInsertion(veh, speed);
494  case DEPART_POSLAT_RIGHT:
495  posLat = -getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
496  break;
497  case DEPART_POSLAT_LEFT:
498  posLat = getWidth() * 0.5 - veh.getVehicleType().getWidth() * 0.5;
499  break;
501  case DEPART_POS_DEFAULT:
502  default:
503  posLat = 0;
504  break;
505  }
506  // try to insert
507  return isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
508 }
509 
510 
511 double
512 MSLane::basePos(const MSVehicle& veh) const {
514 }
515 
516 bool
517 MSLane::checkFailure(MSVehicle* aVehicle, double& speed, double& dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const {
518  if (nspeed < speed) {
519  if (patchSpeed) {
520  speed = MIN2(nspeed, speed);
521  dist = aVehicle->getCarFollowModel().brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
522  } else if (speed > 0) {
523  if (errorMsg != "") {
524  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (" + errorMsg + ")!");
526  }
527  return true;
528  }
529  }
530  return false;
531 }
532 
533 
534 bool
536  double speed, double pos, double posLat, bool patchSpeed,
537  MSMoveReminder::Notification notification) {
538  if (pos < 0 || pos > myLength) {
539  // we may not start there
540  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
541  aVehicle->getID() + "'. Inserting at lane end instead.");
542  pos = myLength;
543  }
544 
545 #ifdef DEBUG_INSERTION
546  if (DEBUG_COND2(aVehicle)) std::cout << "\nIS_INSERTION_SUCCESS\n"
547  << SIMTIME << " lane=" << getID()
548  << " veh '" << aVehicle->getID() << "'\n";
549 #endif
550 
551  aVehicle->setTentativeLaneAndPosition(this, pos, posLat);
552  aVehicle->updateBestLanes(false, this);
553  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
554  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
555  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
556  double seen = getLength() - pos; // == distance from insertion position until the end of the currentLane
557  double dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
558 
559  // before looping through the continuation lanes, check if a stop is scheduled on this lane
560  // (the code is duplicated in the loop)
561  if (aVehicle->hasStops()) {
562  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
563  if (nextStop.lane == this) {
564  std::stringstream msg;
565  msg << "scheduled stop on lane '" << myID << "' too close";
566  const double distToStop = nextStop.endPos - pos;
567  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, distToStop),
568  patchSpeed, msg.str())) {
569  // we may not drive with the given velocity - we cannot stop at the stop
570  return false;
571  }
572  }
573  }
574 
575  const MSRoute& r = aVehicle->getRoute();
576  MSRouteIterator ce = r.begin();
577  int nRouteSuccs = 1;
578  MSLane* currentLane = this;
579  MSLane* nextLane = this;
581  while (seen < dist && ri != bestLaneConts.end()) {
582  // get the next link used...
583  MSLinkCont::const_iterator link = succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
584  if (currentLane->isLinkEnd(link)) {
585  if (&currentLane->getEdge() == r.getLastEdge()) {
586  // reached the end of the route
588  if (checkFailure(aVehicle, speed, dist, cfModel.freeSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed, true),
589  patchSpeed, "arrival speed too low")) {
590  // we may not drive with the given velocity - we cannot match the specified arrival speed
591  return false;
592  }
593  }
594  } else {
595  // lane does not continue
596  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
597  patchSpeed, "junction too close")) {
598  // we may not drive with the given velocity - we cannot stop at the junction
599  return false;
600  }
601  }
602  break;
603  }
604 
605  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength(), aVehicle->getImpatience(), cfModel.getMaxDecel(), 0, posLat)
606  || !(*link)->havePriority()) {
607  // have to stop at junction
608  std::string errorMsg = "";
609  const LinkState state = (*link)->getState();
610  if (state == LINKSTATE_MINOR
611  || state == LINKSTATE_EQUAL
612  || state == LINKSTATE_STOP
613  || state == LINKSTATE_ALLWAY_STOP) {
614  // no sense in trying later
615  errorMsg = "unpriorised junction too close";
616  }
617  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
618  patchSpeed, errorMsg)) {
619  // we may not drive with the given velocity - we cannot stop at the junction in time
620  return false;
621  }
622 #ifdef DEBUG_INSERTION
623  if DEBUG_COND2(aVehicle) {
624  std::cout << "trying insertion before minor link: "
625  << "insertion speed = " << speed << " dist=" << dist
626  << "\n";
627  }
628 #endif
629  break;
630  }
631  // get the next used lane (including internal)
632  nextLane = (*link)->getViaLaneOrLane();
633  // check how next lane affects the journey
634  if (nextLane != 0) {
635 
636  // check if there are stops on the next lane that should be regarded
637  // (this block is duplicated before the loop to deal with the insertion lane)
638  if (aVehicle->hasStops()) {
639  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
640  if (nextStop.lane == nextLane) {
641  std::stringstream msg;
642  msg << "scheduled stop on lane '" << nextStop.lane->getID() << "' too close";
643  const double distToStop = seen + nextStop.endPos;
644  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, distToStop),
645  patchSpeed, msg.str())) {
646  // we may not drive with the given velocity - we cannot stop at the stop
647  return false;
648  }
649  }
650  }
651 
652  // check leader on next lane
653  // XXX check all leaders in the sublane case
654  double gap = 0;
655  MSVehicle* leader = nextLane->getLastAnyVehicle();
656  if (leader != 0) {
657 #ifdef DEBUG_INSERTION
658  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
659  << "leader on lane '" << nextLane->getID() << "': " << leader->getID() << "\n";
660 #endif
661  gap = seen + leader->getBackPositionOnLane(nextLane) - aVehicle->getVehicleType().getMinGap();
662  }
663  if (leader != 0) {
664  if (gap < 0) {
665  return false;
666  }
667  const double nspeed = cfModel.insertionFollowSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
668  if (checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
669  // we may not drive with the given velocity - we crash into the leader
670 #ifdef DEBUG_INSERTION
671  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
672  << " isInsertionSuccess lane=" << getID()
673  << " veh=" << aVehicle->getID()
674  << " pos=" << pos
675  << " posLat=" << posLat
676  << " patchSpeed=" << patchSpeed
677  << " speed=" << speed
678  << " nspeed=" << nspeed
679  << " nextLane=" << nextLane->getID()
680  << " lead=" << leader->getID()
681  << " gap=" << gap
682  << " failed (@641)!\n";
683 #endif
684  return false;
685  }
686  }
687  // check next lane's maximum velocity
688  const double nspeed = cfModel.freeSpeed(aVehicle, speed, seen, nextLane->getVehicleMaxSpeed(aVehicle), true);
689  if (nspeed < speed) {
690  if (patchSpeed) {
691  speed = nspeed;
692  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
693  } else {
694  // we may not drive with the given velocity - we would be too fast on the next lane
695  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (slow lane ahead)!");
697  return false;
698  }
699  }
700  // check traffic on next junction
701  // we cannot use (*link)->opened because a vehicle without priority
702  // may already be comitted to blocking the link and unable to stop
703  const SUMOTime leaveTime = (*link)->getLeaveTime(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength());
704  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed, cfModel.getMaxDecel())) {
705  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen), patchSpeed, "")) {
706  // we may not drive with the given velocity - we crash at the junction
707  return false;
708  }
709  }
710  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
711  seen += nextLane->getLength();
712  currentLane = nextLane;
713  if ((*link)->getViaLane() == 0) {
714  nRouteSuccs++;
715  ++ce;
716  ++ri;
717  }
718  }
719  }
720 
721  // get the pointer to the vehicle next in front of the given position
722  MSLeaderInfo leaders = getLastVehicleInformation(aVehicle, 0, pos);
723  //if (aVehicle->getID() == "disabled") std::cout << " leaders=" << leaders.toString() << "\n";
724  const double nspeed = safeInsertionSpeed(aVehicle, leaders, speed);
725  if (nspeed < 0 || checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
726  // XXX: checking for nspeed<0... Might appear naturally with ballistic update (see #860, Leo)
727  // TODO: check if ballistic update needs adjustments here, refs. #2577
728 
729  // we may not drive with the given velocity - we crash into the leader
730 #ifdef DEBUG_INSERTION
731  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
732  << " isInsertionSuccess lane=" << getID()
733  << " veh=" << aVehicle->getID()
734  << " pos=" << pos
735  << " posLat=" << posLat
736  << " patchSpeed=" << patchSpeed
737  << " speed=" << speed
738  << " nspeed=" << nspeed
739  << " nextLane=" << nextLane->getID()
740  << " leaders=" << leaders.toString()
741  << " failed (@700)!\n";
742 #endif
743  return false;
744  }
745 #ifdef DEBUG_INSERTION
746  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
747  << " speed = " << speed
748  << " nspeed = " << nspeed
749  << std::endl;
750 #endif
751 
752  MSLeaderDistanceInfo followers = getFollowersOnConsecutive(aVehicle, aVehicle->getBackPositionOnLane(), false);
753  for (int i = 0; i < followers.numSublanes(); ++i) {
754  const MSVehicle* follower = followers[i].first;
755  if (follower != 0) {
756  const double backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
757  if (followers[i].second < backGapNeeded) {
758  // too close to the follower on this lane
759 #ifdef DEBUG_INSERTION
760  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
761  << " isInsertionSuccess lane=" << getID()
762  << " veh=" << aVehicle->getID()
763  << " pos=" << pos
764  << " posLat=" << posLat
765  << " patchSpeed=" << patchSpeed
766  << " speed=" << speed
767  << " nspeed=" << nspeed
768  << " follower=" << follower->getID()
769  << " backGapNeeded=" << backGapNeeded
770  << " gap=" << followers[i].second
771  << " failure (@719)!\n";
772 #endif
773  return false;
774  }
775  }
776  }
777  if (followers.numFreeSublanes() > 0) {
778  // check approaching vehicles to prevent rear-end collisions
779  const double backOffset = pos - aVehicle->getVehicleType().getLength();
780  const double missingRearGap = getMissingRearGap(aVehicle, backOffset, speed);
781  if (missingRearGap > 0) {
782  // too close to a follower
783 #ifdef DEBUG_INSERTION
784  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
785  << " isInsertionSuccess lane=" << getID()
786  << " veh=" << aVehicle->getID()
787  << " pos=" << pos
788  << " posLat=" << posLat
789  << " patchSpeed=" << patchSpeed
790  << " speed=" << speed
791  << " nspeed=" << nspeed
792  << " missingRearGap=" << missingRearGap
793  << " failure (@728)!\n";
794 #endif
795  return false;
796  }
797  }
798  // may got negative while adaptation
799  if (speed < 0) {
800 #ifdef DEBUG_INSERTION
801  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
802  << " isInsertionSuccess lane=" << getID()
803  << " veh=" << aVehicle->getID()
804  << " pos=" << pos
805  << " posLat=" << posLat
806  << " patchSpeed=" << patchSpeed
807  << " speed=" << speed
808  << " nspeed=" << nspeed
809  << " failed (@733)!\n";
810 #endif
811  return false;
812  }
813  // enter
814  incorporateVehicle(aVehicle, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
815 #ifdef DEBUG_INSERTION
816  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
817  << " isInsertionSuccess lane=" << getID()
818  << " veh=" << aVehicle->getID()
819  << " pos=" << pos
820  << " posLat=" << posLat
821  << " patchSpeed=" << patchSpeed
822  << " speed=" << speed
823  << " nspeed=" << nspeed
824  << " success!\n";
825 #endif
826  return true;
827 }
828 
829 
830 void
831 MSLane::forceVehicleInsertion(MSVehicle* veh, double pos, MSMoveReminder::Notification notification, double posLat) {
832  veh->updateBestLanes(true, this);
833  bool dummy;
834  const double speed = veh->hasDeparted() ? veh->getSpeed() : getDepartSpeed(*veh, dummy);
835  incorporateVehicle(veh, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
836 }
837 
838 
839 double
840 MSLane::safeInsertionSpeed(const MSVehicle* veh, const MSLeaderInfo& leaders, double speed) {
841  double nspeed = speed;
842  for (int i = 0; i < leaders.numSublanes(); ++i) {
843  const MSVehicle* leader = leaders[i];
844  if (leader != 0) {
845  const double gap = leader->getBackPositionOnLane(this) - veh->getPositionOnLane() - veh->getVehicleType().getMinGap();
846  if (gap < 0) {
847  return -1;
848  }
849  nspeed = MIN2(nspeed,
850  veh->getCarFollowModel().insertionFollowSpeed(veh, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()));
851  }
852  }
853  return nspeed;
854 }
855 
856 
857 // ------ Handling vehicles lapping into lanes ------
858 const MSLeaderInfo&
859 MSLane::getLastVehicleInformation(const MSVehicle* ego, double latOffset, double minPos, bool allowCached) const {
860  if (myLeaderInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || minPos > 0 || !allowCached) {
861  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
863  int freeSublanes = 1; // number of sublanes for which no leader was found
864  //if (ego->getID() == "disabled" && SIMTIME == 58) {
865  // std::cout << "DEBUG\n";
866  //}
867  const MSVehicle* veh = *last;
868  while (freeSublanes > 0 && veh != 0) {
869 #ifdef DEBUG_PLAN_MOVE
870  if (DEBUG_COND2(ego)) {
871  std::cout << " getLastVehicleInformation lane=" << getID() << " minPos=" << minPos << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
872  }
873 #endif
874  if (veh != ego && veh->getPositionOnLane(this) >= minPos) {
875  const double latOffset = veh->getLatOffset(this);
876  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
877 #ifdef DEBUG_PLAN_MOVE
878  if (DEBUG_COND2(ego)) {
879  std::cout << " latOffset=" << latOffset << " newLeaders=" << myLeaderInfoTmp.toString() << "\n";
880  }
881 #endif
882  }
883  veh = *(++last);
884  }
885  if (ego == 0 && minPos == 0) {
886  // update cached value
889  }
890 #ifdef DEBUG_PLAN_MOVE
891  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
892  // << " getLastVehicleInformation lane=" << getID()
893  // << " ego=" << Named::getIDSecure(ego)
894  // << "\n"
895  // << " vehicles=" << toString(myVehicles)
896  // << " partials=" << toString(myPartialVehicles)
897  // << "\n"
898  // << " result=" << myLeaderInfoTmp.toString()
899  // << " cached=" << myLeaderInfo.toString()
900  // << " myLeaderInfoTime=" << myLeaderInfoTime
901  // << "\n";
902 #endif
903  return myLeaderInfoTmp;
904  }
905  return myLeaderInfo;
906 }
907 
908 
909 const MSLeaderInfo&
910 MSLane::getFirstVehicleInformation(const MSVehicle* ego, double latOffset, bool onlyFrontOnLane, double maxPos, bool allowCached) const {
911  if (myFollowerInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || maxPos < myLength || !allowCached || onlyFrontOnLane) {
912  // XXX separate cache for onlyFrontOnLane = true
913  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
915  int freeSublanes = 1; // number of sublanes for which no leader was found
916  const MSVehicle* veh = *first;
917  while (freeSublanes > 0 && veh != 0) {
918 #ifdef DEBUG_PLAN_MOVE
919  if (DEBUG_COND2(ego)) {
920  std::cout << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << " maxPos=" << maxPos << "\n";
921  }
922 #endif
923  if (veh != ego && veh->getPositionOnLane(this) <= maxPos
924  && (!onlyFrontOnLane || veh->isFrontOnLane(this))) {
925  //const double latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
926  const double latOffset = veh->getLatOffset(this);
927 #ifdef DEBUG_PLAN_MOVE
928  if (DEBUG_COND2(ego)) {
929  std::cout << " veh=" << veh->getID() << " latOffset=" << latOffset << "\n";
930  }
931 #endif
932  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
933  }
934  veh = *(++first);
935  }
936  if (ego == 0 && maxPos == std::numeric_limits<double>::max()) {
937  // update cached value
940  }
941 #ifdef DEBUG_PLAN_MOVE
942  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
943  // << " getFirstVehicleInformation lane=" << getID()
944  // << " ego=" << Named::getIDSecure(ego)
945  // << "\n"
946  // << " vehicles=" << toString(myVehicles)
947  // << " partials=" << toString(myPartialVehicles)
948  // << "\n"
949  // << " result=" << myLeaderInfoTmp.toString()
950  // //<< " cached=" << myLeaderInfo.toString()
951  // << " myLeaderInfoTime=" << myLeaderInfoTime
952  // << "\n";
953 #endif
954  return myLeaderInfoTmp;
955  }
956  return myFollowerInfo;
957 }
958 
959 
960 // ------ ------
961 void
963  assert(myVehicles.size() != 0);
964  double cumulatedVehLength = 0.;
965  MSLeaderInfo ahead(this);
966  // iterate over myVehicles and myPartialVehicles merge-sort style
967  VehCont::reverse_iterator veh = myVehicles.rbegin();
968  VehCont::reverse_iterator vehPart = myPartialVehicles.rbegin();
969 #ifdef DEBUG_PLAN_MOVE
970  if (DEBUG_COND) std::cout
971  << "\n"
972  << SIMTIME
973  << " planMovements lane=" << getID()
974  << "\n"
975  << " vehicles=" << toString(myVehicles)
976  << " partials=" << toString(myPartialVehicles)
977  << "\n";
978 #endif
979  for (; veh != myVehicles.rend(); ++veh) {
980  while (vehPart != myPartialVehicles.rend()
981  && ((*vehPart)->getPositionOnLane(this) > (*veh)->getPositionOnLane())) {
982  const double latOffset = (*vehPart)->getLatOffset(this);
983 #ifdef DEBUG_PLAN_MOVE
984  if (DEBUG_COND) {
985  std::cout << " partial ahead: " << (*vehPart)->getID() << " latOffset=" << latOffset << "\n";
986  }
987 #endif
988  ahead.addLeader(*vehPart, false, latOffset);
989  ++vehPart;
990  }
991 #ifdef DEBUG_PLAN_MOVE
992  if (DEBUG_COND) {
993  std::cout << " plan move for: " << (*veh)->getID() << " ahead=" << ahead.toString() << "\n";
994  }
995 #endif
996  (*veh)->planMove(t, ahead, cumulatedVehLength);
997  cumulatedVehLength += (*veh)->getVehicleType().getLengthWithGap();
998  ahead.addLeader(*veh, false, 0);
999  }
1000 }
1001 
1002 
1003 void
1004 MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
1005 #ifdef DEBUG_COLLISIONS
1006  if (DEBUG_COND) {
1007  std::vector<const MSVehicle*> all;
1008  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
1009  all.push_back(*last);
1010  }
1011  std::cout << SIMTIME << " detectCollisions stage=" << stage << " lane=" << getID() << ":\n"
1012  << " vehs=" << toString(myVehicles) << "\n"
1013  << " part=" << toString(myPartialVehicles) << "\n"
1014  << " all=" << toString(all) << "\n"
1015  << "\n";
1016  }
1017 #endif
1018 
1019  if (myVehicles.size() == 0 || myCollisionAction == COLLISION_ACTION_NONE) {
1020  return;
1021  }
1022  std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess> toRemove;
1023  std::set<const MSVehicle*> toTeleport;
1025  // no sublanes
1026  VehCont::iterator lastVeh = myVehicles.end() - 1;
1027  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh; ++veh) {
1028  VehCont::iterator pred = veh + 1;
1029  detectCollisionBetween(timestep, stage, *veh, *pred, toRemove, toTeleport);
1030  }
1031  if (myPartialVehicles.size() > 0) {
1032  detectCollisionBetween(timestep, stage, *lastVeh, myPartialVehicles.front(), toRemove, toTeleport);
1033  }
1034  } else {
1035  // in the sublane-case it is insufficient to check the vehicles ordered
1036  // by their front position as there might be more than 2 vehicles next to each
1037  // other on the same lane
1038  // instead, a moving-window approach is used where all vehicles that
1039  // overlap in the longitudinal direction receive pairwise checks
1040  // XXX for efficiency, all lanes of an edge should be checked together
1041  // (lanechanger-style)
1042 
1043  // XXX quick hack: check each in myVehicles against all others
1044  for (AnyVehicleIterator veh = anyVehiclesBegin(); veh != anyVehiclesEnd(); ++veh) {
1045  MSVehicle* follow = (MSVehicle*)*veh;
1046  for (AnyVehicleIterator veh2 = anyVehiclesBegin(); veh2 != anyVehiclesEnd(); ++veh2) {
1047  MSVehicle* lead = (MSVehicle*)*veh2;
1048  if (lead == follow) {
1049  continue;
1050  }
1051  if (lead->getPositionOnLane(this) < follow->getPositionOnLane(this)) {
1052  continue;
1053  }
1054  if (detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1055  // XXX what about collisions with multiple leaders at once?
1056  break;
1057  }
1058  }
1059  if (follow->getLaneChangeModel().getShadowLane() != 0 && follow->getLane() == this) {
1060  // check whether follow collides on the shadow lane
1061  const MSLane* shadowLane = follow->getLaneChangeModel().getShadowLane();
1062  MSLeaderInfo ahead = shadowLane->getLastVehicleInformation(follow,
1063  getRightSideOnEdge() - shadowLane->getRightSideOnEdge(),
1064  follow->getPositionOnLane());
1065  for (int i = 0; i < ahead.numSublanes(); ++i) {
1066  MSVehicle* lead = const_cast<MSVehicle*>(ahead[i]);
1067  if (lead != 0 && lead != follow && shadowLane->detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1068  break;
1069  }
1070  }
1071  }
1072  }
1073  }
1074 
1076  assert(myLinks.size() == 1);
1077  //std::cout << SIMTIME << " checkJunctionCollisions " << getID() << "\n";
1078  const std::vector<const MSLane*>& foeLanes = myLinks.front()->getFoeLanes();
1079  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
1080  MSVehicle* collider = *veh;
1081  //std::cout << " collider " << collider->getID() << "\n";
1082  PositionVector colliderBoundary = collider->getBoundingBox();
1083  for (std::vector<const MSLane*>::const_iterator it = foeLanes.begin(); it != foeLanes.end(); ++it) {
1084  const MSLane* foeLane = *it;
1085  //std::cout << " foeLane " << foeLane->getID() << "\n";
1086  MSLane::AnyVehicleIterator end = foeLane->anyVehiclesEnd();
1087  for (MSLane::AnyVehicleIterator it_veh = foeLane->anyVehiclesBegin(); it_veh != end; ++it_veh) {
1088  MSVehicle* victim = (MSVehicle*)*it_veh;
1089  //std::cout << " victim " << victim->getID() << "\n";
1090  if (colliderBoundary.overlapsWith(victim->getBoundingBox())) {
1091  // make a detailed check
1092  if (collider->getBoundingPoly().overlapsWith(victim->getBoundingPoly())) {
1093  handleCollisionBetween(timestep, stage, collider, victim, -1, 0, toRemove, toTeleport);
1094  }
1095  }
1096  }
1097  }
1098  }
1099  }
1100 
1101  for (std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
1102  MSVehicle* veh = const_cast<MSVehicle*>(*it);
1103  MSLane* vehLane = veh->getLane();
1105  if (toTeleport.count(veh) > 0) {
1106  MSVehicleTransfer::getInstance()->add(timestep, veh);
1107  } else {
1110  }
1111  }
1112 }
1113 
1114 
1115 bool
1116 MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
1117  std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>& toRemove,
1118  std::set<const MSVehicle*>& toTeleport) const {
1119 #ifndef NO_TRACI
1120  if (myCollisionAction == COLLISION_ACTION_TELEPORT && ((victim->hasInfluencer() && victim->getInfluencer().isVTDAffected(timestep)) ||
1121  (collider->hasInfluencer() && collider->getInfluencer().isVTDAffected(timestep)))) {
1122  return false;
1123  }
1124 #endif
1125  const bool colliderOpposite = collider->getLaneChangeModel().isOpposite();
1126  const bool bothOpposite = victim->getLaneChangeModel().isOpposite() && colliderOpposite;
1127  if (bothOpposite) {
1128  std::swap(victim, collider);
1129  }
1130  const double colliderPos = colliderOpposite ? collider->getBackPositionOnLane(this) : collider->getPositionOnLane(this);
1131  double gap = victim->getBackPositionOnLane(this) - colliderPos - collider->getVehicleType().getMinGap();
1132  if (bothOpposite) {
1133  gap = -gap - 2 * collider->getVehicleType().getMinGap();
1134  }
1135 #ifdef DEBUG_COLLISIONS
1136  if (DEBUG_COND) std::cout << SIMTIME
1137  << " thisLane=" << getID()
1138  << " collider=" << collider->getID()
1139  << " victim=" << victim->getID()
1140  << " colliderLane=" << collider->getLane()->getID()
1141  << " victimLane=" << victim->getLane()->getID()
1142  << " colliderPos=" << colliderPos
1143  << " victimBackPos=" << victim->getBackPositionOnLane(this)
1144  << " colliderLat=" << collider->getCenterOnEdge(this)
1145  << " victimLat=" << victim->getCenterOnEdge(this)
1146  << " gap=" << gap
1147  << "\n";
1148 #endif
1149  if (gap < -NUMERICAL_EPS) {
1150  double latGap = 0;
1152  latGap = (fabs(victim->getCenterOnEdge(this) - collider->getCenterOnEdge(this))
1153  - 0.5 * fabs(victim->getVehicleType().getWidth() + collider->getVehicleType().getWidth()));
1154  if (latGap + NUMERICAL_EPS > 0) {
1155  return false;
1156  }
1157  }
1159  && collider->getLaneChangeModel().isChangingLanes()
1160  && victim->getLaneChangeModel().isChangingLanes()
1161  && victim->getLane() != this) {
1162  // synchroneous lane change maneuver
1163  return false;
1164  }
1165  handleCollisionBetween(timestep, stage, collider, victim, gap, latGap, toRemove, toTeleport);
1166  return true;
1167  }
1168  return false;
1169 }
1170 
1171 
1172 void
1173 MSLane::handleCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
1174  double gap, double latGap, std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>& toRemove,
1175  std::set<const MSVehicle*>& toTeleport) const {
1176  std::string prefix = "Vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1177  if (myCollisionStopTime > 0) {
1178  if (collider->collisionStopTime() >= 0 && victim->collisionStopTime() >= 0) {
1179  return;
1180  }
1181  std::string dummyError;
1184  stop.busstop = "";
1185  stop.containerstop = "";
1186  stop.chargingStation = "";
1187  stop.parkingarea = "";
1188  stop.until = 0;
1189  stop.triggered = false;
1190  stop.containerTriggered = false;
1191  stop.parking = false;
1192  stop.index = 0;
1193  const double victimStopPos = MIN2(victim->getLane()->getLength(),
1194  victim->getPositionOnLane() + victim->getCarFollowModel().brakeGap(victim->getSpeed()));
1195  if (victim->collisionStopTime() < 0) {
1196  stop.lane = victim->getLane()->getID();
1197  // @todo: push victim forward?
1198  stop.startPos = victimStopPos;
1199  stop.endPos = stop.startPos;
1201  victim->addStop(stop, dummyError, 0, true);
1202  }
1203  if (collider->collisionStopTime() < 0) {
1204  stop.lane = collider->getLane()->getID();
1205  stop.startPos = MIN2(collider->getPositionOnLane() + collider->getCarFollowModel().brakeGap(collider->getSpeed()),
1206  MAX2(0.0, victimStopPos - 0.75 * victim->getVehicleType().getLength()));
1207  stop.endPos = stop.startPos;
1208  collider->addStop(stop, dummyError, 0, true);
1209  }
1210  } else {
1211  switch (myCollisionAction) {
1212  case COLLISION_ACTION_WARN:
1213  break;
1215  prefix = "Teleporting vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1216  toRemove.insert(collider);
1217  toTeleport.insert(collider);
1218  break;
1219  case COLLISION_ACTION_REMOVE: {
1220  prefix = "Removing collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1221  bool removeCollider = true;
1222  bool removeVictim = true;
1223 #ifndef NO_TRACI
1224  removeVictim = !(victim->hasInfluencer() && victim->getInfluencer().isVTDAffected(timestep));
1225  removeCollider = !(collider->hasInfluencer() && collider->getInfluencer().isVTDAffected(timestep));
1226  if (removeVictim) {
1227  toRemove.insert(victim);
1228  }
1229  if (removeCollider) {
1230  toRemove.insert(collider);
1231  }
1232  if (!removeVictim) {
1233  if (!removeCollider) {
1234  prefix = "Keeping remote-controlled collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1235  } else {
1236  prefix = "Removing collision participant: vehicle '" + collider->getID() + "', keeping remote-controlled vehicle '" + victim->getID();
1237  }
1238  } else if (!removeCollider) {
1239  prefix = "Keeping remote-controlled collision participant: vehicle '" + collider->getID() + "', removing vehicle '" + victim->getID();
1240  }
1241 #else
1242  toRemove.insert(victim);
1243  toRemove.insert(collider);
1244 #endif
1245  break;
1246  }
1247  default:
1248  break;
1249  }
1250  }
1251  WRITE_WARNING(prefix
1252  + "', lane='" + getID()
1253  + "', gap=" + toString(gap)
1254  + (latGap == 0 ? "" : "', latGap=" + toString(latGap))
1255  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())
1256  + " stage=" + stage + ".");
1258 }
1259 
1260 
1261 bool
1262 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& lanesWithVehiclesToIntegrate) {
1263  // iterate over vehicles in reverse so that move reminders will be called in the correct order
1264  for (VehCont::reverse_iterator i = myVehicles.rbegin(); i != myVehicles.rend();) {
1265  MSVehicle* veh = *i;
1266  // length is needed later when the vehicle may not exist anymore
1267  const double length = veh->getVehicleType().getLengthWithGap();
1268  const double nettoLength = veh->getVehicleType().getLength();
1269  const bool moved = veh->executeMove();
1270  MSLane* const target = veh->getLane();
1271  if (veh->hasArrived()) {
1272  // vehicle has reached its arrival position
1275  } else if (target != 0 && moved) {
1276  if (target->getEdge().isVaporizing()) {
1277  // vehicle has reached a vaporizing edge
1280  } else {
1281  // vehicle has entered a new lane (leaveLane and workOnMoveReminders were already called in MSVehicle::executeMove)
1282  target->myVehBuffer.push_back(veh);
1283  lanesWithVehiclesToIntegrate.push_back(target);
1284  }
1285  } else if (veh->isParking()) {
1286  // vehicle started to park
1288  } else if (veh->getPositionOnLane() > getLength()) {
1289  // for any reasons the vehicle is beyond its lane...
1290  // this should never happen because it is handled in MSVehicle::executeMove
1291  assert(false);
1292  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, target lane='" + getID() + "', time=" +
1293  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1296  } else if (veh->collisionStopTime() == 0) {
1297  veh->resumeFromStopping();
1299  WRITE_WARNING("Removing vehicle '" + veh->getID() + "' after earlier collision, lane='" + veh->getLane()->getID() + ", time=" +
1300  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1304  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "' after earlier collision, lane='" + veh->getLane()->getID() + ", time=" +
1305  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1306  MSVehicleTransfer::getInstance()->add(MSNet::getInstance()->getCurrentTimeStep(), veh);
1307  } else {
1308  ++i;
1309  continue;
1310  }
1311  } else {
1312  ++i;
1313  continue;
1314  }
1315  myBruttoVehicleLengthSum -= length;
1316  myNettoVehicleLengthSum -= nettoLength;
1317  ++i;
1318  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
1319  }
1320  if (myVehicles.size() > 0) {
1322  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
1323  if (!veh->isStopped() && veh->getLane() == this) {
1324  const bool wrongLane = !veh->getLane()->appropriate(veh);
1326  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
1327  if (r1 || r2) {
1328  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1329  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
1330  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
1331  MSVehicle* veh = *(myVehicles.end() - 1);
1334  myVehicles.erase(myVehicles.end() - 1);
1335  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
1336  + reason
1337  + (r2 ? " (highway)" : "")
1338  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1339  if (wrongLane) {
1341  } else if (minorLink) {
1343  } else {
1345  }
1347  }
1348  } // else look for a (waiting) vehicle that isn't stopped?
1349  }
1350  }
1352  // trigger sorting of vehicles as their order may have changed
1353  lanesWithVehiclesToIntegrate.push_back(this);
1354  }
1355  return myVehicles.size() == 0;
1356 }
1357 
1358 
1359 const MSEdge*
1361  const MSEdge* e = myEdge;
1362  while (e->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1363  e = e->getSuccessors()[0];
1364  }
1365  return e;
1366 }
1367 
1368 
1369 // ------ Static (sic!) container methods ------
1370 bool
1371 MSLane::dictionary(const std::string& id, MSLane* ptr) {
1372  DictType::iterator it = myDict.find(id);
1373  if (it == myDict.end()) {
1374  // id not in myDict.
1375  myDict.insert(DictType::value_type(id, ptr));
1376  return true;
1377  }
1378  return false;
1379 }
1380 
1381 
1382 MSLane*
1383 MSLane::dictionary(const std::string& id) {
1384  DictType::iterator it = myDict.find(id);
1385  if (it == myDict.end()) {
1386  // id not in myDict.
1387  return 0;
1388  }
1389  return it->second;
1390 }
1391 
1392 
1393 void
1395  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1396  delete(*i).second;
1397  }
1398  myDict.clear();
1399 }
1400 
1401 
1402 void
1403 MSLane::insertIDs(std::vector<std::string>& into) {
1404  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1405  into.push_back((*i).first);
1406  }
1407 }
1408 
1409 
1410 template<class RTREE> void
1411 MSLane::fill(RTREE& into) {
1412  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1413  MSLane* l = (*i).second;
1414  Boundary b = l->getShape().getBoxBoundary();
1415  b.grow(3.);
1416  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
1417  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
1418  into.Insert(cmin, cmax, l);
1419  }
1420 }
1421 
1422 template void MSLane::fill<NamedRTree>(NamedRTree& into);
1423 #ifndef NO_TRACI
1424 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
1425 #endif
1426 
1427 // ------ ------
1428 bool
1431  return true;
1432  }
1433  if (veh->succEdge(1) == 0) {
1434  assert((int)veh->getBestLanes().size() > veh->getLaneIndex());
1435  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
1436  return true;
1437  } else {
1438  return false;
1439  }
1440  }
1441  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1442  return (link != myLinks.end());
1443 }
1444 
1445 
1446 bool
1448  bool wasInactive = myVehicles.size() == 0;
1449  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter(this));
1450  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
1451  MSVehicle* veh = *i;
1452  assert(veh->getLane() == this);
1453  myVehicles.insert(myVehicles.begin(), veh);
1456  //if (true) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " veh=" << veh->getID() << " (on lane " << veh->getLane()->getID() << ") into lane=" << getID() << " myBrutto=" << myBruttoVehicleLengthSum << "\n";
1457  myEdge->markDelayed();
1458  }
1459  myVehBuffer.clear();
1460  //std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " myVehicles1=" << toString(myVehicles);
1461  if (MSGlobals::gLateralResolution > 0 || myNeighs.size() > 0) {
1462  sort(myVehicles.begin(), myVehicles.end(), vehicle_natural_position_sorter(this));
1463  }
1465 #ifdef DEBUG_VEHICLE_CONTAINER
1466  if (DEBUG_COND) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID()
1467  << " vhicles=" << toString(myVehicles) << " partials=" << toString(myPartialVehicles) << "\n";
1468 #endif
1469  return wasInactive && myVehicles.size() != 0;
1470 }
1471 
1472 
1473 void
1475  if (myPartialVehicles.size() > 1) {
1477  }
1478 }
1479 
1480 bool
1481 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
1482  return i == myLinks.end();
1483 }
1484 
1485 
1486 bool
1487 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
1488  return i == myLinks.end();
1489 }
1490 
1491 bool
1493  return myVehicles.empty() && myPartialVehicles.empty();
1494 }
1495 
1496 bool
1499 }
1500 
1501 MSVehicle*
1503  if (myVehicles.size() == 0) {
1504  return 0;
1505  }
1506  return myVehicles.front();
1507 }
1508 
1509 
1510 MSVehicle*
1512  if (myVehicles.size() == 0) {
1513  return 0;
1514  }
1515  return myVehicles.back();
1516 }
1517 
1518 
1519 MSVehicle*
1521  // all vehicles in myVehicles should have positions smaller or equal to
1522  // those in myPartialVehicles
1523  if (myVehicles.size() > 0) {
1524  return myVehicles.front();
1525  }
1526  if (myPartialVehicles.size() > 0) {
1527  return myPartialVehicles.front();
1528  }
1529  return 0;
1530 }
1531 
1532 
1533 MSVehicle*
1535  MSVehicle* result = 0;
1536  if (myVehicles.size() > 0) {
1537  result = myVehicles.back();
1538  }
1539  if (myPartialVehicles.size() > 0
1540  && (result == 0 || result->getPositionOnLane(this) < myPartialVehicles.back()->getPositionOnLane(this))) {
1541  result = myPartialVehicles.back();
1542  }
1543  return result;
1544 }
1545 
1546 
1547 MSLinkCont::const_iterator
1548 MSLane::succLinkSec(const SUMOVehicle& veh, int nRouteSuccs,
1549  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
1550  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
1551  // check whether the vehicle tried to look beyond its route
1552  if (nRouteEdge == 0) {
1553  // return end (no succeeding link) if so
1554  return succLinkSource.myLinks.end();
1555  }
1556  // if we are on an internal lane there should only be one link and it must be allowed
1557  if (succLinkSource.isInternal()) {
1558  assert(succLinkSource.myLinks.size() == 1);
1559  // could have been disallowed dynamically with a rerouter or via TraCI
1560  // assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
1561  return succLinkSource.myLinks.begin();
1562  }
1563  // a link may be used if
1564  // 1) there is a destination lane ((*link)->getLane()!=0)
1565  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
1566  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
1567 
1568  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
1569  // "conts" stores the best continuations of our current lane
1570  // we should never return an arbitrary link since this may cause collisions
1571 
1572  MSLinkCont::const_iterator link;
1573  if (nRouteSuccs < (int)conts.size()) {
1574  // we go through the links in our list and return the matching one
1575  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
1576  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
1577  // we should use the link if it connects us to the best lane
1578  if ((*link)->getLane() == conts[nRouteSuccs]) {
1579  return link;
1580  }
1581  }
1582  }
1583  } else {
1584  // the source lane is a dead end (no continuations exist)
1585  return succLinkSource.myLinks.end();
1586  }
1587  // the only case where this should happen is for a disconnected route (deliberately ignored)
1588 #ifdef _DEBUG
1589  // the "'" around the ids are missing intentionally in the message below because it slows messaging down, resulting in test timeouts
1590  WRITE_WARNING("Could not find connection between lane " + succLinkSource.getID() + " and lane " + conts[nRouteSuccs]->getID() +
1591  " for vehicle " + veh.getID() + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1592 #endif
1593  return succLinkSource.myLinks.end();
1594 }
1595 
1596 const MSLinkCont&
1598  return myLinks;
1599 }
1600 
1601 
1603 MSLink*
1604 MSLane::getLinkTo(const MSLane* target) const {
1605  MSLinkCont::const_iterator l = myLinks.begin();
1606  if (target->isInternal()) {
1607  while (l != myLinks.end()) {
1608  if ((*l)->getViaLane()->getID() == target->getID()) {
1609  return *l;
1610  }
1611  ++l;
1612  }
1613  } else {
1614  while (l != myLinks.end()) {
1615  if ((*l)->getLane()->getID() == target->getID()) {
1616  return *l;
1617  }
1618  ++l;
1619  }
1620  }
1621  return 0;
1622 }
1623 
1624 MSLink*
1626  if (!isInternal()) {
1627  return 0;
1628  }
1629  const MSLane* internal = this;
1630  const MSLane* lane = this->getCanonicalPredecessorLane();
1631  assert(lane != 0);
1632  while (lane->isInternal()) {
1633  internal = lane;
1634  lane = lane->getCanonicalPredecessorLane();
1635  assert(lane != 0);
1636  }
1637  return lane->getLinkTo(internal);
1638 }
1639 
1640 
1641 void
1642 MSLane::setMaxSpeed(double val) {
1643  myMaxSpeed = val;
1644  myEdge->recalcCache();
1645 }
1646 
1647 
1648 void
1649 MSLane::setLength(double val) {
1650  myLength = val;
1651  myEdge->recalcCache();
1652 }
1653 
1654 
1655 void
1657  //if (getID() == "disabled_lane") std::cout << SIMTIME << " swapAfterLaneChange lane=" << getID() << " myVehicles=" << toString(myVehicles) << " myTmpVehicles=" << toString(myTmpVehicles) << "\n";
1659  myTmpVehicles.clear();
1660  // this needs to be done after finishing lane-changing for all lanes on the
1661  // current edge (MSLaneChanger::updateLanes())
1663 }
1664 
1665 
1666 MSVehicle*
1667 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
1668  assert(remVehicle->getLane() == this);
1669  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
1670  if (remVehicle == *it) {
1671  if (notify) {
1672  remVehicle->leaveLane(notification);
1673  }
1674  myVehicles.erase(it);
1677  break;
1678  }
1679  }
1680  return remVehicle;
1681 }
1682 
1683 
1684 MSLane*
1685 MSLane::getParallelLane(int offset) const {
1686  return myEdge->parallelLane(this, offset);
1687 }
1688 
1689 
1690 void
1692  IncomingLaneInfo ili;
1693  ili.lane = lane;
1694  ili.viaLink = viaLink;
1695  ili.length = lane->getLength();
1696  myIncomingLanes.push_back(ili);
1697 }
1698 
1699 
1700 void
1701 MSLane::addApproachingLane(MSLane* lane, bool warnMultiCon) {
1702  MSEdge* approachingEdge = &lane->getEdge();
1703  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1704  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1705  } else if (approachingEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL && warnMultiCon) {
1706  // whenever a normal edge connects twice, there is a corresponding
1707  // internal edge wich connects twice, one warning is sufficient
1708  WRITE_WARNING("Lane '" + getID() + "' is approached multiple times from edge '" + approachingEdge->getID() + "'. This may cause collisions.");
1709  }
1710  myApproachingLanes[approachingEdge].push_back(lane);
1711 }
1712 
1713 
1714 bool
1716  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1717 }
1718 
1719 
1720 bool
1721 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1722  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1723  if (i == myApproachingLanes.end()) {
1724  return false;
1725  }
1726  const std::vector<MSLane*>& lanes = (*i).second;
1727  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1728 }
1729 
1730 
1732 public:
1733  inline int operator()(const std::pair<const MSVehicle*, double>& p1, const std::pair<const MSVehicle*, double>& p2) const {
1734  return p1.second < p2.second;
1735  }
1736 };
1737 
1738 
1739 double MSLane::getMissingRearGap(const MSVehicle* leader, double backOffset, double leaderSpeed) const {
1740  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1741  // search and check for the vehicle with the largest missing rear gap within
1742  // relevant range
1743  double result = 0;
1744  const double leaderDecel = leader->getCarFollowModel().getMaxDecel();
1745  CLeaderDist followerInfo = getFollowersOnConsecutive(leader, backOffset, false)[0];
1746  const MSVehicle* v = followerInfo.first;
1747  if (v != 0) {
1748  result = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderDecel) - followerInfo.second;
1749  }
1750  return result;
1751 }
1752 
1753 
1754 double
1757  const double maxSpeed = getSpeedLimit() * vc.getMaxSpeedFactor();
1758  // NOTE: For the euler update this is an upper bound on the actual braking distance (see ticket #860)
1759  return maxSpeed * maxSpeed * 0.5 / vc.getMinDeceleration();
1760 }
1761 
1762 
1763 
1764 std::pair<MSVehicle* const, double>
1765 MSLane::getLeader(const MSVehicle* veh, const double vehPos, const std::vector<MSLane*>& bestLaneConts, double dist, bool checkTmpVehicles) const {
1766  // get the leading vehicle for (shadow) veh
1767  // XXX this only works as long as all lanes of an edge have equal length
1768 #ifdef DEBUG_CONTEXT
1769  if (DEBUG_COND2(veh)) {
1770  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " vehs=" << toString(myVehicles) << " tmpVehs=" << toString(myTmpVehicles) << "\n";
1771  }
1772 #endif
1773  if (checkTmpVehicles) {
1774  for (VehCont::const_iterator last = myTmpVehicles.begin(); last != myTmpVehicles.end(); ++last) {
1775  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
1776  MSVehicle* pred = (MSVehicle*)*last;
1777  if (pred == veh) {
1778  continue;
1779  }
1780 #ifdef DEBUG_CONTEXT
1781  if (DEBUG_COND2(veh)) {
1782  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane() << "\n";
1783  }
1784 #endif
1785  if (pred->getPositionOnLane() > vehPos + NUMERICAL_EPS) {
1786  return std::pair<MSVehicle* const, double>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
1787  }
1788  }
1789  } else {
1790  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
1791  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
1792  MSVehicle* pred = (MSVehicle*)*last;
1793  if (pred == veh) {
1794  continue;
1795  }
1796 #ifdef DEBUG_CONTEXT
1797  if (DEBUG_COND2(veh)) {
1798  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos
1799  << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << " predBack=" << pred->getBackPositionOnLane(this) << "\n";
1800  }
1801 #endif
1802  if (pred->getPositionOnLane(this) > vehPos + NUMERICAL_EPS) {
1803  return std::pair<MSVehicle* const, double>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
1804  }
1805  }
1806  }
1807  // XXX from here on the code mirrors MSLaneChanger::getRealLeader
1808  if (bestLaneConts.size() > 0) {
1809  double seen = getLength() - vehPos;
1810  double speed = veh->getSpeed();
1811  if (dist < 0) {
1812  dist = veh->getCarFollowModel().brakeGap(speed) + veh->getVehicleType().getMinGap();
1813  }
1814 #ifdef DEBUG_CONTEXT
1815  if (DEBUG_COND2(veh)) {
1816  std::cout << " getLeader lane=" << getID() << " seen=" << seen << " dist=" << dist << "\n";
1817  }
1818 #endif
1819  if (seen > dist) {
1820  return std::pair<MSVehicle* const, double>(static_cast<MSVehicle*>(0), -1);
1821  }
1822  return getLeaderOnConsecutive(dist, seen, speed, *veh, bestLaneConts);
1823  } else {
1824  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1825  }
1826 }
1827 
1828 
1829 std::pair<MSVehicle* const, double>
1830 MSLane::getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle& veh,
1831  const std::vector<MSLane*>& bestLaneConts) const {
1832 #ifdef DEBUG_CONTEXT
1833  if (DEBUG_COND2(&veh)) {
1834  std::cout << " getLeaderOnConsecutive lane=" << getID() << " ego=" << veh.getID() << " seen=" << seen << " dist=" << dist << " conts=" << toString(bestLaneConts) << "\n";
1835  }
1836 #endif
1837  if (seen > dist) {
1838  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1839  }
1840  int view = 1;
1841  // loop over following lanes
1842  if (myPartialVehicles.size() > 0) {
1843  // XXX
1844  MSVehicle* pred = myPartialVehicles.front();
1845 #ifdef DEBUG_CONTEXT
1846  if (DEBUG_COND2(&veh)) {
1847  std::cout << " partials=" << toString(myPartialVehicles) << "\n";
1848  }
1849 #endif
1850  return std::pair<MSVehicle* const, double>(pred, seen - (getLength() - pred->getBackPositionOnLane(this)) - veh.getVehicleType().getMinGap());
1851  }
1852  const MSLane* nextLane = this;
1853  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1854  do {
1855  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
1856  // get the next link used
1857  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1858  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1859  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
1860 #ifdef DEBUG_CONTEXT
1861  if (DEBUG_COND2(&veh)) {
1862  std::cout << " cannot continue after nextLane=" << nextLane->getID() << "\n";
1863  }
1864 #endif
1865  nextLane->releaseVehicles();
1866  break;
1867  }
1868  // check for link leaders
1869  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
1870  nextLane->releaseVehicles();
1871  if (linkLeaders.size() > 0) {
1872  // XXX if there is more than one link leader we should return the most important
1873  // one (gap, decel) but this is hard to know at this point
1874 #ifdef DEBUG_CONTEXT
1875  if (DEBUG_COND2(&veh)) {
1876  std::cout << " found linkLeader after nextLane=" << nextLane->getID() << "\n";
1877  }
1878 #endif
1879  return linkLeaders[0].vehAndGap;
1880  }
1881  bool nextInternal = (*link)->getViaLane() != 0;
1882  nextLane = (*link)->getViaLaneOrLane();
1883  if (nextLane == 0) {
1884  break;
1885  }
1886  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
1887  MSVehicle* leader = nextLane->getLastAnyVehicle();
1888  if (leader != 0) {
1889 #ifdef DEBUG_CONTEXT
1890  if (DEBUG_COND2(&veh)) {
1891  std::cout << " found leader " << leader->getID() << " on nextLane=" << nextLane->getID() << "\n";
1892  }
1893 #endif
1894  const double dist = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
1895  nextLane->releaseVehicles();
1896  return std::make_pair(leader, dist);
1897  }
1898  nextLane->releaseVehicles();
1899  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1900  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1901  }
1902  seen += nextLane->getLength();
1903  if (seen <= dist) {
1904  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1905  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1906  }
1907  if (!nextInternal) {
1908  view++;
1909  }
1910  } while (seen <= dist);
1911  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1912 }
1913 
1914 
1915 std::pair<MSVehicle* const, double>
1916 MSLane::getCriticalLeader(double dist, double seen, double speed, const MSVehicle& veh) const {
1917  const std::vector<MSLane*>& bestLaneConts = veh.getBestLanesContinuation(this);
1918  std::pair<MSVehicle*, double> result = std::make_pair(static_cast<MSVehicle*>(0), -1);
1919  double safeSpeed = std::numeric_limits<double>::max();
1920  int view = 1;
1921  // loop over following lanes
1922  // @note: we don't check the partial occupator for this lane since it was
1923  // already checked in MSLaneChanger::getRealLeader()
1924  const MSLane* nextLane = this;
1925  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1926  do {
1927  // get the next link used
1928  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1929  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1930  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
1931  return result;
1932  }
1933  // check for link leaders
1934  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
1935  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1936  const MSVehicle* leader = (*it).vehAndGap.first;
1937  if (leader != 0 && leader != result.first) {
1938  // XXX ignoring pedestrians here!
1939  // XXX ignoring the fact that the link leader may alread by following us
1940  // XXX ignoring the fact that we may drive up to the crossing point
1941  const double tmpSpeed = veh.getSafeFollowSpeed((*it).vehAndGap, seen, nextLane, (*it).distToCrossing);
1942  if (tmpSpeed < safeSpeed) {
1943  safeSpeed = tmpSpeed;
1944  result = (*it).vehAndGap;
1945  }
1946  }
1947  }
1948  bool nextInternal = (*link)->getViaLane() != 0;
1949  nextLane = (*link)->getViaLaneOrLane();
1950  if (nextLane == 0) {
1951  break;
1952  }
1953  MSVehicle* leader = nextLane->getLastAnyVehicle();
1954  if (leader != 0 && leader != result.first) {
1955  const double gap = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
1956  const double tmpSpeed = veh.getCarFollowModel().insertionFollowSpeed(leader, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
1957  if (tmpSpeed < safeSpeed) {
1958  safeSpeed = tmpSpeed;
1959  result = std::make_pair(leader, gap);
1960  }
1961  }
1962  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1963  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1964  }
1965  seen += nextLane->getLength();
1966  if (seen <= dist) {
1967  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1968  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1969  }
1970  if (!nextInternal) {
1971  view++;
1972  }
1973  } while (seen <= dist);
1974  return result;
1975 }
1976 
1977 
1978 MSLane*
1980  if (myLogicalPredecessorLane != 0) {
1981  return myLogicalPredecessorLane;
1982  }
1983  if (myLogicalPredecessorLane == 0) {
1985  // get only those edges which connect to this lane
1986  for (MSEdgeVector::iterator i = pred.begin(); i != pred.end();) {
1987  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1988  if (j == myIncomingLanes.end()) {
1989  i = pred.erase(i);
1990  } else {
1991  ++i;
1992  }
1993  }
1994  // get the lane with the "straightest" connection
1995  if (pred.size() != 0) {
1996  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1997  MSEdge* best = *pred.begin();
1998  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1999  myLogicalPredecessorLane = j->lane;
2000  }
2001  }
2002  return myLogicalPredecessorLane;
2003 }
2004 
2005 
2006 MSLane*
2008  for (std::vector<IncomingLaneInfo>::const_iterator i = myIncomingLanes.begin(); i != myIncomingLanes.end(); ++i) {
2009  MSLane* cand = (*i).lane;
2010  if (&(cand->getEdge()) == &fromEdge) {
2011  return (*i).lane;
2012  }
2013  }
2014  return 0;
2015 }
2016 
2017 MSLane*
2019  if (myCanonicalPredecessorLane != 0) {
2021  }
2022  if (myIncomingLanes.size() == 0) {
2023  return 0;
2024  }
2025  // myCanonicalPredecessorLane has not yet been determined and there exist incoming lanes
2026  std::vector<IncomingLaneInfo> candidateLanes = myIncomingLanes;
2027  // get the lane with the priorized (or if this does not apply the "straightest") connection
2028  std::sort(candidateLanes.begin(), candidateLanes.end(), incoming_lane_priority_sorter(this));
2029  IncomingLaneInfo best = *(candidateLanes.begin());
2030 #ifdef DEBUG_LANE_SORTER
2031  std::cout << "\nBest predecessor lane for lane '" << myID << "': '" << best.lane->getID() << "'" << std::endl;
2032 #endif
2033  myCanonicalPredecessorLane = best.lane;
2035 }
2036 
2037 MSLane*
2039  if (myCanonicalSuccessorLane != 0) {
2040  return myCanonicalSuccessorLane;
2041  }
2042  if (myLinks.size() == 0) {
2043  return 0;
2044  }
2045  // myCanonicalSuccessorLane has not yet been determined and there exist outgoing links
2046  std::vector<MSLink*> candidateLinks = myLinks;
2047  // get the lane with the priorized (or if this does not apply the "straightest") connection
2048  std::sort(candidateLinks.begin(), candidateLinks.end(), outgoing_lane_priority_sorter(this));
2049  MSLane* best = (*candidateLinks.begin())->getViaLaneOrLane();
2050 #ifdef DEBUG_LANE_SORTER
2051  std::cout << "\nBest successor lane for lane '" << myID << "': '" << best->getID() << "'" << std::endl;
2052 #endif
2053  myCanonicalSuccessorLane = best;
2054  return myCanonicalSuccessorLane;
2055 }
2056 
2057 
2058 LinkState
2061  if (pred == 0) {
2062  return LINKSTATE_DEADEND;
2063  } else {
2064  return MSLinkContHelper::getConnectingLink(*pred, *this)->getState();
2065  }
2066 }
2067 
2068 
2069 std::vector<const MSLane*>
2071  std::vector<const MSLane*> result;
2072  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
2073  assert((*i)->getLane() != 0);
2074  result.push_back((*i)->getLane());
2075  }
2076  return result;
2077 }
2078 
2079 
2080 void
2084 }
2085 
2086 
2087 void
2091 }
2092 
2093 
2094 int
2096  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
2097  if ((*i)->getLane()->getEdge().isCrossing()) {
2098  return (int)(i - myLinks.begin());
2099  }
2100  }
2101  return -1;
2102 }
2103 
2104 // ------------ Current state retrieval
2105 double
2107  double fractions = myPartialVehicles.size() > 0 ? myLength - myPartialVehicles.front()->getBackPositionOnLane(this) : 0;
2109  if (myVehicles.size() != 0) {
2110  MSVehicle* lastVeh = myVehicles.front();
2111  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2112  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2113  }
2114  }
2115  releaseVehicles();
2116  return (myBruttoVehicleLengthSum + fractions) / myLength;
2117 }
2118 
2119 
2120 double
2122  double fractions = myPartialVehicles.size() > 0 ? myLength - myPartialVehicles.front()->getBackPositionOnLane(this) : 0;
2124  if (myVehicles.size() != 0) {
2125  MSVehicle* lastVeh = myVehicles.front();
2126  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2127  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2128  }
2129  }
2130  releaseVehicles();
2131  return (myNettoVehicleLengthSum + fractions) / myLength;
2132 }
2133 
2134 
2135 double
2137  if (myVehicles.size() == 0) {
2138  return 0;
2139  }
2140  double wtime = 0;
2141  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
2142  wtime += (*i)->getWaitingSeconds();
2143  }
2144  return wtime;
2145 }
2146 
2147 
2148 double
2150  if (myVehicles.size() == 0) {
2151  return myMaxSpeed;
2152  }
2153  double v = 0;
2154  const MSLane::VehCont& vehs = getVehiclesSecure();
2155  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2156  v += (*i)->getSpeed();
2157  }
2158  double ret = v / (double) myVehicles.size();
2159  releaseVehicles();
2160  return ret;
2161 }
2162 
2163 
2164 double
2166  double ret = 0;
2167  const MSLane::VehCont& vehs = getVehiclesSecure();
2168  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2169  ret += (*i)->getCO2Emissions();
2170  }
2171  releaseVehicles();
2172  return ret;
2173 }
2174 
2175 
2176 double
2178  double ret = 0;
2179  const MSLane::VehCont& vehs = getVehiclesSecure();
2180  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2181  ret += (*i)->getCOEmissions();
2182  }
2183  releaseVehicles();
2184  return ret;
2185 }
2186 
2187 
2188 double
2190  double ret = 0;
2191  const MSLane::VehCont& vehs = getVehiclesSecure();
2192  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2193  ret += (*i)->getPMxEmissions();
2194  }
2195  releaseVehicles();
2196  return ret;
2197 }
2198 
2199 
2200 double
2202  double ret = 0;
2203  const MSLane::VehCont& vehs = getVehiclesSecure();
2204  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2205  ret += (*i)->getNOxEmissions();
2206  }
2207  releaseVehicles();
2208  return ret;
2209 }
2210 
2211 
2212 double
2214  double ret = 0;
2215  const MSLane::VehCont& vehs = getVehiclesSecure();
2216  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2217  ret += (*i)->getHCEmissions();
2218  }
2219  releaseVehicles();
2220  return ret;
2221 }
2222 
2223 
2224 double
2226  double ret = 0;
2227  const MSLane::VehCont& vehs = getVehiclesSecure();
2228  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2229  ret += (*i)->getFuelConsumption();
2230  }
2231  releaseVehicles();
2232  return ret;
2233 }
2234 
2235 
2236 double
2238  double ret = 0;
2239  const MSLane::VehCont& vehs = getVehiclesSecure();
2240  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2241  ret += (*i)->getElectricityConsumption();
2242  }
2243  releaseVehicles();
2244  return ret;
2245 }
2246 
2247 
2248 double
2250  double ret = 0;
2251  const MSLane::VehCont& vehs = getVehiclesSecure();
2252  if (vehs.size() == 0) {
2253  releaseVehicles();
2254  return 0;
2255  }
2256  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2257  double sv = (*i)->getHarmonoise_NoiseEmissions();
2258  ret += (double) pow(10., (sv / 10.));
2259  }
2260  releaseVehicles();
2261  return HelpersHarmonoise::sum(ret);
2262 }
2263 
2264 
2265 bool
2266 MSLane::VehPosition::operator()(const MSVehicle* cmp, double pos) const {
2267  return cmp->getPositionOnLane() >= pos;
2268 }
2269 
2270 
2271 int
2273  return v1->getBackPositionOnLane(myLane) > v2->getBackPositionOnLane(myLane);
2274 }
2275 
2276 int
2278  const double pos1 = v1->getBackPositionOnLane(myLane);
2279  const double pos2 = v2->getBackPositionOnLane(myLane);
2280  if (pos1 != pos2) {
2281  return pos1 < pos2;
2282  } else {
2284  }
2285 }
2286 
2288  myEdge(e),
2289  myLaneDir(e->getLanes()[0]->getShape().angleAt2D(0)) {
2290 }
2291 
2292 
2293 int
2294 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
2295 // std::cout << "\nby_connections_to_sorter()";
2296 
2297  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
2298  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
2299  double s1 = 0;
2300  if (ae1 != 0 && ae1->size() != 0) {
2301 // std::cout << "\nsize 1 = " << ae1->size()
2302 // << " anglediff 1 = " << fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.
2303 // << "\nallowed lanes: ";
2304 // for (std::vector<MSLane*>::const_iterator j = ae1->begin(); j != ae1->end(); ++j){
2305 // std::cout << "\n" << (*j)->getID();
2306 // }
2307  s1 = (double) ae1->size() + fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2308  }
2309  double s2 = 0;
2310  if (ae2 != 0 && ae2->size() != 0) {
2311 // std::cout << "\nsize 2 = " << ae2->size()
2312 // << " anglediff 2 = " << fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.
2313 // << "\nallowed lanes: ";
2314 // for (std::vector<MSLane*>::const_iterator j = ae2->begin(); j != ae2->end(); ++j){
2315 // std::cout << "\n" << (*j)->getID();
2316 // }
2317  s2 = (double) ae2->size() + fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2318  }
2319 
2320 // std::cout << "\ne1 = " << e1->getID() << " e2 = " << e2->getID()
2321 // << "\ns1 = " << s1 << " s2 = " << s2
2322 // << std::endl;
2323 
2324  return s1 < s2;
2325 }
2326 
2327 
2329  myLane(targetLane),
2330  myLaneDir(targetLane->getShape().angleAt2D(0)) {}
2331 
2332 int
2334  const MSLane* noninternal1 = laneInfo1.lane;
2335  while (noninternal1->isInternal()) {
2336  assert(noninternal1->getIncomingLanes().size() == 1);
2337  noninternal1 = noninternal1->getIncomingLanes()[0].lane;
2338  }
2339  MSLane* noninternal2 = laneInfo2.lane;
2340  while (noninternal2->isInternal()) {
2341  assert(noninternal2->getIncomingLanes().size() == 1);
2342  noninternal2 = noninternal2->getIncomingLanes()[0].lane;
2343  }
2344 
2345  MSLink* link1 = noninternal1->getLinkTo(myLane);
2346  MSLink* link2 = noninternal2->getLinkTo(myLane);
2347 
2348 #ifdef DEBUG_LANE_SORTER
2349  std::cout << "\nincoming_lane_priority sorter()\n"
2350  << "noninternal predecessor for lane '" << laneInfo1.lane->getID()
2351  << "': '" << noninternal1->getID() << "'\n"
2352  << "noninternal predecessor for lane '" << laneInfo2.lane->getID()
2353  << "': '" << noninternal2->getID() << "'\n";
2354 #endif
2355 
2356  assert(laneInfo1.lane->isInternal() || link1 == laneInfo1.viaLink);
2357  assert(link1 != 0);
2358  assert(link2 != 0);
2359 
2360  // check priority between links
2361  bool priorized1 = true;
2362  bool priorized2 = true;
2363 
2364  std::vector<MSLink*>::const_iterator j;
2365 #ifdef DEBUG_LANE_SORTER
2366  std::cout << "FoeLinks of '" << noninternal1->getID() << "'" << std::endl;
2367 #endif
2368  for (j = link1->getFoeLinks().begin(); j != link1->getFoeLinks().end(); ++j) {
2369 #ifdef DEBUG_LANE_SORTER
2370  std::cout << (*j)->getLaneBefore()->getID() << std::endl;
2371 #endif
2372  if (*j == link2) {
2373  priorized1 = false;
2374  break;
2375  }
2376  }
2377 
2378 #ifdef DEBUG_LANE_SORTER
2379  std::cout << "FoeLinks of '" << noninternal2->getID() << "'" << std::endl;
2380 #endif
2381  for (j = link2->getFoeLinks().begin(); j != link2->getFoeLinks().end(); ++j) {
2382 #ifdef DEBUG_LANE_SORTER
2383  std::cout << (*j)->getLaneBefore()->getID() << std::endl;
2384 #endif
2385  // either link1 is priorized, or it should not appear in link2's foes
2386  if (*j == link2) {
2387  priorized2 = false;
2388  break;
2389  }
2390  }
2391  // if one link is subordinate, the other must be priorized
2392  assert(priorized1 || priorized2);
2393  if (priorized1 != priorized2) {
2394  return priorized1;
2395  }
2396 
2397  // both are priorized, compare angle difference
2398  double d1 = fabs(GeomHelper::angleDiff(noninternal1->getShape().angleAt2D(0), myLaneDir));
2399  double d2 = fabs(GeomHelper::angleDiff(noninternal2->getShape().angleAt2D(0), myLaneDir));
2400 
2401  return d2 > d1;
2402 }
2403 
2404 
2405 
2407  myLane(sourceLane),
2408  myLaneDir(sourceLane->getShape().angleAt2D(0)) {}
2409 
2410 int
2412  const MSLane* target1 = link1->getLane();
2413  const MSLane* target2 = link2->getLane();
2414  if (target2 == 0) {
2415  return true;
2416  }
2417  if (target1 == 0) {
2418  return false;
2419  }
2420 
2421 #ifdef DEBUG_LANE_SORTER
2422  std::cout << "\noutgoing_lane_priority sorter()\n"
2423  << "noninternal successors for lane '" << myLane->getID()
2424  << "': '" << target1->getID() << "' and "
2425  << "'" << target2->getID() << "'\n";
2426 #endif
2427 
2428  // priority of targets
2429  int priority1 = target1->getEdge().getPriority();
2430  int priority2 = target2->getEdge().getPriority();
2431 
2432  if (priority1 != priority2) {
2433  return priority1 > priority2;
2434  }
2435 
2436  // if priority of targets coincides, use angle difference
2437 
2438  // both are priorized, compare angle difference
2439  double d1 = fabs(GeomHelper::angleDiff(target1->getShape().angleAt2D(0), myLaneDir));
2440  double d2 = fabs(GeomHelper::angleDiff(target2->getShape().angleAt2D(0), myLaneDir));
2441 
2442  return d2 > d1;
2443 }
2444 
2445 
2446 void
2448  out.openTag(SUMO_TAG_LANE);
2449  out.writeAttr("id", getID()); // using "id" instead of SUMO_ATTR_ID makes the value only show up in xml state
2452  out.closeTag();
2453  out.closeTag();
2454 }
2455 
2456 
2457 void
2458 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
2459  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
2460  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
2461  if (v != 0) {
2462  v->updateBestLanes(false, this);
2465  v->processNextStop(v->getSpeed());
2466  }
2467  }
2468 }
2469 
2470 
2472 MSLane::getFollowersOnConsecutive(const MSVehicle* ego, double backOffset,
2473  bool allSublanes, double searchDist, bool ignoreMinorLinks) const {
2474  // get the follower vehicle on the lane to change to
2475  const double egoPos = backOffset + ego->getVehicleType().getLength();
2476 #ifdef DEBUG_CONTEXT
2477  if (DEBUG_COND2(ego)) {
2478  std::cout << SIMTIME << " getFollowers lane=" << getID() << " ego=" << ego->getID() << " pos=" << egoPos << "\n";
2479  }
2480 #endif
2481  assert(ego != 0);
2482  const double egoLatDist = ego->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2483  MSCriticalFollowerDistanceInfo result(this, allSublanes ? 0 : ego, allSublanes ? 0 : egoLatDist);
2485  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
2486  const MSVehicle* veh = *last;
2487 #ifdef DEBUG_CONTEXT
2488  if (DEBUG_COND2(ego)) {
2489  std::cout << " veh=" << veh->getID() << " lane=" << veh->getLane()->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
2490  }
2491 #endif
2492  if (veh != ego && veh->getPositionOnLane(this) <= egoPos) {
2493  //const double latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2494  const double latOffset = veh->getLatOffset(this);
2495  const double dist = backOffset - veh->getPositionOnLane(this) - veh->getVehicleType().getMinGap();
2496  result.addFollower(veh, ego, dist, latOffset);
2497 #ifdef DEBUG_CONTEXT
2498  if (DEBUG_COND2(ego)) {
2499  std::cout << " (1) added veh=" << veh->getID() << " latOffset=" << latOffset << " result=" << result.toString() << "\n";
2500  }
2501 #endif
2502  }
2503  }
2504 #ifdef DEBUG_CONTEXT
2505  if (DEBUG_COND2(ego)) {
2506  std::cout << " result.numFreeSublanes=" << result.numFreeSublanes() << "\n";
2507  }
2508 #endif
2509  if (result.numFreeSublanes() > 0) {
2510  // do a tree search among all follower lanes and check for the most
2511  // important vehicle (the one requiring the largest reargap)
2512  // to get a safe bound on the necessary search depth, we need to consider the maximum speed and minimum
2513  // deceleration of potential follower vehicles
2514  if (searchDist == -1) {
2515  searchDist = getMaximumBrakeDist() - backOffset;
2516  }
2517 
2518  std::set<MSLane*> visited;
2519  std::vector<MSLane::IncomingLaneInfo> newFound;
2520  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
2521  while (toExamine.size() != 0) {
2522  for (std::vector<MSLane::IncomingLaneInfo>::iterator it = toExamine.begin(); it != toExamine.end(); ++it) {
2523  MSLane* next = (*it).lane;
2524  searchDist = MAX2(searchDist, next->getMaximumBrakeDist() - backOffset);
2525  MSLeaderInfo first = next->getFirstVehicleInformation(0, 0, false, std::numeric_limits<double>::max(), false);
2526  MSLeaderInfo firstFront = next->getFirstVehicleInformation(0, 0, true);
2527 #ifdef DEBUG_CONTEXT
2528  if (DEBUG_COND2(ego)) {
2529  std::cout << " next=" << next->getID() << " first=" << first.toString() << " firstFront=" << firstFront.toString() << "\n";
2530  }
2531 #endif
2532  for (int i = 0; i < first.numSublanes(); ++i) {
2533  const MSVehicle* v = first[i];
2534  double agap = 0;
2535  if (v != 0 && v != ego) {
2536  if (!v->isFrontOnLane(next)) {
2537  // the front of v is already on divergent trajectory from the ego vehicle
2538  // for which this method is called (in the context of MSLaneChanger).
2539  // Therefore, technically v is not a follower but only an obstruction and
2540  // the gap is not between the front of v and the back of ego
2541  // but rather between the flank of v and the back of ego.
2542  agap = (*it).length - next->getLength() + backOffset
2544  - v->getVehicleType().getMinGap();
2545  if (agap > 0) {
2546  // Only if ego overlaps we treat v as if it were a real follower
2547  // Otherwise we ignore it and look for another follower
2548  v = firstFront[i];
2549  if (v != 0 && v != ego) {
2550  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2551  } else {
2552  v = 0;
2553  }
2554  }
2555  } else {
2556  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2557  if (!(*it).viaLink->havePriority() && !ego->onFurtherEdge(&(*it).lane->getEdge())) {
2558  // if v comes from a minor side road it should not block lane changing
2559  agap = MAX2(agap, 0.0);
2560  }
2561  }
2562  result.addFollower(v, ego, agap, 0, i);
2563 #ifdef DEBUG_CONTEXT
2564  if (DEBUG_COND2(ego)) {
2565  std::cout << " (2) added veh=" << Named::getIDSecure(v) << " agap=" << agap << " next=" << next->getID() << " result=" << result.toString() << "\n";
2566  }
2567 #endif
2568  }
2569  }
2570  if ((*it).length < searchDist) {
2571  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
2572  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
2573  if (visited.find((*j).lane) == visited.end() && ((*j).viaLink->havePriority() || !ignoreMinorLinks)) {
2574  visited.insert((*j).lane);
2576  ili.lane = (*j).lane;
2577  ili.length = (*j).length + (*it).length;
2578  ili.viaLink = (*j).viaLink;
2579  newFound.push_back(ili);
2580  }
2581  }
2582  }
2583  }
2584  toExamine.clear();
2585  swap(newFound, toExamine);
2586  }
2587  //return result;
2588 
2589  }
2590  return result;
2591 }
2592 
2593 
2594 void
2595 MSLane::getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle* ego,
2596  const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result) const {
2597  if (seen > dist) {
2598  return;
2599  }
2600  // check partial vehicles (they might be on a different route and thus not
2601  // found when iterating along bestLaneConts)
2602  for (VehCont::const_iterator it = myPartialVehicles.begin(); it != myPartialVehicles.end(); ++it) {
2603  MSVehicle* veh = *it;
2604  if (!veh->isFrontOnLane(this)) {
2605  result.addLeader(veh, seen);
2606  } else {
2607  break;
2608  }
2609  }
2610  const MSLane* nextLane = this;
2611  int view = 1;
2612  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
2613  // loop over following lanes
2614  while (seen < dist && result.numFreeSublanes() > 0) {
2615  // get the next link used
2616  MSLinkCont::const_iterator link = succLinkSec(*ego, view, *nextLane, bestLaneConts);
2617  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, ego->getVehicleType().getLength(),
2618  ego->getImpatience(), ego->getCarFollowModel().getMaxDecel(), 0, ego->getLateralPositionOnLane()) || (*link)->haveRed()) {
2619  break;
2620  }
2621  // check for link leaders
2622  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(ego, seen);
2623  if (linkLeaders.size() > 0) {
2624  const MSLink::LinkLeader ll = linkLeaders[0];
2625  if (ll.vehAndGap.first != 0) {
2626  // add link leader to all sublanes and return
2627  for (int i = 0; i < result.numSublanes(); ++i) {
2628  MSVehicle* veh = ll.vehAndGap.first;
2629  result.addLeader(veh, ll.vehAndGap.second, 0);
2630  }
2631  return; ;
2632  } // XXX else, deal with pedestrians
2633  }
2634  bool nextInternal = (*link)->getViaLane() != 0;
2635  nextLane = (*link)->getViaLaneOrLane();
2636  if (nextLane == 0) {
2637  break;
2638  }
2639 
2640  MSLeaderInfo leaders = nextLane->getLastVehicleInformation(0, 0, 0, false);
2641 #ifdef DEBUG_CONTEXT
2642  if (DEBUG_COND2(ego)) {
2643  std::cout << SIMTIME << " getLeadersOnConsecutive lane=" << getID() << " nextLane=" << nextLane->getID() << " leaders=" << leaders.toString() << "\n";
2644  }
2645 #endif
2646  // @todo check alignment issues if the lane width changes
2647  const int iMax = MIN2(leaders.numSublanes(), result.numSublanes());
2648  for (int i = 0; i < iMax; ++i) {
2649  const MSVehicle* veh = leaders[i];
2650  if (veh != 0) {
2651 #ifdef DEBUG_CONTEXT
2652  if (DEBUG_COND2(ego)) std::cout << " lead=" << veh->getID()
2653  << " seen=" << seen
2654  << " minGap=" << ego->getVehicleType().getMinGap()
2655  << " backPos=" << veh->getBackPositionOnLane(nextLane)
2656  << " gap=" << seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane)
2657  << "\n";
2658 #endif
2659  result.addLeader(veh, seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane), 0, i);
2660  }
2661  }
2662 
2663  if (nextLane->getVehicleMaxSpeed(ego) < speed) {
2664  dist = ego->getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(ego));
2665  }
2666  seen += nextLane->getLength();
2667  if (seen <= dist) {
2668  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
2669  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
2670  }
2671  if (!nextInternal) {
2672  view++;
2673  }
2674  }
2675 }
2676 
2677 
2678 
2679 MSVehicle*
2681  for (VehCont::const_reverse_iterator i = myPartialVehicles.rbegin(); i != myPartialVehicles.rend(); ++i) {
2682  MSVehicle* veh = *i;
2683  if (veh->isFrontOnLane(this)
2684  && veh != ego
2685  && veh->getPositionOnLane() <= ego->getPositionOnLane()) {
2686 #ifdef DEBUG_CONTEXT
2687  if (DEBUG_COND2(ego)) {
2688  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " found=" << veh->getID() << "\n";
2689  }
2690 #endif
2691  return veh;
2692  }
2693  }
2694 #ifdef DEBUG_CONTEXT
2695  if (DEBUG_COND2(ego)) {
2696  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " nothing found. partials=" << toString(myPartialVehicles) << "\n";
2697  }
2698 #endif
2699  return 0;
2700 }
2701 
2702 
2703 MSLane*
2705  if (myNeighs.size() == 1) {
2706  return dictionary(myNeighs[0]);
2707  }
2708  return 0;
2709 }
2710 
2711 
2712 double
2713 MSLane::getOppositePos(double pos) const {
2714  MSLane* opposite = getOpposite();
2715  if (opposite == 0) {
2716  assert(false);
2717  throw ProcessError("Lane '" + getID() + "' cannot compute oppositePos as there is no opposite lane.");
2718  }
2719  // XXX transformations for curved geometries
2720  return MAX2(0., opposite->getLength() - pos);
2721 
2722 }
2723 
2724 std::pair<MSVehicle* const, double>
2725 MSLane::getFollower(const MSVehicle* ego, double egoPos, double dist, bool ignoreMinorLinks) const {
2726  for (AnyVehicleIterator first = anyVehiclesUpstreamBegin(); first != anyVehiclesUpstreamEnd(); ++first) {
2727  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
2728  MSVehicle* pred = (MSVehicle*)*first;
2729 #ifdef DEBUG_CONTEXT
2730  if (DEBUG_COND2(ego)) {
2731  std::cout << " getFollower lane=" << getID() << " egoPos=" << egoPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << "\n";
2732  }
2733 #endif
2734  if (pred->getPositionOnLane(this) < egoPos && pred != ego) {
2735  return std::pair<MSVehicle* const, double>(pred, egoPos - pred->getPositionOnLane(this) - ego->getVehicleType().getLength() - pred->getVehicleType().getMinGap());
2736  }
2737  }
2738  const double backOffset = egoPos - ego->getVehicleType().getLength();
2739  CLeaderDist result = getFollowersOnConsecutive(ego, backOffset, true, dist, ignoreMinorLinks)[0];
2740  return std::make_pair(const_cast<MSVehicle*>(result.first), result.second);
2741 }
2742 
2743 std::pair<MSVehicle* const, double>
2744 MSLane::getOppositeLeader(const MSVehicle* ego, double dist, bool oppositeDir) const {
2745 #ifdef DEBUG_OPPOSITE
2746  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeLeader lane=" << getID()
2747  << " ego=" << ego->getID()
2748  << " pos=" << ego->getPositionOnLane()
2749  << " posOnOpposite=" << getOppositePos(ego->getPositionOnLane())
2750  << " dist=" << dist
2751  << " oppositeDir=" << oppositeDir
2752  << "\n";
2753 #endif
2754  if (!oppositeDir) {
2755  return getLeader(ego, getOppositePos(ego->getPositionOnLane()), ego->getBestLanesContinuation(this));
2756  } else {
2757  const double egoLength = ego->getVehicleType().getLength();
2758  const double egoPos = ego->getLaneChangeModel().isOpposite() ? ego->getPositionOnLane() : getOppositePos(ego->getPositionOnLane());
2759  std::pair<MSVehicle* const, double> result = getFollower(ego, egoPos + egoLength, dist, true);
2760  result.second -= ego->getVehicleType().getMinGap();
2761  return result;
2762  }
2763 }
2764 
2765 
2766 std::pair<MSVehicle* const, double>
2768 #ifdef DEBUG_OPPOSITE
2769  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeFollower lane=" << getID()
2770  << " ego=" << ego->getID()
2771  << " backPos=" << ego->getBackPositionOnLane()
2772  << " posOnOpposite=" << getOppositePos(ego->getBackPositionOnLane())
2773  << "\n";
2774 #endif
2775  if (ego->getLaneChangeModel().isOpposite()) {
2776  std::pair<MSVehicle* const, double> result = getFollower(ego, getOppositePos(ego->getPositionOnLane()), -1, true);
2777  return result;
2778  } else {
2779  std::pair<MSVehicle* const, double> result = getLeader(ego, getOppositePos(ego->getPositionOnLane() - ego->getVehicleType().getLength()), std::vector<MSLane*>());
2780  if (result.second > 0) {
2781  // follower can be safely ignored since it is going the other way
2782  return std::make_pair(static_cast<MSVehicle*>(0), -1);
2783  } else {
2784  return result;
2785  }
2786  }
2787 }
2788 
2789 
2790 void
2792  const std::string action = oc.getString("collision.action");
2793  if (action == "none") {
2795  } else if (action == "warn") {
2797  } else if (action == "teleport") {
2799  } else if (action == "remove") {
2801  } else {
2802  throw ProcessError("Invalid collision.action '" + action + "'.");
2803  }
2804  myCheckJunctionCollisions = oc.getBool("collision.check-junctions");
2805  myCollisionStopTime = string2time(oc.getString("collision.stoptime"));
2806 }
2807 
2808 
2809 void
2810 MSLane::setPermissions(SVCPermissions permissions, long transientID) {
2811  if (transientID == CHANGE_PERMISSIONS_PERMANENT) {
2812  myPermissions = permissions;
2813  myOriginalPermissions = permissions;
2814  } else {
2815  myPermissionChanges[transientID] = permissions;
2817  }
2818 }
2819 
2820 
2821 void
2822 MSLane::resetPermissions(long transientID) {
2823  myPermissionChanges.erase(transientID);
2824  if (myPermissionChanges.empty()) {
2826  } else {
2827  // combine all permission changes
2829  for (std::map<long, SVCPermissions>::iterator it = myPermissionChanges.begin(); it != myPermissionChanges.end(); ++it) {
2830  myPermissions &= it->second;
2831  }
2832  }
2833 }
2834 
2835 /****************************************************************************/
2836 
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:719
std::pair< MSVehicle *const, double > getFollower(const MSVehicle *ego, double egoPos, double dist, bool ignoreMinorLinks) const
Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane) ...
Definition: MSLane.cpp:2725
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2106
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:2458
static double gLateralResolution
Definition: MSGlobals.h:92
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1126
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1979
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:138
VehCont myVehicles
The lane&#39;s vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1090
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:462
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time, assuming that during...
Definition: MSCFModel.h:263
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:136
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:211
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:132
double getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:2201
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
A free lateral position is chosen.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
The position is given.
MSVehicle * getFirstFullVehicle() const
returns the first vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1511
void resetPermissions(long transientID)
Definition: MSLane.cpp:2822
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
At the leftmost side of the lane.
virtual int addLeader(const MSVehicle *veh, bool beyond, double latOffset=0)
MSLane(const std::string &id, double maxSpeed, double length, MSEdge *const edge, int numericalID, const PositionVector &shape, double width, SVCPermissions permissions, int index, bool isRampAccel)
Constructor.
Definition: MSLane.cpp:161
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:294
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3766
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2272
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:536
const MSEdge * getNextNormal() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1360
std::string containerstop
(Optional) container stop if one is assigned to the stop
static void insertIDs(std::vector< std::string > &into)
Adds the ids of all stored lanes into the given vector.
Definition: MSLane.cpp:1403
void enterLaneAtInsertion(MSLane *enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:2816
Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn&#39;t apply, wrt. the angle differenc...
Definition: MSLane.h:1274
MSLane * parallelLane(const MSLane *const lane, int offset) const
Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist...
Definition: MSEdge.cpp:277
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:2744
bool parking
whether the vehicle is removed from the net while stopping
double getMaxSpeedFactor() const
return the maximum speed factor for all vehicles that ever entered the network
begin/end of the description of a single lane
bool hasDeparted() const
Returns whether this vehicle has already departed.
Stop & getNextStop()
Definition: MSVehicle.cpp:3987
int myI2
index for myPartialVehicles
Definition: MSLane.h:145
bool resumeFromStopping()
Definition: MSVehicle.cpp:3940
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:488
double getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:2225
SUMOTime duration
The stopping duration.
The speed is given.
bool isInsertionSuccess(MSVehicle *vehicle, double speed, double pos, double posLat, bool recheckNextLanes, MSMoveReminder::Notification notification)
Tries to insert the given vehicle with the given state (speed and pos)
Definition: MSLane.cpp:535
#define M_PI
Definition: angles.h:37
void registerTeleportYield()
register one non-collision-related teleport
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:1411
double getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:1755
The vehicle arrived at a junction.
void setMaxSpeed(double val)
Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
Definition: MSLane.cpp:1642
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:454
bool freeInsertion(MSVehicle &veh, double speed, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle on any place.
Definition: MSLane.cpp:313
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:128
This is an uncontrolled, minor link, has to stop.
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:363
std::vector< IncomingLaneInfo > myIncomingLanes
All direct predecessor lanes.
Definition: MSLane.h:1135
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:60
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
int myI2End
end index for myPartialVehicles
Definition: MSLane.h:149
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:201
MSLane * myCanonicalPredecessorLane
Similar to LogicalPredecessorLane,.
Definition: MSLane.h:1141
int myIndex
The lane index.
Definition: MSLane.h:1077
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:1447
The lateral position is chosen randomly.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
SUMOTime myLeaderInfoTime
time step for which myLeaderInfo was last updated
Definition: MSLane.h:1167
If a fixed number of random choices fails, a free lateral position is chosen.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
bool operator()(const MSVehicle *cmp, double pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:2266
static SUMOTime myCollisionStopTime
Definition: MSLane.h:1201
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2070
void handleCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, double gap, double latGap, std::set< const MSVehicle *, SUMOVehicle::ComparatorIdLess > &toRemove, std::set< const MSVehicle *> &toTeleport) const
take action upon collision
Definition: MSLane.cpp:1173
A RT-tree for efficient storing of SUMO&#39;s Named objects.
Definition: NamedRTree.h:72
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1667
bool detectCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, std::set< const MSVehicle *, SUMOVehicle::ComparatorIdLess > &toRemove, std::set< const MSVehicle *> &toTeleport) const
detect whether there is a collision between the two vehicles
Definition: MSLane.cpp:1116
double myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:1147
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1534
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:292
const MSEdge *const myEdge
Definition: MSLane.h:1264
This is a dead end link.
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1691
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:158
T MAX2(T a, T b)
Definition: StdDefs.h:70
double getPMxEmissions() const
Returns the sum of last step PMx emissions.
Definition: MSLane.cpp:2189
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:2287
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:484
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:379
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
The speed is chosen randomly.
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3753
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1481
static void initCollisionOptions(const OptionsCont &oc)
Definition: MSLane.cpp:2791
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:214
const MSRoute & getRoute() const
Returns the current route.
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1604
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2081
SUMOTime until
The time at which the vehicle may continue its journey.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:92
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2018
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:820
This is an uncontrolled, right-before-left link.
std::map< long, SVCPermissions > myPermissionChanges
Definition: MSLane.h:1186
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1880
double getSafeFollowSpeed(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, const MSLane *const lane, double distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:1838
void addNeigh(const std::string &id)
Adds a neighbor to this lane.
Definition: MSLane.cpp:207
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
const SVCPermissions SVCAll
all VClasses are allowed
void gotActive(MSLane *l)
Informs the control that the given lane got active.
virtual double insertionStopSpeed(const MSVehicle *const veh, double speed, double gap) const
Computes the vehicle&#39;s safe speed for approaching an obstacle at insertion without constraints due to...
Definition: MSCFModel.cpp:229
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:223
VehCont myPartialVehicles
The lane&#39;s partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition: MSLane.h:1102
The position is chosen randomly.
static bool myCheckJunctionCollisions
Definition: MSLane.h:1200
This is an uncontrolled, all-way stop link.
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:500
int myI1End
end index for myVehicles
Definition: MSLane.h:147
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:607
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
virtual double insertionFollowSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle&#39;s safe speed (no dawdling) This method is used during the insertion stage...
Definition: MSCFModel.cpp:218
int myDirection
index delta
Definition: MSLane.h:153
std::string parkingarea
(Optional) parking area if one is assigned to the stop
PositionVector myShape
The shape of the lane.
Definition: MSLane.h:1074
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The speed is given.
MSLane * getCanonicalSuccessorLane() const
Definition: MSLane.cpp:2038
void getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle *ego, const std::vector< MSLane *> &bestLaneConts, MSLeaderDistanceInfo &result) const
Returns the immediate leaders and the distance to them (as getLeaderOnConsecutive but for the sublane...
Definition: MSLane.cpp:2595
bool myDownstream
iteration direction
Definition: MSLane.h:151
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2921
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:391
#define SIMTIME
Definition: SUMOTime.h:70
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2465
int getLaneIndex() const
Definition: MSVehicle.cpp:3577
std::vector< std::string > myNeighs
Definition: MSLane.h:1183
static CollisionAction myCollisionAction
the action to take on collisions
Definition: MSLane.h:1199
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:288
std::map< std::string, MSLane *> DictType
definition of the static dictionary type
Definition: MSLane.h:1189
static CollisionAction getCollisionAction()
Definition: MSLane.h:1015
MSLinkCont myLinks
Definition: MSLane.h:1154
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:1004
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSLane.h:1192
Sorts lanes (their origin link) by the priority of their noninternal target edges or...
Definition: MSLane.h:1294
bool isInternal() const
Definition: MSLane.cpp:1497
std::string busstop
(Optional) bus stop if one is assigned to the stop
#define SUMOTime_MIN
Definition: SUMOTime.h:45
void addApproachingLane(MSLane *lane, bool warnMultiCon)
Definition: MSLane.cpp:1701
double departSpeed
(optional) The initial speed of the vehicle
virtual const MSEdge * succEdge(int nSuccs) const =0
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
A road/street connecting two junctions.
Definition: MSEdge.h:80
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:2872
virtual int addLeader(const MSVehicle *veh, double gap, double latOffset=0, int sublane=-1)
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:3638
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:428
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:796
bool checkFailure(MSVehicle *aVehicle, double &speed, double &dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:517
double myLength
Lane length [m].
Definition: MSLane.h:1114
#define max(a, b)
Definition: polyfonts.c:65
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
VehCont myTmpVehicles
Container for lane-changing vehicles. After completion of lane-change- process, the containers will b...
Definition: MSLane.h:1106
int operator()(const IncomingLaneInfo &lane1, const IncomingLaneInfo &lane2) const
comparing operator
Definition: MSLane.cpp:2333
MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else 0.
Definition: MSLane.cpp:1625
const MSVehicle * operator*()
Definition: MSLane.cpp:113
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:2095
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:236
double getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:2165
const bool myIsRampAccel
whether this lane is an acceleration lane
Definition: MSLane.h:1175
Representation of a vehicle.
Definition: SUMOVehicle.h:67
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
int operator()(const std::pair< const MSVehicle *, double > &p1, const std::pair< const MSVehicle *, double > &p2) const
Definition: MSLane.cpp:1733
void setLength(double val)
Sets a new length for the lane (used by TraCI only)
Definition: MSLane.cpp:1649
This is an uncontrolled, minor link, has to brake.
double basePos(const MSVehicle &veh) const
departure position where the vehicle fits fully onto the lane (if possible)
Definition: MSLane.cpp:512
Sorts vehicles by their position (descending)
Definition: MSLane.h:1207
double myRightSideOnEdge
the combined width of all lanes with lower index on myEdge
Definition: MSLane.h:1178
std::string chargingStation
(Optional) charging station if one is assigned to the stop
SVCPermissions myOriginalPermissions
The original vClass permissions for this lane (before temporary modifications)
Definition: MSLane.h:1129
outgoing_lane_priority_sorter(const MSLane *sourceLane)
constructor
Definition: MSLane.cpp:2406
A list of positions.
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2939
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2088
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:3276
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, double latOffset, double minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:859
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:310
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3606
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:824
double getMinDeceleration() const
return the minimum deceleration capability for all vehicles that ever entered the network ...
const std::map< SUMOVehicleClass, double > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:1132
bool isEmpty() const
Definition: MSLane.cpp:1492
bool triggered
whether an arriving person lets the vehicle continue
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
Definition: MSLane.cpp:2767
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
The vehicle arrived at its destination (is deleted)
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:476
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:294
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:887
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false)
Adds a stop.
Definition: MSVehicle.cpp:893
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
int operator()(const MSLink *link1, const MSLink *link2) const
comparing operator
Definition: MSLane.cpp:2411
Sorts edges by their angle relative to the given edge (straight comes first)
Definition: MSLane.h:1253
The maximum speed is used.
std::string toString() const
print a debugging representation
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:831
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:257
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:47
static double rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
T MIN2(T a, T b)
Definition: StdDefs.h:64
MSVehicle * getPartialBehind(const MSVehicle *ego) const
Definition: MSLane.cpp:2680
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:390
void add(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:385
#define POSITION_EPS
Definition: config.h:175
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:2059
double getImpatience() const
Returns this vehicles impatience.
No information given; use default.
virtual bool executeMovements(SUMOTime t, std::vector< MSLane *> &lanesWithVehiclesToIntegrate)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:1262
std::pair< MSVehicle *const, double > getLeader(const MSVehicle *veh, const double vehPos, const std::vector< MSLane *> &bestLaneConts, double dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1765
CollisionAction
Definition: MSLane.h:162
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:598
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:234
bool hasInfluencer() const
Definition: MSVehicle.h:1425
int myRightmostSublane
the index of the rightmost sublane of this lane on myEdge
Definition: MSLane.h:1180
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:1138
double endPos
The stopping position end.
double getMinGap() const
Get the free space in front of vehicles of this class.
SUMOTime collisionStopTime() const
Returns the remaining time a vehicle needs to stop due to a collision. A negative value indicates tha...
Definition: MSVehicle.cpp:1121
Something on a lane to be noticed about vehicle movement.
double getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:201
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2704
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:395
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1656
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
void registerTeleportJam()
register one non-collision-related teleport
double getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:2213
If a fixed number of random choices fails, a free position is chosen.
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of...
Definition: MSLane.h:1157
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
bool containerTriggered
whether an arriving container lets the vehicle continue
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane *> &conts)
Definition: MSLane.cpp:1548
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:2294
Base class for objects which have an id.
Definition: Named.h:46
int myNumericalID
Unique numerical ID (set on reading by netload)
Definition: MSLane.h:1071
std::vector< MSMoveReminder *> myMoveReminders
This lane&#39;s move reminder.
Definition: MSLane.h:1196
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
double getRightSideOnEdge() const
Definition: MSLane.h:924
incoming_lane_priority_sorter(const MSLane *targetLane)
constructor
Definition: MSLane.cpp:2328
std::string lane
The lane to stop at.
void initRestrictions()
initialized vClass-specific speed limits
Definition: MSLane.cpp:195
AnyVehicleIterator & operator++()
Definition: MSLane.cpp:98
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
double departPosLat
(optional) The lateral position the vehicle shall depart from
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1502
void sortPartialVehicles()
sorts myPartialVehicles
Definition: MSLane.cpp:1474
void markDelayed() const
Definition: MSEdge.h:644
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
void setPermissions(SVCPermissions permissions, long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition: MSLane.cpp:2810
virtual std::string toString() const
print a debugging representation
double getElectricityConsumption() const
Returns the sum of last step electricity consumption.
Definition: MSLane.cpp:2237
double safeInsertionSpeed(const MSVehicle *veh, const MSLeaderInfo &leaders, double speed)
return the maximum safe speed for insertion behind leaders (a negative value indicates that safe inse...
Definition: MSLane.cpp:840
double departPos
(optional) The position the vehicle shall depart from
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1371
static SUMOTime gTimeToGridlockHighways
Definition: MSGlobals.h:70
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:42
int addFollower(const MSVehicle *veh, const MSVehicle *ego, double gap, double latOffset=0, int sublane=-1)
std::string myID
The name of the object.
Definition: Named.h:136
The vehicle has departed (was inserted into the network)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3993
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
double getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:2177
Structure representing possible vehicle parameter.
std::pair< MSVehicle *const, double > getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle &veh, const std::vector< MSLane *> &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:1830
int myI1
index for myVehicles
Definition: MSLane.h:143
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2713
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
#define DEBUG_COND
Definition: MSLane.cpp:81
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1145
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:3584
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:363
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:1394
bool nextIsMyVehicles() const
Definition: MSLane.cpp:127
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:1120
Definition of vehicle stop (position and duration)
At the rightmost side of the lane.
At the center of the lane.
const MSLane * myLane
the lane that is being iterated
Definition: MSLane.h:141
A storage for options typed value containers)
Definition: OptionsCont.h:99
double angleAt2D(int pos) const
get angle in certain position of position vector
int index
at which position in the stops list
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1520
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1715
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:2249
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
std::pair< MSVehicle *const, double > getCriticalLeader(double dist, double seen, double speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
Definition: MSLane.cpp:1916
#define LANE_RTREE_QUAL
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:67
double getLength() const
Get vehicle&#39;s length [m].
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:400
const MSLeaderInfo & getFirstVehicleInformation(const MSVehicle *ego, double latOffset, bool onlyFrontOnLane, double maxPos=std::numeric_limits< double >::max(), bool allowCached=true) const
analogue to getLastVehicleInformation but in the upstream direction
Definition: MSLane.cpp:910
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:56
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2277
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:2447
MSLeaderInfo myLeaderInfo
leaders on all sublanes as seen by approaching vehicles (cached)
Definition: MSLane.h:1160
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2403
MSLane * myCanonicalSuccessorLane
Main successor lane,.
Definition: MSLane.h:1144
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define DEBUG_COND2(obj)
Definition: MSLane.cpp:82
void registerCollision()
registers one collision-related teleport
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:353
long long int SUMOTime
Definition: TraCIDefs.h:52
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
double myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:1150
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:2149
#define NUMERICAL_EPS
Definition: config.h:151
MSLeaderInfo myFollowerInfo
followers on all sublanes as seen by vehicles on consecutive lanes (cached)
Definition: MSLane.h:1162
int numSublanes() const
Definition: MSLeaderInfo.h:95
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:187
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
int numFreeSublanes() const
Definition: MSLeaderInfo.h:99
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1115
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:276
No information given; use default.
A free position is chosen.
The class responsible for building and deletion of vehicles.
double getMissingRearGap(const MSVehicle *leader, double backOffset, double leaderSpeed) const
return by how much further the leader must be inserted to avoid rear end collisions ...
Definition: MSLane.cpp:1739
const double myLengthGeometryFactor
precomputed myShape.length / myLength
Definition: MSLane.h:1172
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
MSLeaderInfo myLeaderInfoTmp
Definition: MSLane.h:1164
Insert behind the last vehicle as close as possible to still allow the specified departSpeed. Fallback to DEPART_POS_BASE if there is no vehicle on the departLane yet.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1597
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2933
VehCont myVehBuffer
Buffer for vehicles that moved from their previous lane onto this one. Integrated after all vehicles ...
Definition: MSLane.h:1110
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:174
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1127
double endPos
The stopping position end.
Definition: MSVehicle.h:836
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:442
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1019
MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle *ego, double backOffset, bool allSublanes, double searchDist=-1, bool ignoreMinorLinks=false) const
return the sublane followers with the largest missing rear gap among all predecessor lanes (within di...
Definition: MSLane.cpp:2472
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:144
The edge is an internal edge.
Definition: MSEdge.h:97
SUMOTime myFollowerInfoTime
time step for which myFollowerInfo was last updated
Definition: MSLane.h:1169
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:406
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:89
double myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1123
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:2121
static double sum(double val)
Computes the resulting noise.
const std::string & getID() const
Returns the name of the vehicle.
void registerTeleportWrongLane()
register one non-collision-related teleport
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
Back-at-zero position.
double getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:2136
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
const double myWidth
Lane width [m].
Definition: MSLane.h:1117
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
virtual void incorporateVehicle(MSVehicle *veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator &at, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Inserts the vehicle into this lane, and informs it about entering the network.
Definition: MSLane.cpp:256
bool lastInsertion(MSVehicle &veh, double mspeed, bool patchSpeed)
inserts vehicle as close as possible to the last vehicle on this lane (or at the end of the lane if t...
Definition: MSLane.cpp:276
virtual bool appropriate(const MSVehicle *veh)
Definition: MSLane.cpp:1429
The vehicle is being teleported.
virtual void planMovements(const SUMOTime t)
Compute safe velocities for all vehicles based on positions and speeds from the last time step...
Definition: MSLane.cpp:962
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:1685
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
double getDepartSpeed(const MSVehicle &veh, bool &patchSpeed)
Definition: MSLane.cpp:401
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.