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