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 
int operator()(const MSLink *link1, const MSLink *link2) const
comparing operator
Definition: MSLane.cpp:2411
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:132
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:2458
double getMinGap() const
Get the free space in front of vehicles of this class.
static double gLateralResolution
Definition: MSGlobals.h:92
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1126
VehCont myVehicles
The lane&#39;s vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1090
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:476
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:136
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:2249
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
A free lateral position is chosen.
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:500
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1481
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1520
The position is given.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1548
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
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
virtual std::string toString() const
print a debugging representation
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
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::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
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
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1534
bool parking
whether the vehicle is removed from the net while stopping
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:406
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:796
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1604
int numSublanes() const
Definition: MSLeaderInfo.h:95
begin/end of the description of a single lane
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2272
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
Stop & getNextStop()
Definition: MSVehicle.cpp:3987
int myI2
index for myPartialVehicles
Definition: MSLane.h:145
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:2744
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2106
bool resumeFromStopping()
Definition: MSVehicle.cpp:3940
double getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:2177
bool hasInfluencer() const
Definition: MSVehicle.h:1425
SUMOTime duration
The stopping duration.
double getMinDeceleration() const
return the minimum deceleration capability for all vehicles that ever entered the network ...
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
The speed is given.
virtual const MSEdge * succEdge(int nSuccs) const =0
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
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 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
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
#define M_PI
Definition: angles.h:37
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2704
void registerTeleportYield()
register one non-collision-related teleport
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:1411
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
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:536
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:144
double getPMxEmissions() const
Returns the sum of last step PMx emissions.
Definition: MSLane.cpp:2189
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
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 MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:92
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:2121
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:607
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
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
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.
SUMOTime myLeaderInfoTime
time step for which myLeaderInfo was last updated
Definition: MSLane.h:1167
MSVehicle * getFirstFullVehicle() const
returns the first vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1511
If a fixed number of random choices fails, a free lateral position is chosen.
static SUMOTime myCollisionStopTime
Definition: MSLane.h:1201
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
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
double myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:1147
const MSEdge *const myEdge
Definition: MSLane.h:1264
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
This is a dead end link.
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1691
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
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:484
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:158
T MAX2(T a, T b)
Definition: StdDefs.h:70
const MSRoute & getRoute() const
Returns the current route.
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:2287
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
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.
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
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2081
SUMOTime until
The time at which the vehicle may continue its journey.
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
int getLaneIndex() const
Definition: MSVehicle.cpp:3577
void addNeigh(const std::string &id)
Adds a neighbor to this lane.
Definition: MSLane.cpp:207
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
bool isInternal() const
Definition: MSLane.cpp:1497
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:2294
const SVCPermissions SVCAll
all VClasses are allowed
void gotActive(MSLane *l)
Informs the control that the given lane got active.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:257
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.
double getMaxSpeedFactor() const
return the maximum speed factor for all vehicles that ever entered the network
static bool myCheckJunctionCollisions
Definition: MSLane.h:1200
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:887
This is an uncontrolled, all-way stop link.
int myI1End
end index for myVehicles
Definition: MSLane.h:147
double getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:2201
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
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
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
The speed is given.
bool myDownstream
iteration direction
Definition: MSLane.h:151
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2921
#define SIMTIME
Definition: SUMOTime.h:70
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:379
std::vector< std::string > myNeighs
Definition: MSLane.h:1183
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
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2713
static CollisionAction myCollisionAction
the action to take on collisions
Definition: MSLane.h:1199
std::map< std::string, MSLane * > DictType
definition of the static dictionary type
Definition: MSLane.h:1189
static CollisionAction getCollisionAction()
Definition: MSLane.h:1015
double basePos(const MSVehicle &veh) const
departure position where the vehicle fits fully onto the lane (if possible)
Definition: MSLane.cpp:512
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
double getImpatience() const
Returns this vehicles impatience.
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
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
#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
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2277
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)
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:428
MSLane * getCanonicalSuccessorLane() const
Definition: MSLane.cpp:2038
int numFreeSublanes() const
Definition: MSLeaderInfo.h:99
double myLength
Lane length [m].
Definition: MSLane.h:1114
double getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:2225
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1979
#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
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
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:236
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:2059
const bool myIsRampAccel
whether this lane is an acceleration lane
Definition: MSLane.h:1175
Representation of a vehicle.
Definition: SUMOVehicle.h:67
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3753
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:363
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 getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:201
Sorts vehicles by their position (descending)
Definition: MSLane.h:1207
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:3276
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
double getElectricityConsumption() const
Returns the sum of last step electricity consumption.
Definition: MSLane.cpp:2237
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
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:310
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
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:824
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
const std::map< SUMOVehicleClass, double > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:1132
bool triggered
whether an arriving person lets the vehicle continue
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3766
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1115
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
void markDelayed() const
Definition: MSEdge.h:644
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.
Sorts edges by their angle relative to the given edge (straight comes first)
Definition: MSLane.h:1253
The maximum speed is used.
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 forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:831
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
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:391
T MIN2(T a, T b)
Definition: StdDefs.h:64
void add(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
#define POSITION_EPS
Definition: config.h:176
No information given; use default.
int operator()(const IncomingLaneInfo &lane1, const IncomingLaneInfo &lane2) const
comparing operator
Definition: MSLane.cpp:2333
CollisionAction
Definition: MSLane.h:162
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:598
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2403
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:234
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 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
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.
Something on a lane to be noticed about vehicle movement.
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1656
void registerTeleportJam()
register one non-collision-related teleport
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
If a fixed number of random choices fails, a free position is chosen.
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1127
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2933
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of...
Definition: MSLane.h:1157
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
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:288
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
bool containerTriggered
whether an arriving container lets the vehicle continue
int operator()(const std::pair< const MSVehicle *, double > &p1, const std::pair< const MSVehicle *, double > &p2) const
Definition: MSLane.cpp:1733
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
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
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
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2018
bool operator()(const MSVehicle *cmp, double pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:2266
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:2149
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
void sortPartialVehicles()
sorts myPartialVehicles
Definition: MSLane.cpp:1474
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
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2070
double getLength() const
Get vehicle&#39;s length [m].
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
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
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.
Structure representing possible vehicle parameter.
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
int myI1
index for myVehicles
Definition: MSLane.h:143
#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
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:294
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
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:363
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:1394
bool isEmpty() const
Definition: MSLane.cpp:1492
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:1120
Definition of vehicle stop (position and duration)
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
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
MSVehicle * getPartialBehind(const MSVehicle *ego) const
Definition: MSLane.cpp:2680
bool checkFailure(MSVehicle *aVehicle, double &speed, double &dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:517
A storage for options typed value containers)
Definition: OptionsCont.h:99
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
double getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:1755
int index
at which position in the stops list
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1715
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
Definition: MSLane.cpp:2767
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
#define LANE_RTREE_QUAL
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:67
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
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:138
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) ...
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2465
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:390
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:56
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:2447
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
MSLeaderInfo myLeaderInfo
leaders on all sublanes as seen by approaching vehicles (cached)
Definition: MSLane.h:1160
double getRightSideOnEdge() const
Definition: MSLane.h:924
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
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 nextIsMyVehicles() const
Definition: MSLane.cpp:127
bool closeTag()
Closes the most recently opened tag.
#define DEBUG_COND2(obj)
Definition: MSLane.cpp:82
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
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
double myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:1150
#define NUMERICAL_EPS
Definition: config.h:152
MSLeaderInfo myFollowerInfo
followers on all sublanes as seen by vehicles on consecutive lanes (cached)
Definition: MSLane.h:1162
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:187
std::string toString() const
print a debugging representation
double getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:2213
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1597
No information given; use default.
A free position is chosen.
double getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:2165
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.
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
double endPos
The stopping position end.
Definition: MSVehicle.h:836
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1019
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:488
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:719
The edge is an internal edge.
Definition: MSEdge.h:97
virtual bool executeMovements(SUMOTime t, std::vector< MSLane * > &lanesWithVehiclesToIntegrate)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:1262
SUMOTime myFollowerInfoTime
time step for which myFollowerInfo was last updated
Definition: MSLane.h:1169
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1502
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:89
double myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1123
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:385
static double sum(double val)
Computes the resulting noise.
double getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:2136
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void registerTeleportWrongLane()
register one non-collision-related teleport
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:400
Back-at-zero position.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:454
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:2095
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
double angleAt2D(int pos) const
get angle in certain position of position vector
const double myWidth
Lane width [m].
Definition: MSLane.h:1117
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
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
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
const std::string & getID() const
Returns the name of the vehicle.
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:442
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:395
double getDepartSpeed(const MSVehicle &veh, bool &patchSpeed)
Definition: MSLane.cpp:401
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.