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-2015 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 
39 #include <utils/common/StdDefs.h>
40 #include "MSVehicle.h"
43 #include "MSNet.h"
44 #include "MSVehicleType.h"
45 #include "MSEdge.h"
46 #include "MSEdgeControl.h"
47 #include "MSJunction.h"
48 #include "MSLogicJunction.h"
49 #include "MSLink.h"
50 #include "MSLane.h"
51 #include "MSVehicleTransfer.h"
52 #include "MSGlobals.h"
53 #include "MSVehicleControl.h"
54 #include "MSInsertionControl.h"
55 #include "MSVehicleControl.h"
56 #include <cmath>
57 #include <bitset>
58 #include <iostream>
59 #include <cassert>
60 #include <functional>
61 #include <algorithm>
62 #include <iterator>
63 #include <exception>
64 #include <climits>
65 #include <set>
67 #include <utils/common/ToString.h>
70 #include <utils/geom/GeomHelper.h>
71 
72 #ifdef CHECK_MEMORY_LEAKS
73 #include <foreign/nvwa/debug_new.h>
74 #endif // CHECK_MEMORY_LEAKS
75 
76 
77 // ===========================================================================
78 // static member definitions
79 // ===========================================================================
81 
82 
83 // ===========================================================================
84 // member method definitions
85 // ===========================================================================
86 MSLane::MSLane(const std::string& id, SUMOReal maxSpeed, SUMOReal length, MSEdge* const edge,
87  unsigned int numericalID, const PositionVector& shape, SUMOReal width,
88  SVCPermissions permissions) :
89  Named(id),
90  myShape(shape), myNumericalID(numericalID),
91  myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed),
92  myPermissions(permissions),
93  myLogicalPredecessorLane(0),
94  myBruttoVehicleLengthSum(0), myNettoVehicleLengthSum(0), myInlappingVehicleEnd(10000), myInlappingVehicle(0),
95  myLengthGeometryFactor(MAX2(POSITION_EPS, myShape.length()) / myLength) { // factor should not be 0
97 }
98 
99 
101  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
102  delete *i;
103  }
104 }
105 
106 
107 void
109  myLinks.push_back(link);
110 }
111 
112 
113 // ------ interaction with MSMoveReminder ------
114 void
116  myMoveReminders.push_back(rem);
117  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
118  (*veh)->addReminder(rem);
119  }
120 }
121 
122 
123 
124 // ------ Vehicle emission ------
125 void
126 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
127  assert(pos <= myLength);
128  bool wasInactive = myVehicles.size() == 0;
129  veh->enterLaneAtInsertion(this, pos, speed, notification);
130  if (at == myVehicles.end()) {
131  // vehicle will be the first on the lane
132  myVehicles.push_back(veh);
133  } else {
134  myVehicles.insert(at, veh);
135  }
138  myEdge->markDelayed();
139  if (wasInactive) {
141  }
142 }
143 
144 
145 bool
147  veh.setTentativeLaneAndPosition(this, maxPos);
148  veh.updateBestLanes(false, this);
149  SUMOReal xIn = maxPos;
150  SUMOReal vIn = mspeed;
151  SUMOReal leaderDecel;
152  if (myVehicles.size() != 0) {
153  MSVehicle* leader = myVehicles.front();
154  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
155  vIn = leader->getSpeed();
156  leaderDecel = leader->getCarFollowModel().getMaxDecel();
157  } else {
158  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
159  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
160  if (leader.first != 0) {
161  xIn = getLength() + leader.second;
162  vIn = leader.first->getSpeed();
163  leaderDecel = leader.first->getCarFollowModel().getMaxDecel();
164  } else {
165  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
166  return true;
167  }
168  }
169  const SUMOReal vHlp = 0.5 * (vIn + mspeed);
170  SUMOReal x2 = xIn;// have seen leader length already - skCar::lCar;
171  SUMOReal x1 = x2 - 100.0;
172  SUMOReal x = 0;
173  for (int i = 0; i <= 10; i++) {
174  x = 0.5 * (x1 + x2);
175  veh.setTentativeLaneAndPosition(this, x);
176  SUMOReal vSafe = veh.getCarFollowModel().insertionFollowSpeed(&veh, vHlp, xIn - x, vIn, leaderDecel);
177  if (vSafe < vHlp) {
178  x2 = x;
179  } else {
180  x1 = x;
181  }
182  }
183  if (x < minPos) {
184  return false;
185  } else if (x > maxPos) {
186  x = maxPos;
187  }
188  incorporateVehicle(&veh, x, vHlp, myVehicles.begin());
189  return true;
190 }
191 
192 
193 bool
195  veh.setTentativeLaneAndPosition(this, maxPos);
196  veh.updateBestLanes(false, this);
197  SUMOReal xIn = maxPos;
198  SUMOReal vIn = mspeed;
199  if (myVehicles.size() != 0) {
200  MSVehicle* leader = myVehicles.front();
201  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
202  vIn = leader->getSpeed();
203  } else {
204  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
205  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
206  if (leader.first != 0) {
207  xIn = getLength() + leader.second;
208  vIn = leader.first->getSpeed();
209  } else {
210  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
211  return true;
212  }
213  }
214  const SUMOReal vHlp = 0.5 * (mspeed + vIn);
215  xIn = xIn - vHlp * veh.getCarFollowModel().getHeadwayTime() - veh.getVehicleType().getMinGap();
216  if (xIn < minPos) {
217  return false;
218  } else if (xIn > maxPos) {
219  xIn = maxPos;
220  }
221  incorporateVehicle(&veh, xIn, vHlp, myVehicles.begin());
222  return true;
223 }
224 
225 
226 bool
228  if (myVehicles.size() == 0) {
229  return isInsertionSuccess(&veh, mspeed, myLength / 2, true, MSMoveReminder::NOTIFICATION_DEPARTED);
230  }
231  // go through the lane, look for free positions (starting after the last vehicle)
232  MSLane::VehCont::iterator predIt = myVehicles.begin();
233  SUMOReal maxSpeed = 0;
234  SUMOReal maxPos = 0;
235  MSLane::VehCont::iterator maxIt = myVehicles.begin();
236  while (predIt != myVehicles.end()) {
237  // get leader (may be zero) and follower
238  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
239  const MSVehicle* follower = *predIt;
240  SUMOReal leaderRearPos = getLength();
241  SUMOReal leaderSpeed = mspeed;
242  if (leader != 0) {
243  leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
244  if (leader == getPartialOccupator()) {
245  leaderRearPos = getPartialOccupatorEnd();
246  }
247  leaderSpeed = leader->getSpeed();
248  }
249  const SUMOReal nettoGap = leaderRearPos - follower->getPositionOnLane() - veh.getVehicleType().getLengthWithGap();
250  if (nettoGap > 0) {
251  const SUMOReal tau = veh.getCarFollowModel().getHeadwayTime();
252  const SUMOReal tauDecel = tau * veh.getCarFollowModel().getMaxDecel();
253  const SUMOReal fSpeed = follower->getSpeed();
254  const SUMOReal lhs = nettoGap / tau + tauDecel - fSpeed - fSpeed * fSpeed / (2 * tauDecel) + leaderSpeed * leaderSpeed / (2 * tauDecel);
255  if (lhs >= sqrt(tauDecel * tauDecel + leaderSpeed * leaderSpeed)) {
256  const SUMOReal frontGap = (lhs * lhs - tauDecel * tauDecel - leaderSpeed * leaderSpeed) / (2 * veh.getCarFollowModel().getMaxDecel());
257  const SUMOReal currentMaxSpeed = lhs - tauDecel;
258  if (MIN2(currentMaxSpeed, mspeed) > maxSpeed) {
259  maxSpeed = currentMaxSpeed;
260  maxPos = MIN2(leaderRearPos + frontGap, myLength);
261  maxIt = predIt + 1;
262  }
263  }
264  }
265  ++predIt;
266  }
267  if (maxSpeed > 0) {
268  incorporateVehicle(&veh, maxPos, maxSpeed, maxIt);
269  return true;
270  }
271  return false;
272 }
273 
274 
275 bool
277  MSMoveReminder::Notification notification) {
278  bool adaptableSpeed = true;
279  // try to insert teleporting vehicles fully on this lane
280  const SUMOReal minPos = (notification == MSMoveReminder::NOTIFICATION_TELEPORT ?
281  MIN2(myLength, veh.getVehicleType().getLength()) : 0);
282 
283  if (myVehicles.size() == 0) {
284  // ensure sufficient gap to followers on predecessor lanes
285  const SUMOReal backOffset = minPos - veh.getVehicleType().getLength();
286  const SUMOReal missingRearGap = getMissingRearGap(backOffset, mspeed, veh.getCarFollowModel().getMaxDecel());
287  if (missingRearGap > 0) {
288  if (minPos + missingRearGap <= myLength) {
289  // @note. The rear gap is tailored to mspeed. If it changes due
290  // to a leader vehicle (on subsequent lanes) insertion will
291  // still fail. Under the right combination of acceleration and
292  // deceleration values there might be another insertion
293  // positions that would be successful be we do not look for it.
294  return isInsertionSuccess(&veh, mspeed, minPos + missingRearGap, adaptableSpeed, notification);
295  } else {
296  return false;
297  }
298  } else {
299  return isInsertionSuccess(&veh, mspeed, minPos, adaptableSpeed, notification);
300  }
301 
302  } else {
303  // check whether the vehicle can be put behind the last one if there is such
304  MSVehicle* leader = myVehicles.back();
305  const SUMOReal leaderPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
306  const SUMOReal speed = adaptableSpeed ? leader->getSpeed() : mspeed;
307  const SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
308  if (leaderPos >= frontGapNeeded) {
309  const SUMOReal tspeed = MIN2(veh.getCarFollowModel().insertionFollowSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
310  // check whether we can insert our vehicle behind the last vehicle on the lane
311  if (isInsertionSuccess(&veh, tspeed, minPos, adaptableSpeed, notification)) {
312  return true;
313  }
314  }
315  }
316  // go through the lane, look for free positions (starting after the last vehicle)
317  MSLane::VehCont::iterator predIt = myVehicles.begin();
318  while (predIt != myVehicles.end()) {
319  // get leader (may be zero) and follower
320  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
321  const MSVehicle* follower = *predIt;
322 
323  // patch speed if allowed
324  SUMOReal speed = mspeed;
325  if (adaptableSpeed && leader != 0) {
326  speed = MIN2(leader->getSpeed(), mspeed);
327  }
328 
329  // compute the space needed to not collide with leader
330  SUMOReal frontMax = getLength();
331  if (leader != 0) {
332  SUMOReal leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
333  if (leader == getPartialOccupator()) {
334  leaderRearPos = getPartialOccupatorEnd();
335  }
336  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
337  frontMax = leaderRearPos - frontGapNeeded;
338  }
339  // compute the space needed to not let the follower collide
340  const SUMOReal followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
341  const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
342  const SUMOReal backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
343 
344  // check whether there is enough room (given some extra space for rounding errors)
345  if (frontMax > minPos && backMin + POSITION_EPS < frontMax) {
346  // try to insert vehicle (should be always ok)
347  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, adaptableSpeed, notification)) {
348  return true;
349  }
350  }
351  ++predIt;
352  }
353  // first check at lane's begin
354  return false;
355 }
356 
357 
358 SUMOReal
359 MSLane::getDepartSpeed(const MSVehicle& veh, bool& patchSpeed) {
360  SUMOReal speed = 0;
361  const SUMOVehicleParameter& pars = veh.getParameter();
362  switch (pars.departSpeedProcedure) {
363  case DEPART_SPEED_GIVEN:
364  speed = pars.departSpeed;
365  patchSpeed = false;
366  break;
367  case DEPART_SPEED_RANDOM:
368  speed = RandHelper::rand(getVehicleMaxSpeed(&veh));
369  patchSpeed = true; // @todo check
370  break;
371  case DEPART_SPEED_MAX:
372  speed = getVehicleMaxSpeed(&veh);
373  patchSpeed = true; // @todo check
374  break;
376  default:
377  // speed = 0 was set before
378  patchSpeed = false; // @todo check
379  break;
380  }
381  return speed;
382 }
383 
384 
385 bool
387  SUMOReal pos = 0;
388  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
389  const SUMOVehicleParameter& pars = veh.getParameter();
390  SUMOReal speed = getDepartSpeed(veh, patchSpeed);
391 
392  // determine the position
393  switch (pars.departPosProcedure) {
394  case DEPART_POS_GIVEN:
395  pos = pars.departPos;
396  if (pos < 0.) {
397  pos += myLength;
398  }
399  break;
400  case DEPART_POS_RANDOM:
401  pos = RandHelper::rand(getLength());
402  break;
403  case DEPART_POS_RANDOM_FREE: {
404  for (unsigned int i = 0; i < 10; i++) {
405  // we will try some random positions ...
406  pos = RandHelper::rand(getLength());
407  if (isInsertionSuccess(&veh, speed, pos, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
408  return true;
409  }
410  }
411  // ... and if that doesn't work, we put the vehicle to the free position
412  return freeInsertion(veh, speed);
413  }
414  break;
415  case DEPART_POS_FREE:
416  return freeInsertion(veh, speed);
418  return pWagSimpleInsertion(veh, speed, getLength(), 0.0);
420  return pWagGenericInsertion(veh, speed, getLength(), 0.0);
422  return maxSpeedGapInsertion(veh, speed);
423  case DEPART_POS_BASE:
424  case DEPART_POS_DEFAULT:
425  default:
426  pos = MIN2(static_cast<SUMOReal>(veh.getVehicleType().getLength() + POSITION_EPS), myLength);
427  break;
428  }
429  // try to insert
430  return isInsertionSuccess(&veh, speed, pos, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
431 }
432 
433 
434 bool
435 MSLane::checkFailure(MSVehicle* aVehicle, SUMOReal& speed, SUMOReal& dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const {
436  if (nspeed < speed) {
437  if (patchSpeed) {
438  speed = MIN2(nspeed, speed);
439  dist = aVehicle->getCarFollowModel().brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
440  } else {
441  if (errorMsg != "") {
442  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (" + errorMsg + ")!");
444  }
445  return true;
446  }
447  }
448  return false;
449 }
450 
451 
452 bool
454  SUMOReal speed, SUMOReal pos, bool patchSpeed,
455  MSMoveReminder::Notification notification) {
456  if (pos < 0 || pos > myLength) {
457  // we may not start there
458  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
459  aVehicle->getID() + "'. Inserting at lane end instead.");
460  pos = myLength;
461  }
462  aVehicle->setTentativeLaneAndPosition(this, pos);
463  aVehicle->updateBestLanes(false, this);
464  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
465  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
466  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
467  SUMOReal seen = getLength() - pos;
468  SUMOReal dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
469  const MSRoute& r = aVehicle->getRoute();
470  MSRouteIterator ce = r.begin();
471  unsigned int nRouteSuccs = 1;
472  MSLane* currentLane = this;
473  MSLane* nextLane = this;
475  while (seen < dist && ri != bestLaneConts.end()) {
476  // get the next link used...
477  MSLinkCont::const_iterator link = succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
478  if (currentLane->isLinkEnd(link)) {
479  if (&currentLane->getEdge() == r.getLastEdge()) {
480  // reached the end of the route
482  if (checkFailure(aVehicle, speed, dist, cfModel.freeSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed, true),
483  patchSpeed, "arrival speed too low")) {
484  // we may not drive with the given velocity - we cannot match the specified arrival speed
485  return false;
486  }
487  }
488  } else {
489  // lane does not continue
490  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, seen),
491  patchSpeed, "junction too close")) {
492  // we may not drive with the given velocity - we cannot stop at the junction
493  return false;
494  }
495  }
496  break;
497  }
498  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength(), aVehicle->getImpatience(), cfModel.getMaxDecel(), 0)
499  || !(*link)->havePriority()) {
500  // have to stop at junction
501  std::string errorMsg = "";
502  const LinkState state = (*link)->getState();
503  if (state == LINKSTATE_MINOR
504  || state == LINKSTATE_EQUAL
505  || state == LINKSTATE_STOP
506  || state == LINKSTATE_ALLWAY_STOP) {
507  // no sense in trying later
508  errorMsg = "unpriorised junction too close";
509  }
510  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, seen),
511  patchSpeed, errorMsg)) {
512  // we may not drive with the given velocity - we cannot stop at the junction in time
513  return false;
514  }
515  break;
516  }
517  // get the next used lane (including internal)
518  nextLane = (*link)->getViaLaneOrLane();
519  // check how next lane effects the journey
520  if (nextLane != 0) {
521  // check leader on next lane
522  SUMOReal gap = 0;
523  MSVehicle* leader = nextLane->getLastVehicle();
524  if (leader != 0) {
525  gap = seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - aVehicle->getVehicleType().getMinGap();
526  } else {
527  leader = nextLane->getPartialOccupator();
528  if (leader != 0) {
529  gap = seen + nextLane->getPartialOccupatorEnd() - aVehicle->getVehicleType().getMinGap();
530  }
531  }
532  if (leader != 0) {
533  if (gap < 0) {
534  return false;
535  }
536  const SUMOReal nspeed = cfModel.insertionFollowSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
537  if (checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
538  // we may not drive with the given velocity - we crash into the leader
539  return false;
540  }
541  }
542  // check next lane's maximum velocity
543  const SUMOReal nspeed = cfModel.freeSpeed(aVehicle, speed, seen, nextLane->getVehicleMaxSpeed(aVehicle), true);
544  if (nspeed < speed) {
545  if (patchSpeed) {
546  speed = nspeed;
547  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
548  } else {
549  // we may not drive with the given velocity - we would be too fast on the next lane
550  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (slow lane ahead)!");
552  return false;
553  }
554  }
555  // check traffic on next junction
556  // we cannot use (*link)->opened because a vehicle without priority
557  // may already be comitted to blocking the link and unable to stop
558  const SUMOTime leaveTime = (*link)->getLeaveTime(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength());
559  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed, cfModel.getMaxDecel())) {
560  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, seen), patchSpeed, "")) {
561  // we may not drive with the given velocity - we crash at the junction
562  return false;
563  }
564  }
565  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
566  seen += nextLane->getLength();
567  currentLane = nextLane;
568 #ifdef HAVE_INTERNAL_LANES
569  if ((*link)->getViaLane() == 0) {
570 #else
571  if (true) {
572 #endif
573  nRouteSuccs++;
574  ++ce;
575  ++ri;
576  }
577  }
578  }
579 
580  // get the pointer to the vehicle next in front of the given position
581  MSVehicle* leader = 0;
582  SUMOReal gap = 0;
583  MSLane::VehCont::iterator predIt = find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos));
584  if (predIt != myVehicles.end()) {
585  leader = *predIt;
586  gap = MSVehicle::gap(leader->getPositionOnLane(), leader->getVehicleType().getLength(), pos + aVehicle->getVehicleType().getMinGap());
587  }
588  if (leader == 0 && getPartialOccupator() != 0) {
589  leader = getPartialOccupator();
590  gap = getPartialOccupatorEnd() - pos - aVehicle->getVehicleType().getMinGap();
591  }
592  if (leader != 0) {
593  if (gap < 0) {
594  return false;
595  }
596  const SUMOReal nspeed = cfModel.insertionFollowSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
597  if (checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
598  // we may not drive with the given velocity - we crash into the leader
599  return false;
600  }
601  }
602 
603  // check back vehicle
604  if (predIt != myVehicles.begin()) {
605  // there is direct follower on this lane
606  MSVehicle* follower = *(predIt - 1);
607  SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
608  SUMOReal gap = MSVehicle::gap(pos, aVehicle->getVehicleType().getLength(), follower->getPositionOnLane() + follower->getVehicleType().getMinGap());
609  if (gap < backGapNeeded) {
610  // too close to the follower on this lane
611  return false;
612  }
613  } else {
614  // check approaching vehicles to prevent rear-end collisions
615  const SUMOReal backOffset = pos - aVehicle->getVehicleType().getLength();
616  const SUMOReal missingRearGap = getMissingRearGap(backOffset, speed, aVehicle->getCarFollowModel().getMaxDecel());
617  if (missingRearGap > 0) {
618  // too close to a follower
619  return false;
620  }
621  }
622  // may got negative while adaptation
623  if (speed < 0) {
624  return false;
625  }
626  // enter
627  incorporateVehicle(aVehicle, pos, speed, predIt, notification);
628  return true;
629 }
630 
631 
632 void
634  veh->updateBestLanes(true, this);
635  bool dummy;
636  const SUMOReal speed = veh->hasDeparted() ? veh->getSpeed() : getDepartSpeed(*veh, dummy);
637  incorporateVehicle(veh, pos, speed, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)));
638 }
639 
640 
641 // ------ Handling vehicles lapping into lanes ------
642 SUMOReal
644  myInlappingVehicle = v;
645  myInlappingVehicleEnd = myLength - leftVehicleLength;
646  if (v->getLaneChangeModel().isChangingLanes()) {
647  MSLane* shadowLane = v->getLaneChangeModel().getShadowLane(this);
648  if (shadowLane != 0) {
650  shadowLane->myInlappingVehicle = v;
651  shadowLane->myInlappingVehicleEnd = myLength - leftVehicleLength;
652  }
653  }
654  return myLength;
655 }
656 
657 
658 void
660  if (v == myInlappingVehicle) {
661  myInlappingVehicleEnd = 10000;
662  myInlappingVehicle = 0;
663  if (v->getLaneChangeModel().isChangingLanes()) {
664  MSLane* shadowLane = v->getLaneChangeModel().getShadowLane(this);
665  if (shadowLane != 0 && v == shadowLane->myInlappingVehicle) {
666  shadowLane->myInlappingVehicle = 0;
667  shadowLane->myInlappingVehicleEnd = 10000;
668  }
669  }
670  }
671 }
672 
673 
674 std::pair<MSVehicle*, SUMOReal>
676  if (myVehicles.size() != 0) {
677  // the last vehicle is the one in scheduled by this lane
678  MSVehicle* last = *myVehicles.begin();
679  const SUMOReal pos = last->getPositionOnLane() - last->getVehicleType().getLength();
680  return std::make_pair(last, pos);
681  }
682  if (myInlappingVehicle != 0) {
683  // the last one is a vehicle extending into this lane
684  return std::make_pair(myInlappingVehicle, myInlappingVehicleEnd);
685  }
686  return std::make_pair<MSVehicle*, SUMOReal>(0, 0);
687 }
688 
689 
690 // ------ ------
691 void
693  assert(myVehicles.size() != 0);
694  SUMOReal cumulatedVehLength = 0.;
695  const MSVehicle* pred = getPartialOccupator();
696  for (VehCont::reverse_iterator veh = myVehicles.rbegin(); veh != myVehicles.rend(); ++veh) {
697  if ((*veh)->getLane() == this) {
698  (*veh)->planMove(t, pred, cumulatedVehLength);
699  }
700  pred = *veh;
701  cumulatedVehLength += pred->getVehicleType().getLengthWithGap();
702  }
703 }
704 
705 
706 void
707 MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
708  if (myVehicles.size() == 0) {
709  return;
710  }
711 
712  VehCont::iterator lastVeh = myVehicles.end() - 1;
713  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) {
714  VehCont::iterator pred = veh + 1;
715  if ((*veh)->hasInfluencer() && (*veh)->getInfluencer().isVTDAffected(timestep)) {
716  ++veh;
717  continue;
718  }
719  if ((*pred)->hasInfluencer() && (*pred)->getInfluencer().isVTDAffected(timestep)) {
720  ++veh;
721  continue;
722  }
723  if (handleCollision(timestep, stage, *veh, *pred, (*pred)->getPositionOnLane() - (*pred)->getVehicleType().getLength())) {
724  veh = myVehicles.erase(veh); // remove current vehicle
725  lastVeh = myVehicles.end() - 1;
726  if (veh == myVehicles.end()) {
727  break;
728  }
729  } else {
730  ++veh;
731  }
732  }
733  MSVehicle* predV = getPartialOccupator();
734  if (predV != 0) {
735  if (handleCollision(timestep, stage, *lastVeh, predV, getPartialOccupatorEnd())) {
736  myVehicles.erase(lastVeh);
737  }
738  }
739 }
740 
741 
742 bool
743 MSLane::handleCollision(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim, const SUMOReal victimRear) {
744  const SUMOReal gap = victimRear - collider->getPositionOnLane() - collider->getVehicleType().getMinGap();
745  if (gap < -NUMERICAL_EPS) {
746  if (collider->getLane() == this) {
748  && collider->getLaneChangeModel().isChangingLanes()
749  && victim->getLaneChangeModel().isChangingLanes()
750  && victim->getLane() != this) {
751  // synchroneous lane change maneuver
752  return false;
753  }
754  WRITE_WARNING("Teleporting vehicle '" + collider->getID() + "'; collision with '"
755  + victim->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
756  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " stage=" + stage + ".");
760  MSVehicleTransfer::getInstance()->add(timestep, collider);
761  return true;
762  } else {
763  //WRITE_WARNING("Shadow of vehicle '" + collider->getID() + "'; collision with '"
764  // + victim->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
765  // + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " stage=" + stage + ".");
766  //collider->getLaneChangeModel().endLaneChangeManeuver(MSMoveReminder::NOTIFICATION_TELEPORT);
767  }
768  }
769  return false;
770 }
771 
772 
773 bool
774 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& into) {
775  // iteratate over vehicles in reverse so that move reminders will be called in the correct order
776  for (VehCont::reverse_iterator i = myVehicles.rbegin(); i != myVehicles.rend();) {
777  MSVehicle* veh = *i;
778  if (veh->getLane() != this || veh->getLaneChangeModel().alreadyMoved()) {
779  // this is the shadow during a continuous lane change
780  ++i;
781  continue;
782  }
783  // length is needed later when the vehicle may not exist anymore
784  const SUMOReal length = veh->getVehicleType().getLengthWithGap();
785  const SUMOReal nettoLength = veh->getVehicleType().getLength();
786  bool moved = veh->executeMove();
787  MSLane* target = veh->getLane();
788 #ifndef NO_TRACI
789  bool vtdControlled = veh->hasInfluencer() && veh->getInfluencer().isVTDControlled();
790  if (veh->hasArrived() && !vtdControlled) {
791 #else
792  if (veh->hasArrived()) {
793 #endif
794  // vehicle has reached its arrival position
797  } else if (target != 0 && moved) {
798  if (target->getEdge().isVaporizing()) {
799  // vehicle has reached a vaporizing edge
802  } else {
803  // vehicle has entered a new lane (leaveLane was already called in MSVehicle::executeMove)
804  target->myVehBuffer.push_back(veh);
805  SUMOReal pspeed = veh->getSpeed();
806  SUMOReal oldPos = veh->getPositionOnLane() - SPEED2DIST(veh->getSpeed());
807  veh->workOnMoveReminders(oldPos, veh->getPositionOnLane(), pspeed);
808  into.push_back(target);
809  if (veh->getLaneChangeModel().hasShadowVehicle()) {
810  MSLane* shadowLane = veh->getLaneChangeModel().getShadowLane();
811  if (shadowLane != 0) {
812  into.push_back(shadowLane);
813  shadowLane->myVehBuffer.push_back(veh);
814  }
815  }
816  }
817  } else if (veh->isParking()) {
818  // vehicle started to park
820  } else if (veh->getPositionOnLane() > getLength()) {
821  // for any reasons the vehicle is beyond its lane...
822  // this should never happen because it is handled in MSVehicle::executeMove
823  assert(false);
824  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, target lane='" + getID() + "', time=" +
825  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
828  } else {
829  ++i;
830  continue;
831  }
832  myBruttoVehicleLengthSum -= length;
833  myNettoVehicleLengthSum -= nettoLength;
834  ++i;
835  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
836  }
837  if (myVehicles.size() > 0) {
839  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
840  if (!veh->isStopped() && veh->getLane() == this) {
841  const bool wrongLane = !veh->getLane()->appropriate(veh);
843  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
844  if (r1 || r2) {
845  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
846  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
847  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
848  MSVehicle* veh = *(myVehicles.end() - 1);
851  myVehicles.erase(myVehicles.end() - 1);
852  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
853  + reason
854  + (r2 ? " (highway)" : "")
855  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
856  if (wrongLane) {
858  } else if (minorLink) {
860  } else {
862  }
864  }
865  } // else look for a vehicle that isn't stopped?
866  }
867  }
868  return myVehicles.size() == 0;
869 }
870 
871 
872 const MSEdge*
874  const MSEdge* e = myEdge;
875  while (e->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
876  e = e->getSuccessors()[0];
877  }
878  return e;
879 }
880 
881 
882 // ------ Static (sic!) container methods ------
883 bool
884 MSLane::dictionary(const std::string& id, MSLane* ptr) {
885  DictType::iterator it = myDict.find(id);
886  if (it == myDict.end()) {
887  // id not in myDict.
888  myDict.insert(DictType::value_type(id, ptr));
889  return true;
890  }
891  return false;
892 }
893 
894 
895 MSLane*
896 MSLane::dictionary(const std::string& id) {
897  DictType::iterator it = myDict.find(id);
898  if (it == myDict.end()) {
899  // id not in myDict.
900  return 0;
901  }
902  return it->second;
903 }
904 
905 
906 void
908  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
909  delete(*i).second;
910  }
911  myDict.clear();
912 }
913 
914 
915 void
916 MSLane::insertIDs(std::vector<std::string>& into) {
917  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
918  into.push_back((*i).first);
919  }
920 }
921 
922 
923 template<class RTREE> void
924 MSLane::fill(RTREE& into) {
925  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
926  MSLane* l = (*i).second;
927  Boundary b = l->getShape().getBoxBoundary();
928  b.grow(3.);
929  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
930  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
931  into.Insert(cmin, cmax, l);
932  }
933 }
934 
935 template void MSLane::fill<NamedRTree>(NamedRTree& into);
936 #ifndef NO_TRACI
937 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
938 #endif
939 
940 // ------ ------
941 bool
944  return true;
945  }
946  if (veh->succEdge(1) == 0) {
947  assert(veh->getBestLanes().size() > veh->getLaneIndex());
948  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
949  return true;
950  } else {
951  return false;
952  }
953  }
954  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
955  return (link != myLinks.end());
956 }
957 
958 
959 bool
961  bool wasInactive = myVehicles.size() == 0;
962  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter());
963  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
964  MSVehicle* veh = *i;
965  myVehicles.insert(myVehicles.begin(), veh);
968  myEdge->markDelayed();
969  }
970  myVehBuffer.clear();
971  return wasInactive && myVehicles.size() != 0;
972 }
973 
974 
975 bool
976 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
977  return i == myLinks.end();
978 }
979 
980 
981 bool
982 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
983  return i == myLinks.end();
984 }
985 
986 bool
988  return (myVehicles.empty() && myInlappingVehicle == 0);
989 }
990 
991 MSVehicle*
993  if (myVehicles.size() == 0) {
994  return 0;
995  }
996  return *myVehicles.begin();
997 }
998 
999 
1000 MSVehicle*
1002  if (myVehicles.size() == 0) {
1003  return 0;
1004  }
1005  return *(myVehicles.end() - 1);
1006 }
1007 
1008 
1009 MSLinkCont::const_iterator
1010 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs,
1011  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
1012  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
1013  // check whether the vehicle tried to look beyond its route
1014  if (nRouteEdge == 0) {
1015  // return end (no succeeding link) if so
1016  return succLinkSource.myLinks.end();
1017  }
1018  // if we are on an internal lane there should only be one link and it must be allowed
1019  if (succLinkSource.getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1020  assert(succLinkSource.myLinks.size() == 1);
1021  // could have been disallowed dynamically with a rerouter or via TraCI
1022  // assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
1023  return succLinkSource.myLinks.begin();
1024  }
1025  // a link may be used if
1026  // 1) there is a destination lane ((*link)->getLane()!=0)
1027  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
1028  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
1029 
1030  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
1031  // "conts" stores the best continuations of our current lane
1032  // we should never return an arbitrary link since this may cause collisions
1033  MSLinkCont::const_iterator link;
1034  if (nRouteSuccs < conts.size()) {
1035  // we go through the links in our list and return the matching one
1036  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
1037  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
1038  // we should use the link if it connects us to the best lane
1039  if ((*link)->getLane() == conts[nRouteSuccs]) {
1040  return link;
1041  }
1042  }
1043  }
1044  } else {
1045  // the source lane is a dead end (no continuations exist)
1046  return succLinkSource.myLinks.end();
1047  }
1048  // the only case where this should happen is for a disconnected route (deliberately ignored)
1049 #ifdef _DEBUG
1050  WRITE_WARNING("Could not find connection between lane '" + succLinkSource.getID() + "' and lane '" + conts[nRouteSuccs]->getID() +
1051  "' for vehicle '" + veh.getID() + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1052 #endif
1053  return succLinkSource.myLinks.end();
1054 }
1055 
1056 
1057 
1058 const MSLinkCont&
1060  return myLinks;
1061 }
1062 
1063 
1064 void
1066  myMaxSpeed = val;
1067  myEdge->recalcCache();
1068 }
1069 
1070 
1071 void
1073  myLength = val;
1074  myEdge->recalcCache();
1075 }
1076 
1077 
1078 void
1081  myTmpVehicles.clear();
1082 }
1083 
1084 
1085 MSVehicle*
1086 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
1087  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
1088  if (remVehicle == *it) {
1089  if (notify) {
1090  remVehicle->leaveLane(notification);
1091  }
1092  myVehicles.erase(it);
1095  break;
1096  }
1097  }
1098  return remVehicle;
1099 }
1100 
1101 
1102 MSLane*
1103 MSLane::getParallelLane(int offset) const {
1104  return myEdge->parallelLane(this, offset);
1105 }
1106 
1107 
1108 void
1110  IncomingLaneInfo ili;
1111  ili.lane = lane;
1112  ili.viaLink = viaLink;
1113  ili.length = lane->getLength();
1114  myIncomingLanes.push_back(ili);
1115 }
1116 
1117 
1118 void
1119 MSLane::addApproachingLane(MSLane* lane, bool warnMultiCon) {
1120  MSEdge* approachingEdge = &lane->getEdge();
1121  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1122  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1123  } else if (approachingEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL && warnMultiCon) {
1124  // whenever a normal edge connects twice, there is a corresponding
1125  // internal edge wich connects twice, one warning is sufficient
1126  WRITE_WARNING("Lane '" + getID() + "' is approached multiple times from edge '" + approachingEdge->getID() + "'. This may cause collisions.");
1127  }
1128  myApproachingLanes[approachingEdge].push_back(lane);
1129 }
1130 
1131 
1132 bool
1134  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1135 }
1136 
1137 
1138 bool
1139 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1140  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1141  if (i == myApproachingLanes.end()) {
1142  return false;
1143  }
1144  const std::vector<MSLane*>& lanes = (*i).second;
1145  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1146 }
1147 
1148 
1150 public:
1151  inline int operator()(const std::pair<const MSVehicle* , SUMOReal>& p1, const std::pair<const MSVehicle* , SUMOReal>& p2) const {
1152  return p1.second < p2.second;
1153  }
1154 };
1155 
1156 
1158  SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1159  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1160  // search and check for the vehicle with the largest missing rear gap within
1161  // relevant range
1162  SUMOReal result = 0;
1163  std::pair<MSVehicle* const, SUMOReal> followerInfo = getFollowerOnConsecutive(backOffset, leaderSpeed, leaderMaxDecel);
1164  MSVehicle* v = followerInfo.first;
1165  if (v != 0) {
1166  result = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - followerInfo.second;
1167  }
1168  return result;
1169 }
1170 
1171 
1172 SUMOReal
1175  const SUMOReal maxSpeed = getSpeedLimit() * vc.getMaxSpeedFactor();
1176  // this is an upper bound on the actual braking distance (see ticket #860)
1177  return maxSpeed * maxSpeed * 0.5 / vc.getMinDeceleration();
1178 }
1179 
1180 
1181 std::pair<MSVehicle* const, SUMOReal>
1183  SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1184  // do a tree search among all follower lanes and check for the most
1185  // important vehicle (the one requiring the largest reargap)
1186  // to get a safe bound on the necessary search depth, we need to consider the maximum speed and minimum
1187  // deceleration of potential follower vehicles
1188  SUMOReal dist = getMaximumBrakeDist() - backOffset;
1189 
1190  std::pair<MSVehicle*, SUMOReal> result(static_cast<MSVehicle*>(0), -1);
1191  SUMOReal missingRearGapMax = -std::numeric_limits<SUMOReal>::max();
1192  std::set<MSLane*> visited;
1193  std::vector<MSLane::IncomingLaneInfo> newFound;
1194  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1195  while (toExamine.size() != 0) {
1196  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1197  MSLane* next = (*i).lane;
1198  dist = MAX2(dist, next->getMaximumBrakeDist() - backOffset);
1199  MSVehicle* v = 0;
1200  SUMOReal agap = 0;
1201  if (next->getPartialOccupator() != 0) {
1202  // the front of v is already on divergent trajectory from the ego vehicle
1203  // for which this method is called (in the context of MSLaneChanger).
1204  // Therefore, technically v is not a follower but only an obstruction and
1205  // the gap is not between the front of v and the back of ego
1206  // but rather between the flank of v and the back of ego.
1207  agap = (*i).length - next->getLength() + backOffset - next->getPartialOccupator()->getVehicleType().getMinGap();
1208  if (agap < 0) {
1209  // Only if ego overlaps we treat v as if it were a real follower
1210  v = next->getPartialOccupator();
1211  }
1212  }
1213  if (v == 0 && next->getFirstVehicle() != 0) {
1214  v = next->getFirstVehicle();
1215  agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1216  }
1217  if (v != 0) {
1218  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - agap;
1219  if (missingRearGap > missingRearGapMax) {
1220  missingRearGapMax = missingRearGap;
1221  result.first = v;
1222  result.second = agap;
1223  }
1224  } else {
1225  if ((*i).length < dist) {
1226  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1227  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1228  if (visited.find((*j).lane) == visited.end()) {
1229  visited.insert((*j).lane);
1231  ili.lane = (*j).lane;
1232  ili.length = (*j).length + (*i).length;
1233  ili.viaLink = (*j).viaLink;
1234  newFound.push_back(ili);
1235  }
1236  }
1237  }
1238  }
1239  }
1240  toExamine.clear();
1241  swap(newFound, toExamine);
1242  }
1243  return result;
1244 }
1245 
1246 std::pair<MSVehicle* const, SUMOReal>
1247 MSLane::getLeader(const MSVehicle* veh, const SUMOReal vehPos, bool checkNext) const {
1248  // get the leading vehicle for (shadow) veh
1249  // XXX this only works as long as all lanes of an edge have equal length
1250  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
1251  if ((*i)->getPositionOnLane() > vehPos + NUMERICAL_EPS) {
1252  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
1253  MSVehicle* pred = (MSVehicle*)*i;
1254  return std::pair<MSVehicle* const, SUMOReal>(pred, pred->getPositionOnLane() - pred->getVehicleType().getLength() - veh->getVehicleType().getMinGap() - vehPos);
1255  }
1256  }
1257  // XXX from here on the code mirrors MSLaneChanger::getRealLeader
1258  MSVehicle* pred = getPartialOccupator();
1259  if (pred != 0) {
1260  return std::pair<MSVehicle*, SUMOReal>(pred, getPartialOccupatorEnd() - veh->getVehicleType().getMinGap() - vehPos);
1261  }
1262  if (checkNext) {
1263  SUMOReal seen = getLength() - vehPos;
1264  SUMOReal speed = veh->getSpeed();
1265  SUMOReal dist = veh->getCarFollowModel().brakeGap(speed) + veh->getVehicleType().getMinGap();
1266  if (seen > dist) {
1267  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1268  }
1269  const std::vector<MSLane*>& bestLaneConts = veh->getBestLanesContinuation(this);
1270  return getLeaderOnConsecutive(dist, seen, speed, *veh, bestLaneConts);
1271  } else {
1272  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1273  }
1274 }
1275 
1276 
1277 std::pair<MSVehicle* const, SUMOReal>
1279  const std::vector<MSLane*>& bestLaneConts) const {
1280  if (seen > dist) {
1281  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1282  }
1283  unsigned int view = 1;
1284  // loop over following lanes
1285  if (getPartialOccupator() != 0) {
1286  return std::make_pair(getPartialOccupator(), seen - (getLength() - getPartialOccupatorEnd()) - veh.getVehicleType().getMinGap());
1287  }
1288  const MSLane* nextLane = this;
1289  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1290  do {
1291  // get the next link used
1292  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1293  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1294  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0) || (*link)->haveRed()) {
1295  break;
1296  }
1297 #ifdef HAVE_INTERNAL_LANES
1298  // check for link leaders
1299  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, veh.getVehicleType().getMinGap());
1300  if (linkLeaders.size() > 0) {
1301  // XXX if there is more than one link leader we should return the most important
1302  // one (gap, decel) but this is hard to know at this point
1303  return linkLeaders[0].vehAndGap;
1304  }
1305  bool nextInternal = (*link)->getViaLane() != 0;
1306 #endif
1307  nextLane = (*link)->getViaLaneOrLane();
1308  if (nextLane == 0) {
1309  break;
1310  }
1311  MSVehicle* leader = nextLane->getLastVehicle();
1312  if (leader != 0) {
1313  return std::make_pair(leader, seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap());
1314  } else {
1315  leader = nextLane->getPartialOccupator();
1316  if (leader != 0) {
1317  return std::make_pair(leader, seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1318  }
1319  }
1320  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1321  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1322  }
1323  seen += nextLane->getLength();
1324  if (seen <= dist) {
1325  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1326  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1327  }
1328 #ifdef HAVE_INTERNAL_LANES
1329  if (!nextInternal) {
1330  view++;
1331  }
1332 #else
1333  view++;
1334 #endif
1335  } while (seen <= dist);
1336  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1337 }
1338 
1339 
1340 std::pair<MSVehicle* const, SUMOReal>
1341 MSLane::getCriticalLeader(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle& veh) const {
1342  const std::vector<MSLane*>& bestLaneConts = veh.getBestLanesContinuation(this);
1343  std::pair<MSVehicle*, SUMOReal> result = std::make_pair(static_cast<MSVehicle*>(0), -1);
1345  unsigned int view = 1;
1346  // loop over following lanes
1347  // @note: we don't check the partial occupator for this lane since it was
1348  // already checked in MSLaneChanger::getRealLeader()
1349  const MSLane* nextLane = this;
1350  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1351  do {
1352  // get the next link used
1353  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1354  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1355  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0) || (*link)->haveRed()) {
1356  return result;
1357  }
1358 #ifdef HAVE_INTERNAL_LANES
1359  // check for link leaders
1360  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, veh.getVehicleType().getMinGap());
1361  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1362  const MSVehicle* leader = (*it).vehAndGap.first;
1363  if (leader != 0 && leader != result.first) {
1364  // XXX ignoring pedestrians here!
1365  // XXX ignoring the fact that the link leader may alread by following us
1366  // XXX ignoring the fact that we may drive up to the crossing point
1367  const SUMOReal tmpSpeed = veh.getSafeFollowSpeed((*it).vehAndGap, seen, nextLane, (*it).distToCrossing);
1368  if (tmpSpeed < safeSpeed) {
1369  safeSpeed = tmpSpeed;
1370  result = (*it).vehAndGap;
1371  }
1372  }
1373  }
1374  bool nextInternal = (*link)->getViaLane() != 0;
1375 #endif
1376  nextLane = (*link)->getViaLaneOrLane();
1377  if (nextLane == 0) {
1378  break;
1379  }
1380  MSVehicle* leader = nextLane->getLastVehicle();
1381  if (leader != 0 && leader != result.first) {
1382  const SUMOReal gap = seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
1383  const SUMOReal tmpSpeed = veh.getCarFollowModel().insertionFollowSpeed(leader, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
1384  if (tmpSpeed < safeSpeed) {
1385  safeSpeed = tmpSpeed;
1386  result = std::make_pair(leader, gap);
1387  }
1388  } else {
1389  leader = nextLane->getPartialOccupator();
1390  if (leader != 0 && leader != result.first) {
1391  const SUMOReal gap = seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap();
1392  const SUMOReal tmpSpeed = veh.getCarFollowModel().insertionFollowSpeed(leader, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
1393  if (tmpSpeed < safeSpeed) {
1394  safeSpeed = tmpSpeed;
1395  result = std::make_pair(leader, gap);
1396  }
1397  }
1398  }
1399  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1400  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1401  }
1402  seen += nextLane->getLength();
1403  if (seen <= dist) {
1404  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1405  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1406  }
1407 #ifdef HAVE_INTERNAL_LANES
1408  if (!nextInternal) {
1409  view++;
1410  }
1411 #else
1412  view++;
1413 #endif
1414  } while (seen <= dist);
1415  return result;
1416 }
1417 
1418 
1419 MSLane*
1421  if (myLogicalPredecessorLane != 0) {
1422  return myLogicalPredecessorLane;
1423  }
1424  if (myLogicalPredecessorLane == 0) {
1426  // get only those edges which connect to this lane
1427  for (MSEdgeVector::iterator i = pred.begin(); i != pred.end();) {
1428  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1429  if (j == myIncomingLanes.end()) {
1430  i = pred.erase(i);
1431  } else {
1432  ++i;
1433  }
1434  }
1435  // get the lane with the "straightest" connection
1436  if (pred.size() != 0) {
1437  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1438  MSEdge* best = *pred.begin();
1439  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1440  myLogicalPredecessorLane = (*j).lane;
1441  }
1442  }
1443  return myLogicalPredecessorLane;
1444 }
1445 
1446 
1447 MSLane*
1449  for (std::vector<IncomingLaneInfo>::const_iterator i = myIncomingLanes.begin(); i != myIncomingLanes.end(); ++i) {
1450  MSLane* cand = (*i).lane;
1451  if (&(cand->getEdge()) == &fromEdge) {
1452  return (*i).lane;
1453  }
1454  }
1455  return 0;
1456 }
1457 
1458 
1459 LinkState
1462  if (pred == 0) {
1463  return LINKSTATE_DEADEND;
1464  } else {
1465  return MSLinkContHelper::getConnectingLink(*pred, *this)->getState();
1466  }
1467 }
1468 
1469 
1470 std::vector<const MSLane*>
1472  std::vector<const MSLane*> result;
1473  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
1474  assert((*i)->getLane() != 0);
1475  result.push_back((*i)->getLane());
1476  }
1477  return result;
1478 }
1479 
1480 
1481 void
1485 }
1486 
1487 
1488 void
1492 }
1493 
1494 
1495 int
1497  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
1498  if ((*i)->getLane()->getEdge().isCrossing()) {
1499  return (int)(i - myLinks.begin());
1500  }
1501  }
1502  return -1;
1503 }
1504 
1505 // ------------ Current state retrieval
1506 SUMOReal
1508  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1510  if (myVehicles.size() != 0) {
1511  MSVehicle* lastVeh = myVehicles.front();
1512  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1513  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1514  }
1515  }
1516  releaseVehicles();
1517  return (myBruttoVehicleLengthSum + fractions) / myLength;
1518 }
1519 
1520 
1521 SUMOReal
1523  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1525  if (myVehicles.size() != 0) {
1526  MSVehicle* lastVeh = myVehicles.front();
1527  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1528  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1529  }
1530  }
1531  releaseVehicles();
1532  return (myNettoVehicleLengthSum + fractions) / myLength;
1533 }
1534 
1535 
1536 SUMOReal
1538  return myBruttoVehicleLengthSum;
1539 }
1540 
1541 
1542 SUMOReal
1544  if (myVehicles.size() == 0) {
1545  return 0;
1546  }
1547  SUMOReal wtime = 0;
1548  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
1549  wtime += (*i)->getWaitingSeconds();
1550  }
1551  return wtime;
1552 }
1553 
1554 
1555 SUMOReal
1557  if (myVehicles.size() == 0) {
1558  return myMaxSpeed;
1559  }
1560  SUMOReal v = 0;
1561  const MSLane::VehCont& vehs = getVehiclesSecure();
1562  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1563  v += (*i)->getSpeed();
1564  }
1565  SUMOReal ret = v / (SUMOReal) myVehicles.size();
1566  releaseVehicles();
1567  return ret;
1568 }
1569 
1570 
1571 SUMOReal
1573  SUMOReal ret = 0;
1574  const MSLane::VehCont& vehs = getVehiclesSecure();
1575  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1576  ret += (*i)->getCO2Emissions();
1577  }
1578  releaseVehicles();
1579  return ret;
1580 }
1581 
1582 
1583 SUMOReal
1585  SUMOReal ret = 0;
1586  const MSLane::VehCont& vehs = getVehiclesSecure();
1587  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1588  ret += (*i)->getCOEmissions();
1589  }
1590  releaseVehicles();
1591  return ret;
1592 }
1593 
1594 
1595 SUMOReal
1597  SUMOReal ret = 0;
1598  const MSLane::VehCont& vehs = getVehiclesSecure();
1599  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1600  ret += (*i)->getPMxEmissions();
1601  }
1602  releaseVehicles();
1603  return ret;
1604 }
1605 
1606 
1607 SUMOReal
1609  SUMOReal ret = 0;
1610  const MSLane::VehCont& vehs = getVehiclesSecure();
1611  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1612  ret += (*i)->getNOxEmissions();
1613  }
1614  releaseVehicles();
1615  return ret;
1616 }
1617 
1618 
1619 SUMOReal
1621  SUMOReal ret = 0;
1622  const MSLane::VehCont& vehs = getVehiclesSecure();
1623  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1624  ret += (*i)->getHCEmissions();
1625  }
1626  releaseVehicles();
1627  return ret;
1628 }
1629 
1630 
1631 SUMOReal
1633  SUMOReal ret = 0;
1634  const MSLane::VehCont& vehs = getVehiclesSecure();
1635  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1636  ret += (*i)->getFuelConsumption();
1637  }
1638  releaseVehicles();
1639  return ret;
1640 }
1641 
1642 
1643 SUMOReal
1645  SUMOReal ret = 0;
1646  const MSLane::VehCont& vehs = getVehiclesSecure();
1647  if (vehs.size() == 0) {
1648  releaseVehicles();
1649  return 0;
1650  }
1651  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1652  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
1653  ret += (SUMOReal) pow(10., (sv / 10.));
1654  }
1655  releaseVehicles();
1656  return HelpersHarmonoise::sum(ret);
1657 }
1658 
1659 
1660 bool
1662  return cmp->getPositionOnLane() >= pos;
1663 }
1664 
1665 
1666 int
1668  return v1->getPositionOnLane() > v2->getPositionOnLane();
1669 }
1670 
1672  myEdge(e),
1673  myLaneDir(e->getLanes()[0]->getShape().angleAt2D(0))
1674 { }
1675 
1676 
1677 int
1678 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
1679  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
1680  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
1681  SUMOReal s1 = 0;
1682  if (ae1 != 0 && ae1->size() != 0) {
1683  s1 = (SUMOReal) ae1->size() + fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
1684  }
1685  SUMOReal s2 = 0;
1686  if (ae2 != 0 && ae2->size() != 0) {
1687  s2 = (SUMOReal) ae2->size() + fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
1688  }
1689  return s1 < s2;
1690 }
1691 
1692 
1693 void
1695  out.openTag(SUMO_TAG_LANE);
1698  out.closeTag();
1699  out.closeTag();
1700 }
1701 
1702 
1703 void
1704 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
1705  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
1706  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
1707  assert(v != 0);
1708  v->updateBestLanes(false, this);
1711  }
1712 }
1713 
1714 
1715 
1716 /****************************************************************************/
1717 
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:633
const std::map< SUMOVehicleClass, SUMOReal > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:866
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:1704
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
VehCont myVehicles
The lane&#39;s vehicles. The entering vehicles are inserted at the front of this container and the leavin...
Definition: MSLane.h:840
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:461
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:976
long long int SUMOTime
Definition: SUMOTime.h:43
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle
SUMOReal getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:1543
#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:916
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:873
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:303
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:544
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:1667
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
virtual const MSEdge * succEdge(unsigned int nSuccs) const =0
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
bool hasInfluencer() const
Definition: MSVehicle.h:1114
The speed is given.
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
SUMOReal getImpatience() const
Returns this vehicles impatience.
bool hasShadowVehicle() const
return true if the vehicle currently has a shadow vehicle
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:98
#define M_PI
Definition: angles.h:37
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:294
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:924
The vehicle arrived at a junction.
bool isVTDControlled() const
Definition: MSVehicle.h:1046
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:359
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:124
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:129
This is an uncontrolled, minor link, has to stop.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:93
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:376
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:464
std::vector< IncomingLaneInfo > myIncomingLanes
Definition: MSLane.h:868
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:59
int SVCPermissions
MSVehicle * getFirstVehicle() const
Definition: MSLane.cpp:1001
void setLength(SUMOReal val)
Sets a new length for the lane (used by TraCI only)
Definition: MSLane.cpp:1072
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:108
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:960
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
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:61
SUMOReal getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:1632
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:1086
virtual void incorporateVehicle(MSVehicle *veh, SUMOReal pos, SUMOReal speed, 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:126
const MSEdge *const myEdge
Definition: MSLane.h:939
SUMOReal getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:1173
This is a dead end link.
MSLane(const std::string &id, SUMOReal maxSpeed, SUMOReal length, MSEdge *const edge, unsigned int numericalID, const PositionVector &shape, SUMOReal width, SVCPermissions permissions)
Constructor.
Definition: MSLane.cpp:86
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1109
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:162
SUMOReal getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:1522
T MAX2(T a, T b)
Definition: StdDefs.h:79
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:85
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:1671
The speed is chosen randomly.
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:115
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1482
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:270
This is an uncontrolled, right-before-left link.
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1283
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:286
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:1678
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:1341
bool pWagGenericInsertion(MSVehicle &veh, SUMOReal speed, SUMOReal maxPos, SUMOReal minPos)
Definition: MSLane.cpp:146
const MSEdgeVector & getIncomingEdges() const
Returns the list of edges from which this edge may be reached.
Definition: MSEdge.h:300
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:255
bool freeInsertion(MSVehicle &veh, SUMOReal speed, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle on any place.
Definition: MSLane.cpp:276
The position is chosen randomly.
This is an uncontrolled, all-way stop link.
SUMOReal myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:852
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.cpp:1537
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:118
Generic max-flow insertion by P.Wagner.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
SUMOReal setPartialOccupation(MSVehicle *v, SUMOReal leftVehicleLength)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:643
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1010
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The speed is given.
A gap is chosen where the maximum speed may be achieved.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1904
SUMOReal getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:1620
bool isInsertionSuccess(MSVehicle *vehicle, SUMOReal speed, SUMOReal pos, bool recheckNextLanes, MSMoveReminder::Notification notification)
Tries to insert the given vehicle with the given state (speed and pos)
Definition: MSLane.cpp:453
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:296
void setMaxSpeed(SUMOReal val)
Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
Definition: MSLane.cpp:1065
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:261
std::map< std::string, MSLane * > DictType
definition of the static dictionary type
Definition: MSLane.h:895
virtual bool executeMovements(SUMOTime t, std::vector< MSLane * > &into)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:774
MSLinkCont myLinks
Definition: MSLane.h:887
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:707
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSLane.h:898
void enterLaneAtInsertion(MSLane *enteredLane, SUMOReal pos, SUMOReal speed, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:1833
void addApproachingLane(MSLane *lane, bool warnMultiCon)
Definition: MSLane.cpp:1119
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:81
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:386
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1420
#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:232
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
VehCont myTmpVehicles
Definition: MSLane.h:856
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:1278
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:562
void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:659
void setShadowPartialOccupator(MSLane *lane)
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:1460
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:1157
Representation of a vehicle.
Definition: SUMOVehicle.h:65
std::vector< MSVehicle * > myVehBuffer
Definition: MSLane.h:860
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
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:359
bool alreadyMoved() const
reset the flag whether a vehicle already moved to false
Sorts vehicles by their position (descending)
Definition: MSLane.h:909
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:2188
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:1922
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1489
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:308
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:1103
SUMOReal getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:1556
static SUMOReal gap(SUMOReal predPos, SUMOReal predLength, SUMOReal pos)
Uses the given values to compute the brutto-gap.
Definition: MSVehicle.h:215
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:61
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:827
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:675
void markDelayed() const
Definition: MSEdge.h:586
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:1262
bool handleCollision(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, const SUMOReal victimRear)
detect whether there is a collision. then issue warning and add the vehicle to MSVehicleTransfer ...
Definition: MSLane.cpp:743
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:368
T MIN2(T a, T b)
Definition: StdDefs.h:73
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:188
SUMOReal getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:368
No information given; use default.
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:450
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:869
Something on a lane to be noticed about vehicle movement.
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, bool checkNext) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1247
SUMOReal myLength
Lane length [m].
Definition: MSLane.h:843
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:184
MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:992
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuouss lane change.
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1079
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
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:92
void registerTeleportJam()
register one non-collision-related teleport
virtual SUMOReal getHeadwayTime() const
Get the driver&#39;s reaction time [s].
Definition: MSCFModel.h:203
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:833
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1916
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
Definition: MSLane.h:889
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:270
Base class for objects which have an id.
Definition: Named.h:45
std::vector< MSMoveReminder * > myMoveReminders
This lane&#39;s move reminder.
Definition: MSLane.h:902
bool pWagSimpleInsertion(MSVehicle &veh, SUMOReal speed, SUMOReal maxPos, SUMOReal minPos)
Definition: MSLane.cpp:194
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:1861
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:1471
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:884
SUMOReal getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:1608
static SUMOTime gTimeToGridlockHighways
Definition: MSGlobals.h:68
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:1596
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:235
The vehicle has departed (was inserted into the network)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2591
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
void setTentativeLaneAndPosition(MSLane *lane, const SUMOReal pos)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:2456
Structure representing possible vehicle parameter.
bool operator()(const MSVehicle *cmp, SUMOReal pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:1661
MSVehicle * myInlappingVehicle
The vehicle which laps into this lane.
Definition: MSLane.h:882
SUMOReal myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:873
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:209
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:349
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:907
bool isEmpty() const
Definition: MSLane.cpp:987
SUMOReal getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:1572
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:849
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:224
SUMOReal getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:1584
std::pair< MSVehicle *const, SUMOReal > getFollowerOnConsecutive(SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const
return the follower with the largest missing rear gap among all predecessor lanes (within dist) ...
Definition: MSLane.cpp:1182
bool checkFailure(MSVehicle *aVehicle, SUMOReal &speed, SUMOReal &dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:435
SUMOReal myInlappingVehicleEnd
End position of a vehicle which laps into this lane.
Definition: MSLane.h:879
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:93
bool maxSpeedGapInsertion(MSVehicle &veh, SUMOReal mspeed)
Definition: MSLane.cpp:227
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1133
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:294
#define LANE_RTREE_QUAL
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:65
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
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 ...
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:1694
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:323
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:253
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:315
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:339
#define NUMERICAL_EPS
Definition: config.h:161
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:100
int operator()(const std::pair< const MSVehicle *, SUMOReal > &p1, const std::pair< const MSVehicle *, SUMOReal > &p2) const
Definition: MSLane.cpp:1151
#define DELTA_T
Definition: SUMOTime.h:50
SUMOReal myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:876
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1059
No information given; use default.
A free position is chosen.
The class responsible for building and deletion of vehicles.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:78
Simple max-flow insertion by P.Wagner.
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:354
SUMOReal getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:1644
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:331
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:590
The edge is an internal edge.
Definition: MSEdge.h:98
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:1507
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:83
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void registerTeleportWrongLane()
register one non-collision-related teleport
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
Back-at-zero position.
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:1496
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
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:75
virtual bool appropriate(const MSVehicle *veh)
Definition: MSLane.cpp:942
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:692
const std::string & getID() const
Returns the name of the vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
unsigned int getLaneIndex() const
Definition: MSVehicle.cpp:2449