SUMO - Simulation of Urban MObility
MSLane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
23 // Representation of a lane in the micro simulation
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #include <config.h>
31 
32 #include <cmath>
33 #include <bitset>
34 #include <iostream>
35 #include <cassert>
36 #include <functional>
37 #include <algorithm>
38 #include <iterator>
39 #include <exception>
40 #include <climits>
41 #include <set>
43 #include <utils/common/StdDefs.h>
45 #include <utils/common/ToString.h>
48 #include <utils/geom/GeomHelper.h>
51 #include "MSNet.h"
52 #include "MSVehicleType.h"
53 #include "MSEdge.h"
54 #include "MSEdgeControl.h"
55 #include "MSJunction.h"
56 #include "MSLogicJunction.h"
57 #include "MSLink.h"
58 #include "MSLane.h"
59 #include "MSVehicleTransfer.h"
60 #include "MSGlobals.h"
61 #include "MSVehicleControl.h"
62 #include "MSInsertionControl.h"
63 #include "MSVehicleControl.h"
64 #include "MSLeaderInfo.h"
65 #include "MSVehicle.h"
66 
67 //#define DEBUG_INSERTION
68 //#define DEBUG_PLAN_MOVE
69 //#define DEBUG_EXEC_MOVE
70 //#define DEBUG_CONTEXT
71 //#define DEBUG_OPPOSITE
72 //#define DEBUG_VEHICLE_CONTAINER
73 //#define DEBUG_COLLISIONS
74 //#define DEBUG_JUNCTION_COLLISIONS
75 //#define DEBUG_PEDESTRIAN_COLLISIONS
76 //#define DEBUG_LANE_SORTER
77 //#define DEBUG_NO_CONNECTION
78 
79 #define DEBUG_COND (false)
80 //#define DEBUG_COND2(obj) ((obj != 0 && (obj)->getID() == "disabled"))
81 #define DEBUG_COND2(obj) ((obj != 0 && (obj)->isSelected()))
82 
83 // ===========================================================================
84 // static member definitions
85 // ===========================================================================
91 
92 // ===========================================================================
93 // internal class method definitions
94 // ===========================================================================
95 
96 
99  if (nextIsMyVehicles()) {
100  if (myI1 != myI1End) {
101  myI1 += myDirection;
102  } else if (myI3 != myI3End) {
103  myI3 += myDirection;
104  }
105  // else: already at end
106  } else {
107  myI2 += myDirection;
108  }
109  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::operator++ lane=" << myLane->getID() << " myI1=" << myI1 << " myI2=" << myI2 << "\n";
110  return *this;
111 }
112 
113 
114 const MSVehicle*
116  if (nextIsMyVehicles()) {
117  if (myI1 != myI1End) {
118  return myLane->myVehicles[myI1];
119  } else if (myI3 != myI3End) {
120  return myLane->myTmpVehicles[myI3];
121  } else {
122  return 0;
123  }
124  } else {
125  return myLane->myPartialVehicles[myI2];
126  }
127 }
128 
129 
130 bool
132  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::nextIsMyVehicles lane=" << myLane->getID()
133  // << " myI1=" << myI1
134  // << " myI2=" << myI2
135  // << "\n";
136  if (myI1 == myI1End && myI3 == myI3End) {
137  if (myI2 != myI2End) {
138  return false;
139  } else {
140  return true; // @note. must be caught
141  }
142  } else {
143  if (myI2 == myI2End) {
144  return true;
145  } else {
147  //if (DEBUG_COND2(myLane)) std::cout << " "
148  // << " veh1=" << candFull->getID()
149  // << " isTmp=" << (myI1 == myI1End)
150  // << " veh2=" << myLane->myPartialVehicles[myI2]->getID()
151  // << " pos1=" << cand->getPositionOnLane(myLane)
152  // << " pos2=" << myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)
153  // << "\n";
154  if (cand->getPositionOnLane() < myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)) {
155  return myDownstream;
156  } else {
157  return !myDownstream;
158  }
159  }
160  }
161 }
162 
163 
164 // ===========================================================================
165 // member method definitions
166 // ===========================================================================
167 MSLane::MSLane(const std::string& id, double maxSpeed, double length, MSEdge* const edge,
168  int numericalID, const PositionVector& shape, double width,
169  SVCPermissions permissions, int index, bool isRampAccel) :
170  Named(id),
171  myNumericalID(numericalID), myShape(shape), myIndex(index),
172  myVehicles(), myLength(length), myWidth(width), myStopOffsets(),
173  myEdge(edge), myMaxSpeed(maxSpeed),
174  myPermissions(permissions),
175  myOriginalPermissions(permissions),
180  myLeaderInfo(this, 0, 0),
181  myFollowerInfo(this, 0, 0),
182  myLeaderInfoTmp(this, 0, 0),
185  myLengthGeometryFactor(MAX2(POSITION_EPS, myShape.length()) / myLength), // factor should not be 0
186  myIsRampAccel(isRampAccel),
187  myRightSideOnEdge(0), // initialized in MSEdge::initialize
188  myRightmostSublane(0) {
189  // initialized in MSEdge::initialize
190  initRestrictions();// may be reloaded again from initialized in MSEdge::closeBuilding
191 }
192 
193 
195  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
196  delete *i;
197  }
198 }
199 
200 
201 void
204 }
205 
206 
207 void
209  myLinks.push_back(link);
210 }
211 
212 
213 void
214 MSLane::addNeigh(const std::string& id) {
215  myNeighs.push_back(id);
216 }
217 
218 
219 // ------ interaction with MSMoveReminder ------
220 void
222  myMoveReminders.push_back(rem);
223  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
224  (*veh)->addReminder(rem);
225  }
226  // XXX: Here, the partial occupators are ignored!? Refs. #3255
227 }
228 
229 
230 double
232 #ifdef DEBUG_CONTEXT
233  if (DEBUG_COND2(v)) {
234  std::cout << SIMTIME << " setPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
235  }
236 #endif
237  // XXX update occupancy here?
238  myPartialVehicles.push_back(v);
239  return myLength;
240 }
241 
242 
243 void
245 #ifdef DEBUG_CONTEXT
246  if (DEBUG_COND2(v)) {
247  std::cout << SIMTIME << " resetPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
248  }
249 #endif
250  for (VehCont::iterator i = myPartialVehicles.begin(); i != myPartialVehicles.end(); ++i) {
251  if (v == *i) {
252  myPartialVehicles.erase(i);
253  // XXX update occupancy here?
254  //std::cout << " removed from myPartialVehicles\n";
255  return;
256  }
257  }
258  assert(false);
259 }
260 
261 
262 void
264 #ifdef DEBUG_CONTEXT
265  if (DEBUG_COND2(v)) {
266  std::cout << SIMTIME << " setManeuverReservation. lane=" << getID() << " veh=" << v->getID() << "\n";
267  }
268 #endif
269  myManeuverReservations.push_back(v);
270 }
271 
272 
273 void
275 #ifdef DEBUG_CONTEXT
276  if (DEBUG_COND2(v)) {
277  std::cout << SIMTIME << " resetManeuverReservation(): lane=" << getID() << " veh=" << v->getID() << "\n";
278  }
279 #endif
280  for (VehCont::iterator i = myManeuverReservations.begin(); i != myManeuverReservations.end(); ++i) {
281  if (v == *i) {
282  myManeuverReservations.erase(i);
283  return;
284  }
285  }
286  assert(false);
287 }
288 
289 
290 // ------ Vehicle emission ------
291 void
292 MSLane::incorporateVehicle(MSVehicle* veh, double pos, double speed, double posLat, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
293  assert(pos <= myLength);
294  bool wasInactive = myVehicles.size() == 0;
295  veh->enterLaneAtInsertion(this, pos, speed, posLat, notification);
296  if (at == myVehicles.end()) {
297  // vehicle will be the first on the lane
298  myVehicles.push_back(veh);
299  } else {
300  myVehicles.insert(at, veh);
301  }
304  myEdge->markDelayed();
305  if (wasInactive) {
307  }
308 }
309 
310 
311 bool
312 MSLane::lastInsertion(MSVehicle& veh, double mspeed, double posLat, bool patchSpeed) {
313  double pos = getLength() - POSITION_EPS;
314  MSVehicle* leader = getLastAnyVehicle();
315  // back position of leader relative to this lane
316  double leaderBack;
317  if (leader == 0) {
319  veh.setTentativeLaneAndPosition(this, pos, posLat);
320  veh.updateBestLanes(false, this);
321  std::pair<MSVehicle* const, double> leaderInfo = getLeader(&veh, pos, veh.getBestLanesContinuation(), veh.getCarFollowModel().brakeGap(mspeed));
322  leader = leaderInfo.first;
323  leaderBack = pos + leaderInfo.second + veh.getVehicleType().getMinGap();
324  } else {
325  leaderBack = leader->getBackPositionOnLane(this);
326  //std::cout << " leaderPos=" << leader->getPositionOnLane(this) << " leaderBack=" << leader->getBackPositionOnLane(this) << " leaderLane=" << leader->getLane()->getID() << "\n";
327  }
328  if (leader == 0) {
329  // insert at the end of this lane
330  return isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
331  } else {
332  // try to insert behind the leader
333  const double frontGapNeeded = veh.getCarFollowModel().getSecureGap(mspeed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap() + POSITION_EPS;
334  if (leaderBack >= frontGapNeeded) {
335  pos = MIN2(pos, leaderBack - frontGapNeeded);
336  bool result = isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
337  //if (!result) std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
338  return result;
339  }
340  //std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
341  }
342  return false;
343 }
344 
345 
346 bool
347 MSLane::freeInsertion(MSVehicle& veh, double mspeed, double posLat,
348  MSMoveReminder::Notification notification) {
349  bool adaptableSpeed = true;
350  // try to insert teleporting vehicles fully on this lane
351  const double minPos = (notification == MSMoveReminder::NOTIFICATION_TELEPORT ?
352  MIN2(myLength, veh.getVehicleType().getLength()) : 0);
353  veh.setTentativeLaneAndPosition(this, minPos, 0);
354  if (myVehicles.size() == 0) {
355  // ensure sufficient gap to followers on predecessor lanes
356  const double backOffset = minPos - veh.getVehicleType().getLength();
357  const double missingRearGap = getMissingRearGap(&veh, backOffset, mspeed);
358  if (missingRearGap > 0) {
359  if (minPos + missingRearGap <= myLength) {
360  // @note. The rear gap is tailored to mspeed. If it changes due
361  // to a leader vehicle (on subsequent lanes) insertion will
362  // still fail. Under the right combination of acceleration and
363  // deceleration values there might be another insertion
364  // positions that would be successful be we do not look for it.
365  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " unclear @(340)\n";
366  return isInsertionSuccess(&veh, mspeed, minPos + missingRearGap, posLat, adaptableSpeed, notification);
367  } else {
368  return false;
369  }
370  } else {
371  return isInsertionSuccess(&veh, mspeed, minPos, posLat, adaptableSpeed, notification);
372  }
373 
374  } else {
375  // check whether the vehicle can be put behind the last one if there is such
376  MSVehicle* leader = getFirstFullVehicle(); // @todo reproduction of bogus old behavior. see #1961
377  const double leaderPos = leader->getBackPositionOnLane(this);
378  const double speed = adaptableSpeed ? leader->getSpeed() : mspeed;
379  const double frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
380  if (leaderPos >= frontGapNeeded) {
381  const double tspeed = MIN2(veh.getCarFollowModel().insertionFollowSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
382  // check whether we can insert our vehicle behind the last vehicle on the lane
383  if (isInsertionSuccess(&veh, tspeed, minPos, posLat, adaptableSpeed, notification)) {
384  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " pos=" << minPos<< " speed=" << speed << " tspeed=" << tspeed << " frontGapNeeded=" << frontGapNeeded << " lead=" << leader->getID() << " lPos=" << leaderPos << "\n vehsOnLane=" << toString(myVehicles) << " @(358)\n";
385  return true;
386  }
387  }
388  }
389  // go through the lane, look for free positions (starting after the last vehicle)
390  MSLane::VehCont::iterator predIt = myVehicles.begin();
391  while (predIt != myVehicles.end()) {
392  // get leader (may be zero) and follower
393  // @todo compute secure position in regard to sublane-model
394  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : 0;
395  if (leader == 0 && myPartialVehicles.size() > 0) {
396  leader = myPartialVehicles.front();
397  }
398  const MSVehicle* follower = *predIt;
399 
400  // patch speed if allowed
401  double speed = mspeed;
402  if (adaptableSpeed && leader != 0) {
403  speed = MIN2(leader->getSpeed(), mspeed);
404  }
405 
406  // compute the space needed to not collide with leader
407  double frontMax = getLength();
408  if (leader != 0) {
409  double leaderRearPos = leader->getBackPositionOnLane(this);
410  double frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
411  frontMax = leaderRearPos - frontGapNeeded;
412  }
413  // compute the space needed to not let the follower collide
414  const double followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
415  const double backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
416  const double backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
417 
418  // check whether there is enough room (given some extra space for rounding errors)
419  if (frontMax > minPos && backMin + POSITION_EPS < frontMax) {
420  // try to insert vehicle (should be always ok)
421  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, posLat, adaptableSpeed, notification)) {
422  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " @(393)\n";
423  return true;
424  }
425  }
426  ++predIt;
427  }
428  // first check at lane's begin
429  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " fail final\n";
430  return false;
431 }
432 
433 
434 double
435 MSLane::getDepartSpeed(const MSVehicle& veh, bool& patchSpeed) {
436  double speed = 0;
437  const SUMOVehicleParameter& pars = veh.getParameter();
438  switch (pars.departSpeedProcedure) {
439  case DEPART_SPEED_GIVEN:
440  speed = pars.departSpeed;
441  patchSpeed = false;
442  break;
443  case DEPART_SPEED_RANDOM:
444  speed = RandHelper::rand(getVehicleMaxSpeed(&veh));
445  patchSpeed = true; // @todo check
446  break;
447  case DEPART_SPEED_MAX:
448  speed = getVehicleMaxSpeed(&veh);
449  patchSpeed = true; // @todo check
450  break;
452  default:
453  // speed = 0 was set before
454  patchSpeed = false; // @todo check
455  break;
456  }
457  return speed;
458 }
459 
460 
461 double
463  const SUMOVehicleParameter& pars = veh.getParameter();
464  switch (pars.departPosLatProcedure) {
465  case DEPART_POSLAT_GIVEN:
466  return pars.departPosLat;
467  case DEPART_POSLAT_RIGHT:
468  return -getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
469  case DEPART_POSLAT_LEFT:
470  return getWidth() * 0.5 - veh.getVehicleType().getWidth() * 0.5;
472  return RandHelper::rand(getWidth() - veh.getVehicleType().getWidth()) - getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
475  // @note:
476  // case DEPART_POSLAT_FREE
477  // case DEPART_POSLAT_RANDOM_FREE
478  // are not handled here because they involve multiple insertion attempts
479  default:
480  return 0;
481  }
482 }
483 
484 
485 bool
487  double pos = 0;
488  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
489  const SUMOVehicleParameter& pars = veh.getParameter();
490  double speed = getDepartSpeed(veh, patchSpeed);
491  double posLat = getDepartPosLat(veh);
492 
493  // determine the position
494  switch (pars.departPosProcedure) {
495  case DEPART_POS_GIVEN:
496  pos = pars.departPos;
497  if (pos < 0.) {
498  pos += myLength;
499  }
500  break;
501  case DEPART_POS_RANDOM:
502  pos = RandHelper::rand(getLength());
503  break;
504  case DEPART_POS_RANDOM_FREE: {
505  for (int i = 0; i < 10; i++) {
506  // we will try some random positions ...
507  pos = RandHelper::rand(getLength());
508  posLat = getDepartPosLat(veh); // could be random as well
509  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
510  return true;
511  }
512  }
513  // ... and if that doesn't work, we put the vehicle to the free position
514  return freeInsertion(veh, speed, posLat);
515  }
516  break;
517  case DEPART_POS_FREE:
518  return freeInsertion(veh, speed, posLat);
519  case DEPART_POS_LAST:
520  return lastInsertion(veh, speed, posLat, patchSpeed);
521  case DEPART_POS_BASE:
522  case DEPART_POS_DEFAULT:
523  default:
524  pos = veh.basePos(myEdge);
525  break;
526  }
527  // determine the lateral position for special cases
529  switch (pars.departPosLatProcedure) {
531  for (int i = 0; i < 10; i++) {
532  // we will try some random positions ...
533  posLat = RandHelper::rand(getWidth()) - getWidth() * 0.5;
534  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
535  return true;
536  }
537  }
538  }
539  // no break! continue with DEPART_POS_FREE
540  case DEPART_POSLAT_FREE: {
541  // systematically test all positions until a free lateral position is found
542  double posLatMin = -getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
543  double posLatMax = getWidth() * 0.5 - veh.getVehicleType().getWidth() * 0.5;
544  for (double posLat = posLatMin; posLat < posLatMax; posLat += MSGlobals::gLateralResolution) {
545  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
546  return true;
547  }
548  }
549  return false;
550  }
551  default:
552  break;
553  }
554  }
555  // try to insert
556  return isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
557 }
558 
559 
560 bool
561 MSLane::checkFailure(const MSVehicle* aVehicle, double& speed, double& dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const {
562  if (nspeed < speed) {
563  if (patchSpeed) {
564  speed = MIN2(nspeed, speed);
565  dist = aVehicle->getCarFollowModel().brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
566  } else if (speed > 0) {
568  // Check whether vehicle can stop at the given distance when applying emergency braking
569  double emergencyBrakeGap = 0.5 * speed * speed / aVehicle->getCarFollowModel().getEmergencyDecel();
570  if (emergencyBrakeGap <= dist) {
571  // Vehicle may stop in time with emergency deceleration
572  // stil, emit a warning
573  WRITE_WARNING("Vehicle '" + aVehicle->getID() + "' is inserted in emergency situation.");
574  return false;
575  }
576  }
577 
578  if (errorMsg != "") {
579  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (" + errorMsg + ")!");
581  }
582  return true;
583  }
584  }
585  return false;
586 }
587 
588 
589 bool
591  double speed, double pos, double posLat, bool patchSpeed,
592  MSMoveReminder::Notification notification) {
593  if (pos < 0 || pos > myLength) {
594  // we may not start there
595  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
596  aVehicle->getID() + "'. Inserting at lane end instead.");
597  pos = myLength;
598  }
599 
600 #ifdef DEBUG_INSERTION
601  if (DEBUG_COND2(aVehicle)) {
602  std::cout << "\nIS_INSERTION_SUCCESS\n"
603  << SIMTIME << " lane=" << getID()
604  << " veh '" << aVehicle->getID() << "'\n";
605  }
606 #endif
607 
608  aVehicle->setTentativeLaneAndPosition(this, pos, posLat);
609  aVehicle->updateBestLanes(false, this);
610  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
611  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
612  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
613  double seen = getLength() - pos; // == distance from insertion position until the end of the currentLane
614  double dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
615 
616  // before looping through the continuation lanes, check if a stop is scheduled on this lane
617  // (the code is duplicated in the loop)
618  if (aVehicle->hasStops()) {
619  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
620  if (nextStop.lane == this) {
621  std::stringstream msg;
622  msg << "scheduled stop on lane '" << myID << "' too close";
623  const double distToStop = nextStop.pars.endPos - pos;
624  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, distToStop),
625  patchSpeed, msg.str())) {
626  // we may not drive with the given velocity - we cannot stop at the stop
627  return false;
628  }
629  }
630  }
631 
632  const MSRoute& r = aVehicle->getRoute();
633  MSRouteIterator ce = r.begin();
634  int nRouteSuccs = 1;
635  MSLane* currentLane = this;
636  MSLane* nextLane = this;
638  while (seen < dist && ri != bestLaneConts.end()) {
639  // get the next link used...
640  MSLinkCont::const_iterator link = succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
641  if (currentLane->isLinkEnd(link)) {
642  if (&currentLane->getEdge() == r.getLastEdge()) {
643  // reached the end of the route
645  if (checkFailure(aVehicle, speed, dist, cfModel.freeSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed, true),
646  patchSpeed, "arrival speed too low")) {
647  // we may not drive with the given velocity - we cannot match the specified arrival speed
648  return false;
649  }
650  }
651  } else {
652  // lane does not continue
653  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
654  patchSpeed, "junction too close")) {
655  // we may not drive with the given velocity - we cannot stop at the junction
656  return false;
657  }
658  }
659  break;
660  }
661 
662  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength(), aVehicle->getImpatience(), cfModel.getMaxDecel(), 0, posLat)
663  || !(*link)->havePriority()) {
664  // have to stop at junction
665  std::string errorMsg = "";
666  const LinkState state = (*link)->getState();
667  if (state == LINKSTATE_MINOR
668  || state == LINKSTATE_EQUAL
669  || state == LINKSTATE_STOP
670  || state == LINKSTATE_ALLWAY_STOP) {
671  // no sense in trying later
672  errorMsg = "unpriorised junction too close";
673  }
674  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
675  patchSpeed, errorMsg)) {
676  // we may not drive with the given velocity - we cannot stop at the junction in time
677  return false;
678  }
679 #ifdef DEBUG_INSERTION
680  if DEBUG_COND2(aVehicle) {
681  std::cout << "trying insertion before minor link: "
682  << "insertion speed = " << speed << " dist=" << dist
683  << "\n";
684  }
685 #endif
686  break;
687  }
688  // get the next used lane (including internal)
689  nextLane = (*link)->getViaLaneOrLane();
690  // check how next lane affects the journey
691  if (nextLane != 0) {
692 
693  // check if there are stops on the next lane that should be regarded
694  // (this block is duplicated before the loop to deal with the insertion lane)
695  if (aVehicle->hasStops()) {
696  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
697  if (nextStop.lane == nextLane) {
698  std::stringstream msg;
699  msg << "scheduled stop on lane '" << nextStop.lane->getID() << "' too close";
700  const double distToStop = seen + nextStop.pars.endPos;
701  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, distToStop),
702  patchSpeed, msg.str())) {
703  // we may not drive with the given velocity - we cannot stop at the stop
704  return false;
705  }
706  }
707  }
708 
709  // check leader on next lane
710  MSLeaderInfo leaders = nextLane->getLastVehicleInformation(aVehicle, 0, 0);
711  if (leaders.hasVehicles()) {
712  const double nspeed = nextLane->safeInsertionSpeed(aVehicle, seen, leaders, speed);
713 #ifdef DEBUG_INSERTION
714  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
715  << " leader on lane '" << nextLane->getID() << "': " << leaders.toString() << " nspeed=" << nspeed << "\n";
716 #endif
717  if (nspeed == INVALID_SPEED || checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
718  // we may not drive with the given velocity - we crash into the leader
719 #ifdef DEBUG_INSERTION
720  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
721  << " isInsertionSuccess lane=" << getID()
722  << " veh=" << aVehicle->getID()
723  << " pos=" << pos
724  << " posLat=" << posLat
725  << " patchSpeed=" << patchSpeed
726  << " speed=" << speed
727  << " nspeed=" << nspeed
728  << " nextLane=" << nextLane->getID()
729  << " lead=" << leaders.toString()
730 // << " gap=" << gap
731  << " failed (@641)!\n";
732 #endif
733  return false;
734  }
735  }
736  if (!nextLane->checkForPedestrians(aVehicle, speed, dist, -seen, patchSpeed)) {
737  return false;
738  }
739  // check next lane's maximum velocity
740  const double nspeed = cfModel.freeSpeed(aVehicle, speed, seen, nextLane->getVehicleMaxSpeed(aVehicle), true);
741  if (nspeed < speed) {
742  if (patchSpeed) {
743  speed = nspeed;
744  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
745  } else {
746  // we may not drive with the given velocity - we would be too fast on the next lane
747  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (slow lane ahead)!");
749  return false;
750  }
751  }
752  // check traffic on next junction
753  // we cannot use (*link)->opened because a vehicle without priority
754  // may already be comitted to blocking the link and unable to stop
755  const SUMOTime leaveTime = (*link)->getLeaveTime(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength());
756  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed, cfModel.getMaxDecel())) {
757  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen), patchSpeed, "")) {
758  // we may not drive with the given velocity - we crash at the junction
759  return false;
760  }
761  }
762  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
763  seen += nextLane->getLength();
764  currentLane = nextLane;
765  if ((*link)->getViaLane() == 0) {
766  nRouteSuccs++;
767  ++ce;
768  ++ri;
769  }
770  }
771  }
772 
773  // get the pointer to the vehicle next in front of the given position
774  MSLeaderInfo leaders = getLastVehicleInformation(aVehicle, 0, pos);
775  //if (aVehicle->getID() == "disabled") std::cout << " leaders=" << leaders.toString() << "\n";
776  const double nspeed = safeInsertionSpeed(aVehicle, -pos, leaders, speed);
777  if (nspeed == INVALID_SPEED || checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
778  // we may not drive with the given velocity - we crash into the leader
779 #ifdef DEBUG_INSERTION
780  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
781  << " isInsertionSuccess lane=" << getID()
782  << " veh=" << aVehicle->getID()
783  << " pos=" << pos
784  << " posLat=" << posLat
785  << " patchSpeed=" << patchSpeed
786  << " speed=" << speed
787  << " nspeed=" << nspeed
788  << " nextLane=" << nextLane->getID()
789  << " leaders=" << leaders.toString()
790  << " failed (@700)!\n";
791 #endif
792  return false;
793  }
794 #ifdef DEBUG_INSERTION
795  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
796  << " speed = " << speed
797  << " nspeed = " << nspeed
798  << std::endl;
799 #endif
800 
801  MSLeaderDistanceInfo followers = getFollowersOnConsecutive(aVehicle, aVehicle->getBackPositionOnLane(), false);
802  for (int i = 0; i < followers.numSublanes(); ++i) {
803  const MSVehicle* follower = followers[i].first;
804  if (follower != 0) {
805  const double backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
806  if (followers[i].second < backGapNeeded) {
807  // too close to the follower on this lane
808 #ifdef DEBUG_INSERTION
809  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
810  << " isInsertionSuccess lane=" << getID()
811  << " veh=" << aVehicle->getID()
812  << " pos=" << pos
813  << " posLat=" << posLat
814  << " patchSpeed=" << patchSpeed
815  << " speed=" << speed
816  << " nspeed=" << nspeed
817  << " follower=" << follower->getID()
818  << " backGapNeeded=" << backGapNeeded
819  << " gap=" << followers[i].second
820  << " failure (@719)!\n";
821 #endif
822  return false;
823  }
824  }
825  }
826 
827  if (!checkForPedestrians(aVehicle, speed, dist, pos, patchSpeed)) {
828  return false;
829  }
830 
831  MSLane* shadowLane = aVehicle->getLaneChangeModel().getShadowLane(this);
832 #ifdef DEBUG_INSERTION
833  if (DEBUG_COND2(aVehicle)) {
834  std::cout << " shadowLane=" << Named::getIDSecure(shadowLane) << "\n";
835  }
836 #endif
837  if (shadowLane != 0) {
838  MSLeaderDistanceInfo followers = shadowLane->getFollowersOnConsecutive(aVehicle, aVehicle->getBackPositionOnLane(), false);
839  for (int i = 0; i < followers.numSublanes(); ++i) {
840  const MSVehicle* follower = followers[i].first;
841  if (follower != 0) {
842  const double backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
843  if (followers[i].second < backGapNeeded) {
844  // too close to the follower on this lane
845 #ifdef DEBUG_INSERTION
846  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
847  << " isInsertionSuccess shadowlane=" << shadowLane->getID()
848  << " veh=" << aVehicle->getID()
849  << " pos=" << pos
850  << " posLat=" << posLat
851  << " patchSpeed=" << patchSpeed
852  << " speed=" << speed
853  << " nspeed=" << nspeed
854  << " follower=" << follower->getID()
855  << " backGapNeeded=" << backGapNeeded
856  << " gap=" << followers[i].second
857  << " failure (@812)!\n";
858 #endif
859  return false;
860  }
861  }
862  }
863  const MSLeaderInfo& ahead = shadowLane->getLastVehicleInformation(0, 0, aVehicle->getPositionOnLane(), false);
864  for (int i = 0; i < ahead.numSublanes(); ++i) {
865  const MSVehicle* veh = ahead[i];
866  if (veh != 0) {
867  const double gap = veh->getBackPositionOnLane(shadowLane) - aVehicle->getPositionOnLane() - aVehicle->getVehicleType().getMinGap();
868  const double gapNeeded = aVehicle->getCarFollowModel().getSecureGap(speed, veh->getSpeed(), veh->getCarFollowModel().getMaxDecel());
869  if (gap < gapNeeded) {
870  // too close to the shadow leader
871 #ifdef DEBUG_INSERTION
872  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
873  << " isInsertionSuccess shadowlane=" << shadowLane->getID()
874  << " veh=" << aVehicle->getID()
875  << " pos=" << pos
876  << " posLat=" << posLat
877  << " patchSpeed=" << patchSpeed
878  << " speed=" << speed
879  << " nspeed=" << nspeed
880  << " leader=" << veh->getID()
881  << " gapNeeded=" << gapNeeded
882  << " gap=" << gap
883  << " failure (@842)!\n";
884 #endif
885  return false;
886  }
887  }
888  }
889  }
890  if (followers.numFreeSublanes() > 0) {
891  // check approaching vehicles to prevent rear-end collisions
892  const double backOffset = pos - aVehicle->getVehicleType().getLength();
893  const double missingRearGap = getMissingRearGap(aVehicle, backOffset, speed);
894  if (missingRearGap > 0) {
895  // too close to a follower
896 #ifdef DEBUG_INSERTION
897  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
898  << " isInsertionSuccess lane=" << getID()
899  << " veh=" << aVehicle->getID()
900  << " pos=" << pos
901  << " posLat=" << posLat
902  << " patchSpeed=" << patchSpeed
903  << " speed=" << speed
904  << " nspeed=" << nspeed
905  << " missingRearGap=" << missingRearGap
906  << " failure (@728)!\n";
907 #endif
908  return false;
909  }
910  }
911  // may got negative while adaptation
912  if (speed < 0) {
913 #ifdef DEBUG_INSERTION
914  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
915  << " isInsertionSuccess lane=" << getID()
916  << " veh=" << aVehicle->getID()
917  << " pos=" << pos
918  << " posLat=" << posLat
919  << " patchSpeed=" << patchSpeed
920  << " speed=" << speed
921  << " nspeed=" << nspeed
922  << " failed (@733)!\n";
923 #endif
924  return false;
925  }
926  // enter
927  incorporateVehicle(aVehicle, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
928 #ifdef DEBUG_INSERTION
929  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
930  << " isInsertionSuccess lane=" << getID()
931  << " veh=" << aVehicle->getID()
932  << " pos=" << pos
933  << " posLat=" << posLat
934  << " patchSpeed=" << patchSpeed
935  << " speed=" << speed
936  << " nspeed=" << nspeed
937  << "\n myVehicles=" << toString(myVehicles)
938  << " myPartial=" << toString(myPartialVehicles)
939  << " myManeuverReservations=" << toString(myManeuverReservations)
940  << "\n leaders=" << leaders.toString()
941  << "\n success!\n";
942 #endif
943  return true;
944 }
945 
946 
947 void
948 MSLane::forceVehicleInsertion(MSVehicle* veh, double pos, MSMoveReminder::Notification notification, double posLat) {
949  veh->updateBestLanes(true, this);
950  bool dummy;
951  const double speed = veh->hasDeparted() ? veh->getSpeed() : getDepartSpeed(*veh, dummy);
952  incorporateVehicle(veh, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
953 }
954 
955 
956 double
957 MSLane::safeInsertionSpeed(const MSVehicle* veh, double seen, const MSLeaderInfo& leaders, double speed) {
958  double nspeed = speed;
959 #ifdef DEBUG_INSERTION
960  if (DEBUG_COND2(veh)) {
961  std::cout << SIMTIME << " safeInsertionSpeed veh=" << veh->getID() << " speed=" << speed << "\n";
962  }
963 #endif
964  for (int i = 0; i < leaders.numSublanes(); ++i) {
965  const MSVehicle* leader = leaders[i];
966  if (leader != 0) {
967  const double gap = leader->getBackPositionOnLane(this) + seen - veh->getVehicleType().getMinGap();
968  if (gap < 0) {
969  return INVALID_SPEED;
970  }
971  nspeed = MIN2(nspeed,
972  veh->getCarFollowModel().insertionFollowSpeed(veh, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()));
973 #ifdef DEBUG_INSERTION
974  if (DEBUG_COND2(veh)) {
975  std::cout << " leader=" << leader->getID() << " nspeed=" << nspeed << "\n";
976  }
977 #endif
978  }
979  }
980  return nspeed;
981 }
982 
983 
984 // ------ Handling vehicles lapping into lanes ------
985 const MSLeaderInfo&
986 MSLane::getLastVehicleInformation(const MSVehicle* ego, double latOffset, double minPos, bool allowCached) const {
987  if (myLeaderInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || minPos > 0 || !allowCached) {
988  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
990  int freeSublanes = 1; // number of sublanes for which no leader was found
991  //if (ego->getID() == "disabled" && SIMTIME == 58) {
992  // std::cout << "DEBUG\n";
993  //}
994  const MSVehicle* veh = *last;
995  while (freeSublanes > 0 && veh != 0) {
996 #ifdef DEBUG_PLAN_MOVE
997  if (DEBUG_COND2(ego)) {
998  gDebugFlag1 = true;
999  std::cout << " getLastVehicleInformation lane=" << getID() << " minPos=" << minPos << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
1000  }
1001 #endif
1002  if (veh != ego && veh->getPositionOnLane(this) >= minPos) {
1003  const double latOffset = veh->getLatOffset(this);
1004  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
1005 #ifdef DEBUG_PLAN_MOVE
1006  if (DEBUG_COND2(ego)) {
1007  std::cout << " latOffset=" << latOffset << " newLeaders=" << myLeaderInfoTmp.toString() << "\n";
1008  }
1009 #endif
1010  }
1011  veh = *(++last);
1012  }
1013  if (ego == 0 && minPos == 0) {
1014  // update cached value
1017  }
1018 #ifdef DEBUG_PLAN_MOVE
1019  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
1020  // << " getLastVehicleInformation lane=" << getID()
1021  // << " ego=" << Named::getIDSecure(ego)
1022  // << "\n"
1023  // << " vehicles=" << toString(myVehicles)
1024  // << " partials=" << toString(myPartialVehicles)
1025  // << "\n"
1026  // << " result=" << myLeaderInfoTmp.toString()
1027  // << " cached=" << myLeaderInfo.toString()
1028  // << " myLeaderInfoTime=" << myLeaderInfoTime
1029  // << "\n";
1030  gDebugFlag1 = false;
1031 #endif
1032  return myLeaderInfoTmp;
1033  }
1034  return myLeaderInfo;
1035 }
1036 
1037 
1038 const MSLeaderInfo&
1039 MSLane::getFirstVehicleInformation(const MSVehicle* ego, double latOffset, bool onlyFrontOnLane, double maxPos, bool allowCached) const {
1040  if (myFollowerInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || maxPos < myLength || !allowCached || onlyFrontOnLane) {
1041  // XXX separate cache for onlyFrontOnLane = true
1042  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
1044  int freeSublanes = 1; // number of sublanes for which no leader was found
1045  const MSVehicle* veh = *first;
1046  while (freeSublanes > 0 && veh != 0) {
1047 #ifdef DEBUG_PLAN_MOVE
1048  if (DEBUG_COND2(ego)) {
1049  std::cout << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << " maxPos=" << maxPos << "\n";
1050  }
1051 #endif
1052  if (veh != ego && veh->getPositionOnLane(this) <= maxPos
1053  && (!onlyFrontOnLane || veh->isFrontOnLane(this))) {
1054  //const double latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
1055  const double latOffset = veh->getLatOffset(this);
1056 #ifdef DEBUG_PLAN_MOVE
1057  if (DEBUG_COND2(ego)) {
1058  std::cout << " veh=" << veh->getID() << " latOffset=" << latOffset << "\n";
1059  }
1060 #endif
1061  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
1062  }
1063  veh = *(++first);
1064  }
1065  if (ego == 0 && maxPos == std::numeric_limits<double>::max()) {
1066  // update cached value
1069  }
1070 #ifdef DEBUG_PLAN_MOVE
1071  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
1072  // << " getFirstVehicleInformation lane=" << getID()
1073  // << " ego=" << Named::getIDSecure(ego)
1074  // << "\n"
1075  // << " vehicles=" << toString(myVehicles)
1076  // << " partials=" << toString(myPartialVehicles)
1077  // << "\n"
1078  // << " result=" << myLeaderInfoTmp.toString()
1079  // //<< " cached=" << myLeaderInfo.toString()
1080  // << " myLeaderInfoTime=" << myLeaderInfoTime
1081  // << "\n";
1082 #endif
1083  return myLeaderInfoTmp;
1084  }
1085  return myFollowerInfo;
1086 }
1087 
1088 
1089 // ------ ------
1090 void
1092  assert(myVehicles.size() != 0);
1093  double cumulatedVehLength = 0.;
1094  MSLeaderInfo leaders(this);
1095 
1096  // iterate over myVehicles, myPartialVehicles, and myManeuverReservations merge-sort style
1097  VehCont::reverse_iterator veh = myVehicles.rbegin();
1098  VehCont::reverse_iterator vehPart = myPartialVehicles.rbegin();
1099  VehCont::reverse_iterator vehRes = myManeuverReservations.rbegin();
1100 #ifdef DEBUG_PLAN_MOVE
1101  if (DEBUG_COND) std::cout
1102  << "\n"
1103  << SIMTIME
1104  << " planMovements() lane=" << getID()
1105  << "\n vehicles=" << toString(myVehicles)
1106  << "\n partials=" << toString(myPartialVehicles)
1107  << "\n reservations=" << toString(myManeuverReservations)
1108  << "\n";
1109 #endif
1111  for (; veh != myVehicles.rend(); ++veh) {
1112 #ifdef DEBUG_PLAN_MOVE
1113  if (DEBUG_COND2((*veh))) {
1114  std::cout << " plan move for: " << (*veh)->getID();
1115  }
1116 #endif
1117  updateLeaderInfo(*veh, vehPart, vehRes, leaders);
1118 #ifdef DEBUG_PLAN_MOVE
1119  if (DEBUG_COND2((*veh))) {
1120  std::cout << " leaders=" << leaders.toString() << "\n";
1121  }
1122 #endif
1123  (*veh)->planMove(t, leaders, cumulatedVehLength);
1124  cumulatedVehLength += (*veh)->getVehicleType().getLengthWithGap();
1125  leaders.addLeader(*veh, false, 0);
1126  }
1127 }
1128 
1129 
1130 void
1131 MSLane::updateLeaderInfo(const MSVehicle* veh, VehCont::reverse_iterator& vehPart, VehCont::reverse_iterator& vehRes, MSLeaderInfo& ahead) const {
1132  bool morePartialVehsAhead = vehPart != myPartialVehicles.rend();
1133  bool moreReservationsAhead = vehRes != myManeuverReservations.rend();
1134  bool nextToConsiderIsPartial;
1135 
1136  // Determine relevant leaders for veh
1137  while (moreReservationsAhead || morePartialVehsAhead) {
1138  if ((!moreReservationsAhead || (*vehRes)->getPositionOnLane(this) <= veh->getPositionOnLane())
1139  && (!morePartialVehsAhead || (*vehPart)->getPositionOnLane(this) <= veh->getPositionOnLane())) {
1140  // All relevant downstream vehicles have been collected.
1141  break;
1142  }
1143 
1144  // Check whether next farthest relevant vehicle downstream is a partial vehicle or a maneuver reservation
1145  if (moreReservationsAhead && !morePartialVehsAhead) {
1146  nextToConsiderIsPartial = false;
1147  } else if (morePartialVehsAhead && !moreReservationsAhead) {
1148  nextToConsiderIsPartial = true;
1149  } else {
1150  assert(morePartialVehsAhead && moreReservationsAhead);
1151  // Add farthest downstream vehicle first
1152  nextToConsiderIsPartial = (*vehPart)->getPositionOnLane(this) > (*vehRes)->getPositionOnLane(this);
1153  }
1154  // Add appropriate leader information
1155  if (nextToConsiderIsPartial) {
1156  const double latOffset = (*vehPart)->getLatOffset(this);
1157 #ifdef DEBUG_PLAN_MOVE
1158  if (DEBUG_COND) {
1159  std::cout << " partial ahead: " << (*vehPart)->getID() << " latOffset=" << latOffset << "\n";
1160  }
1161 #endif
1162  ahead.addLeader(*vehPart, false, latOffset);
1163  ++vehPart;
1164  morePartialVehsAhead = vehPart != myPartialVehicles.rend();
1165  } else {
1166  const double latOffset = (*vehRes)->getLatOffset(this);
1167 #ifdef DEBUG_PLAN_MOVE
1168  if (DEBUG_COND) {
1169  std::cout << " reservation ahead: " << (*vehRes)->getID() << " latOffset=" << latOffset << "\n";
1170  }
1171 #endif
1172  ahead.addLeader(*vehRes, false, latOffset);
1173  ++vehRes;
1174  moreReservationsAhead = vehRes != myManeuverReservations.rend();
1175  }
1176  }
1177 }
1178 
1179 
1180 void
1181 MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
1182 #ifdef DEBUG_COLLISIONS
1183  if (DEBUG_COND) {
1184  std::vector<const MSVehicle*> all;
1185  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
1186  all.push_back(*last);
1187  }
1188  std::cout << SIMTIME << " detectCollisions stage=" << stage << " lane=" << getID() << ":\n"
1189  << " vehs=" << toString(myVehicles) << "\n"
1190  << " part=" << toString(myPartialVehicles) << "\n"
1191  << " all=" << toString(all) << "\n"
1192  << "\n";
1193  }
1194 #endif
1195 
1196  if (myVehicles.size() == 0 || myCollisionAction == COLLISION_ACTION_NONE) {
1197  return;
1198  }
1199  std::set<const MSVehicle*, ComparatorIdLess> toRemove;
1200  std::set<const MSVehicle*> toTeleport;
1202  // no sublanes
1203  VehCont::iterator lastVeh = myVehicles.end() - 1;
1204  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh; ++veh) {
1205  VehCont::iterator pred = veh + 1;
1206  detectCollisionBetween(timestep, stage, *veh, *pred, toRemove, toTeleport);
1207  }
1208  if (myPartialVehicles.size() > 0) {
1209  detectCollisionBetween(timestep, stage, *lastVeh, myPartialVehicles.front(), toRemove, toTeleport);
1210  }
1211  } else {
1212  // in the sublane-case it is insufficient to check the vehicles ordered
1213  // by their front position as there might be more than 2 vehicles next to each
1214  // other on the same lane
1215  // instead, a moving-window approach is used where all vehicles that
1216  // overlap in the longitudinal direction receive pairwise checks
1217  // XXX for efficiency, all lanes of an edge should be checked together
1218  // (lanechanger-style)
1219 
1220  // XXX quick hack: check each in myVehicles against all others
1221  for (AnyVehicleIterator veh = anyVehiclesBegin(); veh != anyVehiclesEnd(); ++veh) {
1222  MSVehicle* follow = (MSVehicle*)*veh;
1223  for (AnyVehicleIterator veh2 = anyVehiclesBegin(); veh2 != anyVehiclesEnd(); ++veh2) {
1224  MSVehicle* lead = (MSVehicle*)*veh2;
1225  if (lead == follow) {
1226  continue;
1227  }
1228  if (lead->getPositionOnLane(this) < follow->getPositionOnLane(this)) {
1229  continue;
1230  }
1231  if (detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1232  // XXX what about collisions with multiple leaders at once?
1233  break;
1234  }
1235  }
1236  if (follow->getLaneChangeModel().getShadowLane() != 0 && follow->getLane() == this) {
1237  // check whether follow collides on the shadow lane
1238  const MSLane* shadowLane = follow->getLaneChangeModel().getShadowLane();
1239  MSLeaderInfo ahead = shadowLane->getLastVehicleInformation(follow,
1240  getRightSideOnEdge() - shadowLane->getRightSideOnEdge(),
1241  follow->getPositionOnLane());
1242  for (int i = 0; i < ahead.numSublanes(); ++i) {
1243  MSVehicle* lead = const_cast<MSVehicle*>(ahead[i]);
1244  if (lead != 0 && lead != follow && shadowLane->detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1245  break;
1246  }
1247  }
1248  }
1249  }
1250  }
1251 
1253 #ifdef DEBUG_JUNCTION_COLLISIONS
1254  if (DEBUG_COND) {
1255  std::cout << SIMTIME << " detect junction Collisions stage=" << stage << " lane=" << getID() << ":\n"
1256  << " vehs=" << toString(myVehicles) << "\n"
1257  << " part=" << toString(myPartialVehicles) << "\n"
1258  << "\n";
1259  }
1260 #endif
1261  assert(myLinks.size() == 1);
1262  //std::cout << SIMTIME << " checkJunctionCollisions " << getID() << "\n";
1263  const std::vector<const MSLane*>& foeLanes = myLinks.front()->getFoeLanes();
1264  for (AnyVehicleIterator veh = anyVehiclesBegin(); veh != anyVehiclesEnd(); ++veh) {
1265  MSVehicle* collider = const_cast<MSVehicle*>(*veh);
1266  //std::cout << " collider " << collider->getID() << "\n";
1267  PositionVector colliderBoundary = collider->getBoundingBox();
1268  for (std::vector<const MSLane*>::const_iterator it = foeLanes.begin(); it != foeLanes.end(); ++it) {
1269  const MSLane* foeLane = *it;
1270  //std::cout << " foeLane " << foeLane->getID() << "\n";
1271  MSLane::AnyVehicleIterator end = foeLane->anyVehiclesEnd();
1272  for (MSLane::AnyVehicleIterator it_veh = foeLane->anyVehiclesBegin(); it_veh != end; ++it_veh) {
1273  MSVehicle* victim = (MSVehicle*)*it_veh;
1274  if (victim == collider) {
1275  // may happen if the vehicles lane and shadow lane are siblings
1276  continue;
1277  }
1278  //std::cout << " victim " << victim->getID() << "\n";
1279 #ifdef DEBUG_JUNCTION_COLLISIONS
1280  if (DEBUG_COND && DEBUG_COND2(collider)) {
1281  std::cout << SIMTIME << " foe=" << victim->getID() << " bound=" << colliderBoundary << " foeBound=" << victim->getBoundingBox() << "\n";
1282  }
1283 #endif
1284  if (colliderBoundary.overlapsWith(victim->getBoundingBox())) {
1285  // make a detailed check
1286  if (collider->getBoundingPoly().overlapsWith(victim->getBoundingPoly())) {
1287  handleCollisionBetween(timestep, stage, collider, victim, -1, 0, toRemove, toTeleport);
1288  }
1289  }
1290  }
1291  detectPedestrianJunctionCollision(collider, colliderBoundary, foeLane, timestep, stage);
1292  }
1293  if (myLinks.front()->getWalkingAreaFoe() != 0) {
1294  detectPedestrianJunctionCollision(collider, colliderBoundary, myLinks.front()->getWalkingAreaFoe(), timestep, stage);
1295  }
1296  }
1297  }
1298 
1299  if (myEdge->getPersons().size() > 0 && MSPModel::getModel()->hasPedestrians(this)) {
1300 #ifdef DEBUG_PEDESTRIAN_COLLISIONS
1301  if (DEBUG_COND) {
1302  std::cout << SIMTIME << " detect pedestrian collisions stage=" << stage << " lane=" << getID() << "\n";
1303  }
1304 #endif
1306  for (AnyVehicleIterator it_v = anyVehiclesBegin(); it_v != v_end; ++it_v) {
1307  const MSVehicle* v = *it_v;
1308  const double back = v->getBackPositionOnLane(this);
1309  const double length = v->getVehicleType().getLength();
1310  const double right = v->getRightSideOnEdge(this) - getRightSideOnEdge();
1311  PersonDist leader = MSPModel::getModel()->nextBlocking(this, back, right, right + v->getVehicleType().getWidth());
1312 #ifdef DEBUG_PEDESTRIAN_COLLISIONS
1313  if (DEBUG_COND && DEBUG_COND2(v)) {
1314  std::cout << SIMTIME << " back=" << back << " right=" << right << " person=" << Named::getIDSecure(leader.first) << " dist=" << leader.second << "\n";
1315  }
1316 #endif
1317  if (leader.first != 0 && leader.second < length) {
1318  WRITE_WARNING(
1319  "Vehicle '" + v->getID()
1320  + "' collision with person '" + leader.first->getID()
1321  + "', lane='" + getID()
1322  + "', gap=" + toString(leader.second - length)
1323  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())
1324  + " stage=" + stage + ".");
1326  }
1327  }
1328  }
1329 
1330 
1331  for (std::set<const MSVehicle*, ComparatorIdLess>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
1332  MSVehicle* veh = const_cast<MSVehicle*>(*it);
1333  MSLane* vehLane = veh->getLane();
1335  if (toTeleport.count(veh) > 0) {
1336  MSVehicleTransfer::getInstance()->add(timestep, veh);
1337  } else {
1340  }
1341  }
1342 }
1343 
1344 
1345 void
1346 MSLane::detectPedestrianJunctionCollision(const MSVehicle* collider, const PositionVector& colliderBoundary, const MSLane* foeLane,
1347  SUMOTime timestep, const std::string& stage) {
1348  if (foeLane->getEdge().getPersons().size() > 0 && MSPModel::getModel()->hasPedestrians(foeLane)) {
1349 #ifdef DEBUG_PEDESTRIAN_COLLISIONS
1350  if (DEBUG_COND) {
1351  std::cout << SIMTIME << " detect pedestrian junction collisions stage=" << stage << " lane=" << getID() << " foeLane=" << foeLane->getID() << "\n";
1352  }
1353 #endif
1354  const std::vector<MSTransportable*>& persons = foeLane->getEdge().getSortedPersons(timestep);
1355  for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
1356 #ifdef DEBUG_PEDESTRIAN_COLLISIONS
1357  if (DEBUG_COND) {
1358  std::cout << " collider=" << collider->getID()
1359  << " ped=" << (*it_p)->getID()
1360  << " colliderBoundary=" << colliderBoundary
1361  << " pedBoundary=" << (*it_p)->getBoundingBox()
1362  << "\n";
1363  }
1364 #endif
1365  if (colliderBoundary.overlapsWith((*it_p)->getBoundingBox())) {
1366  WRITE_WARNING(
1367  "Vehicle '" + collider->getID()
1368  + "' collision with person '" + (*it_p)->getID()
1369  + "', lane='" + getID()
1370  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())
1371  + " stage=" + stage + ".");
1373  }
1374  }
1375  }
1376 }
1377 
1378 bool
1379 MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
1380  std::set<const MSVehicle*, ComparatorIdLess>& toRemove,
1381  std::set<const MSVehicle*>& toTeleport) const {
1382  if (myCollisionAction == COLLISION_ACTION_TELEPORT && ((victim->hasInfluencer() && victim->getInfluencer().isRemoteAffected(timestep)) ||
1383  (collider->hasInfluencer() && collider->getInfluencer().isRemoteAffected(timestep)))) {
1384  return false;
1385  }
1386 
1387  // No self-collisions! (This is assumed to be ensured at caller side)
1388  if (collider == victim) {
1389  return false;
1390  }
1391 
1392  const bool colliderOpposite = collider->getLaneChangeModel().isOpposite();
1393  const bool bothOpposite = victim->getLaneChangeModel().isOpposite() && colliderOpposite;
1394  if (bothOpposite) {
1395  std::swap(victim, collider);
1396  }
1397  const double colliderPos = colliderOpposite ? collider->getBackPositionOnLane(this) : collider->getPositionOnLane(this);
1398  double gap = victim->getBackPositionOnLane(this) - colliderPos - myCollisionMinGapFactor * collider->getVehicleType().getMinGap();
1399  if (bothOpposite) {
1400  gap = -gap - 2 * myCollisionMinGapFactor * collider->getVehicleType().getMinGap();
1401  }
1402 #ifdef DEBUG_COLLISIONS
1403  if (DEBUG_COND && (DEBUG_COND2(collider) || DEBUG_COND2(victim))) {
1404  std::cout << SIMTIME
1405  << " thisLane=" << getID()
1406  << " collider=" << collider->getID()
1407  << " victim=" << victim->getID()
1408  << " colliderLane=" << collider->getLane()->getID()
1409  << " victimLane=" << victim->getLane()->getID()
1410  << " colliderPos=" << colliderPos
1411  << " victimBackPos=" << victim->getBackPositionOnLane(this)
1412  << " colliderLat=" << collider->getCenterOnEdge(this)
1413  << " victimLat=" << victim->getCenterOnEdge(this)
1414  << " gap=" << gap
1415  << "\n";
1416  }
1417 #endif
1418  if (gap < -NUMERICAL_EPS) {
1419  double latGap = 0;
1421  latGap = (fabs(victim->getCenterOnEdge(this) - collider->getCenterOnEdge(this))
1422  - 0.5 * fabs(victim->getVehicleType().getWidth() + collider->getVehicleType().getWidth()));
1423  if (latGap + NUMERICAL_EPS > 0) {
1424  return false;
1425  }
1426  }
1428  && collider->getLaneChangeModel().isChangingLanes()
1429  && victim->getLaneChangeModel().isChangingLanes()
1430  && victim->getLane() != this) {
1431  // synchroneous lane change maneuver
1432  return false;
1433  }
1434  handleCollisionBetween(timestep, stage, collider, victim, gap, latGap, toRemove, toTeleport);
1435  return true;
1436  }
1437  return false;
1438 }
1439 
1440 
1441 void
1442 MSLane::handleCollisionBetween(SUMOTime timestep, const std::string& stage, MSVehicle* collider, MSVehicle* victim,
1443  double gap, double latGap, std::set<const MSVehicle*, ComparatorIdLess>& toRemove,
1444  std::set<const MSVehicle*>& toTeleport) const {
1445  std::string prefix = "Vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1446  if (myCollisionStopTime > 0) {
1447  if (collider->collisionStopTime() >= 0 && victim->collisionStopTime() >= 0) {
1448  return;
1449  }
1450  std::string dummyError;
1453  stop.busstop = "";
1454  stop.containerstop = "";
1455  stop.chargingStation = "";
1456  stop.parkingarea = "";
1457  stop.until = 0;
1458  stop.triggered = false;
1459  stop.containerTriggered = false;
1460  stop.parking = false;
1461  stop.index = 0;
1462  const double collisionAngle = RAD2DEG(fabs(GeomHelper::angleDiff(victim->getAngle(), collider->getAngle())));
1463  // determine new speeds from collision angle (@todo account for vehicle mass)
1464  double victimSpeed = victim->getSpeed();
1465  double colliderSpeed = collider->getSpeed();
1466  // double victimOrigSpeed = victim->getSpeed();
1467  // double colliderOrigSpeed = collider->getSpeed();
1468  if (collisionAngle < 45) {
1469  // rear-end collisions
1470  colliderSpeed = MIN2(colliderSpeed, victimSpeed);
1471  } else if (collisionAngle < 135) {
1472  // side collision
1473  colliderSpeed /= 2;
1474  victimSpeed /= 2;
1475  } else {
1476  // frontal collision
1477  colliderSpeed = 0;
1478  victimSpeed = 0;
1479  }
1480  const double victimStopPos = MIN2(victim->getLane()->getLength(),
1481  victim->getPositionOnLane() + victim->getCarFollowModel().brakeGap(victimSpeed, victim->getCarFollowModel().getEmergencyDecel(), 0));
1482  if (victim->collisionStopTime() < 0) {
1483  stop.lane = victim->getLane()->getID();
1484  // @todo: push victim forward?
1485  stop.startPos = victimStopPos;
1486  stop.endPos = stop.startPos;
1488  victim->addStop(stop, dummyError, 0, true);
1489  }
1490  if (collider->collisionStopTime() < 0) {
1491  stop.lane = collider->getLane()->getID();
1492  stop.startPos = MIN2(collider->getPositionOnLane() + collider->getCarFollowModel().brakeGap(colliderSpeed, collider->getCarFollowModel().getEmergencyDecel(), 0),
1493  MAX2(0.0, victimStopPos - 0.75 * victim->getVehicleType().getLength()));
1494  stop.endPos = stop.startPos;
1495  collider->addStop(stop, dummyError, 0, true);
1496  }
1497  //std::cout << " collisionAngle=" << collisionAngle
1498  // << "\n vPos=" << victim->getPositionOnLane() << " vStop=" << victimStopPos << " vSpeed=" << victimOrigSpeed << " vSpeed2=" << victimSpeed << " vSpeed3=" << victim->getSpeed()
1499  // << "\n cPos=" << collider->getPositionOnLane() << " cStop=" << stop.startPos << " cSpeed=" << colliderOrigSpeed << " cSpeed2=" << colliderSpeed << " cSpeed3=" << collider->getSpeed()
1500  // << "\n";
1501  } else {
1502  switch (myCollisionAction) {
1503  case COLLISION_ACTION_WARN:
1504  break;
1506  prefix = "Teleporting vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1507  toRemove.insert(collider);
1508  toTeleport.insert(collider);
1509  break;
1510  case COLLISION_ACTION_REMOVE: {
1511  prefix = "Removing collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1512  bool removeCollider = true;
1513  bool removeVictim = true;
1514  removeVictim = !(victim->hasInfluencer() && victim->getInfluencer().isRemoteAffected(timestep));
1515  removeCollider = !(collider->hasInfluencer() && collider->getInfluencer().isRemoteAffected(timestep));
1516  if (removeVictim) {
1517  toRemove.insert(victim);
1518  }
1519  if (removeCollider) {
1520  toRemove.insert(collider);
1521  }
1522  if (!removeVictim) {
1523  if (!removeCollider) {
1524  prefix = "Keeping remote-controlled collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1525  } else {
1526  prefix = "Removing collision participant: vehicle '" + collider->getID() + "', keeping remote-controlled vehicle '" + victim->getID();
1527  }
1528  } else if (!removeCollider) {
1529  prefix = "Keeping remote-controlled collision participant: vehicle '" + collider->getID() + "', removing vehicle '" + victim->getID();
1530  }
1531  break;
1532  }
1533  default:
1534  break;
1535  }
1536  }
1537  WRITE_WARNING(prefix
1538  + "', lane='" + getID()
1539  + "', gap=" + toString(gap)
1540  + (latGap == 0 ? "" : "', latGap=" + toString(latGap))
1541  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())
1542  + " stage=" + stage + ".");
1543 #ifdef DEBUG_COLLISIONS
1544  if (DEBUG_COND2(collider)) {
1545  toRemove.erase(collider);
1546  toTeleport.erase(collider);
1547  }
1548  if (DEBUG_COND2(victim)) {
1549  toRemove.erase(victim);
1550  toTeleport.erase(victim);
1551  }
1552 #endif
1556 }
1557 
1558 
1559 bool
1560 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& lanesWithVehiclesToIntegrate) {
1561  // iterate over vehicles in reverse so that move reminders will be called in the correct order
1562  for (VehCont::reverse_iterator i = myVehicles.rbegin(); i != myVehicles.rend();) {
1563  MSVehicle* veh = *i;
1564  // length is needed later when the vehicle may not exist anymore
1565  const double length = veh->getVehicleType().getLengthWithGap();
1566  const double nettoLength = veh->getVehicleType().getLength();
1567  const bool moved = veh->executeMove();
1568  MSLane* const target = veh->getLane();
1569  if (veh->hasArrived()) {
1570  // vehicle has reached its arrival position
1571 #ifdef DEBUG_EXEC_MOVE
1572  if DEBUG_COND2(veh) {
1573  std::cout << SIMTIME << " veh " << veh->getID() << " has arrived." << std::endl;
1574  }
1575 #endif
1578  } else if (target != 0 && moved) {
1579  if (target->getEdge().isVaporizing()) {
1580  // vehicle has reached a vaporizing edge
1583  } else {
1584  // vehicle has entered a new lane (leaveLane and workOnMoveReminders were already called in MSVehicle::executeMove)
1585  target->myVehBuffer.push_back(veh);
1586  lanesWithVehiclesToIntegrate.push_back(target);
1587  }
1588  } else if (veh->isParking()) {
1589  // vehicle started to park
1591  myParkingVehicles.insert(veh);
1592  } else if (veh->getPositionOnLane() > getLength()) {
1593  // for any reasons the vehicle is beyond its lane...
1594  // this should never happen because it is handled in MSVehicle::executeMove
1595  assert(false);
1596  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, target lane='" + getID() + "', time=" +
1597  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1600  } else if (veh->collisionStopTime() == 0) {
1601  veh->resumeFromStopping();
1603  WRITE_WARNING("Removing vehicle '" + veh->getID() + "' after earlier collision, lane='" + veh->getLane()->getID() + ", time=" +
1604  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1608  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "' after earlier collision, lane='" + veh->getLane()->getID() + ", time=" +
1609  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1610  MSVehicleTransfer::getInstance()->add(MSNet::getInstance()->getCurrentTimeStep(), veh);
1611  } else {
1612  ++i;
1613  continue;
1614  }
1615  } else {
1616  ++i;
1617  continue;
1618  }
1619  myBruttoVehicleLengthSum -= length;
1620  myNettoVehicleLengthSum -= nettoLength;
1621  ++i;
1622  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
1623  }
1624  if (myVehicles.size() > 0) {
1626  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
1627  if (!veh->isStopped() && veh->getLane() == this) {
1628  const bool wrongLane = !veh->getLane()->appropriate(veh);
1630  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
1631  if (r1 || r2) {
1632  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1633  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
1634  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
1635  MSVehicle* veh = *(myVehicles.end() - 1);
1638  myVehicles.erase(myVehicles.end() - 1);
1639  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
1640  + reason
1641  + (r2 ? " (highway)" : "")
1642  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1643  if (wrongLane) {
1645  } else if (minorLink) {
1647  } else {
1649  }
1651  }
1652  } // else look for a (waiting) vehicle that isn't stopped?
1653  }
1654  } else {
1655  // avoid numerical instability
1658  }
1660  // trigger sorting of vehicles as their order may have changed
1661  lanesWithVehiclesToIntegrate.push_back(this);
1662  }
1663  return myVehicles.size() == 0;
1664 }
1665 
1666 
1667 const MSEdge*
1669  const MSEdge* e = myEdge;
1670  while (e->isInternal()) {
1671  e = e->getSuccessors()[0];
1672  }
1673  return e;
1674 }
1675 
1676 
1677 const MSLane*
1679  if (!this->isInternal()) {
1680  return 0;
1681  }
1682  offset = 0.;
1683  const MSLane* firstInternal = this;
1685  while (pred != 0 && pred->isInternal()) {
1686  firstInternal = pred;
1687  offset += pred->getLength();
1688  pred = firstInternal->getCanonicalPredecessorLane();
1689  }
1690  return firstInternal;
1691 }
1692 
1693 
1694 // ------ Static (sic!) container methods ------
1695 bool
1696 MSLane::dictionary(const std::string& id, MSLane* ptr) {
1697  DictType::iterator it = myDict.find(id);
1698  if (it == myDict.end()) {
1699  // id not in myDict.
1700  myDict.insert(DictType::value_type(id, ptr));
1701  return true;
1702  }
1703  return false;
1704 }
1705 
1706 
1707 MSLane*
1708 MSLane::dictionary(const std::string& id) {
1709  DictType::iterator it = myDict.find(id);
1710  if (it == myDict.end()) {
1711  // id not in myDict.
1712  return 0;
1713  }
1714  return it->second;
1715 }
1716 
1717 
1718 void
1720  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1721  delete(*i).second;
1722  }
1723  myDict.clear();
1724 }
1725 
1726 
1727 void
1728 MSLane::insertIDs(std::vector<std::string>& into) {
1729  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1730  into.push_back((*i).first);
1731  }
1732 }
1733 
1734 
1735 template<class RTREE> void
1736 MSLane::fill(RTREE& into) {
1737  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1738  MSLane* l = (*i).second;
1739  Boundary b = l->getShape().getBoxBoundary();
1740  b.grow(3.);
1741  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
1742  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
1743  into.Insert(cmin, cmax, l);
1744  }
1745 }
1746 
1747 template void MSLane::fill<NamedRTree>(NamedRTree& into);
1748 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
1749 
1750 // ------ ------
1751 bool
1753  if (myEdge->isInternal()) {
1754  return true;
1755  }
1756  if (veh->succEdge(1) == 0) {
1757  assert((int)veh->getBestLanes().size() > veh->getLaneIndex());
1758  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
1759  return true;
1760  } else {
1761  return false;
1762  }
1763  }
1764  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1765  return (link != myLinks.end());
1766 }
1767 
1768 
1769 bool
1771  bool wasInactive = myVehicles.size() == 0;
1772  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter(this));
1773  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
1774  MSVehicle* veh = *i;
1775  assert(veh->getLane() == this);
1776  myVehicles.insert(myVehicles.begin(), veh);
1779  //if (true) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " veh=" << veh->getID() << " (on lane " << veh->getLane()->getID() << ") into lane=" << getID() << " myBrutto=" << myBruttoVehicleLengthSum << "\n";
1780  myEdge->markDelayed();
1781  }
1782  myVehBuffer.clear();
1783  //std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " myVehicles1=" << toString(myVehicles);
1784  if (MSGlobals::gLateralResolution > 0 || myNeighs.size() > 0) {
1785  sort(myVehicles.begin(), myVehicles.end(), vehicle_natural_position_sorter(this));
1786  }
1788 #ifdef DEBUG_VEHICLE_CONTAINER
1789  if (DEBUG_COND) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID()
1790  << " vhicles=" << toString(myVehicles) << " partials=" << toString(myPartialVehicles) << "\n";
1791 #endif
1792  return wasInactive && myVehicles.size() != 0;
1793 }
1794 
1795 
1796 void
1798  if (myPartialVehicles.size() > 1) {
1800  }
1801 }
1802 
1803 
1804 void
1806  if (myManeuverReservations.size() > 1) {
1807 #ifdef DEBUG_CONTEXT
1808  if DEBUG_COND {
1809  std::cout << "sortManeuverReservations on lane " << getID()
1810  << "\nBefore sort: " << toString(myManeuverReservations) << std::endl;
1811  }
1812 #endif
1814 #ifdef DEBUG_CONTEXT
1815  if DEBUG_COND {
1816  std::cout << "After sort: " << toString(myManeuverReservations) << std::endl;
1817  }
1818 #endif
1819  }
1820 }
1821 
1822 
1823 bool
1824 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
1825  return i == myLinks.end();
1826 }
1827 
1828 
1829 bool
1830 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
1831  return i == myLinks.end();
1832 }
1833 
1834 bool
1836  return myVehicles.empty() && myPartialVehicles.empty();
1837 }
1838 
1839 bool
1841  return myEdge->isInternal();
1842 }
1843 
1844 MSVehicle*
1846  if (myVehicles.size() == 0) {
1847  return 0;
1848  }
1849  return myVehicles.front();
1850 }
1851 
1852 
1853 MSVehicle*
1855  if (myVehicles.size() == 0) {
1856  return 0;
1857  }
1858  return myVehicles.back();
1859 }
1860 
1861 
1862 MSVehicle*
1864  // all vehicles in myVehicles should have positions smaller or equal to
1865  // those in myPartialVehicles
1866  if (myVehicles.size() > 0) {
1867  return myVehicles.front();
1868  }
1869  if (myPartialVehicles.size() > 0) {
1870  return myPartialVehicles.front();
1871  }
1872  return 0;
1873 }
1874 
1875 
1876 MSVehicle*
1878  MSVehicle* result = 0;
1879  if (myVehicles.size() > 0) {
1880  result = myVehicles.back();
1881  }
1882  if (myPartialVehicles.size() > 0
1883  && (result == 0 || result->getPositionOnLane(this) < myPartialVehicles.back()->getPositionOnLane(this))) {
1884  result = myPartialVehicles.back();
1885  }
1886  return result;
1887 }
1888 
1889 
1890 MSLinkCont::const_iterator
1891 MSLane::succLinkSec(const SUMOVehicle& veh, int nRouteSuccs,
1892  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
1893  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
1894  // check whether the vehicle tried to look beyond its route
1895  if (nRouteEdge == 0) {
1896  // return end (no succeeding link) if so
1897  return succLinkSource.myLinks.end();
1898  }
1899  // if we are on an internal lane there should only be one link and it must be allowed
1900  if (succLinkSource.isInternal()) {
1901  assert(succLinkSource.myLinks.size() == 1);
1902  // could have been disallowed dynamically with a rerouter or via TraCI
1903  // assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
1904  return succLinkSource.myLinks.begin();
1905  }
1906  // a link may be used if
1907  // 1) there is a destination lane ((*link)->getLane()!=0)
1908  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
1909  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
1910 
1911  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
1912  // "conts" stores the best continuations of our current lane
1913  // we should never return an arbitrary link since this may cause collisions
1914 
1915  MSLinkCont::const_iterator link;
1916  if (nRouteSuccs < (int)conts.size()) {
1917  // we go through the links in our list and return the matching one
1918  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
1919  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
1920  // we should use the link if it connects us to the best lane
1921  if ((*link)->getLane() == conts[nRouteSuccs]) {
1922  return link;
1923  }
1924  }
1925  }
1926  } else {
1927  // the source lane is a dead end (no continuations exist)
1928  return succLinkSource.myLinks.end();
1929  }
1930  // the only case where this should happen is for a disconnected route (deliberately ignored)
1931 #ifdef DEBUG_NO_CONNECTION
1932  // the "'" around the ids are missing intentionally in the message below because it slows messaging down, resulting in test timeouts
1933  WRITE_WARNING("Could not find connection between lane " + succLinkSource.getID() + " and lane " + conts[nRouteSuccs]->getID() +
1934  " for vehicle " + veh.getID() + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1935 #endif
1936  return succLinkSource.myLinks.end();
1937 }
1938 
1939 const MSLinkCont&
1941  return myLinks;
1942 }
1943 
1944 
1946 MSLink*
1947 MSLane::getLinkTo(const MSLane* target) const {
1948  MSLinkCont::const_iterator l = myLinks.begin();
1949  if (target->isInternal()) {
1950  while (l != myLinks.end()) {
1951  if ((*l)->getViaLane()->getID() == target->getID()) {
1952  return *l;
1953  }
1954  ++l;
1955  }
1956  } else {
1957  while (l != myLinks.end()) {
1958  if ((*l)->getLane()->getID() == target->getID()) {
1959  return *l;
1960  }
1961  ++l;
1962  }
1963  }
1964  return 0;
1965 }
1966 
1967 MSLink*
1969  if (!isInternal()) {
1970  return 0;
1971  }
1972  const MSLane* internal = this;
1973  const MSLane* lane = this->getCanonicalPredecessorLane();
1974  assert(lane != 0);
1975  while (lane->isInternal()) {
1976  internal = lane;
1977  lane = lane->getCanonicalPredecessorLane();
1978  assert(lane != 0);
1979  }
1980  return lane->getLinkTo(internal);
1981 }
1982 
1983 
1984 void
1985 MSLane::setMaxSpeed(double val) {
1986  myMaxSpeed = val;
1987  myEdge->recalcCache();
1988 }
1989 
1990 
1991 void
1992 MSLane::setLength(double val) {
1993  myLength = val;
1994  myEdge->recalcCache();
1995 }
1996 
1997 
1998 void
2000  //if (getID() == "disabled_lane") std::cout << SIMTIME << " swapAfterLaneChange lane=" << getID() << " myVehicles=" << toString(myVehicles) << " myTmpVehicles=" << toString(myTmpVehicles) << "\n";
2002  myTmpVehicles.clear();
2003  // this needs to be done after finishing lane-changing for all lanes on the
2004  // current edge (MSLaneChanger::updateLanes())
2006 }
2007 
2008 
2009 MSVehicle*
2010 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
2011  assert(remVehicle->getLane() == this);
2012  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
2013  if (remVehicle == *it) {
2014  if (notify) {
2015  remVehicle->leaveLane(notification);
2016  }
2017  myVehicles.erase(it);
2020  break;
2021  }
2022  }
2023  return remVehicle;
2024 }
2025 
2026 
2027 MSLane*
2028 MSLane::getParallelLane(int offset) const {
2029  return myEdge->parallelLane(this, offset);
2030 }
2031 
2032 
2033 void
2035  IncomingLaneInfo ili;
2036  ili.lane = lane;
2037  ili.viaLink = viaLink;
2038  ili.length = lane->getLength();
2039  myIncomingLanes.push_back(ili);
2040 }
2041 
2042 
2043 void
2044 MSLane::addApproachingLane(MSLane* lane, bool warnMultiCon) {
2045  MSEdge* approachingEdge = &lane->getEdge();
2046  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
2047  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
2048  } else if (!approachingEdge->isInternal() && warnMultiCon) {
2049  // whenever a normal edge connects twice, there is a corresponding
2050  // internal edge wich connects twice, one warning is sufficient
2051  WRITE_WARNING("Lane '" + getID() + "' is approached multiple times from edge '" + approachingEdge->getID() + "'. This may cause collisions.");
2052  }
2053  myApproachingLanes[approachingEdge].push_back(lane);
2054 }
2055 
2056 
2057 bool
2059  return myApproachingLanes.find(edge) != myApproachingLanes.end();
2060 }
2061 
2062 
2063 bool
2064 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
2065  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
2066  if (i == myApproachingLanes.end()) {
2067  return false;
2068  }
2069  const std::vector<MSLane*>& lanes = (*i).second;
2070  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
2071 }
2072 
2073 
2075 public:
2076  inline int operator()(const std::pair<const MSVehicle*, double>& p1, const std::pair<const MSVehicle*, double>& p2) const {
2077  return p1.second < p2.second;
2078  }
2079 };
2080 
2081 
2082 double MSLane::getMissingRearGap(const MSVehicle* leader, double backOffset, double leaderSpeed) const {
2083  // this follows the same logic as getFollowerOnConsecutive. we do a tree
2084  // search and check for the vehicle with the largest missing rear gap within
2085  // relevant range
2086  double result = 0;
2087  const double leaderDecel = leader->getCarFollowModel().getMaxDecel();
2088  CLeaderDist followerInfo = getFollowersOnConsecutive(leader, backOffset, false)[0];
2089  const MSVehicle* v = followerInfo.first;
2090  if (v != 0) {
2091  result = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderDecel) - followerInfo.second;
2092  }
2093  return result;
2094 }
2095 
2096 
2097 double
2100  const double maxSpeed = getSpeedLimit() * vc.getMaxSpeedFactor();
2101  // NOTE: For the euler update this is an upper bound on the actual braking distance (see ticket #860)
2102  return maxSpeed * maxSpeed * 0.5 / vc.getMinDeceleration();
2103 }
2104 
2105 
2106 
2107 std::pair<MSVehicle* const, double>
2108 MSLane::getLeader(const MSVehicle* veh, const double vehPos, const std::vector<MSLane*>& bestLaneConts, double dist, bool checkTmpVehicles) const {
2109  // get the leading vehicle for (shadow) veh
2110  // XXX this only works as long as all lanes of an edge have equal length
2111 #ifdef DEBUG_CONTEXT
2112  if (DEBUG_COND2(veh)) {
2113  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " vehs=" << toString(myVehicles) << " tmpVehs=" << toString(myTmpVehicles) << "\n";
2114  }
2115 #endif
2116  if (checkTmpVehicles) {
2117  for (VehCont::const_iterator last = myTmpVehicles.begin(); last != myTmpVehicles.end(); ++last) {
2118  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
2119  MSVehicle* pred = (MSVehicle*)*last;
2120  if (pred == veh) {
2121  continue;
2122  }
2123 #ifdef DEBUG_CONTEXT
2124  if (DEBUG_COND2(veh)) {
2125  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane() << "\n";
2126  }
2127 #endif
2128  if (pred->getPositionOnLane() > vehPos + NUMERICAL_EPS) {
2129  return std::pair<MSVehicle* const, double>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
2130  }
2131  }
2132  } else {
2133  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
2134  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
2135  MSVehicle* pred = (MSVehicle*)*last;
2136  if (pred == veh) {
2137  continue;
2138  }
2139 #ifdef DEBUG_CONTEXT
2140  if (DEBUG_COND2(veh)) {
2141  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos
2142  << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << " predBack=" << pred->getBackPositionOnLane(this) << "\n";
2143  }
2144 #endif
2145  if (pred->getPositionOnLane(this) > vehPos + NUMERICAL_EPS) {
2146  return std::pair<MSVehicle* const, double>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
2147  }
2148  }
2149  }
2150  // XXX from here on the code mirrors MSLaneChanger::getRealLeader
2151  if (bestLaneConts.size() > 0) {
2152  double seen = getLength() - vehPos;
2153  double speed = veh->getSpeed();
2154  if (dist < 0) {
2155  dist = veh->getCarFollowModel().brakeGap(speed) + veh->getVehicleType().getMinGap();
2156  }
2157 #ifdef DEBUG_CONTEXT
2158  if (DEBUG_COND2(veh)) {
2159  std::cout << " getLeader lane=" << getID() << " seen=" << seen << " dist=" << dist << "\n";
2160  }
2161 #endif
2162  if (seen > dist) {
2163  return std::pair<MSVehicle* const, double>(static_cast<MSVehicle*>(0), -1);
2164  }
2165  return getLeaderOnConsecutive(dist, seen, speed, *veh, bestLaneConts);
2166  } else {
2167  return std::make_pair(static_cast<MSVehicle*>(0), -1);
2168  }
2169 }
2170 
2171 
2172 std::pair<MSVehicle* const, double>
2173 MSLane::getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle& veh,
2174  const std::vector<MSLane*>& bestLaneConts) const {
2175 #ifdef DEBUG_CONTEXT
2176  if (DEBUG_COND2(&veh)) {
2177  std::cout << " getLeaderOnConsecutive lane=" << getID() << " ego=" << veh.getID() << " seen=" << seen << " dist=" << dist << " conts=" << toString(bestLaneConts) << "\n";
2178  }
2179 #endif
2180  if (seen > dist && !isInternal()) {
2181  return std::make_pair(static_cast<MSVehicle*>(0), -1);
2182  }
2183  int view = 1;
2184  // loop over following lanes
2185  if (myPartialVehicles.size() > 0) {
2186  // XXX
2187  MSVehicle* pred = myPartialVehicles.front();
2188  const double gap = seen - (getLength() - pred->getBackPositionOnLane(this)) - veh.getVehicleType().getMinGap();
2189 #ifdef DEBUG_CONTEXT
2190  if (DEBUG_COND2(&veh)) {
2191  std::cout << " predGap=" << gap << " partials=" << toString(myPartialVehicles) << "\n";
2192  }
2193 #endif
2194  // make sure pred is really a leader and not doing continous lane-changing behind ego
2195  if (gap > 0) {
2196  return std::pair<MSVehicle* const, double>(pred, gap);
2197  }
2198  }
2199  const MSLane* nextLane = this;
2200  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
2201  do {
2202  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
2203  // get the next link used
2204  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
2205  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
2206  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
2207 #ifdef DEBUG_CONTEXT
2208  if (DEBUG_COND2(&veh)) {
2209  std::cout << " cannot continue after nextLane=" << nextLane->getID() << "\n";
2210  }
2211 #endif
2212  nextLane->releaseVehicles();
2213  break;
2214  }
2215  // check for link leaders
2216 #ifdef DEBUG_CONTEXT
2217  if (DEBUG_COND2(&veh)) {
2218  gDebugFlag1 = true;
2219  }
2220 #endif
2221  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
2222 #ifdef DEBUG_CONTEXT
2223  gDebugFlag1 = false;
2224 #endif
2225  nextLane->releaseVehicles();
2226  if (linkLeaders.size() > 0) {
2227  std::pair<MSVehicle*, double> result;
2228  double shortestGap = std::numeric_limits<double>::max();
2229  for (auto ll : linkLeaders) {
2230  double gap = ll.vehAndGap.second;
2231  MSVehicle* lVeh = ll.vehAndGap.first;
2232  if (lVeh != 0) {
2233  // leader is a vehicle, not a pedestrian
2234  gap += lVeh->getCarFollowModel().brakeGap(lVeh->getSpeed(), lVeh->getCarFollowModel().getMaxDecel(), 0);
2235  }
2236 #ifdef DEBUG_CONTEXT
2237  if (DEBUG_COND2(&veh)) {
2238  std::cout << " linkLeader candidate " << Named::getIDSecure(lVeh)
2239  << " isLeader=" << ((*link)->isLeader(&veh, lVeh))
2240  << " gap=" << ll.vehAndGap.second
2241  << " gap+brakeing=" << gap
2242  << "\n";
2243  }
2244 #endif
2245  if (lVeh != 0 && !(*link)->isLeader(&veh, lVeh, false)) {
2246  continue;
2247  }
2248  if (gap < shortestGap) {
2249  shortestGap = gap;
2250  result = ll.vehAndGap;
2251  }
2252  }
2253  if (shortestGap != std::numeric_limits<double>::max()) {
2254 #ifdef DEBUG_CONTEXT
2255  if (DEBUG_COND2(&veh)) {
2256  std::cout << " found linkLeader after nextLane=" << nextLane->getID() << "\n";
2257  }
2258 #endif
2259  return result;
2260  }
2261  }
2262  bool nextInternal = (*link)->getViaLane() != 0;
2263  nextLane = (*link)->getViaLaneOrLane();
2264  if (nextLane == 0) {
2265  break;
2266  }
2267  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
2268  MSVehicle* leader = nextLane->getLastAnyVehicle();
2269  if (leader != 0) {
2270 #ifdef DEBUG_CONTEXT
2271  if (DEBUG_COND2(&veh)) {
2272  std::cout << " found leader " << leader->getID() << " on nextLane=" << nextLane->getID() << "\n";
2273  }
2274 #endif
2275  const double dist = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
2276  nextLane->releaseVehicles();
2277  return std::make_pair(leader, dist);
2278  }
2279  nextLane->releaseVehicles();
2280  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
2281  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
2282  }
2283  seen += nextLane->getLength();
2284  if (seen <= dist) {
2285  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
2286  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
2287  }
2288  if (!nextInternal) {
2289  view++;
2290  }
2291  } while (seen <= dist || nextLane->isInternal());
2292  return std::make_pair(static_cast<MSVehicle*>(0), -1);
2293 }
2294 
2295 
2296 std::pair<MSVehicle* const, double>
2297 MSLane::getCriticalLeader(double dist, double seen, double speed, const MSVehicle& veh) const {
2298 #ifdef DEBUG_CONTEXT
2299  if (DEBUG_COND2(&veh)) {
2300  std::cout << SIMTIME << " getCriticalLeader. lane=" << getID() << " veh=" << veh.getID() << "\n";
2301  }
2302 #endif
2303  const std::vector<MSLane*>& bestLaneConts = veh.getBestLanesContinuation(this);
2304  std::pair<MSVehicle*, double> result = std::make_pair(static_cast<MSVehicle*>(0), -1);
2305  double safeSpeed = std::numeric_limits<double>::max();
2306  int view = 1;
2307  // loop over following lanes
2308  // @note: we don't check the partial occupator for this lane since it was
2309  // already checked in MSLaneChanger::getRealLeader()
2310  const MSLane* nextLane = this;
2311  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
2312  do {
2313  // get the next link used
2314  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
2315  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
2316  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
2317  return result;
2318  }
2319  // check for link leaders
2320  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
2321  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
2322  const MSVehicle* leader = (*it).vehAndGap.first;
2323  if (leader != 0 && leader != result.first) {
2324  // XXX ignoring pedestrians here!
2325  // XXX ignoring the fact that the link leader may alread by following us
2326  // XXX ignoring the fact that we may drive up to the crossing point
2327  const double tmpSpeed = veh.getSafeFollowSpeed((*it).vehAndGap, seen, nextLane, (*it).distToCrossing);
2328 #ifdef DEBUG_CONTEXT
2329  if (DEBUG_COND2(&veh)) {
2330  std::cout << " linkLeader=" << leader->getID() << " gap=" << result.second << " tmpSpeed=" << tmpSpeed << " safeSpeed=" << safeSpeed << "\n";
2331  }
2332 #endif
2333  if (tmpSpeed < safeSpeed) {
2334  safeSpeed = tmpSpeed;
2335  result = (*it).vehAndGap;
2336  }
2337  }
2338  }
2339  bool nextInternal = (*link)->getViaLane() != 0;
2340  nextLane = (*link)->getViaLaneOrLane();
2341  if (nextLane == 0) {
2342  break;
2343  }
2344  MSVehicle* leader = nextLane->getLastAnyVehicle();
2345  if (leader != 0 && leader != result.first) {
2346  const double gap = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
2347  const double tmpSpeed = veh.getCarFollowModel().insertionFollowSpeed(leader, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
2348  if (tmpSpeed < safeSpeed) {
2349  safeSpeed = tmpSpeed;
2350  result = std::make_pair(leader, gap);
2351  }
2352  }
2353  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
2354  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
2355  }
2356  seen += nextLane->getLength();
2357  if (seen <= dist) {
2358  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
2359  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
2360  }
2361  if (!nextInternal) {
2362  view++;
2363  }
2364  } while (seen <= dist || nextLane->isInternal());
2365  return result;
2366 }
2367 
2368 
2369 MSLane*
2371  if (myLogicalPredecessorLane != 0) {
2372  return myLogicalPredecessorLane;
2373  }
2374  if (myLogicalPredecessorLane == 0) {
2376  // get only those edges which connect to this lane
2377  for (MSEdgeVector::iterator i = pred.begin(); i != pred.end();) {
2378  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
2379  if (j == myIncomingLanes.end()) {
2380  i = pred.erase(i);
2381  } else {
2382  ++i;
2383  }
2384  }
2385  // get the lane with the "straightest" connection
2386  if (pred.size() != 0) {
2387  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
2388  MSEdge* best = *pred.begin();
2389  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
2390  myLogicalPredecessorLane = j->lane;
2391  }
2392  }
2393  return myLogicalPredecessorLane;
2394 }
2395 
2396 
2397 MSLane*
2399  for (std::vector<IncomingLaneInfo>::const_iterator i = myIncomingLanes.begin(); i != myIncomingLanes.end(); ++i) {
2400  MSLane* cand = (*i).lane;
2401  if (&(cand->getEdge()) == &fromEdge) {
2402  return (*i).lane;
2403  }
2404  }
2405  return 0;
2406 }
2407 
2408 MSLane*
2410  if (myCanonicalPredecessorLane != 0) {
2412  }
2413  if (myIncomingLanes.size() == 0) {
2414  return 0;
2415  }
2416  // myCanonicalPredecessorLane has not yet been determined and there exist incoming lanes
2417  std::vector<IncomingLaneInfo> candidateLanes = myIncomingLanes;
2418  // get the lane with the priorized (or if this does not apply the "straightest") connection
2419  std::sort(candidateLanes.begin(), candidateLanes.end(), incoming_lane_priority_sorter(this));
2420  IncomingLaneInfo best = *(candidateLanes.begin());
2421 #ifdef DEBUG_LANE_SORTER
2422  std::cout << "\nBest predecessor lane for lane '" << myID << "': '" << best.lane->getID() << "'" << std::endl;
2423 #endif
2424  myCanonicalPredecessorLane = best.lane;
2426 }
2427 
2428 MSLane*
2430  if (myCanonicalSuccessorLane != 0) {
2431  return myCanonicalSuccessorLane;
2432  }
2433  if (myLinks.size() == 0) {
2434  return 0;
2435  }
2436  // myCanonicalSuccessorLane has not yet been determined and there exist outgoing links
2437  std::vector<MSLink*> candidateLinks = myLinks;
2438  // get the lane with the priorized (or if this does not apply the "straightest") connection
2439  std::sort(candidateLinks.begin(), candidateLinks.end(), outgoing_lane_priority_sorter(this));
2440  MSLane* best = (*candidateLinks.begin())->getViaLaneOrLane();
2441 #ifdef DEBUG_LANE_SORTER
2442  std::cout << "\nBest successor lane for lane '" << myID << "': '" << best->getID() << "'" << std::endl;
2443 #endif
2444  myCanonicalSuccessorLane = best;
2445  return myCanonicalSuccessorLane;
2446 }
2447 
2448 
2449 LinkState
2452  if (pred == 0) {
2453  return LINKSTATE_DEADEND;
2454  } else {
2455  return MSLinkContHelper::getConnectingLink(*pred, *this)->getState();
2456  }
2457 }
2458 
2459 
2460 const std::vector<std::pair<const MSLane*, const MSEdge*> >
2462  std::vector<std::pair<const MSLane*, const MSEdge*> > result;
2463  for (const MSLink* link : myLinks) {
2464  assert(link->getLane() != nullptr);
2465  result.push_back(std::make_pair(link->getLane(), link->getViaLane() == nullptr ? nullptr : &link->getViaLane()->getEdge()));
2466  }
2467  return result;
2468 }
2469 
2470 
2471 void
2475 }
2476 
2477 
2478 void
2482 }
2483 
2484 
2485 int
2487  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
2488  if ((*i)->getLane()->getEdge().isCrossing()) {
2489  return (int)(i - myLinks.begin());
2490  }
2491  }
2492  return -1;
2493 }
2494 
2495 // ------------ Current state retrieval
2496 double
2498  double fractions = myPartialVehicles.size() > 0 ? MIN2(myLength, myLength - myPartialVehicles.front()->getBackPositionOnLane(this)) : 0;
2500  if (myVehicles.size() != 0) {
2501  MSVehicle* lastVeh = myVehicles.front();
2502  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2503  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2504  }
2505  }
2506  releaseVehicles();
2507  return MIN2(1., (myBruttoVehicleLengthSum + fractions) / myLength);
2508 }
2509 
2510 
2511 double
2513  double fractions = myPartialVehicles.size() > 0 ? MIN2(myLength, myLength - myPartialVehicles.front()->getBackPositionOnLane(this)) : 0;
2515  if (myVehicles.size() != 0) {
2516  MSVehicle* lastVeh = myVehicles.front();
2517  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2518  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2519  }
2520  }
2521  releaseVehicles();
2522  return (myNettoVehicleLengthSum + fractions) / myLength;
2523 }
2524 
2525 
2526 double
2528  if (myVehicles.size() == 0) {
2529  return 0;
2530  }
2531  double wtime = 0;
2532  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
2533  wtime += (*i)->getWaitingSeconds();
2534  }
2535  return wtime;
2536 }
2537 
2538 
2539 double
2541  if (myVehicles.size() == 0) {
2542  return myMaxSpeed;
2543  }
2544  double v = 0;
2545  const MSLane::VehCont& vehs = getVehiclesSecure();
2546  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2547  v += (*i)->getSpeed();
2548  }
2549  double ret = v / (double) myVehicles.size();
2550  releaseVehicles();
2551  return ret;
2552 }
2553 
2554 
2555 double
2557  double ret = 0;
2558  const MSLane::VehCont& vehs = getVehiclesSecure();
2559  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2560  ret += (*i)->getCO2Emissions();
2561  }
2562  releaseVehicles();
2563  return ret;
2564 }
2565 
2566 
2567 double
2569  double ret = 0;
2570  const MSLane::VehCont& vehs = getVehiclesSecure();
2571  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2572  ret += (*i)->getCOEmissions();
2573  }
2574  releaseVehicles();
2575  return ret;
2576 }
2577 
2578 
2579 double
2581  double ret = 0;
2582  const MSLane::VehCont& vehs = getVehiclesSecure();
2583  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2584  ret += (*i)->getPMxEmissions();
2585  }
2586  releaseVehicles();
2587  return ret;
2588 }
2589 
2590 
2591 double
2593  double ret = 0;
2594  const MSLane::VehCont& vehs = getVehiclesSecure();
2595  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2596  ret += (*i)->getNOxEmissions();
2597  }
2598  releaseVehicles();
2599  return ret;
2600 }
2601 
2602 
2603 double
2605  double ret = 0;
2606  const MSLane::VehCont& vehs = getVehiclesSecure();
2607  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2608  ret += (*i)->getHCEmissions();
2609  }
2610  releaseVehicles();
2611  return ret;
2612 }
2613 
2614 
2615 double
2617  double ret = 0;
2618  const MSLane::VehCont& vehs = getVehiclesSecure();
2619  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2620  ret += (*i)->getFuelConsumption();
2621  }
2622  releaseVehicles();
2623  return ret;
2624 }
2625 
2626 
2627 double
2629  double ret = 0;
2630  const MSLane::VehCont& vehs = getVehiclesSecure();
2631  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2632  ret += (*i)->getElectricityConsumption();
2633  }
2634  releaseVehicles();
2635  return ret;
2636 }
2637 
2638 
2639 double
2641  double ret = 0;
2642  const MSLane::VehCont& vehs = getVehiclesSecure();
2643  if (vehs.size() == 0) {
2644  releaseVehicles();
2645  return 0;
2646  }
2647  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2648  double sv = (*i)->getHarmonoise_NoiseEmissions();
2649  ret += (double) pow(10., (sv / 10.));
2650  }
2651  releaseVehicles();
2652  return HelpersHarmonoise::sum(ret);
2653 }
2654 
2655 
2656 bool
2657 MSLane::VehPosition::operator()(const MSVehicle* cmp, double pos) const {
2658  return cmp->getPositionOnLane() >= pos;
2659 }
2660 
2661 
2662 int
2664  return v1->getBackPositionOnLane(myLane) > v2->getBackPositionOnLane(myLane);
2665 }
2666 
2667 int
2669  const double pos1 = v1->getBackPositionOnLane(myLane);
2670  const double pos2 = v2->getBackPositionOnLane(myLane);
2671  if (pos1 != pos2) {
2672  return pos1 < pos2;
2673  } else {
2675  }
2676 }
2677 
2679  myEdge(e),
2680  myLaneDir(e->getLanes()[0]->getShape().angleAt2D(0)) {
2681 }
2682 
2683 
2684 int
2685 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
2686 // std::cout << "\nby_connections_to_sorter()";
2687 
2688  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
2689  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
2690  double s1 = 0;
2691  if (ae1 != 0 && ae1->size() != 0) {
2692 // std::cout << "\nsize 1 = " << ae1->size()
2693 // << " anglediff 1 = " << fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.
2694 // << "\nallowed lanes: ";
2695 // for (std::vector<MSLane*>::const_iterator j = ae1->begin(); j != ae1->end(); ++j){
2696 // std::cout << "\n" << (*j)->getID();
2697 // }
2698  s1 = (double) ae1->size() + fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2699  }
2700  double s2 = 0;
2701  if (ae2 != 0 && ae2->size() != 0) {
2702 // std::cout << "\nsize 2 = " << ae2->size()
2703 // << " anglediff 2 = " << fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.
2704 // << "\nallowed lanes: ";
2705 // for (std::vector<MSLane*>::const_iterator j = ae2->begin(); j != ae2->end(); ++j){
2706 // std::cout << "\n" << (*j)->getID();
2707 // }
2708  s2 = (double) ae2->size() + fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2709  }
2710 
2711 // std::cout << "\ne1 = " << e1->getID() << " e2 = " << e2->getID()
2712 // << "\ns1 = " << s1 << " s2 = " << s2
2713 // << std::endl;
2714 
2715  return s1 < s2;
2716 }
2717 
2718 
2720  myLane(targetLane),
2721  myLaneDir(targetLane->getShape().angleAt2D(0)) {}
2722 
2723 int
2725  const MSLane* noninternal1 = laneInfo1.lane;
2726  while (noninternal1->isInternal()) {
2727  assert(noninternal1->getIncomingLanes().size() == 1);
2728  noninternal1 = noninternal1->getIncomingLanes()[0].lane;
2729  }
2730  MSLane* noninternal2 = laneInfo2.lane;
2731  while (noninternal2->isInternal()) {
2732  assert(noninternal2->getIncomingLanes().size() == 1);
2733  noninternal2 = noninternal2->getIncomingLanes()[0].lane;
2734  }
2735 
2736  MSLink* link1 = noninternal1->getLinkTo(myLane);
2737  MSLink* link2 = noninternal2->getLinkTo(myLane);
2738 
2739 #ifdef DEBUG_LANE_SORTER
2740  std::cout << "\nincoming_lane_priority sorter()\n"
2741  << "noninternal predecessor for lane '" << laneInfo1.lane->getID()
2742  << "': '" << noninternal1->getID() << "'\n"
2743  << "noninternal predecessor for lane '" << laneInfo2.lane->getID()
2744  << "': '" << noninternal2->getID() << "'\n";
2745 #endif
2746 
2747  assert(laneInfo1.lane->isInternal() || link1 == laneInfo1.viaLink);
2748  assert(link1 != 0);
2749  assert(link2 != 0);
2750 
2751  // check priority between links
2752  bool priorized1 = true;
2753  bool priorized2 = true;
2754 
2755  std::vector<MSLink*>::const_iterator j;
2756 #ifdef DEBUG_LANE_SORTER
2757  std::cout << "FoeLinks of '" << noninternal1->getID() << "'" << std::endl;
2758 #endif
2759  for (j = link1->getFoeLinks().begin(); j != link1->getFoeLinks().end(); ++j) {
2760 #ifdef DEBUG_LANE_SORTER
2761  std::cout << (*j)->getLaneBefore()->getID() << std::endl;
2762 #endif
2763  if (*j == link2) {
2764  priorized1 = false;
2765  break;
2766  }
2767  }
2768 
2769 #ifdef DEBUG_LANE_SORTER
2770  std::cout << "FoeLinks of '" << noninternal2->getID() << "'" << std::endl;
2771 #endif
2772  for (j = link2->getFoeLinks().begin(); j != link2->getFoeLinks().end(); ++j) {
2773 #ifdef DEBUG_LANE_SORTER
2774  std::cout << (*j)->getLaneBefore()->getID() << std::endl;
2775 #endif
2776  // either link1 is priorized, or it should not appear in link2's foes
2777  if (*j == link2) {
2778  priorized2 = false;
2779  break;
2780  }
2781  }
2782  // if one link is subordinate, the other must be priorized
2783  assert(priorized1 || priorized2);
2784  if (priorized1 != priorized2) {
2785  return priorized1;
2786  }
2787 
2788  // both are priorized, compare angle difference
2789  double d1 = fabs(GeomHelper::angleDiff(noninternal1->getShape().angleAt2D(0), myLaneDir));
2790  double d2 = fabs(GeomHelper::angleDiff(noninternal2->getShape().angleAt2D(0), myLaneDir));
2791 
2792  return d2 > d1;
2793 }
2794 
2795 
2796 
2798  myLane(sourceLane),
2799  myLaneDir(sourceLane->getShape().angleAt2D(0)) {}
2800 
2801 int
2803  const MSLane* target1 = link1->getLane();
2804  const MSLane* target2 = link2->getLane();
2805  if (target2 == 0) {
2806  return true;
2807  }
2808  if (target1 == 0) {
2809  return false;
2810  }
2811 
2812 #ifdef DEBUG_LANE_SORTER
2813  std::cout << "\noutgoing_lane_priority sorter()\n"
2814  << "noninternal successors for lane '" << myLane->getID()
2815  << "': '" << target1->getID() << "' and "
2816  << "'" << target2->getID() << "'\n";
2817 #endif
2818 
2819  // priority of targets
2820  int priority1 = target1->getEdge().getPriority();
2821  int priority2 = target2->getEdge().getPriority();
2822 
2823  if (priority1 != priority2) {
2824  return priority1 > priority2;
2825  }
2826 
2827  // if priority of targets coincides, use angle difference
2828 
2829  // both are priorized, compare angle difference
2830  double d1 = fabs(GeomHelper::angleDiff(target1->getShape().angleAt2D(0), myLaneDir));
2831  double d2 = fabs(GeomHelper::angleDiff(target2->getShape().angleAt2D(0), myLaneDir));
2832 
2833  return d2 > d1;
2834 }
2835 
2836 void
2838  myParkingVehicles.insert(veh);
2839 }
2840 
2841 
2842 void
2844  myParkingVehicles.erase(veh);
2845 }
2846 
2847 void
2849  out.openTag(SUMO_TAG_LANE);
2850  out.writeAttr("id", getID()); // using "id" instead of SUMO_ATTR_ID makes the value only show up in xml state
2853  out.closeTag();
2854  out.closeTag();
2855 }
2856 
2857 
2858 void
2859 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
2860  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
2861  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
2862  // vehicle could be removed due to options
2863  if (v != 0) {
2864  v->updateBestLanes(false, this);
2867  v->processNextStop(v->getSpeed());
2868  }
2869  }
2870 }
2871 
2872 
2873 double
2875  if (myStopOffsets.size() == 0) {
2876  return 0.;
2877  }
2878  if ((myStopOffsets.begin()->first & veh->getVClass()) != 0) {
2879  return myStopOffsets.begin()->second;
2880  } else {
2881  return 0.;
2882  }
2883 }
2884 
2885 
2886 
2888 MSLane::getFollowersOnConsecutive(const MSVehicle* ego, double backOffset,
2889  bool allSublanes, double searchDist, bool ignoreMinorLinks) const {
2890  // get the follower vehicle on the lane to change to
2891  const double egoPos = backOffset + ego->getVehicleType().getLength();
2892 #ifdef DEBUG_CONTEXT
2893  if (DEBUG_COND2(ego)) {
2894  std::cout << SIMTIME << " getFollowers lane=" << getID() << " ego=" << ego->getID() << " pos=" << egoPos << "\n";
2895  }
2896 #endif
2897  assert(ego != 0);
2898  const double egoLatDist = ego->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2899  MSCriticalFollowerDistanceInfo result(this, allSublanes ? 0 : ego, allSublanes ? 0 : egoLatDist);
2901  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
2902  const MSVehicle* veh = *last;
2903 #ifdef DEBUG_CONTEXT
2904  if (DEBUG_COND2(ego)) {
2905  std::cout << " veh=" << veh->getID() << " lane=" << veh->getLane()->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
2906  }
2907 #endif
2908  if (veh != ego && veh->getPositionOnLane(this) < egoPos) {
2909  //const double latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2910  const double latOffset = veh->getLatOffset(this);
2911  const double dist = backOffset - veh->getPositionOnLane(this) - veh->getVehicleType().getMinGap();
2912  result.addFollower(veh, ego, dist, latOffset);
2913 #ifdef DEBUG_CONTEXT
2914  if (DEBUG_COND2(ego)) {
2915  std::cout << " (1) added veh=" << veh->getID() << " latOffset=" << latOffset << " result=" << result.toString() << "\n";
2916  }
2917 #endif
2918  }
2919  }
2920 #ifdef DEBUG_CONTEXT
2921  if (DEBUG_COND2(ego)) {
2922  std::cout << " result.numFreeSublanes=" << result.numFreeSublanes() << "\n";
2923  }
2924 #endif
2925  if (result.numFreeSublanes() > 0) {
2926  // do a tree search among all follower lanes and check for the most
2927  // important vehicle (the one requiring the largest reargap)
2928  // to get a safe bound on the necessary search depth, we need to consider the maximum speed and minimum
2929  // deceleration of potential follower vehicles
2930  if (searchDist == -1) {
2931  searchDist = getMaximumBrakeDist() - backOffset;
2932  }
2933 
2934  std::set<MSLane*> visited;
2935  std::vector<MSLane::IncomingLaneInfo> newFound;
2936  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
2937  while (toExamine.size() != 0) {
2938  for (std::vector<MSLane::IncomingLaneInfo>::iterator it = toExamine.begin(); it != toExamine.end(); ++it) {
2939  MSLane* next = (*it).lane;
2940  searchDist = MAX2(searchDist, next->getMaximumBrakeDist() - backOffset);
2941  MSLeaderInfo first = next->getFirstVehicleInformation(0, 0, false, std::numeric_limits<double>::max(), false);
2942  MSLeaderInfo firstFront = next->getFirstVehicleInformation(0, 0, true);
2943 #ifdef DEBUG_CONTEXT
2944  if (DEBUG_COND2(ego)) {
2945  std::cout << " next=" << next->getID() << " first=" << first.toString() << " firstFront=" << firstFront.toString() << "\n";
2946  }
2947 #endif
2948  for (int i = 0; i < first.numSublanes(); ++i) {
2949  const MSVehicle* v = first[i];
2950  double agap = 0;
2951  if (v != 0 && v != ego) {
2952  if (!v->isFrontOnLane(next)) {
2953  // the front of v is already on divergent trajectory from the ego vehicle
2954  // for which this method is called (in the context of MSLaneChanger).
2955  // Therefore, technically v is not a follower but only an obstruction and
2956  // the gap is not between the front of v and the back of ego
2957  // but rather between the flank of v and the back of ego.
2958  agap = (*it).length - next->getLength() + backOffset
2960  - v->getVehicleType().getMinGap();
2961  if (agap > 0) {
2962  // Only if ego overlaps we treat v as if it were a real follower
2963  // Otherwise we ignore it and look for another follower
2964  v = firstFront[i];
2965  if (v != 0 && v != ego) {
2966  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2967  } else {
2968  v = 0;
2969  }
2970  }
2971  } else {
2972  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2973  if (!(*it).viaLink->havePriority() && !ego->onFurtherEdge(&(*it).lane->getEdge())
2974  && ego->isOnRoad() // during insertion, this can lead to collisions because ego's further lanes are not set (see #3053)
2975  ) {
2976  // if v comes from a minor side road it should not block lane changing
2977  agap = MAX2(agap, 0.0);
2978  }
2979  }
2980  result.addFollower(v, ego, agap, 0, i);
2981 #ifdef DEBUG_CONTEXT
2982  if (DEBUG_COND2(ego)) {
2983  std::cout << " (2) added veh=" << Named::getIDSecure(v) << " agap=" << agap << " next=" << next->getID() << " result=" << result.toString() << "\n";
2984  }
2985 #endif
2986  }
2987  }
2988  if ((*it).length < searchDist) {
2989  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
2990  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
2991  if (visited.find((*j).lane) == visited.end() && ((*j).viaLink->havePriority() || !ignoreMinorLinks)) {
2992  visited.insert((*j).lane);
2994  ili.lane = (*j).lane;
2995  ili.length = (*j).length + (*it).length;
2996  ili.viaLink = (*j).viaLink;
2997  newFound.push_back(ili);
2998  }
2999  }
3000  }
3001  }
3002  toExamine.clear();
3003  swap(newFound, toExamine);
3004  }
3005  //return result;
3006 
3007  }
3008  return result;
3009 }
3010 
3011 
3012 void
3013 MSLane::getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle* ego,
3014  const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result) const {
3015  if (seen > dist) {
3016  return;
3017  }
3018  // check partial vehicles (they might be on a different route and thus not
3019  // found when iterating along bestLaneConts)
3020  for (VehCont::const_iterator it = myPartialVehicles.begin(); it != myPartialVehicles.end(); ++it) {
3021  MSVehicle* veh = *it;
3022  if (!veh->isFrontOnLane(this)) {
3023  result.addLeader(veh, seen, veh->getLatOffset(this));
3024  } else {
3025  break;
3026  }
3027  }
3028  const MSLane* nextLane = this;
3029  int view = 1;
3030  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
3031  // loop over following lanes
3032  while (seen < dist && result.numFreeSublanes() > 0) {
3033  // get the next link used
3034  MSLinkCont::const_iterator link = succLinkSec(*ego, view, *nextLane, bestLaneConts);
3035  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, ego->getVehicleType().getLength(),
3036  ego->getImpatience(), ego->getCarFollowModel().getMaxDecel(), 0, ego->getLateralPositionOnLane()) || (*link)->haveRed()) {
3037  break;
3038  }
3039  // check for link leaders
3040  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(ego, seen);
3041  if (linkLeaders.size() > 0) {
3042  const MSLink::LinkLeader ll = linkLeaders[0];
3043  if (ll.vehAndGap.first != 0 && (*link)->isLeader(ego, ll.vehAndGap.first)) {
3044  // add link leader to all sublanes and return
3045  for (int i = 0; i < result.numSublanes(); ++i) {
3046  MSVehicle* veh = ll.vehAndGap.first;
3047 #ifdef DEBUG_CONTEXT
3048  if (DEBUG_COND2(ego)) {
3049  std::cout << " linkleader=" << veh->getID() << " gap=" << ll.vehAndGap.second << "\n";
3050  }
3051 #endif
3052  result.addLeader(veh, ll.vehAndGap.second, 0);
3053  }
3054  return; ;
3055  } // XXX else, deal with pedestrians
3056  }
3057  bool nextInternal = (*link)->getViaLane() != 0;
3058  nextLane = (*link)->getViaLaneOrLane();
3059  if (nextLane == 0) {
3060  break;
3061  }
3062 
3063  MSLeaderInfo leaders = nextLane->getLastVehicleInformation(0, 0, 0, false);
3064 #ifdef DEBUG_CONTEXT
3065  if (DEBUG_COND2(ego)) {
3066  std::cout << SIMTIME << " getLeadersOnConsecutive lane=" << getID() << " nextLane=" << nextLane->getID() << " leaders=" << leaders.toString() << "\n";
3067  }
3068 #endif
3069  // @todo check alignment issues if the lane width changes
3070  const int iMax = MIN2(leaders.numSublanes(), result.numSublanes());
3071  for (int i = 0; i < iMax; ++i) {
3072  const MSVehicle* veh = leaders[i];
3073  if (veh != 0) {
3074 #ifdef DEBUG_CONTEXT
3075  if (DEBUG_COND2(ego)) std::cout << " lead=" << veh->getID()
3076  << " seen=" << seen
3077  << " minGap=" << ego->getVehicleType().getMinGap()
3078  << " backPos=" << veh->getBackPositionOnLane(nextLane)
3079  << " gap=" << seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane)
3080  << "\n";
3081 #endif
3082  result.addLeader(veh, seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane), 0, i);
3083  }
3084  }
3085 
3086  if (nextLane->getVehicleMaxSpeed(ego) < speed) {
3087  dist = ego->getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(ego));
3088  }
3089  seen += nextLane->getLength();
3090  if (seen <= dist) {
3091  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
3092  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
3093  }
3094  if (!nextInternal) {
3095  view++;
3096  }
3097  }
3098 }
3099 
3100 
3101 
3102 MSVehicle*
3104  for (VehCont::const_reverse_iterator i = myPartialVehicles.rbegin(); i != myPartialVehicles.rend(); ++i) {
3105  MSVehicle* veh = *i;
3106  if (veh->isFrontOnLane(this)
3107  && veh != ego
3108  && veh->getPositionOnLane() <= ego->getPositionOnLane()) {
3109 #ifdef DEBUG_CONTEXT
3110  if (DEBUG_COND2(ego)) {
3111  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " found=" << veh->getID() << "\n";
3112  }
3113 #endif
3114  return veh;
3115  }
3116  }
3117 #ifdef DEBUG_CONTEXT
3118  if (DEBUG_COND2(ego)) {
3119  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " nothing found. partials=" << toString(myPartialVehicles) << "\n";
3120  }
3121 #endif
3122  return 0;
3123 }
3124 
3127  MSLeaderInfo result(this);
3128  for (VehCont::const_iterator it = myPartialVehicles.begin(); it != myPartialVehicles.end(); ++it) {
3129  MSVehicle* veh = *it;
3130  if (!veh->isFrontOnLane(this)) {
3131  result.addLeader(veh, false, veh->getLatOffset(this));
3132  } else {
3133  break;
3134  }
3135  }
3136  return result;
3137 }
3138 
3139 
3140 MSLane*
3142  if (myNeighs.size() == 1) {
3143  return dictionary(myNeighs[0]);
3144  }
3145  return 0;
3146 }
3147 
3148 
3149 double
3150 MSLane::getOppositePos(double pos) const {
3151  MSLane* opposite = getOpposite();
3152  if (opposite == 0) {
3153  assert(false);
3154  throw ProcessError("Lane '" + getID() + "' cannot compute oppositePos as there is no opposite lane.");
3155  }
3156  // XXX transformations for curved geometries
3157  return MAX2(0., opposite->getLength() - pos);
3158 
3159 }
3160 
3161 std::pair<MSVehicle* const, double>
3162 MSLane::getFollower(const MSVehicle* ego, double egoPos, double dist, bool ignoreMinorLinks) const {
3163  for (AnyVehicleIterator first = anyVehiclesUpstreamBegin(); first != anyVehiclesUpstreamEnd(); ++first) {
3164  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
3165  MSVehicle* pred = (MSVehicle*)*first;
3166 #ifdef DEBUG_CONTEXT
3167  if (DEBUG_COND2(ego)) {
3168  std::cout << " getFollower lane=" << getID() << " egoPos=" << egoPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << "\n";
3169  }
3170 #endif
3171  if (pred->getPositionOnLane(this) < egoPos && pred != ego) {
3172  return std::pair<MSVehicle* const, double>(pred, egoPos - pred->getPositionOnLane(this) - ego->getVehicleType().getLength() - pred->getVehicleType().getMinGap());
3173  }
3174  }
3175  const double backOffset = egoPos - ego->getVehicleType().getLength();
3176  CLeaderDist result = getFollowersOnConsecutive(ego, backOffset, true, dist, ignoreMinorLinks)[0];
3177  return std::make_pair(const_cast<MSVehicle*>(result.first), result.second);
3178 }
3179 
3180 std::pair<MSVehicle* const, double>
3181 MSLane::getOppositeLeader(const MSVehicle* ego, double dist, bool oppositeDir) const {
3182 #ifdef DEBUG_OPPOSITE
3183  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeLeader lane=" << getID()
3184  << " ego=" << ego->getID()
3185  << " pos=" << ego->getPositionOnLane()
3186  << " posOnOpposite=" << getOppositePos(ego->getPositionOnLane())
3187  << " dist=" << dist
3188  << " oppositeDir=" << oppositeDir
3189  << "\n";
3190 #endif
3191  if (!oppositeDir) {
3192  return getLeader(ego, getOppositePos(ego->getPositionOnLane()), ego->getBestLanesContinuation(this));
3193  } else {
3194  const double egoLength = ego->getVehicleType().getLength();
3195  const double egoPos = ego->getLaneChangeModel().isOpposite() ? ego->getPositionOnLane() : getOppositePos(ego->getPositionOnLane());
3196  std::pair<MSVehicle* const, double> result = getFollower(ego, egoPos + egoLength, dist, true);
3197  result.second -= ego->getVehicleType().getMinGap();
3198  return result;
3199  }
3200 }
3201 
3202 
3203 std::pair<MSVehicle* const, double>
3205 #ifdef DEBUG_OPPOSITE
3206  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeFollower lane=" << getID()
3207  << " ego=" << ego->getID()
3208  << " backPos=" << ego->getBackPositionOnLane()
3209  << " posOnOpposite=" << getOppositePos(ego->getBackPositionOnLane())
3210  << "\n";
3211 #endif
3212  if (ego->getLaneChangeModel().isOpposite()) {
3213  std::pair<MSVehicle* const, double> result = getFollower(ego, getOppositePos(ego->getPositionOnLane()), -1, true);
3214  return result;
3215  } else {
3216  std::pair<MSVehicle* const, double> result = getLeader(ego, getOppositePos(ego->getPositionOnLane() - ego->getVehicleType().getLength()), std::vector<MSLane*>());
3217  if (result.second > 0) {
3218  // follower can be safely ignored since it is going the other way
3219  return std::make_pair(static_cast<MSVehicle*>(0), -1);
3220  } else {
3221  return result;
3222  }
3223  }
3224 }
3225 
3226 
3227 void
3229  const std::string action = oc.getString("collision.action");
3230  if (action == "none") {
3232  } else if (action == "warn") {
3234  } else if (action == "teleport") {
3236  } else if (action == "remove") {
3238  } else {
3239  WRITE_ERROR("Invalid collision.action '" + action + "'.");
3240  }
3241  myCheckJunctionCollisions = oc.getBool("collision.check-junctions");
3242  myCollisionStopTime = string2time(oc.getString("collision.stoptime"));
3243  myCollisionMinGapFactor = oc.getFloat("collision.mingap-factor");
3244 }
3245 
3246 
3247 void
3248 MSLane::setPermissions(SVCPermissions permissions, long long transientID) {
3249  if (transientID == CHANGE_PERMISSIONS_PERMANENT) {
3250  myPermissions = permissions;
3251  myOriginalPermissions = permissions;
3252  } else {
3253  myPermissionChanges[transientID] = permissions;
3255  }
3256 }
3257 
3258 
3259 void
3260 MSLane::resetPermissions(long long transientID) {
3261  myPermissionChanges.erase(transientID);
3262  if (myPermissionChanges.empty()) {
3264  } else {
3265  // combine all permission changes
3267  for (const auto& item : myPermissionChanges) {
3268  myPermissions &= item.second;
3269  }
3270  }
3271 }
3272 
3273 
3274 bool
3275 MSLane::checkForPedestrians(const MSVehicle* aVehicle, double& speed, double& dist, double pos, bool patchSpeed) const {
3276  if (getEdge().getPersons().size() > 0 && MSPModel::getModel()->hasPedestrians(this)) {
3277 #ifdef DEBUG_INSERTION
3278  if (DEBUG_COND2(aVehicle)) {
3279  std::cout << SIMTIME << " check for pedestrians on lane=" << getID() << " pos=" << pos << "\n";
3280  }
3281 #endif
3282  PersonDist leader = MSPModel::getModel()->nextBlocking(this, pos - aVehicle->getVehicleType().getLength(),
3283  aVehicle->getRightSideOnLane(), aVehicle->getRightSideOnLane() + aVehicle->getVehicleType().getWidth(), ceil(speed / aVehicle->getCarFollowModel().getMaxDecel()));
3284  if (leader.first != 0) {
3285  const double gap = leader.second - aVehicle->getVehicleType().getLengthWithGap();
3286  const double stopSpeed = aVehicle->getCarFollowModel().stopSpeed(aVehicle, speed, gap);
3287  if (gap < 0 || checkFailure(aVehicle, speed, dist, stopSpeed, patchSpeed, "")) {
3288  // we may not drive with the given velocity - we crash into the pedestrian
3289 #ifdef DEBUG_INSERTION
3290  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
3291  << " isInsertionSuccess lane=" << getID()
3292  << " veh=" << aVehicle->getID()
3293  << " pos=" << pos
3294  << " posLat=" << aVehicle->getLateralPositionOnLane()
3295  << " patchSpeed=" << patchSpeed
3296  << " speed=" << speed
3297  << " stopSpeed=" << stopSpeed
3298  << " pedestrianLeader=" << leader.first->getID()
3299  << " failed (@796)!\n";
3300 #endif
3301  return false;
3302  }
3303  }
3304  }
3305  return true;
3306 }
3307 
3308 /****************************************************************************/
3309 
void detectPedestrianJunctionCollision(const MSVehicle *collider, const PositionVector &colliderBoundary, const MSLane *foeLane, SUMOTime timestep, const std::string &stage)
detect whether a vehicle collids with pedestrians on the junction
Definition: MSLane.cpp:1346
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:762
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
std::pair< MSVehicle *const, double > getFollower(const MSVehicle *ego, double egoPos, double dist, bool ignoreMinorLinks) const
Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane) ...
Definition: MSLane.cpp:3162
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2497
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:2859
static double gLateralResolution
Definition: MSGlobals.h:85
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1227
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2370
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:131
VehCont myVehicles
The lane&#39;s vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1174
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:485
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time tau (i...
Definition: MSCFModel.h:307
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:129
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:262
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:125
double getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:2592
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:617
A free lateral position is chosen.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
The position is given.
long long int SUMOTime
Definition: SUMOTime.h:36
MSVehicle * getFirstFullVehicle() const
returns the first vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1854
At the leftmost side of the lane.
virtual int addLeader(const MSVehicle *veh, bool beyond, double latOffset=0)
MSLane(const std::string &id, double maxSpeed, double length, MSEdge *const edge, int numericalID, const PositionVector &shape, double width, SVCPermissions permissions, int index, bool isRampAccel)
Constructor.
Definition: MSLane.cpp:167
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:273
double getAngle() const
Returns the vehicle&#39;s direction in radians.
Definition: MSVehicle.h:681
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to, const std::string &info="")
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:827
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:4889
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2663
void sortManeuverReservations()
sorts myManeuverReservations
Definition: MSLane.cpp:1805
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:625
const MSEdge * getNextNormal() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1668
std::string containerstop
(Optional) container stop if one is assigned to the stop
static void insertIDs(std::vector< std::string > &into)
Adds the ids of all stored lanes into the given vector.
Definition: MSLane.cpp:1728
void enterLaneAtInsertion(MSLane *enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:3917
void updateLeaderInfo(const MSVehicle *veh, VehCont::reverse_iterator &vehPart, VehCont::reverse_iterator &vehRes, MSLeaderInfo &ahead) const
This updates the MSLeaderInfo argument with respect to the given MSVehicle. All leader-vehicles on th...
Definition: MSLane.cpp:1131
Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn&#39;t apply, wrt. the angle differenc...
Definition: MSLane.h:1376
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:275
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
Definition: MSPModel.h:85
virtual void removeParking(MSVehicle *veh)
remove parking vehicle. This must be syncrhonized when running with GUI
Definition: MSLane.cpp:2843
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:3181
#define LANE_RTREE_QUAL
Definition: Helper.h:74
bool parking
whether the vehicle is removed from the net while stopping
double getMaxSpeedFactor() const
return the maximum speed factor for all vehicles that ever entered the network
begin/end of the description of a single lane
bool hasDeparted() const
Returns whether this vehicle has already departed.
bool checkFailure(const MSVehicle *aVehicle, double &speed, double &dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:561
Stop & getNextStop()
Definition: MSVehicle.cpp:5186
int myI2
index for myPartialVehicles
Definition: MSLane.h:151
bool resumeFromStopping()
Definition: MSVehicle.cpp:5135
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:561
double getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:2616
SUMOTime duration
The stopping duration.
The speed is given.
bool isInsertionSuccess(MSVehicle *vehicle, double speed, double pos, double posLat, bool recheckNextLanes, MSMoveReminder::Notification notification)
Tries to insert the given vehicle with the given state (speed and pos)
Definition: MSLane.cpp:590
void registerTeleportYield()
register one non-collision-related teleport
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:1736
double getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:2098
The vehicle arrived at a junction.
void setMaxSpeed(double val)
Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
Definition: MSLane.cpp:1985
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSVehicle.h:931
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:122
This is an uncontrolled, minor link, has to stop.
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:337
static bool haveLateralDynamics()
whether any kind of lateral dynamics is active
std::vector< IncomingLaneInfo > myIncomingLanes
All direct predecessor lanes.
Definition: MSLane.h:1236
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:57
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
int myI2End
end index for myPartialVehicles
Definition: MSLane.h:157
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:399
void addLink(MSLink *link)
Delayed initialization.
Definition: MSLane.cpp:208
MSLane * myCanonicalPredecessorLane
Similar to LogicalPredecessorLane,.
Definition: MSLane.h:1242
int myIndex
The lane index.
Definition: MSLane.h:1161
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:61
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:1770
The lateral position is chosen randomly.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
static double myCollisionMinGapFactor
Definition: MSLane.h:1303
SUMOTime myLeaderInfoTime
time step for which myLeaderInfo was last updated
Definition: MSLane.h:1268
If a fixed number of random choices fails, a free lateral position is chosen.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
bool operator()(const MSVehicle *cmp, double pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:2657
AnyVehicleIterator is a structure, which manages the iteration through all vehicles on the lane...
Definition: MSLane.h:100
static SUMOTime myCollisionStopTime
Definition: MSLane.h:1302
Notification
Definition of a vehicle state.
virtual void resetManeuverReservation(MSVehicle *v)
Unregisters a vehicle, which previously registered for maneuvering into this lane.
Definition: MSLane.cpp:274
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:67
A RT-tree for efficient storing of SUMO&#39;s Named objects.
Definition: NamedRTree.h:65
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2010
double myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:1248
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1877
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:290
const MSEdge *const myEdge
Definition: MSLane.h:1366
std::map< long long, SVCPermissions > myPermissionChanges
Definition: MSLane.h:1287
This is a dead end link.
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:2034
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:160
T MAX2(T a, T b)
Definition: StdDefs.h:68
double getPMxEmissions() const
Returns the sum of last step PMx emissions.
Definition: MSLane.cpp:2580
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:2678
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:507
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:399
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:449
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:62
The speed is chosen randomly.
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:4876
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1824
static void initCollisionOptions(const OptionsCont &oc)
Definition: MSLane.cpp:3228
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:221
const MSRoute & getRoute() const
Returns the current route.
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1947
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2472
SUMOTime until
The time at which the vehicle may continue its journey.
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false, MSRouteIterator *searchStart=0)
Adds a stop.
Definition: MSVehicle.cpp:1144
double getRightSideOnLane() const
Get the vehicle&#39;s lateral position on the lane:
Definition: MSVehicle.cpp:4642
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:85
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2409
This is an uncontrolled, right-before-left link.
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:3131
double getSafeFollowSpeed(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, const MSLane *const lane, double distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:2440
void addNeigh(const std::string &id)
Adds a neighbor to this lane.
Definition: MSLane.cpp:214
#define RAD2DEG(x)
Definition: GeomHelper.h:39
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
const std::string & getID() const
Returns the id.
Definition: Named.h:69
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
const SVCPermissions SVCAll
all VClasses are allowed
void gotActive(MSLane *l)
Informs the control that the given lane got active.
virtual double insertionStopSpeed(const MSVehicle *const veh, double speed, double gap) const
Computes the vehicle&#39;s safe speed for approaching an obstacle at insertion without constraints due to...
Definition: MSCFModel.cpp:284
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:231
VehCont myPartialVehicles
The lane&#39;s partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition: MSLane.h:1186
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:872
The position is chosen randomly.
static bool myCheckJunctionCollisions
Definition: MSLane.h:1301
This is an uncontrolled, all-way stop link.
virtual void setManeuverReservation(MSVehicle *v)
Registers the lane change intentions (towards this lane) for the given vehicle.
Definition: MSLane.cpp:263
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:523
int myI1End
end index for myVehicles
Definition: MSLane.h:155
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:754
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
virtual double insertionFollowSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle&#39;s safe speed (no dawdling) This method is used during the insertion stage...
Definition: MSCFModel.cpp:273
int myDirection
index delta
Definition: MSLane.h:163
std::string parkingarea
(Optional) parking area if one is assigned to the stop
PositionVector myShape
The shape of the lane.
Definition: MSLane.h:1158
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:242
int myI3
index for myTmpVehicles
Definition: MSLane.h:153
The speed is given.
MSLane * getCanonicalSuccessorLane() const
Definition: MSLane.cpp:2429
std::set< const MSVehicle * > myParkingVehicles
Definition: MSLane.h:1207
void getLeadersOnConsecutive(double dist, double seen, double speed, const MSVehicle *ego, const std::vector< MSLane *> &bestLaneConts, MSLeaderDistanceInfo &result) const
Returns the immediate leaders and the distance to them (as getLeaderOnConsecutive but for the sublane...
Definition: MSLane.cpp:3013
bool myDownstream
iteration direction
Definition: MSLane.h:161
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4027
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:365
#define SIMTIME
Definition: SUMOTime.h:65
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:3527
int getLaneIndex() const
Definition: MSVehicle.cpp:4625
std::vector< std::string > myNeighs
Definition: MSLane.h:1284
static CollisionAction myCollisionAction
the action to take on collisions
Definition: MSLane.h:1300
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:267
std::map< std::string, MSLane *> DictType
definition of the static dictionary type
Definition: MSLane.h:1290
static CollisionAction getCollisionAction()
Definition: MSLane.h:1090
MSLinkCont myLinks
Definition: MSLane.h:1255
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:1181
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSLane.h:1293
Sorts lanes (their origin link) by the priority of their noninternal target edges or...
Definition: MSLane.h:1396
bool isInternal() const
Definition: MSLane.cpp:1840
std::string busstop
(Optional) bus stop if one is assigned to the stop
#define SUMOTime_MIN
Definition: SUMOTime.h:38
void addApproachingLane(MSLane *lane, bool warnMultiCon)
Definition: MSLane.cpp:2044
double departSpeed
(optional) The initial speed of the vehicle
virtual const MSEdge * succEdge(int nSuccs) const =0
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
A road/street connecting two junctions.
Definition: MSEdge.h:75
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:3977
virtual int addLeader(const MSVehicle *veh, double gap, double latOffset=0, int sublane=-1)
double getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:4686
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:486
No information given; use default.
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:887
double myLength
Lane length [m].
Definition: MSLane.h:1210
void resetPermissions(long long transientID)
Definition: MSLane.cpp:3260
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
VehCont myTmpVehicles
Container for lane-changing vehicles. After completion of lane-change- process, the containers will b...
Definition: MSLane.h:1190
void setPermissions(SVCPermissions permissions, long long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition: MSLane.cpp:3248
int operator()(const IncomingLaneInfo &lane1, const IncomingLaneInfo &lane2) const
comparing operator
Definition: MSLane.cpp:2724
MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else 0.
Definition: MSLane.cpp:1968
const MSVehicle * operator*()
Definition: MSLane.cpp:115
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:2486
The vehicle is involved in a collision.
Definition: MSNet.h:509
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:244
double getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:2556
const bool myIsRampAccel
whether this lane is an acceleration lane
Definition: MSLane.h:1276
Representation of a vehicle.
Definition: SUMOVehicle.h:60
static bool gCheckRoutes
Definition: MSGlobals.h:79
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
int operator()(const std::pair< const MSVehicle *, double > &p1, const std::pair< const MSVehicle *, double > &p2) const
Definition: MSLane.cpp:2076
void setLength(double val)
Sets a new length for the lane (used by TraCI only)
Definition: MSLane.cpp:1992
static MSPModel * getModel()
Definition: MSPModel.cpp:59
This is an uncontrolled, minor link, has to brake.
Sorts vehicles by their position (descending)
Definition: MSLane.h:1309
double myRightSideOnEdge
the combined width of all lanes with lower index on myEdge
Definition: MSLane.h:1279
std::string chargingStation
(Optional) charging station if one is assigned to the stop
bool lastInsertion(MSVehicle &veh, double mspeed, double posLat, bool patchSpeed)
inserts vehicle as close as possible to the last vehicle on this lane (or at the end of the lane if t...
Definition: MSLane.cpp:312
SVCPermissions myOriginalPermissions
The original vClass permissions for this lane (before temporary modifications)
Definition: MSLane.h:1230
outgoing_lane_priority_sorter(const MSLane *sourceLane)
constructor
Definition: MSLane.cpp:2797
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:4045
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2479
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:4379
double getEmergencyDecel() const
Get the vehicle type&#39;s maximal phisically possible deceleration [m/s^2].
Definition: MSCFModel.h:226
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, double latOffset, double minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:986
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:309
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:171
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:4654
double getMinDeceleration() const
return the minimum deceleration capability for all vehicles that ever entered the network ...
const std::map< SUMOVehicleClass, double > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:1233
bool isEmpty() const
Definition: MSLane.cpp:1835
bool triggered
whether an arriving person lets the vehicle continue
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
Definition: MSLane.cpp:3204
bool checkForPedestrians(const MSVehicle *aVehicle, double &speed, double &dist, double pos, bool patchSpeed) const
check whether pedestrians on this lane interfere with vehicle insertion
Definition: MSLane.cpp:3275
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:58
The vehicle arrived at its destination (is deleted)
double safeInsertionSpeed(const MSVehicle *veh, double seen, const MSLeaderInfo &leaders, double speed)
return the maximum safe speed for insertion behind leaders (a negative value indicates that safe inse...
Definition: MSLane.cpp:957
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:499
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:298
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:990
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
int operator()(const MSLink *link1, const MSLink *link2) const
comparing operator
Definition: MSLane.cpp:2802
Sorts edges by their angle relative to the given edge (straight comes first)
Definition: MSLane.h:1355
The maximum speed is used.
std::string toString() const
print a debugging representation
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:948
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:256
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
T MIN2(T a, T b)
Definition: StdDefs.h:62
MSVehicle * getPartialBehind(const MSVehicle *ego) const
Definition: MSLane.cpp:3103
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:119
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:411
void add(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:405
#define POSITION_EPS
Definition: config.h:172
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:2450
double getImpatience() const
Returns this vehicles impatience.
No information given; use default.
virtual bool executeMovements(SUMOTime t, std::vector< MSLane *> &lanesWithVehiclesToIntegrate)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:1560
std::pair< MSVehicle *const, double > getLeader(const MSVehicle *veh, const double vehPos, const std::vector< MSLane *> &bestLaneConts, double dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:2108
CollisionAction
Definition: MSLane.h:172
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:740
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0 ...
Definition: MSPModel.h:91
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:301
bool hasInfluencer() const
Definition: MSVehicle.h:1572
int myRightmostSublane
the index of the rightmost sublane of this lane on myEdge
Definition: MSLane.h:1281
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:1239
double endPos
The stopping position end.
double getMinGap() const
Get the free space in front of vehicles of this class.
SUMOTime collisionStopTime() const
Returns the remaining time a vehicle needs to stop due to a collision. A negative value indicates tha...
Definition: MSVehicle.cpp:1422
Something on a lane to be noticed about vehicle movement.
const std::vector< std::pair< const MSLane *, const MSEdge * > > getOutgoingViaLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2461
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:218
double basePos(const MSEdge *edge) const
departure position where the vehicle fits fully onto the edge (if possible)
Definition: MSVehicle.cpp:1678
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3141
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:417
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1999
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:224
void registerTeleportJam()
register one non-collision-related teleport
double getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:2604
If a fixed number of random choices fails, a free position is chosen.
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of...
Definition: MSLane.h:1258
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:83
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:921
bool containerTriggered
whether an arriving container lets the vehicle continue
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane *> &conts)
Definition: MSLane.cpp:1891
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:2685
Base class for objects which have an id.
Definition: Named.h:49
std::map< SVCPermissions, double > myStopOffsets
Definition: MSLane.h:1218
int myNumericalID
Unique numerical ID (set on reading by netload)
Definition: MSLane.h:1155
std::vector< MSMoveReminder *> myMoveReminders
This lane&#39;s move reminder.
Definition: MSLane.h:1297
VehCont myManeuverReservations
The vehicles which registered maneuvering into the lane within their current action step...
Definition: MSLane.h:1202
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:436
double getRightSideOnEdge() const
Definition: MSLane.h:981
incoming_lane_priority_sorter(const MSLane *targetLane)
constructor
Definition: MSLane.cpp:2719
MSLeaderInfo getPartialBeyond() const
get all vehicles that are inlapping from consecutive edges
Definition: MSLane.cpp:3126
std::string lane
The lane to stop at.
void initRestrictions()
initialized vClass-specific speed limits
Definition: MSLane.cpp:202
AnyVehicleIterator & operator++()
Definition: MSLane.cpp:98
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
double departPosLat
(optional) The lateral position the vehicle shall depart from
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:248
std::pair< const MSPerson *, double > PersonDist
Definition: MSPModel.h:38
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1845
void sortPartialVehicles()
sorts myPartialVehicles
Definition: MSLane.cpp:1797
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:924
void markDelayed() const
Definition: MSEdge.h:622
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
bool freeInsertion(MSVehicle &veh, double speed, double posLat, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle on any place.
Definition: MSLane.cpp:347
virtual std::string toString() const
print a debugging representation
double getElectricityConsumption() const
Returns the sum of last step electricity consumption.
Definition: MSLane.cpp:2628
double departPos
(optional) The position the vehicle shall depart from
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1696
static SUMOTime gTimeToGridlockHighways
Definition: MSGlobals.h:63
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:35
int addFollower(const MSVehicle *veh, const MSVehicle *ego, double gap, double latOffset=0, int sublane=-1)
std::string myID
The name of the object.
Definition: Named.h:121
SUMOVehicleClass getVClass() const
Returns the vehicle&#39;s access class.
The vehicle has departed (was inserted into the network)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:5196
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
double getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:2568
Structure representing possible vehicle parameter.
std::pair< MSVehicle *const, double > getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle &veh, const std::vector< MSLane *> &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:2173
int myI1
index for myVehicles
Definition: MSLane.h:149
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3150
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
#define DEBUG_COND
Definition: MSLane.cpp:79
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1446
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:4632
#define M_PI
Definition: odrSpiral.cpp:40
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:362
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:1719
const MSLane * getFirstInternalInConnection(double &offset) const
Returns 0 if the lane is not internal. Otherwise the first part of the connection (sequence of intern...
Definition: MSLane.cpp:1678
bool nextIsMyVehicles() const
Definition: MSLane.cpp:131
int myI3End
end index for myTmpVehicles
Definition: MSLane.h:159
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:1221
Definition of vehicle stop (position and duration)
At the rightmost side of the lane.
bool hasVehicles() const
Definition: MSLeaderInfo.h:96
bool detectCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, std::set< const MSVehicle *, ComparatorIdLess > &toRemove, std::set< const MSVehicle *> &toTeleport) const
detect whether there is a collision between the two vehicles
Definition: MSLane.cpp:1379
At the center of the lane.
const MSLane * myLane
the lane that is being iterated
Definition: MSLane.h:147
A storage for options typed value containers)
Definition: OptionsCont.h:92
double angleAt2D(int pos) const
get angle in certain position of position vector
int index
at which position in the stops list
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1863
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:2058
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:2640
double getStopOffset(const MSVehicle *veh) const
Returns vehicle class specific stopOffset for the vehicle.
Definition: MSLane.cpp:2874
#define INVALID_SPEED
Definition: MSCFModel.h:33
std::pair< MSVehicle *const, double > getCriticalLeader(double dist, double seen, double speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
Definition: MSLane.cpp:2297
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:60
double getLength() const
Get vehicle&#39;s length [m].
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:423
const MSLeaderInfo & getFirstVehicleInformation(const MSVehicle *ego, double latOffset, bool onlyFrontOnLane, double maxPos=std::numeric_limits< double >::max(), bool allowCached=true) const
analogue to getLastVehicleInformation but in the upstream direction
Definition: MSLane.cpp:1039
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:52
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2668
bool isRemoteAffected(SUMOTime t) const
Definition: MSVehicle.cpp:492
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:2848
MSLeaderInfo myLeaderInfo
leaders on all sublanes as seen by approaching vehicles (cached)
Definition: MSLane.h:1261
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:3445
MSLane * myCanonicalSuccessorLane
Main successor lane,.
Definition: MSLane.h:1245
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
#define DEBUG_COND2(obj)
Definition: MSLane.cpp:81
void registerCollision()
registers one collision-related teleport
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:352
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
double myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:1251
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:2540
#define NUMERICAL_EPS
Definition: config.h:148
MSLeaderInfo myFollowerInfo
followers on all sublanes as seen by vehicles on consecutive lanes (cached)
Definition: MSLane.h:1263
int numSublanes() const
Definition: MSLeaderInfo.h:88
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:194
MSLane * getShadowLane() const
Returns the lane the vehicle&#39;s shadow is on during continuous/sublane lane change.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:67
void addParking(MSVehicle *veh)
add parking vehicle. This should only used during state loading
Definition: MSLane.cpp:2837
int numFreeSublanes() const
Definition: MSLeaderInfo.h:92
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1386
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:322
No information given; use default.
A free position is chosen.
The class responsible for building and deletion of vehicles.
double getMissingRearGap(const MSVehicle *leader, double backOffset, double leaderSpeed) const
return by how much further the leader must be inserted to avoid rear end collisions ...
Definition: MSLane.cpp:2082
const double myLengthGeometryFactor
precomputed myShape.length / myLength
Definition: MSLane.h:1273
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:71
MSLeaderInfo myLeaderInfoTmp
Definition: MSLane.h:1265
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.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1940
double getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:4648
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4039
VehCont myVehBuffer
Buffer for vehicles that moved from their previous lane onto this one. Integrated after all vehicles ...
Definition: MSLane.h:1194
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:167
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1428
double getDepartPosLat(const MSVehicle &veh)
Definition: MSLane.cpp:462
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:479
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1094
MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle *ego, double backOffset, bool allSublanes, double searchDist=-1, bool ignoreMinorLinks=false) const
return the sublane followers with the largest missing rear gap among all predecessor lanes (within di...
Definition: MSLane.cpp:2888
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:137
SUMOTime myFollowerInfoTime
time step for which myFollowerInfo was last updated
Definition: MSLane.h:1270
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:429
void handleCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, double gap, double latGap, std::set< const MSVehicle *, ComparatorIdLess > &toRemove, std::set< const MSVehicle *> &toTeleport) const
take action upon collision
Definition: MSLane.cpp:1442
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:82
double myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1224
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:2512
static double sum(double val)
Computes the resulting noise.
const std::string & getID() const
Returns the name of the vehicle.
void registerTeleportWrongLane()
register one non-collision-related teleport
Representation of a lane in the micro simulation.
Definition: MSLane.h:71
Back-at-zero position.
double getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:2527
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
void descheduleDeparture(const SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
const double myWidth
Lane width [m].
Definition: MSLane.h:1213
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
virtual void incorporateVehicle(MSVehicle *veh, double pos, double speed, double posLat, 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:292
virtual bool appropriate(const MSVehicle *veh)
Definition: MSLane.cpp:1752
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:1091
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:2028
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:915
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
double getDepartSpeed(const MSVehicle &veh, bool &patchSpeed)
Definition: MSLane.cpp:435
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.