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