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