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 /****************************************************************************/
13 // Representation of a lane in the micro simulation
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
16 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
38 #include <utils/common/StdDefs.h>
39 #include "MSVehicle.h"
41 #include "MSNet.h"
42 #include "MSVehicleType.h"
43 #include "MSEdge.h"
44 #include "MSEdgeControl.h"
45 #include "MSJunction.h"
46 #include "MSLogicJunction.h"
47 #include "MSLink.h"
48 #include "MSLane.h"
49 #include "MSVehicleTransfer.h"
50 #include "MSGlobals.h"
51 #include "MSVehicleControl.h"
52 #include "MSInsertionControl.h"
53 #include "MSVehicleControl.h"
54 #include <cmath>
55 #include <bitset>
56 #include <iostream>
57 #include <cassert>
58 #include <functional>
59 #include <algorithm>
60 #include <iterator>
61 #include <exception>
62 #include <climits>
63 #include <set>
65 #include <utils/common/ToString.h>
68 #include <utils/geom/Line.h>
69 #include <utils/geom/GeomHelper.h>
70 
71 #ifdef CHECK_MEMORY_LEAKS
72 #include <foreign/nvwa/debug_new.h>
73 #endif // CHECK_MEMORY_LEAKS
74 
75 
76 // ===========================================================================
77 // static member definitions
78 // ===========================================================================
80 
81 
82 // ===========================================================================
83 // member method definitions
84 // ===========================================================================
85 MSLane::MSLane(const std::string& id, SUMOReal maxSpeed, SUMOReal length, MSEdge* const edge,
86  unsigned int numericalID, const PositionVector& shape, SUMOReal width,
87  SVCPermissions permissions) :
88  Named(id),
89  myShape(shape), myNumericalID(numericalID),
90  myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed),
91  myPermissions(permissions),
92  myLogicalPredecessorLane(0),
93  myBruttoVehicleLengthSum(0), myNettoVehicleLengthSum(0), myInlappingVehicleEnd(10000), myInlappingVehicle(0),
94  myLengthGeometryFactor(myShape.length() / myLength) {}
95 
96 
98  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
99  delete *i;
100  }
101 }
102 
103 
104 void
106  myLinks.push_back(link);
107 }
108 
109 
110 // ------ interaction with MSMoveReminder ------
111 void
113  myMoveReminders.push_back(rem);
114  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
115  (*veh)->addReminder(rem);
116  }
117 }
118 
119 
120 
121 // ------ Vehicle emission ------
122 void
123 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
124  assert(pos <= myLength);
125  bool wasInactive = myVehicles.size() == 0;
126  veh->enterLaneAtInsertion(this, pos, speed, notification);
127  if (at == myVehicles.end()) {
128  // vehicle will be the first on the lane
129  myVehicles.push_back(veh);
130  } else {
131  myVehicles.insert(at, veh);
132  }
135  if (wasInactive) {
137  }
138 }
139 
140 
141 bool
143  SUMOReal xIn = maxPos;
144  SUMOReal vIn = mspeed;
145  SUMOReal leaderDecel;
146  veh.getBestLanes(true, this);
147  if (myVehicles.size() != 0) {
148  MSVehicle* leader = myVehicles.front();
149  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
150  vIn = leader->getSpeed();
151  leaderDecel = leader->getCarFollowModel().getMaxDecel();
152  } else {
153  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
154  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
155  if (leader.first != 0) {
156  xIn = getLength() + leader.second;
157  vIn = leader.first->getSpeed();
158  leaderDecel = leader.first->getCarFollowModel().getMaxDecel();
159  } else {
160  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
161  return true;
162  }
163  }
164  const SUMOReal vHlp = 0.5 * (vIn + mspeed);
165  SUMOReal x2 = xIn;// have seen leader length already - skCar::lCar;
166  SUMOReal x1 = x2 - 100.0;
167  SUMOReal x = 0;
168  for (int i = 0; i <= 10; i++) {
169  x = 0.5 * (x1 + x2);
170  SUMOReal vSafe = veh.getCarFollowModel().followSpeed(&veh, vHlp, xIn - x, vIn, leaderDecel);
171  if (vSafe < vHlp) {
172  x2 = x;
173  } else {
174  x1 = x;
175  }
176  }
177  if (x < minPos) {
178  return false;
179  } else if (x > maxPos) {
180  x = maxPos;
181  }
182  incorporateVehicle(&veh, x, vHlp, myVehicles.begin());
183  return true;
184 }
185 
186 
187 bool
189  SUMOReal xIn = maxPos;
190  SUMOReal vIn = mspeed;
191  veh.getBestLanes(true, this);
192  if (myVehicles.size() != 0) {
193  MSVehicle* leader = myVehicles.front();
194  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
195  vIn = leader->getSpeed();
196  } else {
197  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
198  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
199  if (leader.first != 0) {
200  xIn = getLength() + leader.second;
201  vIn = leader.first->getSpeed();
202  } else {
203  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
204  return true;
205  }
206  }
207  const SUMOReal vHlp = 0.5 * (mspeed + vIn);
208  xIn = xIn - vHlp * veh.getCarFollowModel().getHeadwayTime() - veh.getVehicleType().getMinGap();
209  if (xIn < minPos) {
210  return false;
211  } else if (xIn > maxPos) {
212  xIn = maxPos;
213  }
214  incorporateVehicle(&veh, xIn, vHlp, myVehicles.begin());
215  return true;
216 }
217 
218 
219 bool
221  if (myVehicles.size() == 0) {
222  return isInsertionSuccess(&veh, mspeed, myLength / 2, true);
223  }
224  // go through the lane, look for free positions (starting after the last vehicle)
225  MSLane::VehCont::iterator predIt = myVehicles.begin();
226  SUMOReal maxSpeed = 0;
227  SUMOReal maxPos = 0;
228  MSLane::VehCont::iterator maxIt = myVehicles.begin();
229  while (predIt != myVehicles.end()) {
230  // get leader (may be zero) and follower
231  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
232  const MSVehicle* follower = *predIt;
233  SUMOReal leaderRearPos = getLength();
234  SUMOReal leaderSpeed = mspeed;
235  if (leader != 0) {
236  leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
237  if (leader == getPartialOccupator()) {
238  leaderRearPos = getPartialOccupatorEnd();
239  }
240  leaderSpeed = leader->getSpeed();
241  }
242  const SUMOReal nettoGap = leaderRearPos - follower->getPositionOnLane() - veh.getVehicleType().getLengthWithGap();
243  if (nettoGap > 0) {
244  const SUMOReal tau = veh.getCarFollowModel().getHeadwayTime();
245  const SUMOReal tauDecel = tau * veh.getCarFollowModel().getMaxDecel();
246  const SUMOReal fSpeed = follower->getSpeed();
247  const SUMOReal lhs = nettoGap / tau + tauDecel - fSpeed - fSpeed * fSpeed / (2 * tauDecel) + leaderSpeed * leaderSpeed / (2 * tauDecel);
248  if (lhs >= sqrt(tauDecel * tauDecel + leaderSpeed * leaderSpeed)) {
249  const SUMOReal frontGap = (lhs * lhs - tauDecel * tauDecel - leaderSpeed * leaderSpeed) / (2 * veh.getCarFollowModel().getMaxDecel());
250  const SUMOReal currentMaxSpeed = lhs - tauDecel;
251  if (MIN2(currentMaxSpeed, mspeed) > maxSpeed) {
252  maxSpeed = currentMaxSpeed;
253  maxPos = leaderRearPos + frontGap;
254  maxIt = predIt + 1;
255  }
256  }
257  }
258  ++predIt;
259  }
260  if (maxSpeed > 0) {
261  incorporateVehicle(&veh, maxPos, maxSpeed, maxIt);
262  return true;
263  }
264  return false;
265 }
266 
267 
268 bool
270  MSMoveReminder::Notification notification) {
271  bool adaptableSpeed = true;
272  if (myVehicles.size() == 0) {
273  if (isInsertionSuccess(&veh, mspeed, 0, adaptableSpeed, notification)) {
274  return true;
275  }
276  } else {
277  // check whether the vehicle can be put behind the last one if there is such
278  MSVehicle* leader = myVehicles.back();
279  SUMOReal leaderPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
280  SUMOReal speed = mspeed;
281  if (adaptableSpeed) {
282  speed = leader->getSpeed();
283  }
284  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
285  if (leaderPos - frontGapNeeded >= 0) {
286  SUMOReal tspeed = MIN2(veh.getCarFollowModel().followSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
287  // check whether we can insert our vehicle behind the last vehicle on the lane
288  if (isInsertionSuccess(&veh, tspeed, 0, adaptableSpeed, notification)) {
289  return true;
290  }
291  }
292  }
293  // go through the lane, look for free positions (starting after the last vehicle)
294  MSLane::VehCont::iterator predIt = myVehicles.begin();
295  while (predIt != myVehicles.end()) {
296  // get leader (may be zero) and follower
297  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
298  const MSVehicle* follower = *predIt;
299 
300  // patch speed if allowed
301  SUMOReal speed = mspeed;
302  if (adaptableSpeed && leader != 0) {
303  speed = MIN2(leader->getSpeed(), mspeed);
304  }
305 
306  // compute the space needed to not collide with leader
307  SUMOReal frontMax = getLength();
308  if (leader != 0) {
309  SUMOReal leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
310  if (leader == getPartialOccupator()) {
311  leaderRearPos = getPartialOccupatorEnd();
312  }
313  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
314  frontMax = leaderRearPos - frontGapNeeded;
315  }
316  // compute the space needed to not let the follower collide
317  const SUMOReal followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
318  const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
319  const SUMOReal backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
320 
321  // check whether there is enough room (given some extra space for rounding errors)
322  if (frontMax > 0 && backMin + POSITION_EPS < frontMax) {
323  // try to insert vehicle (should be always ok)
324  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, adaptableSpeed, notification)) {
325  return true;
326  }
327  }
328  ++predIt;
329  }
330  // first check at lane's begin
331  return false;
332 }
333 
334 
335 bool
337  SUMOReal pos = 0;
338  SUMOReal speed = 0;
339  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
340 
341  // determine the speed
342  const SUMOVehicleParameter& pars = veh.getParameter();
343  switch (pars.departSpeedProcedure) {
344  case DEPART_SPEED_GIVEN:
345  speed = pars.departSpeed;
346  patchSpeed = false;
347  break;
348  case DEPART_SPEED_RANDOM:
349  speed = RandHelper::rand(MIN2(veh.getMaxSpeed(), getVehicleMaxSpeed(&veh)));
350  patchSpeed = true; // @todo check
351  break;
352  case DEPART_SPEED_MAX:
353  speed = MIN2(veh.getMaxSpeed(), getVehicleMaxSpeed(&veh));
354  patchSpeed = true; // @todo check
355  break;
357  default:
358  // speed = 0 was set before
359  patchSpeed = false; // @todo check
360  break;
361  }
362 
363  // determine the position
364  switch (pars.departPosProcedure) {
365  case DEPART_POS_GIVEN:
366  pos = pars.departPos;
367  if (pos < 0.) {
368  pos += myLength;
369  }
370  break;
371  case DEPART_POS_RANDOM:
372  pos = RandHelper::rand(getLength());
373  break;
374  case DEPART_POS_RANDOM_FREE: {
375  for (unsigned int i = 0; i < 10; i++) {
376  // we will try some random positions ...
377  pos = RandHelper::rand(getLength());
378  if (isInsertionSuccess(&veh, speed, pos, patchSpeed)) {
379  return true;
380  }
381  }
382  // ... and if that doesn't work, we put the vehicle to the free position
383  return freeInsertion(veh, speed);
384  }
385  break;
386  case DEPART_POS_FREE:
387  return freeInsertion(veh, speed);
389  return pWagSimpleInsertion(veh, speed, getLength(), 0.0);
391  return pWagGenericInsertion(veh, speed, getLength(), 0.0);
393  return maxSpeedGapInsertion(veh, speed);
394  case DEPART_POS_BASE:
395  case DEPART_POS_DEFAULT:
396  default:
397  pos = MIN2(static_cast<SUMOReal>(veh.getVehicleType().getLength() + POSITION_EPS), myLength);
398  break;
399  }
400  // try to insert
401  return isInsertionSuccess(&veh, speed, pos, patchSpeed);
402 }
403 
404 
405 bool
406 MSLane::checkFailure(MSVehicle* aVehicle, SUMOReal& speed, SUMOReal& dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const {
407  if (nspeed < speed) {
408  if (patchSpeed) {
409  speed = MIN2(nspeed, speed);
410  dist = aVehicle->getCarFollowModel().brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
411  } else {
412  if (errorMsg != "") {
413  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (" + errorMsg + ")!");
415  }
416  return true;
417  }
418  }
419  return false;
420 }
421 
422 
423 bool
425  SUMOReal speed, SUMOReal pos, bool patchSpeed,
426  MSMoveReminder::Notification notification) {
427  if (pos < 0 || pos > myLength) {
428  // we may not start there
429  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
430  aVehicle->getID() + "'. Inserting at lane end instead.");
431  pos = myLength;
432  }
433  aVehicle->getBestLanes(true, this);
434  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
435  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
436  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
437  SUMOReal seen = getLength() - pos;
438  SUMOReal dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
439  const MSRoute& r = aVehicle->getRoute();
440  MSRouteIterator ce = r.begin();
441  unsigned int nRouteSuccs = 1;
442  MSLane* currentLane = this;
443  MSLane* nextLane = this;
444  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
445  while (seen < dist && ri != bestLaneConts.end()) {
446  // get the next link used...
447  MSLinkCont::const_iterator link = succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
448  if (currentLane->isLinkEnd(link)) {
449  if (&currentLane->getEdge() == r.getLastEdge()) {
450  // reached the end of the route
452  if (checkFailure(aVehicle, speed, dist, cfModel.freeSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed),
453  patchSpeed, "arrival speed too low")) {
454  // we may not drive with the given velocity - we cannot match the specified arrival speed
455  return false;
456  }
457  }
458  } else {
459  // lane does not continue
460  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, seen),
461  patchSpeed, "junction too close")) {
462  // we may not drive with the given velocity - we cannot stop at the junction
463  return false;
464  }
465  }
466  break;
467  }
468  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength(), aVehicle->getImpatience(), cfModel.getMaxDecel(), 0)
469  || !(*link)->havePriority()) {
470  // have to stop at junction
471  std::string errorMsg = "";
472  const LinkState state = (*link)->getState();
473  if (state == LINKSTATE_MINOR
474  || state == LINKSTATE_EQUAL
475  || state == LINKSTATE_STOP
476  || state == LINKSTATE_ALLWAY_STOP) {
477  // no sense in trying later
478  errorMsg = "unpriorised junction too close";
479  }
480  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, seen),
481  patchSpeed, errorMsg)) {
482  // we may not drive with the given velocity - we cannot stop at the junction in time
483  return false;
484  }
485  break;
486  }
487  // get the next used lane (including internal)
488  nextLane = (*link)->getViaLaneOrLane();
489  // check how next lane effects the journey
490  if (nextLane != 0) {
491  arrivalTime += TIME2STEPS(nextLane->getLength() / speed);
492  SUMOReal gap = 0;
493  MSVehicle* leader = currentLane->getPartialOccupator();
494  if (leader != 0) {
495  gap = seen + currentLane->getPartialOccupatorEnd() - currentLane->getLength() - aVehicle->getVehicleType().getMinGap();
496  } else {
497  // check leader on next lane
498  leader = nextLane->getLastVehicle();
499  if (leader != 0) {
500  gap = seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - aVehicle->getVehicleType().getMinGap();
501  }
502  }
503  if (leader != 0) {
504  if (gap < 0) {
505  return false;
506  }
507  const SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
508  if (checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
509  // we may not drive with the given velocity - we crash into the leader
510  return false;
511  }
512  }
513  // check next lane's maximum velocity
514  const SUMOReal nspeed = nextLane->getVehicleMaxSpeed(aVehicle);
515  if (nspeed < speed) {
516  if (patchSpeed) {
517  speed = MIN2(cfModel.freeSpeed(aVehicle, speed, seen, nspeed), speed);
518  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
519  } else {
520  // we may not drive with the given velocity - we would be too fast on the next lane
521  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (slow lane ahead)!");
523  return false;
524  }
525  }
526  // check traffic on next junction
527  // we cannot use (*link)->opened because a vehicle without priority
528  // may already be comitted to blocking the link and unable to stop
529  const SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
530  const SUMOTime leaveTime = arrivalTime + TIME2STEPS((*link)->getLength() * speed);
531  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed, cfModel.getMaxDecel())) {
532  if (checkFailure(aVehicle, speed, dist, cfModel.followSpeed(aVehicle, speed, seen, 0, 0),
533  patchSpeed, "")) {
534  // we may not drive with the given velocity - we crash at the junction
535  return false;
536  }
537  }
538  seen += nextLane->getLength();
539  currentLane = nextLane;
540 #ifdef HAVE_INTERNAL_LANES
541  if ((*link)->getViaLane() == 0) {
542 #else
543  if (true) {
544 #endif
545  nRouteSuccs++;
546  ++ce;
547  ++ri;
548  }
549  }
550  }
551 
552  // get the pointer to the vehicle next in front of the given position
553  MSLane::VehCont::iterator predIt = find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos));
554  if (predIt != myVehicles.end()) {
555  // ok, there is one (a leader)
556  MSVehicle* leader = *predIt;
557  SUMOReal frontGapNeeded = cfModel.getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
558  SUMOReal gap = MSVehicle::gap(leader->getPositionOnLane(), leader->getVehicleType().getLength(), pos + aVehicle->getVehicleType().getMinGap());
559  if (gap < frontGapNeeded) {
560  // too close to the leader on this lane
561  return false;
562  }
563  }
564 
565  // check back vehicle
566  if (predIt != myVehicles.begin()) {
567  // there is direct follower on this lane
568  MSVehicle* follower = *(predIt - 1);
569  SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
570  SUMOReal gap = MSVehicle::gap(pos, aVehicle->getVehicleType().getLength(), follower->getPositionOnLane() + follower->getVehicleType().getMinGap());
571  if (gap < backGapNeeded) {
572  // too close to the follower on this lane
573  return false;
574  }
575  } else {
576  // check approaching vehicles to prevent rear-end collisions
577  // to compute an uper bound on the look-back distance we need
578  // the chosenSpeedFactor, minGap and maxDeceleration of approaching vehicles
579  // since we do not know these we use the values from the vehicle to be inserted
580  // and add a safety factor
581  const SUMOReal dist = 2 * (aVehicle->getCarFollowModel().brakeGap(myMaxSpeed) + aVehicle->getVehicleType().getMinGap());
582  const SUMOReal backOffset = pos - aVehicle->getVehicleType().getLength();
583  const SUMOReal missingRearGap = getMissingRearGap(dist, backOffset, speed, aVehicle->getCarFollowModel().getMaxDecel());
584  if (missingRearGap > 0) {
585  // too close to a follower
586  const SUMOReal neededStartPos = pos + missingRearGap;
587  if (myVehicles.size() == 0 && notification == MSMoveReminder::NOTIFICATION_TELEPORT && neededStartPos <= myLength) {
588  // shift starting positiong as needed entering from teleport
589  pos = neededStartPos;
590  } else {
591  return false;
592  }
593  }
594  }
595  // may got negative while adaptation
596  if (speed < 0) {
597  return false;
598  }
599  // enter
600  incorporateVehicle(aVehicle, pos, speed, predIt, notification);
601  return true;
602 }
603 
604 
605 void
607  veh->getBestLanes(true, this);
608  incorporateVehicle(veh, pos, veh->getSpeed(), find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)));
609 }
610 
611 
612 // ------ Handling vehicles lapping into lanes ------
613 SUMOReal
615  myInlappingVehicle = v;
616  if (leftVehicleLength > myLength) {
618  } else {
619  myInlappingVehicleEnd = myLength - leftVehicleLength;
620  }
621  return myLength;
622 }
623 
624 
625 void
627  if (v == myInlappingVehicle) {
628  myInlappingVehicleEnd = 10000;
629  }
630  myInlappingVehicle = 0;
631 }
632 
633 
634 std::pair<MSVehicle*, SUMOReal>
636  if (myVehicles.size() != 0) {
637  // the last vehicle is the one in scheduled by this lane
638  MSVehicle* last = *myVehicles.begin();
639  const SUMOReal pos = last->getPositionOnLane() - last->getVehicleType().getLength();
640  return std::make_pair(last, pos);
641  }
642  if (myInlappingVehicle != 0) {
643  // the last one is a vehicle extending into this lane
644  return std::make_pair(myInlappingVehicle, myInlappingVehicleEnd);
645  }
646  return std::make_pair<MSVehicle*, SUMOReal>(0, 0);
647 }
648 
649 
650 // ------ ------
651 void
653  assert(myVehicles.size() != 0);
654  SUMOReal cumulatedVehLength = 0.;
655  const MSVehicle* pred = getPartialOccupator();
656  for (VehCont::reverse_iterator veh = myVehicles.rbegin(); veh != myVehicles.rend(); ++veh) {
657  if ((*veh)->getLane() == this) {
658  (*veh)->planMove(t, pred, cumulatedVehLength);
659  }
660  pred = *veh;
661  cumulatedVehLength += pred->getVehicleType().getLengthWithGap();
662  }
663 }
664 
665 
666 void
667 MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
668  if (myVehicles.size() < 2) {
669  return;
670  }
671 
672  VehCont::iterator lastVeh = myVehicles.end() - 1;
673  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) {
674  VehCont::iterator pred = veh + 1;
675  if ((*veh)->hasInfluencer() && (*veh)->getInfluencer().isVTDControlled()) {
676  ++veh;
677  continue;
678  }
679  if ((*pred)->hasInfluencer() && (*pred)->getInfluencer().isVTDControlled()) {
680  ++veh;
681  continue;
682  }
683  SUMOReal gap = (*pred)->getPositionOnLane() - (*pred)->getVehicleType().getLength() - (*veh)->getPositionOnLane() - (*veh)->getVehicleType().getMinGap();
684  if (gap < -NUMERICAL_EPS) {
685  MSVehicle* vehV = *veh;
686  if (vehV->getLane() == this) {
687  WRITE_WARNING("Teleporting vehicle '" + vehV->getID() + "'; collision with '"
688  + (*pred)->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
689  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " stage=" + stage + ".");
693  MSVehicleTransfer::getInstance()->addVeh(timestep, vehV);
694  veh = myVehicles.erase(veh); // remove current vehicle
695  lastVeh = myVehicles.end() - 1;
696  if (veh == myVehicles.end()) {
697  break;
698  }
699  } else {
700  WRITE_WARNING("Shadow of vehicle '" + vehV->getID() + "'; collision with '"
701  + (*pred)->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
702  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " stage=" + stage + ".");
703  veh = myVehicles.erase(veh); // remove current vehicle
704  lastVeh = myVehicles.end() - 1;
706  if (veh == myVehicles.end()) {
707  break;
708  }
709  }
710  } else {
711  ++veh;
712  }
713  }
714 }
715 
716 
717 bool
718 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& into) {
719  // iteratate over vehicles in reverse so that move reminders will be called in the correct order
720  for (VehCont::reverse_iterator i = myVehicles.rbegin(); i != myVehicles.rend();) {
721  MSVehicle* veh = *i;
722  if (veh->getLane() != this || veh->getLaneChangeModel().alreadyMoved()) {
723  // this is the shadow during a continuous lane change
724  ++i;
725  continue;
726  }
727  // length is needed later when the vehicle may not exist anymore
728  const SUMOReal length = veh->getVehicleType().getLengthWithGap();
729  const SUMOReal nettoLength = veh->getVehicleType().getLength();
730  bool moved = veh->executeMove();
731  MSLane* target = veh->getLane();
732 #ifndef NO_TRACI
733  bool vtdControlled = veh->hasInfluencer() && veh->getInfluencer().isVTDControlled();
734  if (veh->hasArrived() && !vtdControlled) {
735 #else
736  if (veh->hasArrived()) {
737 #endif
738  // vehicle has reached its arrival position
741  } else if (target != 0 && moved) {
742  if (target->getEdge().isVaporizing()) {
743  // vehicle has reached a vaporizing edge
746  } else {
747  // vehicle has entered a new lane (leaveLane was already called in MSVehicle::executeMove)
748  target->myVehBuffer.push_back(veh);
749  SUMOReal pspeed = veh->getSpeed();
750  SUMOReal oldPos = veh->getPositionOnLane() - SPEED2DIST(veh->getSpeed());
751  veh->workOnMoveReminders(oldPos, veh->getPositionOnLane(), pspeed);
752  into.push_back(target);
753  if (veh->getLaneChangeModel().isChangingLanes()) {
754  MSLane* shadowLane = veh->getLaneChangeModel().getShadowLane();
755  if (shadowLane != 0) {
756  into.push_back(shadowLane);
757  shadowLane->myVehBuffer.push_back(veh);
758  }
759  }
760  }
761  } else if (veh->isParking()) {
762  // vehicle started to park
765  } else if (veh->getPositionOnLane() > getLength()) {
766  // for any reasons the vehicle is beyond its lane...
767  // this should never happen because it is handled in MSVehicle::executeMove
768  assert(false);
769  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, targetLane='" + getID() + "', time=" +
770  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
773  } else {
774  ++i;
775  continue;
776  }
777  myBruttoVehicleLengthSum -= length;
778  myNettoVehicleLengthSum -= nettoLength;
779  ++i;
780  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
781  }
782  if (myVehicles.size() > 0) {
784  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
785  if (!veh->isStopped()) {
786  const bool wrongLane = !veh->getLane()->appropriate(veh);
788  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
789  if (r1 || r2) {
790  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
791  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
792  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
793  MSVehicle* veh = *(myVehicles.end() - 1);
796  myVehicles.erase(myVehicles.end() - 1);
797  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
798  + reason
799  + (r2 ? " (highway)" : "")
800  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
801  if (wrongLane) {
803  } else if (minorLink) {
805  } else {
807  }
809  }
810  } // else look for a vehicle that isn't stopped?
811  }
812  }
813  return myVehicles.size() == 0;
814 }
815 
816 
817 const MSEdge*
819  const MSEdge* e = myEdge;
820  while (e->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
821  e = e->getFollower(0);
822  }
823  return e;
824 }
825 
826 
827 // ------ Static (sic!) container methods ------
828 bool
829 MSLane::dictionary(const std::string& id, MSLane* ptr) {
830  DictType::iterator it = myDict.find(id);
831  if (it == myDict.end()) {
832  // id not in myDict.
833  myDict.insert(DictType::value_type(id, ptr));
834  return true;
835  }
836  return false;
837 }
838 
839 
840 MSLane*
841 MSLane::dictionary(const std::string& id) {
842  DictType::iterator it = myDict.find(id);
843  if (it == myDict.end()) {
844  // id not in myDict.
845  return 0;
846  }
847  return it->second;
848 }
849 
850 
851 void
853  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
854  delete(*i).second;
855  }
856  myDict.clear();
857 }
858 
859 
860 void
861 MSLane::insertIDs(std::vector<std::string>& into) {
862  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
863  into.push_back((*i).first);
864  }
865 }
866 
867 
868 template<class RTREE> void
869 MSLane::fill(RTREE& into) {
870  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
871  MSLane* l = (*i).second;
872  Boundary b = l->getShape().getBoxBoundary();
873  b.grow(3.);
874  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
875  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
876  into.Insert(cmin, cmax, l);
877  }
878 }
879 
880 template void MSLane::fill<NamedRTree>(NamedRTree& into);
881 #ifndef NO_TRACI
882 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
883 #endif
884 
885 // ------ ------
886 bool
889  return true;
890  }
891  if (veh->succEdge(1) == 0) {
892  assert(veh->getBestLanes().size() > veh->getLaneIndex());
893  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
894  return true;
895  } else {
896  return false;
897  }
898  }
899  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
900  return (link != myLinks.end());
901 }
902 
903 
904 bool
906  bool wasInactive = myVehicles.size() == 0;
907  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter());
908  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
909  MSVehicle* veh = *i;
910  myVehicles.insert(myVehicles.begin(), veh);
913  }
914  myVehBuffer.clear();
915  return wasInactive && myVehicles.size() != 0;
916 }
917 
918 
919 bool
920 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
921  return i == myLinks.end();
922 }
923 
924 
925 bool
926 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
927  return i == myLinks.end();
928 }
929 
930 
931 MSVehicle*
933  if (myVehicles.size() == 0) {
934  return 0;
935  }
936  return *myVehicles.begin();
937 }
938 
939 
940 const MSVehicle*
942  if (myVehicles.size() == 0) {
943  return 0;
944  }
945  return *(myVehicles.end() - 1);
946 }
947 
948 
949 MSLinkCont::const_iterator
950 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs,
951  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
952  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
953  // check whether the vehicle tried to look beyond its route
954  if (nRouteEdge == 0) {
955  // return end (no succeeding link) if so
956  return succLinkSource.myLinks.end();
957  }
958  // if we are on an internal lane there should only be one link and it must be allowed
959  if (succLinkSource.getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
960  assert(succLinkSource.myLinks.size() == 1);
961  assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
962  return succLinkSource.myLinks.begin();
963  }
964  // a link may be used if
965  // 1) there is a destination lane ((*link)->getLane()!=0)
966  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
967  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
968 
969  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
970  // "conts" stores the best continuations of our current lane
971  // we should never return an arbitrary link since this may cause collisions
972  MSLinkCont::const_iterator link;
973  if (nRouteSuccs < conts.size()) {
974  // we go through the links in our list and return the matching one
975  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
976  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
977  // we should use the link if it connects us to the best lane
978  if ((*link)->getLane() == conts[nRouteSuccs]) {
979  return link;
980  }
981  }
982  }
983  } else {
984  // the source lane is a dead end (no continuations exist)
985  return succLinkSource.myLinks.end();
986  }
987  // the only case where this should happen is for a disconnected route (deliberately ignored)
988 #ifdef _DEBUG
989  WRITE_WARNING("Could not find connection between '" + succLinkSource.getID() + "' and '" + conts[nRouteSuccs]->getID() +
990  "' for vehicle '" + veh.getID() + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
991 #endif
992  return succLinkSource.myLinks.end();
993 }
994 
995 
996 
997 const MSLinkCont&
999  return myLinks;
1000 }
1001 
1002 
1003 void
1006  myTmpVehicles.clear();
1007 }
1008 
1009 
1010 MSVehicle*
1011 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
1012  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
1013  if (remVehicle == *it) {
1014  if (notify) {
1015  remVehicle->leaveLane(notification);
1016  }
1017  myVehicles.erase(it);
1020  break;
1021  }
1022  }
1023  return remVehicle;
1024 }
1025 
1026 
1027 MSLane*
1028 MSLane::getParallelLane(int offset) const {
1029  return myEdge->parallelLane(this, offset);
1030 }
1031 
1032 
1033 void
1035  IncomingLaneInfo ili;
1036  ili.lane = lane;
1037  ili.viaLink = viaLink;
1038  ili.length = lane->getLength();
1039  myIncomingLanes.push_back(ili);
1040 }
1041 
1042 
1043 void
1045  MSEdge* approachingEdge = &lane->getEdge();
1046  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1047  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1048  }
1049  myApproachingLanes[approachingEdge].push_back(lane);
1050 }
1051 
1052 
1053 bool
1055  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1056 }
1057 
1058 
1059 bool
1060 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1061  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1062  if (i == myApproachingLanes.end()) {
1063  return false;
1064  }
1065  const std::vector<MSLane*>& lanes = (*i).second;
1066  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1067 }
1068 
1069 
1071 public:
1072  inline int operator()(const std::pair<const MSVehicle* , SUMOReal>& p1, const std::pair<const MSVehicle* , SUMOReal>& p2) const {
1073  return p1.second < p2.second;
1074  }
1075 };
1076 
1077 
1079  SUMOReal dist, SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1080  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1081  // search until dist and check for the vehicle with the largest missing rear gap
1082  SUMOReal result = 0;
1083  std::set<MSLane*> visited;
1084  std::vector<MSLane::IncomingLaneInfo> newFound;
1085  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1086  while (toExamine.size() != 0) {
1087  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1088  MSLane* next = (*i).lane;
1089  if (next->getFirstVehicle() != 0) {
1090  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1091  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1092  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(
1093  v->getCarFollowModel().maxNextSpeed(v->getSpeed(), v), leaderSpeed, leaderMaxDecel) - agap;
1094  result = MAX2(result, missingRearGap);
1095  } else {
1096  if ((*i).length < dist) {
1097  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1098  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1099  if (visited.find((*j).lane) == visited.end()) {
1100  visited.insert((*j).lane);
1102  ili.lane = (*j).lane;
1103  ili.length = (*j).length + (*i).length;
1104  ili.viaLink = (*j).viaLink;
1105  newFound.push_back(ili);
1106  }
1107  }
1108  }
1109  }
1110  }
1111  toExamine.clear();
1112  swap(newFound, toExamine);
1113  }
1114  return result;
1115 }
1116 
1117 
1118 std::pair<MSVehicle* const, SUMOReal>
1120  SUMOReal backOffset, SUMOReal leaderMaxDecel) const {
1121  // do a tree search among all follower lanes and check for the most
1122  // important vehicle (the one requiring the largest reargap)
1123  std::pair<MSVehicle*, SUMOReal> result(static_cast<MSVehicle*>(0), -1);
1124  SUMOReal missingRearGapMax = 0;
1125  std::set<MSLane*> visited;
1126  std::vector<MSLane::IncomingLaneInfo> newFound;
1127  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1128  while (toExamine.size() != 0) {
1129  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1130  MSLane* next = (*i).lane;
1131  if (next->getFirstVehicle() != 0) {
1132  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1133  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1134  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - agap;
1135  if (missingRearGap > missingRearGapMax) {
1136  missingRearGapMax = missingRearGap;
1137  result.first = v;
1138  result.second = agap;
1139  }
1140  } else {
1141  if ((*i).length < dist) {
1142  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1143  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1144  if (visited.find((*j).lane) == visited.end()) {
1145  visited.insert((*j).lane);
1147  ili.lane = (*j).lane;
1148  ili.length = (*j).length + (*i).length;
1149  ili.viaLink = (*j).viaLink;
1150  newFound.push_back(ili);
1151  }
1152  }
1153  }
1154  }
1155  }
1156  toExamine.clear();
1157  swap(newFound, toExamine);
1158  }
1159  return result;
1160 }
1161 
1162 
1163 std::pair<MSVehicle* const, SUMOReal>
1165  const std::vector<MSLane*>& bestLaneConts) const {
1166  if (seen > dist) {
1167  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1168  }
1169  unsigned int view = 1;
1170  // loop over following lanes
1171  if (getPartialOccupator() != 0) {
1172  return std::make_pair(getPartialOccupator(), seen - (getLength() - getPartialOccupatorEnd()) - veh.getVehicleType().getMinGap());
1173  }
1174  const MSLane* nextLane = this;
1175  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
1176  do {
1177  // get the next link used
1178  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1179  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1180  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0) || (*link)->getState() == LINKSTATE_TL_RED) {
1181  break;
1182  }
1183 #ifdef HAVE_INTERNAL_LANES
1184  // check for link leaders
1185  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, veh.getVehicleType().getMinGap());
1186  if (linkLeaders.size() > 0) {
1187  // XXX if there is more than one link leader we should return the most important
1188  // one (gap, decel) but this is hard to know at this point
1189  return linkLeaders[0].first;
1190  }
1191  bool nextInternal = (*link)->getViaLane() != 0;
1192 #endif
1193  nextLane = (*link)->getViaLaneOrLane();
1194  if (nextLane == 0) {
1195  break;
1196  }
1197  arrivalTime += TIME2STEPS(nextLane->getLength() / speed);
1198  MSVehicle* leader = nextLane->getLastVehicle();
1199  if (leader != 0) {
1200  return std::make_pair(leader, seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap());
1201  } else {
1202  leader = nextLane->getPartialOccupator();
1203  if (leader != 0) {
1204  return std::make_pair(leader, seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1205  }
1206  }
1207  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1208  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1209  }
1210  seen += nextLane->getLength();
1211 #ifdef HAVE_INTERNAL_LANES
1212  if (!nextInternal) {
1213  view++;
1214  }
1215 #else
1216  view++;
1217 #endif
1218  } while (seen <= dist);
1219  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1220 }
1221 
1222 
1223 MSLane*
1225  if (myLogicalPredecessorLane != 0) {
1226  return myLogicalPredecessorLane;
1227  }
1228  if (myLogicalPredecessorLane == 0) {
1229  std::vector<MSEdge*> pred = myEdge->getIncomingEdges();
1230  // get only those edges which connect to this lane
1231  for (std::vector<MSEdge*>::iterator i = pred.begin(); i != pred.end();) {
1232  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1233  if (j == myIncomingLanes.end()) {
1234  i = pred.erase(i);
1235  } else {
1236  ++i;
1237  }
1238  }
1239  // get the edge with the most connections to this lane's edge
1240  if (pred.size() != 0) {
1241  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1242  MSEdge* best = *pred.begin();
1243  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1244  myLogicalPredecessorLane = (*j).lane;
1245  }
1246  }
1247  return myLogicalPredecessorLane;
1248 }
1249 
1250 
1251 void
1255 }
1256 
1257 
1258 void
1262 }
1263 
1264 
1265 // ------------ Current state retrieval
1266 SUMOReal
1268  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1270  if (myVehicles.size() != 0) {
1271  MSVehicle* lastVeh = myVehicles.front();
1272  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1273  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1274  }
1275  }
1276  releaseVehicles();
1277  return (myBruttoVehicleLengthSum + fractions) / myLength;
1278 }
1279 
1280 
1281 SUMOReal
1283  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1285  if (myVehicles.size() != 0) {
1286  MSVehicle* lastVeh = myVehicles.front();
1287  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1288  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1289  }
1290  }
1291  releaseVehicles();
1292  return (myBruttoVehicleLengthSum + fractions) / myLength;
1293 }
1294 
1295 
1296 SUMOReal
1298  return myBruttoVehicleLengthSum;
1299 }
1300 
1301 
1302 SUMOReal
1304  if (myVehicles.size() == 0) {
1305  return 0;
1306  }
1307  SUMOReal wtime = 0;
1308  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
1309  wtime += (*i)->getWaitingSeconds();
1310  }
1311  return wtime;
1312 }
1313 
1314 
1315 SUMOReal
1317  if (myVehicles.size() == 0) {
1318  return myMaxSpeed;
1319  }
1320  SUMOReal v = 0;
1321  const MSLane::VehCont& vehs = getVehiclesSecure();
1322  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1323  v += (*i)->getSpeed();
1324  }
1325  SUMOReal ret = v / (SUMOReal) myVehicles.size();
1326  releaseVehicles();
1327  return ret;
1328 }
1329 
1330 
1331 SUMOReal
1333  SUMOReal ret = 0;
1334  const MSLane::VehCont& vehs = getVehiclesSecure();
1335  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1336  ret += (*i)->getCO2Emissions();
1337  }
1338  releaseVehicles();
1339  return ret;
1340 }
1341 
1342 
1343 SUMOReal
1345  SUMOReal ret = 0;
1346  const MSLane::VehCont& vehs = getVehiclesSecure();
1347  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1348  ret += (*i)->getCOEmissions();
1349  }
1350  releaseVehicles();
1351  return ret;
1352 }
1353 
1354 
1355 SUMOReal
1357  SUMOReal ret = 0;
1358  const MSLane::VehCont& vehs = getVehiclesSecure();
1359  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1360  ret += (*i)->getPMxEmissions();
1361  }
1362  releaseVehicles();
1363  return ret;
1364 }
1365 
1366 
1367 SUMOReal
1369  SUMOReal ret = 0;
1370  const MSLane::VehCont& vehs = getVehiclesSecure();
1371  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1372  ret += (*i)->getNOxEmissions();
1373  }
1374  releaseVehicles();
1375  return ret;
1376 }
1377 
1378 
1379 SUMOReal
1381  SUMOReal ret = 0;
1382  const MSLane::VehCont& vehs = getVehiclesSecure();
1383  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1384  ret += (*i)->getHCEmissions();
1385  }
1386  releaseVehicles();
1387  return ret;
1388 }
1389 
1390 
1391 SUMOReal
1393  SUMOReal ret = 0;
1394  const MSLane::VehCont& vehs = getVehiclesSecure();
1395  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1396  ret += (*i)->getFuelConsumption();
1397  }
1398  releaseVehicles();
1399  return ret;
1400 }
1401 
1402 
1403 SUMOReal
1405  SUMOReal ret = 0;
1406  const MSLane::VehCont& vehs = getVehiclesSecure();
1407  if (vehs.size() == 0) {
1408  releaseVehicles();
1409  return 0;
1410  }
1411  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1412  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
1413  ret += (SUMOReal) pow(10., (sv / 10.));
1414  }
1415  releaseVehicles();
1416  return HelpersHarmonoise::sum(ret);
1417 }
1418 
1419 
1420 bool
1422  return cmp->getPositionOnLane() >= pos;
1423 }
1424 
1425 
1426 int
1428  return v1->getPositionOnLane() > v2->getPositionOnLane();
1429 }
1430 
1432  myEdge(e),
1433  myLaneDir(e->getLanes()[0]->getShape().getBegLine().atan2PositiveAngle())
1434 { }
1435 
1436 
1437 int
1438 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
1439  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
1440  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
1441  SUMOReal s1 = 0;
1442  if (ae1 != 0 && ae1->size() != 0) {
1443  s1 = (SUMOReal) ae1->size() + GeomHelper::getMinAngleDiff((*ae1)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / M_PI / 2.;
1444  }
1445  SUMOReal s2 = 0;
1446  if (ae2 != 0 && ae2->size() != 0) {
1447  s2 = (SUMOReal) ae2->size() + GeomHelper::getMinAngleDiff((*ae2)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / M_PI / 2.;
1448  }
1449  return s1 < s2;
1450 }
1451 
1452 
1453 void
1455  out.openTag(SUMO_TAG_LANE);
1458  out.closeTag();
1459  out.closeTag();
1460 }
1461 
1462 
1463 void
1464 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
1465  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
1466  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
1467  assert(v != 0);
1468  v->getBestLanes(true, this);
1471  }
1472 }
1473 
1474 
1475 
1476 /****************************************************************************/
1477 
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:606
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:1464
virtual const std::vector< LaneQ > & getBestLanes(bool forceRebuild=false, MSLane *startLane=0) const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1752
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
VehCont myVehicles
The lane's vehicles. The entering vehicles are inserted at the front of this container and the leavin...
Definition: MSLane.h:773
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:452
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:920
SUMOVehicleClass getVehicleClass() const
Get this vehicle type'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:1303
#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:861
const MSEdge * getInternalFollower() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:818
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:303
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:531
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:1427
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
SUMOReal getMaxSpeed() const
Returns the maximum speed.
virtual const MSEdge * succEdge(unsigned int nSuccs) const =0
Returns the nSuccs'th successor of edge the vehicle is currently at.
bool hasInfluencer() const
Definition: MSVehicle.h:1036
The speed is given.
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
SUMOReal getImpatience() const
Returns this vehicles impatience.
#define M_PI
Definition: angles.h:37
void registerTeleportYield()
register one non-collision-related teleport
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:869
MSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:59
The vehicle arrived at a junction.
bool isVTDControlled() const
Definition: MSVehicle.h:974
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:362
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:124
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle's safe speed (no dawdling)
This is an uncontrolled, minor link, has to stop.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:92
SUMOReal getLength() const
Returns the lane's length.
Definition: MSLane.h:370
SUMOReal departSpeed
(optional) The initial speed of the vehicle
virtual SUMOReal maxNextSpeed(SUMOReal speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:86
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:459
std::vector< IncomingLaneInfo > myIncomingLanes
Definition: MSLane.h:798
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:58
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:105
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:905
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:61
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
SUMOReal getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:1392
A RT-tree for efficient storing of SUMO's Named objects.
Definition: NamedRTree.h:70
SUMOReal getLength() const
Get vehicle's length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1011
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:123
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:85
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1034
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:154
SUMOReal getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:1282
T MAX2(T a, T b)
Definition: StdDefs.h:71
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:86
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:1431
The speed is chosen randomly.
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:112
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1252
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:232
This is an uncontrolled, right-before-left link.
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1134
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:283
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:1438
void gotActive(MSLane *l)
Informs the control that the given lane got active.
bool pWagGenericInsertion(MSVehicle &veh, SUMOReal speed, SUMOReal maxPos, SUMOReal minPos)
Definition: MSLane.cpp:142
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:210
bool freeInsertion(MSVehicle &veh, SUMOReal speed, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle on any place.
Definition: MSLane.cpp:269
The position is chosen randomly.
This is an uncontrolled, all-way stop link.
SUMOReal myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:785
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.cpp:1297
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:614
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:950
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
The speed is given.
A gap is chosen where the maximum speed may be achieved.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1740
SUMOReal getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:1380
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:296
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle's end.
Definition: MSLane.h:261
std::map< std::string, MSLane * > DictType
definition of the static dictionary type
Definition: MSLane.h:825
virtual bool executeMovements(SUMOTime t, std::vector< MSLane * > &into)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:718
MSLinkCont myLinks
Definition: MSLane.h:817
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:667
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSLane.h:828
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:1677
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:73
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:336
virtual bool isInsertionSuccess(MSVehicle *vehicle, SUMOReal speed, SUMOReal pos, bool recheckNextLanes, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle with the given state (speed and pos)
Definition: MSLane.cpp:424
MSLane * getLogicalPredecessorLane() const
Definition: MSLane.cpp:1224
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver's reaction time.
Definition: MSCFModel.h:213
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
VehCont myTmpVehicles
Definition: MSLane.h:789
std::pair< MSVehicle *const, SUMOReal > getLeaderOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the leader and the distance to him.
Definition: MSLane.cpp:1164
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:557
void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:626
void addVeh(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
Representation of a vehicle.
Definition: SUMOVehicle.h:63
std::vector< MSVehicle * > myVehBuffer
Definition: MSLane.h:793
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.
bool alreadyMoved() const
reset the flag whether a vehicle already moved to false
Sorts vehicles by their position (descending)
Definition: MSLane.h:839
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle's current lane and their successors...
Definition: MSVehicle.cpp:2025
A list of positions.
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1259
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:263
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:1028
SUMOReal getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:1316
static SUMOReal gap(SUMOReal predPos, SUMOReal predLength, SUMOReal pos)
Uses the given values to compute the brutto-gap.
Definition: MSVehicle.h:212
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs'th successor of edge the vehicle is currently at.
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:751
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:635
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.
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:270
T MIN2(T a, T b)
Definition: StdDefs.h:65
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
#define POSITION_EPS
Definition: config.h:186
SUMOReal getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:362
MSEdge * myEdge
The lane's edge, for routing only.
Definition: MSLane.h:782
No information given; use default.
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:446
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:799
Something on a lane to be noticed about vehicle movement.
SUMOReal myLength
Lane length [m].
Definition: MSLane.h:776
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
Definition: MSCFModel.h:165
virtual MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:932
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:1004
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
virtual const MSVehicle * getFirstVehicle() const
Definition: MSLane.cpp:941
void registerTeleportJam()
register one non-collision-related teleport
virtual SUMOReal getHeadwayTime() const
Get the driver's reaction time [s].
Definition: MSCFModel.h:184
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:757
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
Definition: MSLane.h:819
Base class for objects which have an id.
Definition: Named.h:45
std::vector< MSMoveReminder * > myMoveReminders
This lane's move reminder.
Definition: MSLane.h:832
bool pWagSimpleInsertion(MSVehicle &veh, SUMOReal speed, SUMOReal maxPos, SUMOReal minPos)
Definition: MSLane.cpp:188
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:1709
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_UNKNOWN) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:213
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:829
SUMOReal getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:1368
static SUMOTime gTimeToGridlockHighways
Definition: MSGlobals.h:67
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:1356
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:204
const std::vector< MSEdge * > & getIncomingEdges() const
Returns the list of edges from which this edge may be reached.
Definition: MSEdge.h:240
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2293
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
Structure representing possible vehicle parameter.
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed) const
Computes the vehicle's safe speed without a leader.
Definition: MSCFModel.cpp:92
bool operator()(const MSVehicle *cmp, SUMOReal pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:1421
MSVehicle * myInlappingVehicle
The vehicle which laps into this lane.
Definition: MSLane.h:812
SUMOReal myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:803
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:198
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:294
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:852
SUMOReal getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:1332
SUMOReal getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:1344
bool checkFailure(MSVehicle *aVehicle, SUMOReal &speed, SUMOReal &dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:406
The link has red light (must brake)
static SUMOReal getMinAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
Definition: GeomHelper.cpp:391
SUMOReal myInlappingVehicleEnd
End position of a vehicle which laps into this lane.
Definition: MSLane.h:809
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:94
bool maxSpeedGapInsertion(MSVehicle &veh, SUMOReal mspeed)
Definition: MSLane.cpp:220
std::pair< MSVehicle *const, SUMOReal > getFollowerOnConsecutive(SUMOReal dist, SUMOReal leaderSpeed, SUMOReal backOffset, SUMOReal predMaxDecel) const
Definition: MSLane.cpp:1119
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1054
static SUMOReal sum(SUMOReal val)
Computes the resulting noise.
SUMOReal getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:291
#define LANE_RTREE_QUAL
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:64
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
SUMOReal getMissingRearGap(SUMOReal dist, 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:1078
const MSEdge * getFollower(unsigned int n) const
Returns the n-th of the following edges.
Definition: MSEdge.h:257
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:1454
const PositionVector & getShape() const
Returns this lane'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:70
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:215
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:284
#define NUMERICAL_EPS
Definition: config.h:159
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:97
int operator()(const std::pair< const MSVehicle *, SUMOReal > &p1, const std::pair< const MSVehicle *, SUMOReal > &p2) const
Definition: MSLane.cpp:1072
SUMOReal myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:806
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:998
No information given; use default.
A free position is chosen.
The class responsible for building and deletion of vehicles.
Simple max-flow insertion by P.Wagner.
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:354
SUMOReal getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:1404
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:328
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:579
The edge is an internal edge.
Definition: MSEdge.h:90
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:1267
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.
virtual const std::string & getID() const =0
Get the vehicle's ID.
void addApproachingLane(MSLane *lane)
Definition: MSLane.cpp:1044
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
virtual bool appropriate(const MSVehicle *veh)
Definition: MSLane.cpp:887
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:652
const std::string & getID() const
Returns the name of the vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
unsigned int getLaneIndex() const
Definition: MSVehicle.cpp:2240