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