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