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