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*, SUMOVehicle::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*, SUMOVehicle::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*, SUMOVehicle::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*, SUMOVehicle::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
int operator()(const MSLink *link1, const MSLink *link2) const
comparing operator
Definition: MSLane.cpp:2688
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:131
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:2745
double getMinGap() const
Get the free space in front of vehicles of this class.
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
VehCont myVehicles
The lane&#39;s vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1156
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:489
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:135
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
double getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:2526
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
A free lateral position is chosen.
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:513
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1758
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1797
The position is given.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1825
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
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
virtual std::string toString() const
print a debugging representation
void sortManeuverReservations()
sorts myManeuverReservations
Definition: MSLane.cpp:1750
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
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::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
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
Sorts lanes (IncomingLaneInfos) by their priority or, if this doesn&#39;t apply, wrt. the angle differenc...
Definition: MSLane.h:1353
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
#define LANE_RTREE_QUAL
Definition: Helper.h:78
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1811
bool parking
whether the vehicle is removed from the net while stopping
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:419
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:882
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1881
int numSublanes() const
Definition: MSLeaderInfo.h:94
begin/end of the description of a single lane
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
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2549
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
Stop & getNextStop()
Definition: MSVehicle.cpp:4806
int myI2
index for myPartialVehicles
Definition: MSLane.h:148
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:3052
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2383
bool resumeFromStopping()
Definition: MSVehicle.cpp:4755
double getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:2454
bool hasInfluencer() const
Definition: MSVehicle.h:1543
SUMOTime duration
The stopping duration.
double getMinDeceleration() const
return the minimum deceleration capability for all vehicles that ever entered the network ...
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
The speed is given.
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 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
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
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3012
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 getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:628
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:143
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSVehicle.h:917
double getPMxEmissions() const
Returns the sum of last step PMx emissions.
Definition: MSLane.cpp:2466
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
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:128
This is an uncontrolled, minor link, has to stop.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:91
double getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:2398
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:723
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
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
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.
static double myCollisionMinGapFactor
Definition: MSLane.h:1280
SUMOTime myLeaderInfoTime
time step for which myLeaderInfo was last updated
Definition: MSLane.h:1245
MSVehicle * getFirstFullVehicle() const
returns the first vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1788
If a fixed number of random choices fails, a free lateral position is chosen.
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
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
const MSEdge *const myEdge
Definition: MSLane.h:1343
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
This is a dead end link.
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1968
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
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:497
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
const MSRoute & getRoute() const
Returns the current route.
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:2564
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
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:58
The speed is chosen randomly.
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
bool hasDeparted() const
Returns whether this vehicle has already departed.
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:876
The vehicle got vaporized.
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:402
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
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
int getLaneIndex() const
Definition: MSVehicle.cpp:4314
void addNeigh(const std::string &id)
Adds a neighbor to this lane.
Definition: MSLane.cpp:212
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
bool isInternal() const
Definition: MSLane.cpp:1774
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:2571
const SVCPermissions SVCAll
all VClasses are allowed
void gotActive(MSLane *l)
Informs the control that the given lane got active.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
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
The position is chosen randomly.
double getMaxSpeedFactor() const
return the maximum speed factor for all vehicles that ever entered the network
static bool myCheckJunctionCollisions
Definition: MSLane.h:1278
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:973
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
int myI1End
end index for myVehicles
Definition: MSLane.h:150
double getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:2478
bool hasVehicles() const
Definition: MSLeaderInfo.h:102
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:47
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
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns the information whether the given polygon overlaps with this.
The speed is given.
std::set< const MSVehicle * > myParkingVehicles
Definition: MSLane.h:1189
bool myDownstream
iteration direction
Definition: MSLane.h:154
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3674
#define SIMTIME
Definition: SUMOTime.h:71
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:392
std::vector< std::string > myNeighs
Definition: MSLane.h:1261
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
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3021
static CollisionAction myCollisionAction
the action to take on collisions
Definition: MSLane.h:1277
std::map< std::string, MSLane * > DictType
definition of the static dictionary type
Definition: MSLane.h:1267
static CollisionAction getCollisionAction()
Definition: MSLane.h:1069
double basePos(const MSVehicle &veh) const
departure position where the vehicle fits fully onto the lane (if possible)
Definition: MSLane.cpp:559
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
double getImpatience() const
Returns this vehicles impatience.
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
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
#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
const std::string & getID() const
Returns the id.
Definition: Named.h:65
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
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2554
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)
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:484
MSLane * getCanonicalSuccessorLane() const
Definition: MSLane.cpp:2315
int numFreeSublanes() const
Definition: MSLeaderInfo.h:98
double myLength
Lane length [m].
Definition: MSLane.h:1192
double getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:2502
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2256
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
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
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
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:242
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:2336
const bool myIsRampAccel
whether this lane is an acceleration lane
Definition: MSLane.h:1253
Representation of a vehicle.
Definition: SUMOVehicle.h:66
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:4565
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:343
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 getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:211
Sorts vehicles by their position (descending)
Definition: MSLane.h:1286
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:4026
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
double getElectricityConsumption() const
Returns the sum of last step electricity consumption.
Definition: MSLane.cpp:2514
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
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:306
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
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
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
const std::map< SUMOVehicleClass, double > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:1210
bool triggered
whether an arriving person lets the vehicle continue
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:64
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:4578
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
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1332
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
void markDelayed() const
Definition: MSEdge.h:627
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
Sorts edges by their angle relative to the given edge (straight comes first)
Definition: MSLane.h:1332
The maximum speed is used.
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 forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:940
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:46
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:371
T MIN2(T a, T b)
Definition: StdDefs.h:67
void add(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
#define POSITION_EPS
Definition: config.h:175
bool isRemoteAffected(SUMOTime t) const
Definition: MSVehicle.cpp:478
No information given; use default.
int operator()(const IncomingLaneInfo &lane1, const IncomingLaneInfo &lane2) const
comparing operator
Definition: MSLane.cpp:2610
CollisionAction
Definition: MSLane.h:165
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:709
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:3120
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
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 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
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.
Something on a lane to be noticed about vehicle movement.
MSLane * getShadowLane() const
Returns the lane the vehicle&#39;s shadow is on during continuous/sublane lane change.
double getRightSideOnLane() const
Get the vehicle&#39;s lateral position on the lane:
Definition: MSVehicle.cpp:4331
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1933
void registerTeleportJam()
register one non-collision-related teleport
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:229
If a fixed number of random choices fails, a free position is chosen.
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1358
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:3686
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
All direct internal and direct (disregarding internal predecessors) non-internal predecessor lanes of...
Definition: MSLane.h:1235
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
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:272
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
int operator()(const std::pair< const MSVehicle *, double > &p1, const std::pair< const MSVehicle *, double > &p2) const
Definition: MSLane.cpp:2010
Base class for objects which have an id.
Definition: Named.h:45
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
void handleCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, double gap, double latGap, std::set< const MSVehicle *, SUMOVehicle::ComparatorIdLess > &toRemove, std::set< const MSVehicle * > &toTeleport) const
take action upon collision
Definition: MSLane.cpp:1418
incoming_lane_priority_sorter(const MSLane *targetLane)
constructor
Definition: MSLane.cpp:2605
std::string lane
The lane to stop at.
void initRestrictions()
initialized vClass-specific speed limits
Definition: MSLane.cpp:200
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2295
bool operator()(const MSVehicle *cmp, double pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:2543
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:2426
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
void sortPartialVehicles()
sorts myPartialVehicles
Definition: MSLane.cpp:1742
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
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2347
double getLength() const
Get vehicle&#39;s length [m].
bool checkFailure(const MSVehicle *aVehicle, double &speed, double &dist, const double nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:564
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:135
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.
Structure representing possible vehicle parameter.
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
int myI1
index for myVehicles
Definition: MSLane.h:146
#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
int getPriority() const
Returns the priority of the edge.
Definition: MSEdge.h:278
#define M_PI
Definition: odrSpiral.cpp:40
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
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:359
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:1662
bool isEmpty() const
Definition: MSLane.cpp:1769
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:125
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:1198
Definition of vehicle stop (position and duration)
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
At the rightmost side of the lane.
At the center of the lane.
const MSLane * myLane
the lane that is being iterated
Definition: MSLane.h:144
MSVehicle * getPartialBehind(const MSVehicle *ego) const
Definition: MSLane.cpp:2974
A storage for options typed value containers)
Definition: OptionsCont.h:98
MSLeaderInfo getPartialBeyond() const
get all vehicles that are inlapping from consecutive edges
Definition: MSLane.cpp:2997
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
double getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:2032
int index
at which position in the stops list
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1992
#define INVALID_SPEED
Definition: MSCFModel.h:39
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
Definition: MSLane.cpp:3075
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:439
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:66
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
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:137
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:3202
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:403
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:2734
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:439
MSLeaderInfo myLeaderInfo
leaders on all sublanes as seen by approaching vehicles (cached)
Definition: MSLane.h:1238
double getRightSideOnEdge() const
Definition: MSLane.h:960
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
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 nextIsMyVehicles() const
Definition: MSLane.cpp:132
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:176
bool closeTag()
Closes the most recently opened tag.
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
#define DEBUG_COND2(obj)
Definition: MSLane.cpp:86
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:319
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
double myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:1228
#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
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:192
std::string toString() const
print a debugging representation
double getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:2490
void addParking(MSVehicle *veh)
add parking vehicle. This should only used during state loading
Definition: MSLane.cpp:2723
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1874
No information given; use default.
A free position is chosen.
double getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:2442
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.
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
double getDepartPosLat(const MSVehicle &veh)
Definition: MSLane.cpp:460
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1073
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:564
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:752
virtual bool executeMovements(SUMOTime t, std::vector< MSLane * > &lanesWithVehiclesToIntegrate)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:1507
SUMOTime myFollowerInfoTime
time step for which myFollowerInfo was last updated
Definition: MSLane.h:1247
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1779
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:88
double myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1201
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:398
static double sum(double val)
Computes the resulting noise.
double getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:2413
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void registerTeleportWrongLane()
register one non-collision-related teleport
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:413
Back-at-zero position.
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:2372
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
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
void descheduleDeparture(const SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
double angleAt2D(int pos) const
get angle in certain position of position vector
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) ...
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:73
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
bool detectCollisionBetween(SUMOTime timestep, const std::string &stage, MSVehicle *collider, MSVehicle *victim, std::set< const MSVehicle *, SUMOVehicle::ComparatorIdLess > &toRemove, std::set< const MSVehicle * > &toTeleport) const
detect whether there is a collision between the two vehicles
Definition: MSLane.cpp:1355
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:901
const std::string & getID() const
Returns the name of the vehicle.
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:482
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:408
double getDepartSpeed(const MSVehicle &veh, bool &patchSpeed)
Definition: MSLane.cpp:433
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.