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