SUMO - Simulation of Urban MObility
MSLane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
14 // Representation of a lane in the micro simulation
15 /****************************************************************************/
16 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
17 // Copyright (C) 2001-2014 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"
41 #include "MSPModel.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) {}
97 
98 
100  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
101  delete *i;
102  }
103 }
104 
105 
106 void
108  myLinks.push_back(link);
109 }
110 
111 
112 // ------ interaction with MSMoveReminder ------
113 void
115  myMoveReminders.push_back(rem);
116  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
117  (*veh)->addReminder(rem);
118  }
119 }
120 
121 
122 
123 // ------ Vehicle emission ------
124 void
125 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
126  assert(pos <= myLength);
127  bool wasInactive = myVehicles.size() == 0;
128  veh->enterLaneAtInsertion(this, pos, speed, notification);
129  if (at == myVehicles.end()) {
130  // vehicle will be the first on the lane
131  myVehicles.push_back(veh);
132  } else {
133  myVehicles.insert(at, veh);
134  }
137  if (wasInactive) {
139  }
140 }
141 
142 
143 bool
145  SUMOReal xIn = maxPos;
146  SUMOReal vIn = mspeed;
147  SUMOReal leaderDecel;
148  if (myVehicles.size() != 0) {
149  MSVehicle* leader = myVehicles.front();
150  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
151  vIn = leader->getSpeed();
152  leaderDecel = leader->getCarFollowModel().getMaxDecel();
153  } else {
154  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
155  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
156  if (leader.first != 0) {
157  xIn = getLength() + leader.second;
158  vIn = leader.first->getSpeed();
159  leaderDecel = leader.first->getCarFollowModel().getMaxDecel();
160  } else {
161  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
162  return true;
163  }
164  }
165  const SUMOReal vHlp = 0.5 * (vIn + mspeed);
166  SUMOReal x2 = xIn;// have seen leader length already - skCar::lCar;
167  SUMOReal x1 = x2 - 100.0;
168  SUMOReal x = 0;
169  for (int i = 0; i <= 10; i++) {
170  x = 0.5 * (x1 + x2);
171  SUMOReal vSafe = veh.getCarFollowModel().followSpeed(&veh, vHlp, xIn - x, vIn, leaderDecel);
172  if (vSafe < vHlp) {
173  x2 = x;
174  } else {
175  x1 = x;
176  }
177  }
178  if (x < minPos) {
179  return false;
180  } else if (x > maxPos) {
181  x = maxPos;
182  }
183  incorporateVehicle(&veh, x, vHlp, myVehicles.begin());
184  return true;
185 }
186 
187 
188 bool
190  SUMOReal xIn = maxPos;
191  SUMOReal vIn = mspeed;
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 = MIN2(leaderRearPos + frontGap, myLength);
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->updateBestLanes(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 / MAX2(speed, NUMERICAL_EPS));
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() / MAX2(speed, NUMERICAL_EPS));
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 = cfModel.freeSpeed(aVehicle, speed, seen, nextLane->getVehicleMaxSpeed(aVehicle));
515  if (nspeed < speed) {
516  if (patchSpeed) {
517  speed = nspeed;
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 / MAX2(speed, NUMERICAL_EPS));
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->updateBestLanes(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()->add(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
764  } else if (veh->getPositionOnLane() > getLength()) {
765  // for any reasons the vehicle is beyond its lane...
766  // this should never happen because it is handled in MSVehicle::executeMove
767  assert(false);
768  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, targetLane='" + getID() + "', time=" +
769  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
772  } else {
773  ++i;
774  continue;
775  }
776  myBruttoVehicleLengthSum -= length;
777  myNettoVehicleLengthSum -= nettoLength;
778  ++i;
779  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
780  }
781  if (myVehicles.size() > 0) {
783  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
784  if (!veh->isStopped()) {
785  const bool wrongLane = !veh->getLane()->appropriate(veh);
787  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
788  if (r1 || r2) {
789  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
790  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
791  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
792  MSVehicle* veh = *(myVehicles.end() - 1);
795  myVehicles.erase(myVehicles.end() - 1);
796  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
797  + reason
798  + (r2 ? " (highway)" : "")
799  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
800  if (wrongLane) {
802  } else if (minorLink) {
804  } else {
806  }
808  }
809  } // else look for a vehicle that isn't stopped?
810  }
811  }
812  return myVehicles.size() == 0;
813 }
814 
815 
816 const MSEdge*
818  const MSEdge* e = myEdge;
819  while (e->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
820  e = e->getFollower(0);
821  }
822  return e;
823 }
824 
825 
826 // ------ Static (sic!) container methods ------
827 bool
828 MSLane::dictionary(const std::string& id, MSLane* ptr) {
829  DictType::iterator it = myDict.find(id);
830  if (it == myDict.end()) {
831  // id not in myDict.
832  myDict.insert(DictType::value_type(id, ptr));
833  return true;
834  }
835  return false;
836 }
837 
838 
839 MSLane*
840 MSLane::dictionary(const std::string& id) {
841  DictType::iterator it = myDict.find(id);
842  if (it == myDict.end()) {
843  // id not in myDict.
844  return 0;
845  }
846  return it->second;
847 }
848 
849 
850 void
852  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
853  delete(*i).second;
854  }
855  myDict.clear();
856 }
857 
858 
859 void
860 MSLane::insertIDs(std::vector<std::string>& into) {
861  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
862  into.push_back((*i).first);
863  }
864 }
865 
866 
867 template<class RTREE> void
868 MSLane::fill(RTREE& into) {
869  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
870  MSLane* l = (*i).second;
871  Boundary b = l->getShape().getBoxBoundary();
872  b.grow(3.);
873  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
874  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
875  into.Insert(cmin, cmax, l);
876  }
877 }
878 
879 template void MSLane::fill<NamedRTree>(NamedRTree& into);
880 #ifndef NO_TRACI
881 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
882 #endif
883 
884 // ------ ------
885 bool
888  return true;
889  }
890  if (veh->succEdge(1) == 0) {
891  assert(veh->getBestLanes().size() > veh->getLaneIndex());
892  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
893  return true;
894  } else {
895  return false;
896  }
897  }
898  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
899  return (link != myLinks.end());
900 }
901 
902 
903 bool
905  bool wasInactive = myVehicles.size() == 0;
906  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter());
907  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
908  MSVehicle* veh = *i;
909  myVehicles.insert(myVehicles.begin(), veh);
912  }
913  myVehBuffer.clear();
914  return wasInactive && myVehicles.size() != 0;
915 }
916 
917 
918 bool
919 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
920  return i == myLinks.end();
921 }
922 
923 
924 bool
925 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
926  return i == myLinks.end();
927 }
928 
929 
930 MSVehicle*
932  if (myVehicles.size() == 0) {
933  return 0;
934  }
935  return *myVehicles.begin();
936 }
937 
938 
939 const MSVehicle*
941  if (myVehicles.size() == 0) {
942  return 0;
943  }
944  return *(myVehicles.end() - 1);
945 }
946 
947 
948 MSLinkCont::const_iterator
949 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs,
950  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
951  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
952  // check whether the vehicle tried to look beyond its route
953  if (nRouteEdge == 0) {
954  // return end (no succeeding link) if so
955  return succLinkSource.myLinks.end();
956  }
957  // if we are on an internal lane there should only be one link and it must be allowed
958  if (succLinkSource.getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
959  assert(succLinkSource.myLinks.size() == 1);
960  assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
961  return succLinkSource.myLinks.begin();
962  }
963  // a link may be used if
964  // 1) there is a destination lane ((*link)->getLane()!=0)
965  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
966  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
967 
968  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
969  // "conts" stores the best continuations of our current lane
970  // we should never return an arbitrary link since this may cause collisions
971  MSLinkCont::const_iterator link;
972  if (nRouteSuccs < conts.size()) {
973  // we go through the links in our list and return the matching one
974  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
975  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
976  // we should use the link if it connects us to the best lane
977  if ((*link)->getLane() == conts[nRouteSuccs]) {
978  return link;
979  }
980  }
981  }
982  } else {
983  // the source lane is a dead end (no continuations exist)
984  return succLinkSource.myLinks.end();
985  }
986  // the only case where this should happen is for a disconnected route (deliberately ignored)
987 #ifdef _DEBUG
988  WRITE_WARNING("Could not find connection between '" + succLinkSource.getID() + "' and '" + conts[nRouteSuccs]->getID() +
989  "' for vehicle '" + veh.getID() + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
990 #endif
991  return succLinkSource.myLinks.end();
992 }
993 
994 
995 
996 const MSLinkCont&
998  return myLinks;
999 }
1000 
1001 
1002 void
1005  myTmpVehicles.clear();
1006 }
1007 
1008 
1009 MSVehicle*
1010 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
1011  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
1012  if (remVehicle == *it) {
1013  if (notify) {
1014  remVehicle->leaveLane(notification);
1015  }
1016  myVehicles.erase(it);
1019  break;
1020  }
1021  }
1022  return remVehicle;
1023 }
1024 
1025 
1026 MSLane*
1027 MSLane::getParallelLane(int offset) const {
1028  return myEdge->parallelLane(this, offset);
1029 }
1030 
1031 
1032 void
1034  IncomingLaneInfo ili;
1035  ili.lane = lane;
1036  ili.viaLink = viaLink;
1037  ili.length = lane->getLength();
1038  myIncomingLanes.push_back(ili);
1039 }
1040 
1041 
1042 void
1044  MSEdge* approachingEdge = &lane->getEdge();
1045  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1046  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1047  }
1048  myApproachingLanes[approachingEdge].push_back(lane);
1049 }
1050 
1051 
1052 bool
1054  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1055 }
1056 
1057 
1058 bool
1059 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1060  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1061  if (i == myApproachingLanes.end()) {
1062  return false;
1063  }
1064  const std::vector<MSLane*>& lanes = (*i).second;
1065  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1066 }
1067 
1068 
1070 public:
1071  inline int operator()(const std::pair<const MSVehicle* , SUMOReal>& p1, const std::pair<const MSVehicle* , SUMOReal>& p2) const {
1072  return p1.second < p2.second;
1073  }
1074 };
1075 
1076 
1078  SUMOReal dist, SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1079  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1080  // search until dist and check for the vehicle with the largest missing rear gap
1081  SUMOReal result = 0;
1082  std::set<MSLane*> visited;
1083  std::vector<MSLane::IncomingLaneInfo> newFound;
1084  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1085  while (toExamine.size() != 0) {
1086  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1087  MSLane* next = (*i).lane;
1088  if (next->getFirstVehicle() != 0) {
1089  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1090  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1091  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(
1092  v->getCarFollowModel().maxNextSpeed(v->getSpeed(), v), leaderSpeed, leaderMaxDecel) - agap;
1093  result = MAX2(result, missingRearGap);
1094  } else {
1095  if ((*i).length < dist) {
1096  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1097  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1098  if (visited.find((*j).lane) == visited.end()) {
1099  visited.insert((*j).lane);
1101  ili.lane = (*j).lane;
1102  ili.length = (*j).length + (*i).length;
1103  ili.viaLink = (*j).viaLink;
1104  newFound.push_back(ili);
1105  }
1106  }
1107  }
1108  }
1109  }
1110  toExamine.clear();
1111  swap(newFound, toExamine);
1112  }
1113  return result;
1114 }
1115 
1116 
1117 std::pair<MSVehicle* const, SUMOReal>
1119  SUMOReal backOffset, SUMOReal leaderMaxDecel) const {
1120  // do a tree search among all follower lanes and check for the most
1121  // important vehicle (the one requiring the largest reargap)
1122  std::pair<MSVehicle*, SUMOReal> result(static_cast<MSVehicle*>(0), -1);
1123  SUMOReal missingRearGapMax = 0;
1124  std::set<MSLane*> visited;
1125  std::vector<MSLane::IncomingLaneInfo> newFound;
1126  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1127  while (toExamine.size() != 0) {
1128  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1129  MSLane* next = (*i).lane;
1130  if (next->getFirstVehicle() != 0) {
1131  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1132  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1133  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - agap;
1134  if (missingRearGap > missingRearGapMax) {
1135  missingRearGapMax = missingRearGap;
1136  result.first = v;
1137  result.second = agap;
1138  }
1139  } else {
1140  if ((*i).length < dist) {
1141  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1142  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1143  if (visited.find((*j).lane) == visited.end()) {
1144  visited.insert((*j).lane);
1146  ili.lane = (*j).lane;
1147  ili.length = (*j).length + (*i).length;
1148  ili.viaLink = (*j).viaLink;
1149  newFound.push_back(ili);
1150  }
1151  }
1152  }
1153  }
1154  }
1155  toExamine.clear();
1156  swap(newFound, toExamine);
1157  }
1158  return result;
1159 }
1160 
1161 
1162 std::pair<MSVehicle* const, SUMOReal>
1164  const std::vector<MSLane*>& bestLaneConts) const {
1165  if (seen > dist) {
1166  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1167  }
1168  unsigned int view = 1;
1169  // loop over following lanes
1170  if (getPartialOccupator() != 0) {
1171  return std::make_pair(getPartialOccupator(), seen - (getLength() - getPartialOccupatorEnd()) - veh.getVehicleType().getMinGap());
1172  }
1173  const MSLane* nextLane = this;
1174  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1175  do {
1176  // get the next link used
1177  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1178  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1179  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0) || (*link)->getState() == LINKSTATE_TL_RED) {
1180  break;
1181  }
1182 #ifdef HAVE_INTERNAL_LANES
1183  // check for link leaders
1184  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, veh.getVehicleType().getMinGap());
1185  if (linkLeaders.size() > 0) {
1186  // XXX if there is more than one link leader we should return the most important
1187  // one (gap, decel) but this is hard to know at this point
1188  return linkLeaders[0].vehAndGap;
1189  }
1190  bool nextInternal = (*link)->getViaLane() != 0;
1191 #endif
1192  nextLane = (*link)->getViaLaneOrLane();
1193  if (nextLane == 0) {
1194  break;
1195  }
1196  MSVehicle* leader = nextLane->getLastVehicle();
1197  if (leader != 0) {
1198  return std::make_pair(leader, seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap());
1199  } else {
1200  leader = nextLane->getPartialOccupator();
1201  if (leader != 0) {
1202  return std::make_pair(leader, seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1203  }
1204  }
1205  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1206  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1207  }
1208  seen += nextLane->getLength();
1209  if (seen <= dist) {
1210  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1211  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1212  }
1213 #ifdef HAVE_INTERNAL_LANES
1214  if (!nextInternal) {
1215  view++;
1216  }
1217 #else
1218  view++;
1219 #endif
1220  } while (seen <= dist);
1221  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1222 }
1223 
1224 
1225 MSLane*
1227  if (myLogicalPredecessorLane != 0) {
1228  return myLogicalPredecessorLane;
1229  }
1230  if (myLogicalPredecessorLane == 0) {
1231  std::vector<MSEdge*> pred = myEdge->getIncomingEdges();
1232  // get only those edges which connect to this lane
1233  for (std::vector<MSEdge*>::iterator i = pred.begin(); i != pred.end();) {
1234  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1235  if (j == myIncomingLanes.end()) {
1236  i = pred.erase(i);
1237  } else {
1238  ++i;
1239  }
1240  }
1241  // get the edge with the most connections to this lane's edge
1242  if (pred.size() != 0) {
1243  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1244  MSEdge* best = *pred.begin();
1245  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1246  myLogicalPredecessorLane = (*j).lane;
1247  }
1248  }
1249  return myLogicalPredecessorLane;
1250 }
1251 
1252 
1253 LinkState
1256  if (pred == 0) {
1257  return LINKSTATE_DEADEND;
1258  } else {
1259  return MSLinkContHelper::getConnectingLink(*pred, *this)->getState();
1260  }
1261 }
1262 
1263 
1264 std::vector<const MSLane*>
1266  std::vector<const MSLane*> result;
1267  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
1268  assert((*i)->getLane() != 0);
1269  result.push_back((*i)->getLane());
1270  }
1271  return result;
1272 }
1273 
1274 
1275 void
1279 }
1280 
1281 
1282 void
1286 }
1287 
1288 
1289 int
1291  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
1292  if ((*i)->getLane()->getEdge().isCrossing()) {
1293  return (int)(i - myLinks.begin());
1294  }
1295  }
1296  return -1;
1297 }
1298 
1299 // ------------ Current state retrieval
1300 SUMOReal
1302  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1304  if (myVehicles.size() != 0) {
1305  MSVehicle* lastVeh = myVehicles.front();
1306  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1307  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1308  }
1309  }
1310  releaseVehicles();
1311  return (myBruttoVehicleLengthSum + fractions) / myLength;
1312 }
1313 
1314 
1315 SUMOReal
1317  SUMOReal fractions = myInlappingVehicle != 0 ? myLength - myInlappingVehicleEnd : 0;
1319  if (myVehicles.size() != 0) {
1320  MSVehicle* lastVeh = myVehicles.front();
1321  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
1322  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
1323  }
1324  }
1325  releaseVehicles();
1326  return (myNettoVehicleLengthSum + fractions) / myLength;
1327 }
1328 
1329 
1330 SUMOReal
1332  return myBruttoVehicleLengthSum;
1333 }
1334 
1335 
1336 SUMOReal
1338  if (myVehicles.size() == 0) {
1339  return 0;
1340  }
1341  SUMOReal wtime = 0;
1342  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
1343  wtime += (*i)->getWaitingSeconds();
1344  }
1345  return wtime;
1346 }
1347 
1348 
1349 SUMOReal
1351  if (myVehicles.size() == 0) {
1352  return myMaxSpeed;
1353  }
1354  SUMOReal v = 0;
1355  const MSLane::VehCont& vehs = getVehiclesSecure();
1356  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1357  v += (*i)->getSpeed();
1358  }
1359  SUMOReal ret = v / (SUMOReal) myVehicles.size();
1360  releaseVehicles();
1361  return ret;
1362 }
1363 
1364 
1365 SUMOReal
1367  SUMOReal ret = 0;
1368  const MSLane::VehCont& vehs = getVehiclesSecure();
1369  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1370  ret += (*i)->getCO2Emissions();
1371  }
1372  releaseVehicles();
1373  return ret;
1374 }
1375 
1376 
1377 SUMOReal
1379  SUMOReal ret = 0;
1380  const MSLane::VehCont& vehs = getVehiclesSecure();
1381  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1382  ret += (*i)->getCOEmissions();
1383  }
1384  releaseVehicles();
1385  return ret;
1386 }
1387 
1388 
1389 SUMOReal
1391  SUMOReal ret = 0;
1392  const MSLane::VehCont& vehs = getVehiclesSecure();
1393  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1394  ret += (*i)->getPMxEmissions();
1395  }
1396  releaseVehicles();
1397  return ret;
1398 }
1399 
1400 
1401 SUMOReal
1403  SUMOReal ret = 0;
1404  const MSLane::VehCont& vehs = getVehiclesSecure();
1405  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1406  ret += (*i)->getNOxEmissions();
1407  }
1408  releaseVehicles();
1409  return ret;
1410 }
1411 
1412 
1413 SUMOReal
1415  SUMOReal ret = 0;
1416  const MSLane::VehCont& vehs = getVehiclesSecure();
1417  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1418  ret += (*i)->getHCEmissions();
1419  }
1420  releaseVehicles();
1421  return ret;
1422 }
1423 
1424 
1425 SUMOReal
1427  SUMOReal ret = 0;
1428  const MSLane::VehCont& vehs = getVehiclesSecure();
1429  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1430  ret += (*i)->getFuelConsumption();
1431  }
1432  releaseVehicles();
1433  return ret;
1434 }
1435 
1436 
1437 SUMOReal
1439  SUMOReal ret = 0;
1440  const MSLane::VehCont& vehs = getVehiclesSecure();
1441  if (vehs.size() == 0) {
1442  releaseVehicles();
1443  return 0;
1444  }
1445  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1446  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
1447  ret += (SUMOReal) pow(10., (sv / 10.));
1448  }
1449  releaseVehicles();
1450  return HelpersHarmonoise::sum(ret);
1451 }
1452 
1453 
1454 bool
1456  return cmp->getPositionOnLane() >= pos;
1457 }
1458 
1459 
1460 int
1462  return v1->getPositionOnLane() > v2->getPositionOnLane();
1463 }
1464 
1466  myEdge(e),
1467  myLaneDir(e->getLanes()[0]->getShape().getBegLine().atan2PositiveAngle())
1468 { }
1469 
1470 
1471 int
1472 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
1473  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
1474  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
1475  SUMOReal s1 = 0;
1476  if (ae1 != 0 && ae1->size() != 0) {
1477  s1 = (SUMOReal) ae1->size() + GeomHelper::getMinAngleDiff((*ae1)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / M_PI / 2.;
1478  }
1479  SUMOReal s2 = 0;
1480  if (ae2 != 0 && ae2->size() != 0) {
1481  s2 = (SUMOReal) ae2->size() + GeomHelper::getMinAngleDiff((*ae2)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / M_PI / 2.;
1482  }
1483  return s1 < s2;
1484 }
1485 
1486 
1487 void
1489  out.openTag(SUMO_TAG_LANE);
1492  out.closeTag();
1493  out.closeTag();
1494 }
1495 
1496 
1497 void
1498 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
1499  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
1500  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
1501  assert(v != 0);
1502  v->updateBestLanes(true, this);
1505  }
1506 }
1507 
1508 
1509 
1510 /****************************************************************************/
1511 
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:1498
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
VehCont myVehicles
The lane's vehicles. The entering vehicles are inserted at the front of this container and the leavin...
Definition: MSLane.h:780
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:454
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:919
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:1337
#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:860
const MSEdge * getInternalFollower() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:817
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:538
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:1461
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:1043
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:868
MSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:60
The vehicle arrived at a junction.
bool isVTDControlled() const
Definition: MSVehicle.h:981
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:93
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:462
std::vector< IncomingLaneInfo > myIncomingLanes
Definition: MSLane.h:805
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:58
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:107
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:904
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:1426
A RT-tree for efficient storing of SUMO's Named objects.
Definition: NamedRTree.h:72
SUMOReal getLength() const
Get vehicle's length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1010
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:125
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:1033
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
SUMOReal getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:1316
T MAX2(T a, T b)
Definition: StdDefs.h:72
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:87
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:1465
The speed is chosen randomly.
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:114
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1276
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:1129
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:1472
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:144
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:216
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:792
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.cpp:1331
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:949
#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:1750
SUMOReal getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:1414
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:832
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:824
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:835
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:1678
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:74
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:1226
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:796
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:1163
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:561
void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:626
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:1254
Representation of a vehicle.
Definition: SUMOVehicle.h:64
std::vector< MSVehicle * > myVehBuffer
Definition: MSLane.h:800
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:846
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:2035
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:1768
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:1283
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:269
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:1027
SUMOReal getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:1350
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:755
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:316
T MIN2(T a, T b)
Definition: StdDefs.h:66
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'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:789
No information given; use default.
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:448
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:806
Something on a lane to be noticed about vehicle movement.
SUMOReal myLength
Lane length [m].
Definition: MSLane.h:783
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:931
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:1003
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
virtual const MSVehicle * getFirstVehicle() const
Definition: MSLane.cpp:940
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:761
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1762
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
Definition: MSLane.h:826
Base class for objects which have an id.
Definition: Named.h:45
std::vector< MSMoveReminder * > myMoveReminders
This lane's move reminder.
Definition: MSLane.h:839
bool pWagSimpleInsertion(MSVehicle &veh, SUMOReal speed, SUMOReal maxPos, SUMOReal minPos)
Definition: MSLane.cpp:189
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:1710
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:1265
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:828
SUMOReal getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:1402
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:1390
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:215
const std::vector< MSEdge * > & getIncomingEdges() const
Returns the list of edges from which this edge may be reached.
Definition: MSEdge.h:271
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2328
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:1455
MSVehicle * myInlappingVehicle
The vehicle which laps into this lane.
Definition: MSLane.h:819
SUMOReal myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:810
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:206
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:300
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:851
SUMOReal getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:1366
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:221
SUMOReal getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:1378
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:395
SUMOReal myInlappingVehicleEnd
End position of a vehicle which laps into this lane.
Definition: MSLane.h:816
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:95
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:1118
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1053
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:65
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:1077
const MSEdge * getFollower(unsigned int n) const
Returns the n-th of the following edges.
Definition: MSEdge.h:288
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:1488
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:71
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:290
#define NUMERICAL_EPS
Definition: config.h:159
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:99
int operator()(const std::pair< const MSVehicle *, SUMOReal > &p1, const std::pair< const MSVehicle *, SUMOReal > &p2) const
Definition: MSLane.cpp:1071
SUMOReal myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:813
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:997
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:1438
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:328
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:581
The edge is an internal edge.
Definition: MSEdge.h:91
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:1301
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:1290
virtual const std::string & getID() const =0
Get the vehicle's ID.
void addApproachingLane(MSLane *lane)
Definition: MSLane.cpp:1043
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:886
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:2258