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