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