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