SUMO - Simulation of Urban MObility
MSLane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
14 // Representation of a lane in the micro simulation
15 /****************************************************************************/
16 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
17 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
18 /****************************************************************************/
19 //
20 // This file is part of SUMO.
21 // SUMO is free software: you can redistribute it and/or modify
22 // it under the terms of the GNU General Public License as published by
23 // the Free Software Foundation, either version 3 of the License, or
24 // (at your option) any later version.
25 //
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 #ifdef CHECK_MEMORY_LEAKS
74 #include <foreign/nvwa/debug_new.h>
75 #endif // CHECK_MEMORY_LEAKS
76 
77 //#define DEBUG_INSERTION
78 //#define DEBUG_PLAN_MOVE
79 //#define DEBUG_CONTEXT
80 //#define DEBUG_OPPOSITE
81 //#define DEBUG_VEHICLE_CONTAINER
82 //#define DEBUG_COLLISIONS
83 #define DEBUG_COND (getID() == "disabled")
84 #define DEBUG_COND2(obj) ((obj != 0 && (obj)->getID() == "disabled"))
85 
86 // ===========================================================================
87 // static member definitions
88 // ===========================================================================
92 
93 // ===========================================================================
94 // internal class method definitions
95 // ===========================================================================
96 
97 
100  if (nextIsMyVehicles()) {
101  if (myI1 != myI1End) {
102  myI1 += myDirection;
103  }
104  // else: already at end
105  } else {
106  myI2 += myDirection;
107  }
108  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::operator++ lane=" << myLane->getID() << " myI1=" << myI1 << " myI2=" << myI2 << "\n";
109  return *this;
110 }
111 
112 
113 const MSVehicle*
115  if (nextIsMyVehicles()) {
116  if (myI1 != myI1End) {
117  return myLane->myVehicles[myI1];
118  } else {
119  return 0;
120  }
121  } else {
122  return myLane->myPartialVehicles[myI2];
123  }
124 }
125 
126 
127 bool
129  //if (DEBUG_COND2(myLane)) std::cout << SIMTIME << " AnyVehicleIterator::nextIsMyVehicles lane=" << myLane->getID()
130  // << " myI1=" << myI1
131  // << " myI2=" << myI2
132  // << "\n";
133  if (myI1 == myI1End) {
134  if (myI2 != myI2End) {
135  return false;
136  } else {
137  return true; // @note. must be caught
138  }
139  } else {
140  if (myI2 == myI2End) {
141  return true;
142  } else {
143  //if (DEBUG_COND2(myLane)) std::cout << " "
144  // << " veh1=" << myLane->myVehicles[myI1]->getID()
145  // << " veh2=" << myLane->myPartialVehicles[myI2]->getID()
146  // << " pos1=" << myLane->myVehicles[myI1]->getPositionOnLane(myLane)
147  // << " pos2=" << myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)
148  // << "\n";
149  if (myLane->myVehicles[myI1]->getPositionOnLane(myLane) < myLane->myPartialVehicles[myI2]->getPositionOnLane(myLane)) {
150  return myDownstream;
151  } else {
152  return !myDownstream;
153  }
154  }
155  }
156 }
157 
158 
159 // ===========================================================================
160 // member method definitions
161 // ===========================================================================
162 MSLane::MSLane(const std::string& id, SUMOReal maxSpeed, SUMOReal length, MSEdge* const edge,
163  int numericalID, const PositionVector& shape, SUMOReal width,
164  SVCPermissions permissions, int index) :
165  Named(id),
166  myNumericalID(numericalID), myShape(shape), myIndex(index),
167  myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed),
168  myPermissions(permissions),
169  myOriginalPermissions(permissions),
172  myLeaderInfo(this, 0, 0),
173  myFollowerInfo(this, 0, 0),
174  myLeaderInfoTmp(this, 0, 0),
177  myLengthGeometryFactor(MAX2(POSITION_EPS, myShape.length()) / myLength), // factor should not be 0
178  myRightSideOnEdge(0), // initialized in MSEdge::initialize
179  myRightmostSublane(0) { // initialized in MSEdge::initialize
181 }
182 
183 
185  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
186  delete *i;
187  }
188 }
189 
190 
191 void
193  myLinks.push_back(link);
194 }
195 
196 
197 void
198 MSLane::addNeigh(const std::string& id) {
199  myNeighs.push_back(id);
200 }
201 
202 
203 // ------ interaction with MSMoveReminder ------
204 void
206  myMoveReminders.push_back(rem);
207  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
208  (*veh)->addReminder(rem);
209  }
210 }
211 
212 
213 SUMOReal
215 #ifdef DEBUG_CONTEXT
216  if (DEBUG_COND2(v)) {
217  std::cout << SIMTIME << " setPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
218  }
219 #endif
220  // XXX update occupancy here?
221  myPartialVehicles.push_back(v);
222  return myLength;
223 }
224 
225 
226 void
228 #ifdef DEBUG_CONTEXT
229  if (DEBUG_COND2(v)) {
230  std::cout << SIMTIME << " resetPartialOccupation. lane=" << getID() << " veh=" << v->getID() << "\n";
231  }
232 #endif
233  for (VehCont::iterator i = myPartialVehicles.begin(); i != myPartialVehicles.end(); ++i) {
234  if (v == *i) {
235  myPartialVehicles.erase(i);
236  // XXX update occupancy here?
237  //std::cout << " removed from myPartialVehicles\n";
238  return;
239  }
240  }
241  assert(false);
242 }
243 
244 
245 // ------ Vehicle emission ------
246 void
247 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, SUMOReal posLat, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
248  assert(pos <= myLength);
249  bool wasInactive = myVehicles.size() == 0;
250  veh->enterLaneAtInsertion(this, pos, speed, posLat, notification);
251  if (at == myVehicles.end()) {
252  // vehicle will be the first on the lane
253  myVehicles.push_back(veh);
254  } else {
255  myVehicles.insert(at, veh);
256  }
259  myEdge->markDelayed();
260  if (wasInactive) {
262  }
263 }
264 
265 
266 bool
267 MSLane::lastInsertion(MSVehicle& veh, SUMOReal mspeed, bool patchSpeed) {
268  // XXX interpret departPosLat value
269  const SUMOReal posLat = 0;
270  SUMOReal pos = getLength() - POSITION_EPS;
271  MSVehicle* leader = getLastAnyVehicle();
272  // back position of leader relative to this lane
273  SUMOReal leaderBack;
274  if (leader == 0) {
276  veh.setTentativeLaneAndPosition(this, pos, posLat);
277  veh.updateBestLanes(false, this);
278  std::pair<MSVehicle* const, SUMOReal> leaderInfo = getLeader(&veh, pos, veh.getBestLanesContinuation(), veh.getCarFollowModel().brakeGap(mspeed));
279  leader = leaderInfo.first;
280  leaderBack = pos + leaderInfo.second + veh.getVehicleType().getMinGap();
281  } else {
282  leaderBack = leader->getBackPositionOnLane(this);
283  //std::cout << " leaderPos=" << leader->getPositionOnLane(this) << " leaderBack=" << leader->getBackPositionOnLane(this) << " leaderLane=" << leader->getLane()->getID() << "\n";
284  }
285  if (leader == 0) {
286  // insert at the end of this lane
287  return isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
288  } else {
289  // try to insert behind the leader
290  const SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(mspeed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap() + POSITION_EPS;
291  if (leaderBack >= frontGapNeeded) {
292  pos = MIN2(pos, leaderBack - frontGapNeeded);
293  bool result = isInsertionSuccess(&veh, mspeed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
294  //if (!result) std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
295  return result;
296  }
297  //std::cout << " insertLast failed for " << veh.getID() << " pos=" << pos << " leaderBack=" << leaderBack << " frontGapNeeded=" << frontGapNeeded << "\n";
298  }
299  return false;
300 }
301 
302 
303 bool
305  MSMoveReminder::Notification notification) {
306  bool adaptableSpeed = true;
307  // try to insert teleporting vehicles fully on this lane
308  const SUMOReal minPos = (notification == MSMoveReminder::NOTIFICATION_TELEPORT ?
309  MIN2(myLength, veh.getVehicleType().getLength()) : 0);
310 
311  if (myVehicles.size() == 0) {
312  // ensure sufficient gap to followers on predecessor lanes
313  const SUMOReal backOffset = minPos - veh.getVehicleType().getLength();
314  const SUMOReal missingRearGap = getMissingRearGap(backOffset, mspeed, veh.getCarFollowModel().getMaxDecel());
315  if (missingRearGap > 0) {
316  if (minPos + missingRearGap <= myLength) {
317  // @note. The rear gap is tailored to mspeed. If it changes due
318  // to a leader vehicle (on subsequent lanes) insertion will
319  // still fail. Under the right combination of acceleration and
320  // deceleration values there might be another insertion
321  // positions that would be successful be we do not look for it.
322  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " unclear @(340)\n";
323  return isInsertionSuccess(&veh, mspeed, minPos + missingRearGap, 0, adaptableSpeed, notification);
324  } else {
325  return false;
326  }
327  } else {
328  return isInsertionSuccess(&veh, mspeed, minPos, 0, adaptableSpeed, notification);
329  }
330 
331  } else {
332  // check whether the vehicle can be put behind the last one if there is such
333  MSVehicle* leader = getFirstFullVehicle(); // @todo reproduction of bogus old behavior. see #1961
334  const SUMOReal leaderPos = leader->getBackPositionOnLane(this);
335  const SUMOReal speed = adaptableSpeed ? leader->getSpeed() : mspeed;
336  const SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
337  if (leaderPos >= frontGapNeeded) {
338  const SUMOReal tspeed = MIN2(veh.getCarFollowModel().insertionFollowSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
339  // check whether we can insert our vehicle behind the last vehicle on the lane
340  if (isInsertionSuccess(&veh, tspeed, minPos, 0, adaptableSpeed, notification)) {
341  //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";
342  return true;
343  }
344  }
345  }
346  // go through the lane, look for free positions (starting after the last vehicle)
347  MSLane::VehCont::iterator predIt = myVehicles.begin();
348  while (predIt != myVehicles.end()) {
349  // get leader (may be zero) and follower
350  // @todo compute secure position in regard to sublane-model
351  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : 0;
352  if (leader == 0 && myPartialVehicles.size() > 0) {
353  leader = myPartialVehicles.front();
354  }
355  const MSVehicle* follower = *predIt;
356 
357  // patch speed if allowed
358  SUMOReal speed = mspeed;
359  if (adaptableSpeed && leader != 0) {
360  speed = MIN2(leader->getSpeed(), mspeed);
361  }
362 
363  // compute the space needed to not collide with leader
364  SUMOReal frontMax = getLength();
365  if (leader != 0) {
366  SUMOReal leaderRearPos = leader->getBackPositionOnLane(this);
367  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
368  frontMax = leaderRearPos - frontGapNeeded;
369  }
370  // compute the space needed to not let the follower collide
371  const SUMOReal followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
372  const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
373  const SUMOReal backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
374 
375  // check whether there is enough room (given some extra space for rounding errors)
376  if (frontMax > minPos && backMin + POSITION_EPS < frontMax) {
377  // try to insert vehicle (should be always ok)
378  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, 0, adaptableSpeed, notification)) {
379  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " @(393)\n";
380  return true;
381  }
382  }
383  ++predIt;
384  }
385  // first check at lane's begin
386  //std::cout << SIMTIME << " freeInsertion lane=" << getID() << " veh=" << veh.getID() << " fail final\n";
387  return false;
388 }
389 
390 
391 SUMOReal
392 MSLane::getDepartSpeed(const MSVehicle& veh, bool& patchSpeed) {
393  SUMOReal speed = 0;
394  const SUMOVehicleParameter& pars = veh.getParameter();
395  switch (pars.departSpeedProcedure) {
396  case DEPART_SPEED_GIVEN:
397  speed = pars.departSpeed;
398  patchSpeed = false;
399  break;
400  case DEPART_SPEED_RANDOM:
401  speed = RandHelper::rand(getVehicleMaxSpeed(&veh));
402  patchSpeed = true; // @todo check
403  break;
404  case DEPART_SPEED_MAX:
405  speed = getVehicleMaxSpeed(&veh);
406  patchSpeed = true; // @todo check
407  break;
409  default:
410  // speed = 0 was set before
411  patchSpeed = false; // @todo check
412  break;
413  }
414  return speed;
415 }
416 
417 
418 bool
420  SUMOReal pos = 0;
421  SUMOReal posLat = 0;
422  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
423  const SUMOVehicleParameter& pars = veh.getParameter();
424  SUMOReal speed = getDepartSpeed(veh, patchSpeed);
425 
426  // determine the position
427  switch (pars.departPosProcedure) {
428  case DEPART_POS_GIVEN:
429  pos = pars.departPos;
430  if (pos < 0.) {
431  pos += myLength;
432  }
433  break;
434  case DEPART_POS_RANDOM:
435  pos = RandHelper::rand(getLength());
436  break;
437  case DEPART_POS_RANDOM_FREE: {
438  for (int i = 0; i < 10; i++) {
439  // we will try some random positions ...
440  pos = RandHelper::rand(getLength());
443  posLat = RandHelper::rand(getWidth() - veh.getVehicleType().getWidth()) - getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
444  }
445  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
446  return true;
447  }
448  }
449  // ... and if that doesn't work, we put the vehicle to the free position
450  return freeInsertion(veh, speed);
451  }
452  break;
453  case DEPART_POS_FREE:
454  return freeInsertion(veh, speed);
455  case DEPART_POS_LAST:
456  return lastInsertion(veh, speed, patchSpeed);
457  case DEPART_POS_BASE:
458  case DEPART_POS_DEFAULT:
459  default:
460  pos = basePos(veh);
461  break;
462  }
463  // determine the lateral position
464  switch (pars.departPosLatProcedure) {
465  case DEPART_POSLAT_GIVEN:
466  posLat = pars.departPosLat;
467  break;
469  posLat = RandHelper::rand(getWidth() - veh.getVehicleType().getWidth()) - getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
470  break;
472  for (int i = 0; i < 10; i++) {
473  // we will try some random positions ...
474  posLat = RandHelper::rand(getWidth()) - getWidth() * 0.5;
475  if (isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED)) {
476  return true;
477  }
478  }
479  // ... and if that doesn't work, we put the vehicle to the free position
480  return freeInsertion(veh, speed);
481  }
482  break;
483  case DEPART_POSLAT_FREE:
484  return freeInsertion(veh, speed);
485  case DEPART_POSLAT_RIGHT:
486  posLat = -getWidth() * 0.5 + veh.getVehicleType().getWidth() * 0.5;
487  break;
488  case DEPART_POSLAT_LEFT:
489  posLat = getWidth() * 0.5 - veh.getVehicleType().getWidth() * 0.5;
490  break;
492  case DEPART_POS_DEFAULT:
493  default:
494  posLat = 0;
495  break;
496  }
497  // try to insert
498  return isInsertionSuccess(&veh, speed, pos, posLat, patchSpeed, MSMoveReminder::NOTIFICATION_DEPARTED);
499 }
500 
501 
502 SUMOReal
503 MSLane::basePos(const MSVehicle& veh) const {
505 }
506 
507 bool
508 MSLane::checkFailure(MSVehicle* aVehicle, SUMOReal& speed, SUMOReal& dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const {
509  if (nspeed < speed) {
510  if (patchSpeed) {
511  speed = MIN2(nspeed, speed);
512  dist = aVehicle->getCarFollowModel().brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
513  } else if (speed > 0) {
514  if (errorMsg != "") {
515  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (" + errorMsg + ")!");
517  }
518  return true;
519  }
520  }
521  return false;
522 }
523 
524 
525 bool
527  SUMOReal speed, SUMOReal pos, SUMOReal posLat, bool patchSpeed,
528  MSMoveReminder::Notification notification) {
529  if (pos < 0 || pos > myLength) {
530  // we may not start there
531  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
532  aVehicle->getID() + "'. Inserting at lane end instead.");
533  pos = myLength;
534  }
535 
536 #ifdef DEBUG_INSERTION
537  if (DEBUG_COND2(aVehicle)) std::cout << "\nIS_INSERTION_SUCCESS\n"
538  << SIMTIME << " lane=" << getID()
539  << " veh '" << aVehicle->getID() << "'\n";
540 #endif
541 
542  aVehicle->setTentativeLaneAndPosition(this, pos, posLat);
543  aVehicle->updateBestLanes(false, this);
544  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
545  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
546  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
547  SUMOReal seen = getLength() - pos; // == distance from insertion position until the end of the currentLane
548  SUMOReal dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
549 
550  // before looping through the continuation lanes, check if a stop is scheduled on this lane
551  // (the code is duplicated in the loop)
552  if (aVehicle->hasStops()) {
553  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
554  if (nextStop.lane == this) {
555  std::stringstream msg;
556  msg << "scheduled stop on lane '" << myID << "' too close";
557  const SUMOReal distToStop = nextStop.endPos - pos; // XXX: Please approve whether endPos is appropriate, here. (Leo)
558  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, distToStop),
559  patchSpeed, msg.str())) {
560  // we may not drive with the given velocity - we cannot stop at the stop
561  return false;
562  }
563  }
564  }
565 
566  const MSRoute& r = aVehicle->getRoute();
567  MSRouteIterator ce = r.begin();
568  int nRouteSuccs = 1;
569  MSLane* currentLane = this;
570  MSLane* nextLane = this;
572  while (seen < dist && ri != bestLaneConts.end()) {
573  // get the next link used...
574  MSLinkCont::const_iterator link = succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
575  if (currentLane->isLinkEnd(link)) {
576  if (&currentLane->getEdge() == r.getLastEdge()) {
577  // reached the end of the route
579  if (checkFailure(aVehicle, speed, dist, cfModel.freeSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed, true),
580  patchSpeed, "arrival speed too low")) {
581  // we may not drive with the given velocity - we cannot match the specified arrival speed
582  return false;
583  }
584  }
585  } else {
586  // lane does not continue
587  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
588  patchSpeed, "junction too close")) {
589  // we may not drive with the given velocity - we cannot stop at the junction
590  return false;
591  }
592  }
593  break;
594  }
595 
596  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength(), aVehicle->getImpatience(), cfModel.getMaxDecel(), 0, posLat)
597  || !(*link)->havePriority()) {
598  // have to stop at junction
599  std::string errorMsg = "";
600  const LinkState state = (*link)->getState();
601  if (state == LINKSTATE_MINOR
602  || state == LINKSTATE_EQUAL
603  || state == LINKSTATE_STOP
604  || state == LINKSTATE_ALLWAY_STOP) {
605  // no sense in trying later
606  errorMsg = "unpriorised junction too close";
607  }
608  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen),
609  patchSpeed, errorMsg)) {
610  // we may not drive with the given velocity - we cannot stop at the junction in time
611  return false;
612  }
613 #ifdef DEBUG_INSERTION
614  if DEBUG_COND2(aVehicle) {
615  std::cout << "trying insertion before minor link: "
616  << "insertion speed = " << speed << " dist=" << dist
617  << "\n";
618  }
619 #endif
620  break;
621  }
622  // get the next used lane (including internal)
623  nextLane = (*link)->getViaLaneOrLane();
624  // check how next lane affects the journey
625  if (nextLane != 0) {
626 
627  // check if there are stops on the next lane that should be regarded
628  // (this block is duplicated before the loop to deal with the insertion lane)
629  if (aVehicle->hasStops()) {
630  const MSVehicle::Stop& nextStop = aVehicle->getNextStop();
631  if (nextStop.lane == nextLane) {
632  std::stringstream msg;
633  msg << "scheduled stop on lane '" << nextStop.lane->getID() << "' too close";
634  const SUMOReal distToStop = seen + nextStop.endPos;
635  if (checkFailure(aVehicle, speed, dist, cfModel.stopSpeed(aVehicle, speed, distToStop),
636  patchSpeed, msg.str())) {
637  // we may not drive with the given velocity - we cannot stop at the stop
638  return false;
639  }
640  }
641  }
642 
643  // check leader on next lane
644  // XXX check all leaders in the sublane case
645  SUMOReal gap = 0;
646  MSVehicle* leader = nextLane->getLastAnyVehicle();
647  if (leader != 0) {
648 #ifdef DEBUG_INSERTION
649  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
650  << "leader on lane '" << nextLane->getID() << "': " << leader->getID() << "\n";
651 #endif
652  gap = seen + leader->getBackPositionOnLane(nextLane) - aVehicle->getVehicleType().getMinGap();
653  }
654  if (leader != 0) {
655  if (gap < 0) {
656  return false;
657  }
658  const SUMOReal nspeed = cfModel.insertionFollowSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
659  if (checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
660  // we may not drive with the given velocity - we crash into the leader
661 #ifdef DEBUG_INSERTION
662  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
663  << " isInsertionSuccess lane=" << getID()
664  << " veh=" << aVehicle->getID()
665  << " pos=" << pos
666  << " posLat=" << posLat
667  << " patchSpeed=" << patchSpeed
668  << " speed=" << speed
669  << " nspeed=" << nspeed
670  << " nextLane=" << nextLane->getID()
671  << " lead=" << leader->getID()
672  << " gap=" << gap
673  << " failed (@641)!\n";
674 #endif
675  return false;
676  }
677  }
678  // check next lane's maximum velocity
679  const SUMOReal nspeed = cfModel.freeSpeed(aVehicle, speed, seen, nextLane->getVehicleMaxSpeed(aVehicle), true);
680  if (nspeed < speed) {
681  if (patchSpeed) {
682  speed = nspeed;
683  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
684  } else {
685  // we may not drive with the given velocity - we would be too fast on the next lane
686  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using the given velocity (slow lane ahead)!");
688  return false;
689  }
690  }
691  // check traffic on next junction
692  // we cannot use (*link)->opened because a vehicle without priority
693  // may already be comitted to blocking the link and unable to stop
694  const SUMOTime leaveTime = (*link)->getLeaveTime(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength());
695  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed, cfModel.getMaxDecel())) {
696  if (checkFailure(aVehicle, speed, dist, cfModel.insertionStopSpeed(aVehicle, speed, seen), patchSpeed, "")) {
697  // we may not drive with the given velocity - we crash at the junction
698  return false;
699  }
700  }
701  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
702  seen += nextLane->getLength();
703  currentLane = nextLane;
704 #ifdef HAVE_INTERNAL_LANES
705  if ((*link)->getViaLane() == 0) {
706 #else
707  if (true) {
708 #endif
709  nRouteSuccs++;
710  ++ce;
711  ++ri;
712  }
713  }
714  }
715 
716  // get the pointer to the vehicle next in front of the given position
717  MSLeaderInfo leaders = getLastVehicleInformation(aVehicle, 0, pos);
718  //if (aVehicle->getID() == "disabled") std::cout << " leaders=" << leaders.toString() << "\n";
719  const SUMOReal nspeed = safeInsertionSpeed(aVehicle, leaders, speed);
720  if (nspeed < 0 || checkFailure(aVehicle, speed, dist, nspeed, patchSpeed, "")) {
721  // XXX: checking for nspeed<0... Might appear naturally with ballistic update (see #860, Leo)
722  // TODO: check if ballistic update needs adjustments here, refs. #2577
723 
724  // we may not drive with the given velocity - we crash into the leader
725 #ifdef DEBUG_INSERTION
726  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
727  << " isInsertionSuccess lane=" << getID()
728  << " veh=" << aVehicle->getID()
729  << " pos=" << pos
730  << " posLat=" << posLat
731  << " patchSpeed=" << patchSpeed
732  << " speed=" << speed
733  << " nspeed=" << nspeed
734  << " nextLane=" << nextLane->getID()
735  << " leaders=" << leaders.toString()
736  << " failed (@700)!\n";
737 #endif
738  return false;
739  }
740 #ifdef DEBUG_INSERTION
741  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
742  << " speed = " << speed
743  << " nspeed = " << nspeed
744  << std::endl;
745 #endif
746 
747  MSLeaderDistanceInfo followers = getFollowersOnConsecutive(aVehicle, false);
748  for (int i = 0; i < followers.numSublanes(); ++i) {
749  const MSVehicle* follower = followers[i].first;
750  if (follower != 0) {
751  const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), speed, cfModel.getMaxDecel());
752  if (followers[i].second < backGapNeeded) {
753  // too close to the follower on this lane
754 #ifdef DEBUG_INSERTION
755  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
756  << " isInsertionSuccess lane=" << getID()
757  << " veh=" << aVehicle->getID()
758  << " pos=" << pos
759  << " posLat=" << posLat
760  << " patchSpeed=" << patchSpeed
761  << " speed=" << speed
762  << " nspeed=" << nspeed
763  << " follower=" << follower->getID()
764  << " backGapNeeded=" << backGapNeeded
765  << " gap=" << followers[i].second
766  << " failure (@719)!\n";
767 #endif
768  return false;
769  }
770  }
771  }
772  if (followers.numFreeSublanes() > 0) {
773  // check approaching vehicles to prevent rear-end collisions
774  const SUMOReal backOffset = pos - aVehicle->getVehicleType().getLength();
775  const SUMOReal missingRearGap = getMissingRearGap(backOffset, speed, aVehicle->getCarFollowModel().getMaxDecel());
776  if (missingRearGap > 0) {
777  // too close to a follower
778 #ifdef DEBUG_INSERTION
779  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
780  << " isInsertionSuccess lane=" << getID()
781  << " veh=" << aVehicle->getID()
782  << " pos=" << pos
783  << " posLat=" << posLat
784  << " patchSpeed=" << patchSpeed
785  << " speed=" << speed
786  << " nspeed=" << nspeed
787  << " missingRearGap=" << missingRearGap
788  << " failure (@728)!\n";
789 #endif
790  return false;
791  }
792  }
793  // may got negative while adaptation
794  if (speed < 0) {
795 #ifdef DEBUG_INSERTION
796  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
797  << " isInsertionSuccess lane=" << getID()
798  << " veh=" << aVehicle->getID()
799  << " pos=" << pos
800  << " posLat=" << posLat
801  << " patchSpeed=" << patchSpeed
802  << " speed=" << speed
803  << " nspeed=" << nspeed
804  << " failed (@733)!\n";
805 #endif
806  return false;
807  }
808  // enter
809  incorporateVehicle(aVehicle, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
810 #ifdef DEBUG_INSERTION
811  if (DEBUG_COND2(aVehicle)) std::cout << SIMTIME
812  << " isInsertionSuccess lane=" << getID()
813  << " veh=" << aVehicle->getID()
814  << " pos=" << pos
815  << " posLat=" << posLat
816  << " patchSpeed=" << patchSpeed
817  << " speed=" << speed
818  << " nspeed=" << nspeed
819  << " success!\n";
820 #endif
821  return true;
822 }
823 
824 
825 void
827  veh->updateBestLanes(true, this);
828  bool dummy;
829  const SUMOReal speed = veh->hasDeparted() ? veh->getSpeed() : getDepartSpeed(*veh, dummy);
830  incorporateVehicle(veh, pos, speed, posLat, find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)), notification);
831 }
832 
833 
834 SUMOReal
835 MSLane::safeInsertionSpeed(const MSVehicle* veh, const MSLeaderInfo& leaders, SUMOReal speed) {
836  SUMOReal nspeed = speed;
837  for (int i = 0; i < leaders.numSublanes(); ++i) {
838  const MSVehicle* leader = leaders[i];
839  if (leader != 0) {
840  const SUMOReal gap = leader->getBackPositionOnLane(this) - veh->getPositionOnLane() - veh->getVehicleType().getMinGap();
841  if (gap < 0) {
842  return -1;
843  }
844  nspeed = MIN2(nspeed,
845  veh->getCarFollowModel().insertionFollowSpeed(veh, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()));
846  }
847  }
848  return nspeed;
849 }
850 
851 
852 // ------ Handling vehicles lapping into lanes ------
853 const MSLeaderInfo&
854 MSLane::getLastVehicleInformation(const MSVehicle* ego, SUMOReal latOffset, SUMOReal minPos, bool allowCached) const {
855  if (myLeaderInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || minPos > 0 || !allowCached) {
856  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
858  int freeSublanes = 1; // number of sublanes for which no leader was found
859  //if (ego->getID() == "disabled" && SIMTIME == 58) {
860  // std::cout << "DEBUG\n";
861  //}
862  const MSVehicle* veh = *last;
863  while (freeSublanes > 0 && veh != 0) {
864 #ifdef DEBUG_PLAN_MOVE
865  if (DEBUG_COND2(ego)) {
866  std::cout << " getLastVehicleInformation lane=" << getID() << " minPos=" << minPos << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
867  }
868 #endif
869  if (veh != ego && veh->getPositionOnLane(this) >= minPos) {
870  const SUMOReal latOffset = veh->getLatOffset(this);
871  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
872 #ifdef DEBUG_PLAN_MOVE
873  if (DEBUG_COND2(ego)) {
874  std::cout << " latOffset=" << latOffset << " newLeaders=" << myLeaderInfoTmp.toString() << "\n";
875  }
876 #endif
877  }
878  veh = *(++last);
879  }
880  if (ego == 0 && minPos == 0) {
881  // update cached value
884  }
885 #ifdef DEBUG_PLAN_MOVE
886  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
887  // << " getLastVehicleInformation lane=" << getID()
888  // << " ego=" << Named::getIDSecure(ego)
889  // << "\n"
890  // << " vehicles=" << toString(myVehicles)
891  // << " partials=" << toString(myPartialVehicles)
892  // << "\n"
893  // << " result=" << myLeaderInfoTmp.toString()
894  // << " cached=" << myLeaderInfo.toString()
895  // << " myLeaderInfoTime=" << myLeaderInfoTime
896  // << "\n";
897 #endif
898  return myLeaderInfoTmp;
899  }
900  return myLeaderInfo;
901 }
902 
903 
904 const MSLeaderInfo&
905 MSLane::getFirstVehicleInformation(const MSVehicle* ego, SUMOReal latOffset, bool onlyFrontOnLane, SUMOReal maxPos, bool allowCached) const {
906  if (myFollowerInfoTime < MSNet::getInstance()->getCurrentTimeStep() || ego != 0 || maxPos < myLength || !allowCached || onlyFrontOnLane) {
907  // XXX separate cache for onlyFrontOnLane = true
908  myLeaderInfoTmp = MSLeaderInfo(this, ego, latOffset);
910  int freeSublanes = 1; // number of sublanes for which no leader was found
911  const MSVehicle* veh = *first;
912  while (freeSublanes > 0 && veh != 0) {
913 #ifdef DEBUG_PLAN_MOVE
914  if (DEBUG_COND2(ego)) {
915  std::cout << " veh=" << veh->getID() << " pos=" << veh->getPositionOnLane(this) << " maxPos=" << maxPos << "\n";
916  }
917 #endif
918  if (veh != ego && veh->getPositionOnLane(this) <= maxPos
919  && (!onlyFrontOnLane || veh->isFrontOnLane(this))) {
920  //const SUMOReal latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
921  const SUMOReal latOffset = veh->getLatOffset(this);
922 #ifdef DEBUG_PLAN_MOVE
923  if (DEBUG_COND2(ego)) {
924  std::cout << " veh=" << veh->getID() << " latOffset=" << latOffset << "\n";
925  }
926 #endif
927  freeSublanes = myLeaderInfoTmp.addLeader(veh, true, latOffset);
928  }
929  veh = *(++first);
930  }
931  if (ego == 0 && maxPos == std::numeric_limits<SUMOReal>::max()) {
932  // update cached value
935  }
936 #ifdef DEBUG_PLAN_MOVE
937  //if (DEBUG_COND2(ego)) std::cout << SIMTIME
938  // << " getFirstVehicleInformation lane=" << getID()
939  // << " ego=" << Named::getIDSecure(ego)
940  // << "\n"
941  // << " vehicles=" << toString(myVehicles)
942  // << " partials=" << toString(myPartialVehicles)
943  // << "\n"
944  // << " result=" << myLeaderInfoTmp.toString()
945  // //<< " cached=" << myLeaderInfo.toString()
946  // << " myLeaderInfoTime=" << myLeaderInfoTime
947  // << "\n";
948 #endif
949  return myLeaderInfoTmp;
950  }
951  return myFollowerInfo;
952 }
953 
954 
955 // ------ ------
956 void
958  assert(myVehicles.size() != 0);
959  SUMOReal cumulatedVehLength = 0.;
960  MSLeaderInfo ahead(this);
961  // iterate over myVehicles and myPartialVehicles merge-sort style
962  VehCont::reverse_iterator veh = myVehicles.rbegin();
963  VehCont::reverse_iterator vehPart = myPartialVehicles.rbegin();
964 #ifdef DEBUG_PLAN_MOVE
965  if (DEBUG_COND) std::cout
966  << "\n"
967  << SIMTIME
968  << " planMovements lane=" << getID()
969  << "\n"
970  << " vehicles=" << toString(myVehicles)
971  << " partials=" << toString(myPartialVehicles)
972  << "\n";
973 #endif
974  for (; veh != myVehicles.rend(); ++veh) {
975  while (vehPart != myPartialVehicles.rend()
976  && ((*vehPart)->getPositionOnLane(this) > (*veh)->getPositionOnLane())) {
977  const SUMOReal latOffset = (*vehPart)->getLatOffset(this);
978 #ifdef DEBUG_PLAN_MOVE
979  if (DEBUG_COND) {
980  std::cout << " partial ahead: " << (*vehPart)->getID() << " latOffset=" << latOffset << "\n";
981  }
982 #endif
983  ahead.addLeader(*vehPart, false, latOffset);
984  ++vehPart;
985  }
986 #ifdef DEBUG_PLAN_MOVE
987  if (DEBUG_COND) {
988  std::cout << " plan move for: " << (*veh)->getID() << " ahead=" << ahead.toString() << "\n";
989  }
990 #endif
991  (*veh)->planMove(t, ahead, cumulatedVehLength);
992  cumulatedVehLength += (*veh)->getVehicleType().getLengthWithGap();
993  ahead.addLeader(*veh, false, 0);
994  }
995 }
996 
997 
998 void
999 MSLane::detectCollisions(SUMOTime timestep, const std::string& stage) {
1000 #ifdef DEBUG_COLLISIONS
1001  if (DEBUG_COND) {
1002  std::vector<const MSVehicle*> all;
1003  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
1004  all.push_back(*last);
1005  }
1006  std::cout << SIMTIME << " detectCollisions stage=" << stage << " lane=" << getID() << ":\n"
1007  << " vehs=" << toString(myVehicles) << "\n"
1008  << " part=" << toString(myPartialVehicles) << "\n"
1009  << " all=" << toString(all) << "\n"
1010  << "\n";
1011  }
1012 #endif
1013 
1014  if (myVehicles.size() == 0 || myCollisionAction == COLLISION_ACTION_NONE) {
1015  return;
1016  }
1017  std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess> toRemove;
1018  std::set<const MSVehicle*> toTeleport;
1020  // no sublanes
1021  VehCont::iterator lastVeh = myVehicles.end() - 1;
1022  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh; ++veh) {
1023  VehCont::iterator pred = veh + 1;
1024  detectCollisionBetween(timestep, stage, *veh, *pred, toRemove, toTeleport);
1025  }
1026  if (myPartialVehicles.size() > 0) {
1027  detectCollisionBetween(timestep, stage, *lastVeh, myPartialVehicles.front(), toRemove, toTeleport);
1028  }
1029  } else {
1030  // in the sublane-case it is insufficient to check the vehicles ordered
1031  // by their front position as there might be more than 2 vehicles next to each
1032  // other on the same lane
1033  // instead, a moving-window approach is used where all vehicles that
1034  // overlap in the longitudinal direction receive pairwise checks
1035  // XXX for efficiency, all lanes of an edge should be checked together
1036  // (lanechanger-style)
1037 
1038  // XXX quick hack: check each in myVehicles against all others
1039  for (AnyVehicleIterator veh = anyVehiclesBegin(); veh != anyVehiclesEnd(); ++veh) {
1040  MSVehicle* follow = (MSVehicle*)*veh;
1041  for (AnyVehicleIterator veh2 = anyVehiclesBegin(); veh2 != anyVehiclesEnd(); ++veh2) {
1042  MSVehicle* lead = (MSVehicle*)*veh2;
1043  if (lead == follow) {
1044  continue;
1045  }
1046  if (lead->getPositionOnLane(this) < follow->getPositionOnLane(this)) {
1047  continue;
1048  }
1049  if (detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1050  break;
1051  }
1052  }
1053  if (follow->getLaneChangeModel().getShadowLane() != 0 && follow->getLane() == this) {
1054  // check whether follow collides on the shadow lane
1055  const MSLane* shadowLane = follow->getLaneChangeModel().getShadowLane();
1056  MSLeaderInfo ahead = shadowLane->getLastVehicleInformation(follow,
1057  getRightSideOnEdge() - shadowLane->getRightSideOnEdge(),
1058  follow->getPositionOnLane());
1059  for (int i = 0; i < ahead.numSublanes(); ++i) {
1060  const MSVehicle* lead = ahead[i];
1061  if (lead != 0 && lead != follow && shadowLane->detectCollisionBetween(timestep, stage, follow, lead, toRemove, toTeleport)) {
1062  break;
1063  }
1064  }
1065  }
1066  }
1067  }
1068 
1070  assert(myLinks.size() == 1);
1071  //std::cout << SIMTIME << " checkJunctionCollisions " << getID() << "\n";
1072  const std::vector<const MSLane*>& foeLanes = myLinks.front()->getFoeLanes();
1073  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
1074  const MSVehicle* collider = *veh;
1075  //std::cout << " collider " << collider->getID() << "\n";
1076  PositionVector colliderBoundary = collider->getBoundingBox();
1077  for (std::vector<const MSLane*>::const_iterator it = foeLanes.begin(); it != foeLanes.end(); ++it) {
1078  const MSLane* foeLane = *it;
1079  //std::cout << " foeLane " << foeLane->getID() << "\n";
1080  MSLane::AnyVehicleIterator end = foeLane->anyVehiclesEnd();
1081  for (MSLane::AnyVehicleIterator it_veh = foeLane->anyVehiclesBegin(); it_veh != end; ++it_veh) {
1082  MSVehicle* victim = (MSVehicle*)*it_veh;
1083  //std::cout << " victim " << victim->getID() << "\n";
1084  if (colliderBoundary.overlapsWith(victim->getBoundingBox())) {
1085  // make a detailed check
1086  if (collider->getBoundingPoly().overlapsWith(victim->getBoundingPoly())) {
1087  handleCollisionBetween(timestep, stage, collider, victim, -1, 0, toRemove, toTeleport);
1088  }
1089  }
1090  }
1091  }
1092  }
1093  }
1094 
1095  for (std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
1096  MSVehicle* veh = const_cast<MSVehicle*>(*it);
1097  MSLane* vehLane = veh->getLane();
1099  if (toTeleport.count(veh) > 0) {
1100  MSVehicleTransfer::getInstance()->add(timestep, veh);
1101  } else {
1104  }
1105  }
1106 }
1107 
1108 
1109 bool
1110 MSLane::detectCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
1111  std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>& toRemove,
1112  std::set<const MSVehicle*>& toTeleport) const {
1113  assert(collider->isFrontOnLane(this));
1114 #ifndef NO_TRACI
1115  if (myCollisionAction == COLLISION_ACTION_TELEPORT && ((victim->hasInfluencer() && victim->getInfluencer()->isVTDAffected(timestep)) ||
1116  (collider->hasInfluencer() && collider->getInfluencer()->isVTDAffected(timestep)))) {
1117  return false;
1118  }
1119 #endif
1120  const bool colliderOpposite = collider->getLaneChangeModel().isOpposite();
1121  const bool bothOpposite = victim->getLaneChangeModel().isOpposite() && colliderOpposite;
1122  if (bothOpposite) {
1123  std::swap(victim, collider);
1124  }
1125  const SUMOReal colliderPos = colliderOpposite ? collider->getBackPositionOnLane(this) : collider->getPositionOnLane(this);
1126  SUMOReal gap = victim->getBackPositionOnLane(this) - colliderPos - collider->getVehicleType().getMinGap();
1127  if (bothOpposite) {
1128  gap = -gap - 2 * collider->getVehicleType().getMinGap();
1129  }
1130 #ifdef DEBUG_COLLISIONS
1131  if (DEBUG_COND) std::cout << SIMTIME
1132  << " thisLane=" << getID()
1133  << " collider=" << collider->getID()
1134  << " victim=" << victim->getID()
1135  << " colliderLane=" << collider->getLane()->getID()
1136  << " victimLane=" << victim->getLane()->getID()
1137  << " colliderPos=" << colliderPos
1138  << " victimBackPos=" << victim->getBackPositionOnLane(this)
1139  << " colliderLat=" << collider->getCenterOnEdge(this)
1140  << " victimLat=" << victim->getCenterOnEdge(this)
1141  << " gap=" << gap
1142  << "\n";
1143 #endif
1144  if (gap < -NUMERICAL_EPS) {
1145  SUMOReal latGap = 0;
1147  latGap = (fabs(victim->getCenterOnEdge(this) - collider->getCenterOnEdge(this))
1148  - 0.5 * fabs(victim->getVehicleType().getWidth() + collider->getVehicleType().getWidth()));
1149  if (latGap + NUMERICAL_EPS > 0) {
1150  return false;
1151  }
1152  }
1154  && collider->getLaneChangeModel().isChangingLanes()
1155  && victim->getLaneChangeModel().isChangingLanes()
1156  && victim->getLane() != this) {
1157  // synchroneous lane change maneuver
1158  return false;
1159  }
1160  handleCollisionBetween(timestep, stage, collider, victim, gap, latGap, toRemove, toTeleport);
1161  return true;
1162  }
1163  return false;
1164 }
1165 
1166 
1167 void
1168 MSLane::handleCollisionBetween(SUMOTime timestep, const std::string& stage, const MSVehicle* collider, const MSVehicle* victim,
1169  SUMOReal gap, SUMOReal latGap, std::set<const MSVehicle*, SUMOVehicle::ComparatorIdLess>& toRemove,
1170  std::set<const MSVehicle*>& toTeleport) const {
1171  std::string prefix;
1172  switch (myCollisionAction) {
1173  case COLLISION_ACTION_WARN:
1174  prefix = "Vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1175  break;
1177  prefix = "Teleporting vehicle '" + collider->getID() + "'; collision with vehicle '" + victim->getID() ;
1178  toRemove.insert(collider);
1179  toTeleport.insert(collider);
1180  break;
1181  case COLLISION_ACTION_REMOVE: {
1182  prefix = "Removing collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1183  bool removeCollider = true;
1184  bool removeVictim = true;
1185 #ifndef NO_TRACI
1186  removeVictim = !(victim->hasInfluencer() && victim->getInfluencer()->isVTDAffected(timestep));
1187  removeCollider = !(collider->hasInfluencer() && collider->getInfluencer()->isVTDAffected(timestep));
1188  if (removeVictim) {
1189  toRemove.insert(victim);
1190  }
1191  if (removeCollider) {
1192  toRemove.insert(collider);
1193  }
1194  if (!removeVictim) {
1195  if (!removeCollider) {
1196  prefix = "Keeping remote-controlled collision participants: vehicle '" + collider->getID() + "', vehicle '" + victim->getID();
1197  } else {
1198  prefix = "Removing collision participant: vehicle '" + collider->getID() + "', keeping remote-controlled vehicle '" + victim->getID();
1199  }
1200  } else if (!removeCollider) {
1201  prefix = "Keeping remote-controlled collision participant: vehicle '" + collider->getID() + "', removing vehicle '" + victim->getID();
1202  }
1203 #else
1204  toRemove.insert(victim);
1205  toRemove.insert(collider);
1206 #endif
1207  break;
1208  }
1209  default:
1210  break;
1211  }
1212  WRITE_WARNING(prefix
1213  + "', lane='" + getID()
1214  + "', gap=" + toString(gap)
1215  + (latGap == 0 ? "" : "', latGap=" + toString(latGap))
1216  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())
1217  + " stage=" + stage + ".");
1219 }
1220 
1221 
1222 bool
1223 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& lanesWithVehiclesToIntegrate) {
1224  // iterate over vehicles in reverse so that move reminders will be called in the correct order
1225  for (VehCont::reverse_iterator i = myVehicles.rbegin(); i != myVehicles.rend();) {
1226  MSVehicle* veh = *i;
1227  // length is needed later when the vehicle may not exist anymore
1228  const SUMOReal length = veh->getVehicleType().getLengthWithGap();
1229  const SUMOReal nettoLength = veh->getVehicleType().getLength();
1230  const bool moved = veh->executeMove();
1231  MSLane* const target = veh->getLane();
1232  if (veh->hasArrived()) {
1233  // vehicle has reached its arrival position
1236  } else if (target != 0 && moved) {
1237  if (target->getEdge().isVaporizing()) {
1238  // vehicle has reached a vaporizing edge
1241  } else {
1242  // vehicle has entered a new lane (leaveLane and workOnMoveReminders were already called in MSVehicle::executeMove)
1243  target->myVehBuffer.push_back(veh);
1244  lanesWithVehiclesToIntegrate.push_back(target);
1245  }
1246  } else if (veh->isParking()) {
1247  // vehicle started to park
1249  } else if (veh->getPositionOnLane() > getLength()) {
1250  // for any reasons the vehicle is beyond its lane...
1251  // this should never happen because it is handled in MSVehicle::executeMove
1252  assert(false);
1253  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond end of lane, target lane='" + getID() + "', time=" +
1254  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1257  } else {
1258  ++i;
1259  continue;
1260  }
1261  myBruttoVehicleLengthSum -= length;
1262  myNettoVehicleLengthSum -= nettoLength;
1263  ++i;
1264  i = VehCont::reverse_iterator(myVehicles.erase(i.base()));
1265  }
1266  if (myVehicles.size() > 0) {
1268  MSVehicle* veh = myVehicles.back(); // the vehice at the front of the queue
1269  if (!veh->isStopped() && veh->getLane() == this) {
1270  const bool wrongLane = !veh->getLane()->appropriate(veh);
1272  const bool r2 = MSGlobals::gTimeToGridlockHighways > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlockHighways && veh->getLane()->getSpeedLimit() > 69. / 3.6 && wrongLane;
1273  if (r1 || r2) {
1274  const MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1275  const bool minorLink = !wrongLane && (link != myLinks.end()) && !((*link)->havePriority());
1276  const std::string reason = (wrongLane ? " (wrong lane)" : (minorLink ? " (yield)" : " (jam)"));
1277  MSVehicle* veh = *(myVehicles.end() - 1);
1280  myVehicles.erase(myVehicles.end() - 1);
1281  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long"
1282  + reason
1283  + (r2 ? " (highway)" : "")
1284  + ", lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1285  if (wrongLane) {
1287  } else if (minorLink) {
1289  } else {
1291  }
1293  }
1294  } // else look for a (waiting) vehicle that isn't stopped?
1295  }
1296  }
1298  // trigger sorting of vehicles as their order may have changed
1299  lanesWithVehiclesToIntegrate.push_back(this);
1300  }
1301  return myVehicles.size() == 0;
1302 }
1303 
1304 
1305 const MSEdge*
1307  const MSEdge* e = myEdge;
1308  while (e->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1309  e = e->getSuccessors()[0];
1310  }
1311  return e;
1312 }
1313 
1314 
1315 // ------ Static (sic!) container methods ------
1316 bool
1317 MSLane::dictionary(const std::string& id, MSLane* ptr) {
1318  DictType::iterator it = myDict.find(id);
1319  if (it == myDict.end()) {
1320  // id not in myDict.
1321  myDict.insert(DictType::value_type(id, ptr));
1322  return true;
1323  }
1324  return false;
1325 }
1326 
1327 
1328 MSLane*
1329 MSLane::dictionary(const std::string& id) {
1330  DictType::iterator it = myDict.find(id);
1331  if (it == myDict.end()) {
1332  // id not in myDict.
1333  return 0;
1334  }
1335  return it->second;
1336 }
1337 
1338 
1339 void
1341  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1342  delete(*i).second;
1343  }
1344  myDict.clear();
1345 }
1346 
1347 
1348 void
1349 MSLane::insertIDs(std::vector<std::string>& into) {
1350  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1351  into.push_back((*i).first);
1352  }
1353 }
1354 
1355 
1356 template<class RTREE> void
1357 MSLane::fill(RTREE& into) {
1358  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
1359  MSLane* l = (*i).second;
1360  Boundary b = l->getShape().getBoxBoundary();
1361  b.grow(3.);
1362  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
1363  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
1364  into.Insert(cmin, cmax, l);
1365  }
1366 }
1367 
1368 template void MSLane::fill<NamedRTree>(NamedRTree& into);
1369 #ifndef NO_TRACI
1370 template void MSLane::fill<LANE_RTREE_QUAL>(LANE_RTREE_QUAL& into);
1371 #endif
1372 
1373 // ------ ------
1374 bool
1377  return true;
1378  }
1379  if (veh->succEdge(1) == 0) {
1380  assert((int)veh->getBestLanes().size() > veh->getLaneIndex());
1381  if (veh->getBestLanes()[veh->getLaneIndex()].bestLaneOffset == 0) {
1382  return true;
1383  } else {
1384  return false;
1385  }
1386  }
1387  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
1388  return (link != myLinks.end());
1389 }
1390 
1391 
1392 bool
1394  bool wasInactive = myVehicles.size() == 0;
1395  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter(this));
1396  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
1397  MSVehicle* veh = *i;
1398  assert(veh->getLane() == this);
1399  myVehicles.insert(myVehicles.begin(), veh);
1402  //if (true) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " veh=" << veh->getID() << " (on lane " << veh->getLane()->getID() << ") into lane=" << getID() << " myBrutto=" << myBruttoVehicleLengthSum << "\n";
1403  myEdge->markDelayed();
1404  }
1405  myVehBuffer.clear();
1406  //std::cout << SIMTIME << " integrateNewVehicle lane=" << getID() << " myVehicles1=" << toString(myVehicles);
1407  if (MSGlobals::gLateralResolution > 0 || myNeighs.size() > 0) {
1408  sort(myVehicles.begin(), myVehicles.end(), vehicle_natural_position_sorter(this));
1409  }
1411 #ifdef DEBUG_VEHICLE_CONTAINER
1412  if (DEBUG_COND) std::cout << SIMTIME << " integrateNewVehicle lane=" << getID()
1413  << " vhicles=" << toString(myVehicles) << " partials=" << toString(myPartialVehicles) << "\n";
1414 #endif
1415  return wasInactive && myVehicles.size() != 0;
1416 }
1417 
1418 
1419 void
1421  if (myPartialVehicles.size() > 1) {
1423  }
1424 }
1425 
1426 bool
1427 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
1428  return i == myLinks.end();
1429 }
1430 
1431 
1432 bool
1433 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
1434  return i == myLinks.end();
1435 }
1436 
1437 bool
1439  return myVehicles.empty() && myPartialVehicles.empty();
1440 }
1441 
1442 bool
1445 }
1446 
1447 MSVehicle*
1449  if (myVehicles.size() == 0) {
1450  return 0;
1451  }
1452  return myVehicles.front();
1453 }
1454 
1455 
1456 MSVehicle*
1458  if (myVehicles.size() == 0) {
1459  return 0;
1460  }
1461  return myVehicles.back();
1462 }
1463 
1464 
1465 MSVehicle*
1467  // all vehicles in myVehicles should have positions smaller or equal to
1468  // those in myPartialVehicles
1469  if (myVehicles.size() > 0) {
1470  return myVehicles.front();
1471  }
1472  if (myPartialVehicles.size() > 0) {
1473  return myPartialVehicles.front();
1474  }
1475  return 0;
1476 }
1477 
1478 
1479 MSVehicle*
1481  MSVehicle* result = 0;
1482  if (myVehicles.size() > 0) {
1483  result = myVehicles.back();
1484  }
1485  if (myPartialVehicles.size() > 0
1486  && (result == 0 || result->getPositionOnLane(this) < myPartialVehicles.back()->getPositionOnLane(this))) {
1487  result = myPartialVehicles.back();
1488  }
1489  return result;
1490 }
1491 
1492 
1493 MSLinkCont::const_iterator
1494 MSLane::succLinkSec(const SUMOVehicle& veh, int nRouteSuccs,
1495  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) {
1496  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
1497  // check whether the vehicle tried to look beyond its route
1498  if (nRouteEdge == 0) {
1499  // return end (no succeeding link) if so
1500  return succLinkSource.myLinks.end();
1501  }
1502  // if we are on an internal lane there should only be one link and it must be allowed
1503  if (succLinkSource.isInternal()) {
1504  assert(succLinkSource.myLinks.size() == 1);
1505  // could have been disallowed dynamically with a rerouter or via TraCI
1506  // assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
1507  return succLinkSource.myLinks.begin();
1508  }
1509  // a link may be used if
1510  // 1) there is a destination lane ((*link)->getLane()!=0)
1511  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
1512  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
1513 
1514  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
1515  // "conts" stores the best continuations of our current lane
1516  // we should never return an arbitrary link since this may cause collisions
1517 
1518  MSLinkCont::const_iterator link;
1519  if (nRouteSuccs < (int)conts.size()) {
1520  // we go through the links in our list and return the matching one
1521  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
1522  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
1523  // we should use the link if it connects us to the best lane
1524  if ((*link)->getLane() == conts[nRouteSuccs]) {
1525  return link;
1526  }
1527  }
1528  }
1529  } else {
1530  // the source lane is a dead end (no continuations exist)
1531  return succLinkSource.myLinks.end();
1532  }
1533  // the only case where this should happen is for a disconnected route (deliberately ignored)
1534 #ifdef _DEBUG
1535  // the "'" around the ids are missing intentionally in the message below because it slows messaging down, resulting in test timeouts
1536  WRITE_WARNING("Could not find connection between lane " + succLinkSource.getID() + " and lane " + conts[nRouteSuccs]->getID() +
1537  " for vehicle " + veh.getID() + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1538 #endif
1539  return succLinkSource.myLinks.end();
1540 }
1541 
1542 
1543 
1544 const MSLinkCont&
1546  return myLinks;
1547 }
1548 
1549 
1550 void
1552  myMaxSpeed = val;
1553  myEdge->recalcCache();
1554 }
1555 
1556 
1557 void
1559  myLength = val;
1560  myEdge->recalcCache();
1561 }
1562 
1563 
1564 void
1566  //if (getID() == "disabled_lane") std::cout << SIMTIME << " swapAfterLaneChange lane=" << getID() << " myVehicles=" << toString(myVehicles) << " myTmpVehicles=" << toString(myTmpVehicles) << "\n";
1568  myTmpVehicles.clear();
1569  // this needs to be done after finishing lane-changing for all lanes on the
1570  // current edge (MSLaneChanger::updateLanes())
1572 }
1573 
1574 
1575 MSVehicle*
1576 MSLane::removeVehicle(MSVehicle* remVehicle, MSMoveReminder::Notification notification, bool notify) {
1577  assert(remVehicle->getLane() == this);
1578  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
1579  if (remVehicle == *it) {
1580  if (notify) {
1581  remVehicle->leaveLane(notification);
1582  }
1583  myVehicles.erase(it);
1586  break;
1587  }
1588  }
1589  return remVehicle;
1590 }
1591 
1592 
1593 MSLane*
1594 MSLane::getParallelLane(int offset) const {
1595  return myEdge->parallelLane(this, offset);
1596 }
1597 
1598 
1599 void
1601  IncomingLaneInfo ili;
1602  ili.lane = lane;
1603  ili.viaLink = viaLink;
1604  ili.length = lane->getLength();
1605  myIncomingLanes.push_back(ili);
1606 }
1607 
1608 
1609 void
1610 MSLane::addApproachingLane(MSLane* lane, bool warnMultiCon) {
1611  MSEdge* approachingEdge = &lane->getEdge();
1612  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1613  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1614  } else if (approachingEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL && warnMultiCon) {
1615  // whenever a normal edge connects twice, there is a corresponding
1616  // internal edge wich connects twice, one warning is sufficient
1617  WRITE_WARNING("Lane '" + getID() + "' is approached multiple times from edge '" + approachingEdge->getID() + "'. This may cause collisions.");
1618  }
1619  myApproachingLanes[approachingEdge].push_back(lane);
1620 }
1621 
1622 
1623 bool
1625  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1626 }
1627 
1628 
1629 bool
1630 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1631  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1632  if (i == myApproachingLanes.end()) {
1633  return false;
1634  }
1635  const std::vector<MSLane*>& lanes = (*i).second;
1636  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1637 }
1638 
1639 
1641 public:
1642  inline int operator()(const std::pair<const MSVehicle*, SUMOReal>& p1, const std::pair<const MSVehicle*, SUMOReal>& p2) const {
1643  return p1.second < p2.second;
1644  }
1645 };
1646 
1647 
1649  SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1650  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1651  // search and check for the vehicle with the largest missing rear gap within
1652  // relevant range
1653  SUMOReal result = 0;
1654  std::pair<MSVehicle* const, SUMOReal> followerInfo = getFollowerOnConsecutive(backOffset, leaderSpeed, leaderMaxDecel);
1655  MSVehicle* v = followerInfo.first;
1656  if (v != 0) {
1657  result = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - followerInfo.second;
1658  }
1659  return result;
1660 }
1661 
1662 
1663 SUMOReal
1666  const SUMOReal maxSpeed = getSpeedLimit() * vc.getMaxSpeedFactor();
1667  // NOTE: For the euler update this is an upper bound on the actual braking distance (see ticket #860)
1668  return maxSpeed * maxSpeed * 0.5 / vc.getMinDeceleration();
1669 }
1670 
1671 
1672 std::pair<MSVehicle* const, SUMOReal>
1674  SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel, SUMOReal dist, bool ignoreMinorLinks) const {
1675  // do a tree search among all follower lanes and check for the most
1676  // important vehicle (the one requiring the largest reargap)
1677  // to get a safe bound on the necessary search depth, we need to consider the maximum speed and minimum
1678  // deceleration of potential follower vehicles
1679  if (dist == -1) {
1680  dist = getMaximumBrakeDist() - backOffset;
1681  }
1682 #ifdef DEBUG_CONTEXT
1683  if (DEBUG_COND) std::cout << SIMTIME << " getFollowerOnConsecutive"
1684  << " backOffset=" << backOffset
1685  << " leaderSpeed=" << leaderSpeed
1686  << " dist=" << dist
1687  << "\n";
1688 #endif
1689  std::pair<MSVehicle*, SUMOReal> result(static_cast<MSVehicle*>(0), -1);
1690  SUMOReal missingRearGapMax = -std::numeric_limits<SUMOReal>::max();
1691  std::set<MSLane*> visited;
1692  std::vector<MSLane::IncomingLaneInfo> newFound;
1693  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1694  while (toExamine.size() != 0) {
1695  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1696  MSLane* next = (*i).lane;
1697 #ifdef DEBUG_CONTEXT
1698  if (DEBUG_COND) {
1699  std::cout << SIMTIME << " nextLane=" << next->getID() << "\n";
1700  }
1701 #endif
1702  // XXX: why take a MAX here? Even if some upcoming lane allows to go faster, the follower should be able
1703  // to brake in time if we only consider 'next->getMaximumBrakeDist() - backOffset'.
1704  dist = MAX2(dist, next->getMaximumBrakeDist() - backOffset);
1705  // Checking the first vehicle on the considered lane.
1706  // XXX: Could there be a problem if someone fast is just overtaking a a slow first vehicle, e.g.? (Leo) Refs.#2578
1707  MSVehicle* v = next->getFirstAnyVehicle();
1708  SUMOReal agap = 0;
1709  if (v != 0) {
1710  // the front of v is already on divergent trajectory from the ego vehicle
1711  // for which this method is called (in the context of MSLaneChanger).
1712  // Therefore, technically v is not a follower but only an obstruction and
1713  // the gap is not between the front of v and the back of ego
1714  // but rather between the flank of v and the back of ego.
1715  if (!v->isFrontOnLane(next)) {
1716  agap = (*i).length - next->getLength() + backOffset
1718  - v->getVehicleType().getMinGap();
1719  if (agap > 0) {
1720  // Only if ego overlaps we treat v as if it were a real follower
1721  // Otherwise we ignore it and look for another follower
1722  v = next->getFirstFullVehicle();
1723  if (v != 0) {
1724  agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1725  }
1726  }
1727  } else {
1728  agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1729  }
1730 #ifdef DEBUG_CONTEXT
1731  if (DEBUG_COND) std::cout << SIMTIME << " "
1732  << " v=" << Named::getIDSecure(v)
1733  << " agap=" << agap
1734  << " dist=" << dist
1735  << "\n";
1736 #endif
1737  }
1738  if (v != 0) {
1739  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(v->getSpeed(), leaderSpeed, leaderMaxDecel) - agap;
1740  if (missingRearGap > missingRearGapMax) {
1741  missingRearGapMax = missingRearGap;
1742  result.first = v;
1743  result.second = agap;
1744  }
1745  } else {
1746  if ((*i).length < dist) {
1747  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1748  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1749  if (visited.find((*j).lane) == visited.end() && ((*j).viaLink->havePriority() || !ignoreMinorLinks)) {
1750  visited.insert((*j).lane);
1752  ili.lane = (*j).lane;
1753  ili.length = (*j).length + (*i).length;
1754  ili.viaLink = (*j).viaLink;
1755  newFound.push_back(ili);
1756  }
1757  }
1758  }
1759  }
1760  }
1761  toExamine.clear();
1762  swap(newFound, toExamine);
1763  }
1764  return result;
1765 }
1766 
1767 std::pair<MSVehicle* const, SUMOReal>
1768 MSLane::getLeader(const MSVehicle* veh, const SUMOReal vehPos, const std::vector<MSLane*>& bestLaneConts, SUMOReal dist, bool checkTmpVehicles) const {
1769  // get the leading vehicle for (shadow) veh
1770  // XXX this only works as long as all lanes of an edge have equal length
1771 #ifdef DEBUG_CONTEXT
1772  if (DEBUG_COND2(veh)) {
1773  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " vehs=" << toString(myVehicles) << " tmpVehs=" << toString(myTmpVehicles) << "\n";
1774  }
1775 #endif
1776  if (checkTmpVehicles) {
1777  for (VehCont::const_iterator last = myTmpVehicles.begin(); last != myTmpVehicles.end(); ++last) {
1778  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
1779  MSVehicle* pred = (MSVehicle*)*last;
1780  if (pred == veh) {
1781  continue;
1782  }
1783 #ifdef DEBUG_CONTEXT
1784  if (DEBUG_COND2(veh)) {
1785  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane() << "\n";
1786  }
1787 #endif
1788  if (pred->getPositionOnLane() > vehPos + NUMERICAL_EPS) {
1789  return std::pair<MSVehicle* const, SUMOReal>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
1790  }
1791  }
1792  } else {
1793  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
1794  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
1795  MSVehicle* pred = (MSVehicle*)*last;
1796  if (pred == veh) {
1797  continue;
1798  }
1799 #ifdef DEBUG_CONTEXT
1800  if (DEBUG_COND2(veh)) {
1801  std::cout << " getLeader lane=" << getID() << " ego=" << veh->getID() << " egoPos=" << vehPos
1802  << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << " predBack=" << pred->getBackPositionOnLane(this) << "\n";
1803  }
1804 #endif
1805  if (pred->getPositionOnLane(this) > vehPos + NUMERICAL_EPS) {
1806  return std::pair<MSVehicle* const, SUMOReal>(pred, pred->getBackPositionOnLane(this) - veh->getVehicleType().getMinGap() - vehPos);
1807  }
1808  }
1809  }
1810  // XXX from here on the code mirrors MSLaneChanger::getRealLeader
1811  if (bestLaneConts.size() > 0) {
1812  SUMOReal seen = getLength() - vehPos;
1813  SUMOReal speed = veh->getSpeed();
1814  if (dist < 0) {
1815  dist = veh->getCarFollowModel().brakeGap(speed) + veh->getVehicleType().getMinGap();
1816  }
1817 #ifdef DEBUG_CONTEXT
1818  if (DEBUG_COND2(veh)) {
1819  std::cout << " getLeader lane=" << getID() << " seen=" << seen << " dist=" << dist << "\n";
1820  }
1821 #endif
1822  if (seen > dist) {
1823  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1824  }
1825  return getLeaderOnConsecutive(dist, seen, speed, *veh, bestLaneConts);
1826  } else {
1827  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1828  }
1829 }
1830 
1831 
1832 std::pair<MSVehicle* const, SUMOReal>
1834  const std::vector<MSLane*>& bestLaneConts) const {
1835 #ifdef DEBUG_CONTEXT
1836  if (DEBUG_COND2(&veh)) {
1837  std::cout << " getLeaderOnConsecutive lane=" << getID() << " ego=" << veh.getID() << " seen=" << seen << " dist=" << dist << " conts=" << toString(bestLaneConts) << "\n";
1838  }
1839 #endif
1840  if (seen > dist) {
1841  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1842  }
1843  int view = 1;
1844  // loop over following lanes
1845  if (myPartialVehicles.size() > 0) {
1846  // XXX
1847  MSVehicle* pred = myPartialVehicles.front();
1848 #ifdef DEBUG_CONTEXT
1849  if (DEBUG_COND2(&veh)) {
1850  std::cout << " partials=" << toString(myPartialVehicles) << "\n";
1851  }
1852 #endif
1853  return std::pair<MSVehicle* const, SUMOReal>(pred, seen - (getLength() - pred->getBackPositionOnLane(this)) - veh.getVehicleType().getMinGap());
1854  }
1855  const MSLane* nextLane = this;
1856  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1857  do {
1858  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
1859  // get the next link used
1860  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1861  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1862  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
1863 #ifdef DEBUG_CONTEXT
1864  if (DEBUG_COND2(&veh)) {
1865  std::cout << " cannot continue after nextLane=" << nextLane->getID() << "\n";
1866  }
1867 #endif
1868  nextLane->releaseVehicles();
1869  break;
1870  }
1871 #ifdef HAVE_INTERNAL_LANES
1872  // check for link leaders
1873  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
1874  nextLane->releaseVehicles();
1875  if (linkLeaders.size() > 0) {
1876  // XXX if there is more than one link leader we should return the most important
1877  // one (gap, decel) but this is hard to know at this point
1878 #ifdef DEBUG_CONTEXT
1879  if (DEBUG_COND2(&veh)) {
1880  std::cout << " found linkLeader after nextLane=" << nextLane->getID() << "\n";
1881  }
1882 #endif
1883  return linkLeaders[0].vehAndGap;
1884  }
1885  bool nextInternal = (*link)->getViaLane() != 0;
1886 #endif
1887  nextLane = (*link)->getViaLaneOrLane();
1888  if (nextLane == 0) {
1889  break;
1890  }
1891  nextLane->getVehiclesSecure(); // lock against running sim when called from GUI for time gap coloring
1892  MSVehicle* leader = nextLane->getLastAnyVehicle();
1893  if (leader != 0) {
1894 #ifdef DEBUG_CONTEXT
1895  if (DEBUG_COND2(&veh)) {
1896  std::cout << " found leader " << leader->getID() << " on nextLane=" << nextLane->getID() << "\n";
1897  }
1898 #endif
1899  const SUMOReal dist = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
1900  nextLane->releaseVehicles();
1901  return std::make_pair(leader, dist);
1902  }
1903  nextLane->releaseVehicles();
1904  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1905  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1906  }
1907  seen += nextLane->getLength();
1908  if (seen <= dist) {
1909  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1910  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1911  }
1912 #ifdef HAVE_INTERNAL_LANES
1913  if (!nextInternal) {
1914  view++;
1915  }
1916 #else
1917  view++;
1918 #endif
1919  } while (seen <= dist);
1920  return std::make_pair(static_cast<MSVehicle*>(0), -1);
1921 }
1922 
1923 
1924 std::pair<MSVehicle* const, SUMOReal>
1925 MSLane::getCriticalLeader(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle& veh) const {
1926  const std::vector<MSLane*>& bestLaneConts = veh.getBestLanesContinuation(this);
1927  std::pair<MSVehicle*, SUMOReal> result = std::make_pair(static_cast<MSVehicle*>(0), -1);
1929  int view = 1;
1930  // loop over following lanes
1931  // @note: we don't check the partial occupator for this lane since it was
1932  // already checked in MSLaneChanger::getRealLeader()
1933  const MSLane* nextLane = this;
1934  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
1935  do {
1936  // get the next link used
1937  MSLinkCont::const_iterator link = succLinkSec(veh, view, *nextLane, bestLaneConts);
1938  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength(),
1939  veh.getImpatience(), veh.getCarFollowModel().getMaxDecel(), 0, veh.getLateralPositionOnLane()) || (*link)->haveRed()) {
1940  return result;
1941  }
1942 #ifdef HAVE_INTERNAL_LANES
1943  // check for link leaders
1944  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(&veh, seen);
1945  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1946  const MSVehicle* leader = (*it).vehAndGap.first;
1947  if (leader != 0 && leader != result.first) {
1948  // XXX ignoring pedestrians here!
1949  // XXX ignoring the fact that the link leader may alread by following us
1950  // XXX ignoring the fact that we may drive up to the crossing point
1951  const SUMOReal tmpSpeed = veh.getSafeFollowSpeed((*it).vehAndGap, seen, nextLane, (*it).distToCrossing);
1952  if (tmpSpeed < safeSpeed) {
1953  safeSpeed = tmpSpeed;
1954  result = (*it).vehAndGap;
1955  }
1956  }
1957  }
1958  bool nextInternal = (*link)->getViaLane() != 0;
1959 #endif
1960  nextLane = (*link)->getViaLaneOrLane();
1961  if (nextLane == 0) {
1962  break;
1963  }
1964  MSVehicle* leader = nextLane->getLastAnyVehicle();
1965  if (leader != 0 && leader != result.first) {
1966  const SUMOReal gap = seen + leader->getBackPositionOnLane(nextLane) - veh.getVehicleType().getMinGap();
1967  const SUMOReal tmpSpeed = veh.getCarFollowModel().insertionFollowSpeed(leader, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
1968  if (tmpSpeed < safeSpeed) {
1969  safeSpeed = tmpSpeed;
1970  result = std::make_pair(leader, gap);
1971  }
1972  }
1973  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1974  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1975  }
1976  seen += nextLane->getLength();
1977  if (seen <= dist) {
1978  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
1979  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
1980  }
1981 #ifdef HAVE_INTERNAL_LANES
1982  if (!nextInternal) {
1983  view++;
1984  }
1985 #else
1986  view++;
1987 #endif
1988  } while (seen <= dist);
1989  return result;
1990 }
1991 
1992 
1993 MSLane*
1995  if (myLogicalPredecessorLane != 0) {
1996  return myLogicalPredecessorLane;
1997  }
1998  if (myLogicalPredecessorLane == 0) {
2000  // get only those edges which connect to this lane
2001  for (MSEdgeVector::iterator i = pred.begin(); i != pred.end();) {
2002  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
2003  if (j == myIncomingLanes.end()) {
2004  i = pred.erase(i);
2005  } else {
2006  ++i;
2007  }
2008  }
2009  // get the lane with the "straightest" connection
2010  if (pred.size() != 0) {
2011  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
2012  MSEdge* best = *pred.begin();
2013  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
2014  myLogicalPredecessorLane = (*j).lane;
2015  }
2016  }
2017  return myLogicalPredecessorLane;
2018 }
2019 
2020 
2021 MSLane*
2023  for (std::vector<IncomingLaneInfo>::const_iterator i = myIncomingLanes.begin(); i != myIncomingLanes.end(); ++i) {
2024  MSLane* cand = (*i).lane;
2025  if (&(cand->getEdge()) == &fromEdge) {
2026  return (*i).lane;
2027  }
2028  }
2029  return 0;
2030 }
2031 
2032 
2033 LinkState
2036  if (pred == 0) {
2037  return LINKSTATE_DEADEND;
2038  } else {
2039  return MSLinkContHelper::getConnectingLink(*pred, *this)->getState();
2040  }
2041 }
2042 
2043 
2044 std::vector<const MSLane*>
2046  std::vector<const MSLane*> result;
2047  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
2048  assert((*i)->getLane() != 0);
2049  result.push_back((*i)->getLane());
2050  }
2051  return result;
2052 }
2053 
2054 
2055 void
2059 }
2060 
2061 
2062 void
2066 }
2067 
2068 
2069 int
2071  for (MSLinkCont::const_iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
2072  if ((*i)->getLane()->getEdge().isCrossing()) {
2073  return (int)(i - myLinks.begin());
2074  }
2075  }
2076  return -1;
2077 }
2078 
2079 // ------------ Current state retrieval
2080 SUMOReal
2082  SUMOReal fractions = myPartialVehicles.size() > 0 ? myLength - myPartialVehicles.front()->getBackPositionOnLane(this) : 0;
2084  if (myVehicles.size() != 0) {
2085  MSVehicle* lastVeh = myVehicles.front();
2086  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2087  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2088  }
2089  }
2090  releaseVehicles();
2091  return (myBruttoVehicleLengthSum + fractions) / myLength;
2092 }
2093 
2094 
2095 SUMOReal
2097  SUMOReal fractions = myPartialVehicles.size() > 0 ? myLength - myPartialVehicles.front()->getBackPositionOnLane(this) : 0;
2099  if (myVehicles.size() != 0) {
2100  MSVehicle* lastVeh = myVehicles.front();
2101  if (lastVeh->getPositionOnLane() < lastVeh->getVehicleType().getLength()) {
2102  fractions -= (lastVeh->getVehicleType().getLength() - lastVeh->getPositionOnLane());
2103  }
2104  }
2105  releaseVehicles();
2106  return (myNettoVehicleLengthSum + fractions) / myLength;
2107 }
2108 
2109 
2110 SUMOReal
2112  if (myVehicles.size() == 0) {
2113  return 0;
2114  }
2115  SUMOReal wtime = 0;
2116  for (VehCont::const_iterator i = myVehicles.begin(); i != myVehicles.end(); ++i) {
2117  wtime += (*i)->getWaitingSeconds();
2118  }
2119  return wtime;
2120 }
2121 
2122 
2123 SUMOReal
2125  if (myVehicles.size() == 0) {
2126  return myMaxSpeed;
2127  }
2128  SUMOReal v = 0;
2129  const MSLane::VehCont& vehs = getVehiclesSecure();
2130  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2131  v += (*i)->getSpeed();
2132  }
2133  SUMOReal ret = v / (SUMOReal) myVehicles.size();
2134  releaseVehicles();
2135  return ret;
2136 }
2137 
2138 
2139 SUMOReal
2141  SUMOReal ret = 0;
2142  const MSLane::VehCont& vehs = getVehiclesSecure();
2143  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2144  ret += (*i)->getCO2Emissions();
2145  }
2146  releaseVehicles();
2147  return ret;
2148 }
2149 
2150 
2151 SUMOReal
2153  SUMOReal ret = 0;
2154  const MSLane::VehCont& vehs = getVehiclesSecure();
2155  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2156  ret += (*i)->getCOEmissions();
2157  }
2158  releaseVehicles();
2159  return ret;
2160 }
2161 
2162 
2163 SUMOReal
2165  SUMOReal ret = 0;
2166  const MSLane::VehCont& vehs = getVehiclesSecure();
2167  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2168  ret += (*i)->getPMxEmissions();
2169  }
2170  releaseVehicles();
2171  return ret;
2172 }
2173 
2174 
2175 SUMOReal
2177  SUMOReal ret = 0;
2178  const MSLane::VehCont& vehs = getVehiclesSecure();
2179  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2180  ret += (*i)->getNOxEmissions();
2181  }
2182  releaseVehicles();
2183  return ret;
2184 }
2185 
2186 
2187 SUMOReal
2189  SUMOReal ret = 0;
2190  const MSLane::VehCont& vehs = getVehiclesSecure();
2191  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2192  ret += (*i)->getHCEmissions();
2193  }
2194  releaseVehicles();
2195  return ret;
2196 }
2197 
2198 
2199 SUMOReal
2201  SUMOReal ret = 0;
2202  const MSLane::VehCont& vehs = getVehiclesSecure();
2203  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2204  ret += (*i)->getFuelConsumption();
2205  }
2206  releaseVehicles();
2207  return ret;
2208 }
2209 
2210 
2211 SUMOReal
2213  SUMOReal ret = 0;
2214  const MSLane::VehCont& vehs = getVehiclesSecure();
2215  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2216  ret += (*i)->getElectricityConsumption();
2217  }
2218  releaseVehicles();
2219  return ret;
2220 }
2221 
2222 
2223 SUMOReal
2225  SUMOReal ret = 0;
2226  const MSLane::VehCont& vehs = getVehiclesSecure();
2227  if (vehs.size() == 0) {
2228  releaseVehicles();
2229  return 0;
2230  }
2231  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2232  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
2233  ret += (SUMOReal) pow(10., (sv / 10.));
2234  }
2235  releaseVehicles();
2236  return HelpersHarmonoise::sum(ret);
2237 }
2238 
2239 
2240 bool
2242  return cmp->getPositionOnLane() >= pos;
2243 }
2244 
2245 
2246 int
2248  return v1->getBackPositionOnLane(myLane) > v2->getBackPositionOnLane(myLane);
2249 }
2250 
2251 int
2253  const SUMOReal pos1 = v1->getBackPositionOnLane(myLane);
2254  const SUMOReal pos2 = v2->getBackPositionOnLane(myLane);
2255  if (pos1 != pos2) {
2256  return pos1 < pos2;
2257  } else {
2259  }
2260 }
2261 
2263  myEdge(e),
2264  myLaneDir(e->getLanes()[0]->getShape().angleAt2D(0)) {
2265 }
2266 
2267 
2268 int
2269 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
2270  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
2271  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
2272  SUMOReal s1 = 0;
2273  if (ae1 != 0 && ae1->size() != 0) {
2274  s1 = (SUMOReal) ae1->size() + fabs(GeomHelper::angleDiff((*ae1)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2275  }
2276  SUMOReal s2 = 0;
2277  if (ae2 != 0 && ae2->size() != 0) {
2278  s2 = (SUMOReal) ae2->size() + fabs(GeomHelper::angleDiff((*ae2)[0]->getShape().angleAt2D(0), myLaneDir)) / M_PI / 2.;
2279  }
2280  return s1 < s2;
2281 }
2282 
2283 
2284 void
2286  out.openTag(SUMO_TAG_LANE);
2287  out.writeAttr("id", getID()); // using "id" instead of SUMO_ATTR_ID makes the value only show up in xml state
2290  out.closeTag();
2291  out.closeTag();
2292 }
2293 
2294 
2295 void
2296 MSLane::loadState(std::vector<std::string>& vehIds, MSVehicleControl& vc) {
2297  for (std::vector<std::string>::const_iterator it = vehIds.begin(); it != vehIds.end(); ++it) {
2298  MSVehicle* v = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
2299  if (v != 0) {
2300  v->updateBestLanes(false, this);
2303  v->processNextStop(v->getSpeed());
2304  }
2305  }
2306 }
2307 
2308 
2310 MSLane::getFollowersOnConsecutive(const MSVehicle* ego, bool allSublanes) const {
2311  // get the follower vehicle on the lane to change to
2312 #ifdef DEBUG_CONTEXT
2313  if (DEBUG_COND2(ego)) {
2314  std::cout << SIMTIME << " getFollowers lane=" << getID() << " ego=" << ego->getID() << " pos=" << ego->getPositionOnLane() << "\n";
2315  }
2316 #endif
2317  assert(ego != 0);
2318  assert(&ego->getLane()->getEdge() == &getEdge());
2319  const SUMOReal egoLatDist = ego->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2320  MSCriticalFollowerDistanceInfo result(this, allSublanes ? 0 : ego, allSublanes ? 0 : egoLatDist);
2322  for (AnyVehicleIterator last = anyVehiclesBegin(); last != anyVehiclesEnd(); ++last) {
2323  const MSVehicle* veh = *last;
2324 #ifdef DEBUG_CONTEXT
2325  if (DEBUG_COND2(ego)) {
2326  std::cout << " veh=" << veh->getID() << " lane=" << veh->getLane()->getID() << " pos=" << veh->getPositionOnLane(this) << "\n";
2327  }
2328 #endif
2329  if (veh != ego && veh->getPositionOnLane(this) <= ego->getPositionOnLane()) {
2330  //const SUMOReal latOffset = veh->getLane()->getRightSideOnEdge() - getRightSideOnEdge();
2331  const SUMOReal latOffset = veh->getLatOffset(this);
2332  const SUMOReal dist = ego->getBackPositionOnLane() - veh->getPositionOnLane(this) - veh->getVehicleType().getMinGap();
2333  result.addFollower(veh, ego, dist, latOffset);
2334 #ifdef DEBUG_CONTEXT
2335  if (DEBUG_COND2(ego)) {
2336  std::cout << " (1) added veh=" << veh->getID() << " latOffset=" << latOffset << " result=" << result.toString() << "\n";
2337  }
2338 #endif
2339  }
2340  }
2341 #ifdef DEBUG_CONTEXT
2342  if (DEBUG_COND2(ego)) {
2343  std::cout << " result.numFreeSublanes=" << result.numFreeSublanes() << "\n";
2344  }
2345 #endif
2346  if (result.numFreeSublanes() > 0) {
2347  const SUMOReal backOffset = ego->getBackPositionOnLane(ego->getLane());
2348  // do a tree search among all follower lanes and check for the most
2349  // important vehicle (the one requiring the largest reargap)
2350  // to get a safe bound on the necessary search depth, we need to consider the maximum speed and minimum
2351  // deceleration of potential follower vehicles
2352  SUMOReal dist = getMaximumBrakeDist() - backOffset;
2353 
2354  std::set<MSLane*> visited;
2355  std::vector<MSLane::IncomingLaneInfo> newFound;
2356  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
2357  while (toExamine.size() != 0) {
2358  for (std::vector<MSLane::IncomingLaneInfo>::iterator it = toExamine.begin(); it != toExamine.end(); ++it) {
2359  MSLane* next = (*it).lane;
2360  dist = MAX2(dist, next->getMaximumBrakeDist() - backOffset);
2361  MSLeaderInfo first = next->getFirstVehicleInformation(0, 0, false);
2362  MSLeaderInfo firstFront = next->getFirstVehicleInformation(0, 0, true);
2363 #ifdef DEBUG_CONTEXT
2364  if (DEBUG_COND2(ego)) {
2365  std::cout << " next=" << next->getID() << " first=" << first.toString() << " firstFront=" << firstFront.toString() << "\n";
2366  }
2367 #endif
2368  for (int i = 0; i < first.numSublanes(); ++i) {
2369  const MSVehicle* v = first[i];
2370  SUMOReal agap = 0;
2371  if (v != 0 && v != ego) {
2372  if (!v->isFrontOnLane(next)) {
2373  // the front of v is already on divergent trajectory from the ego vehicle
2374  // for which this method is called (in the context of MSLaneChanger).
2375  // Therefore, technically v is not a follower but only an obstruction and
2376  // the gap is not between the front of v and the back of ego
2377  // but rather between the flank of v and the back of ego.
2378  agap = (*it).length - next->getLength() + backOffset
2380  - v->getVehicleType().getMinGap();
2381  if (agap > 0) {
2382  // Only if ego overlaps we treat v as if it were a real follower
2383  // Otherwise we ignore it and look for another follower
2384  v = firstFront[i];
2385  if (v != 0 && v != ego) {
2386  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2387  } else {
2388  v = 0;
2389  }
2390  }
2391  } else {
2392  agap = (*it).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
2393  }
2394  result.addFollower(v, ego, agap, 0, i);
2395 #ifdef DEBUG_CONTEXT
2396  if (DEBUG_COND2(ego)) {
2397  std::cout << " (2) added veh=" << Named::getIDSecure(v) << " agap=" << agap << " next=" << next->getID() << " result=" << result.toString() << "\n";
2398  }
2399 #endif
2400  }
2401  }
2402  if ((*it).length < dist) {
2403  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
2404  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
2405  if (visited.find((*j).lane) == visited.end()) {
2406  visited.insert((*j).lane);
2408  ili.lane = (*j).lane;
2409  ili.length = (*j).length + (*it).length;
2410  ili.viaLink = (*j).viaLink;
2411  newFound.push_back(ili);
2412  }
2413  }
2414  }
2415  }
2416  toExamine.clear();
2417  swap(newFound, toExamine);
2418  }
2419  //return result;
2420 
2421  }
2422  return result;
2423 }
2424 
2425 
2426 void
2428  const std::vector<MSLane*>& bestLaneConts, MSLeaderDistanceInfo& result) const {
2429  if (seen > dist) {
2430  return;
2431  }
2432  // check partial vehicles (they might be on a different route and thus not
2433  // found when iterating along bestLaneConts)
2434  for (VehCont::const_iterator it = myPartialVehicles.begin(); it != myPartialVehicles.end(); ++it) {
2435  MSVehicle* veh = *it;
2436  if (!veh->isFrontOnLane(this)) {
2437  result.addLeader(veh, seen);
2438  } else {
2439  break;
2440  }
2441  }
2442  const MSLane* nextLane = this;
2443  int view = 1;
2444  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / MAX2(speed, NUMERICAL_EPS));
2445  // loop over following lanes
2446  while (seen < dist && result.numFreeSublanes() > 0) {
2447  // get the next link used
2448  MSLinkCont::const_iterator link = succLinkSec(*ego, view, *nextLane, bestLaneConts);
2449  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, ego->getVehicleType().getLength(),
2450  ego->getImpatience(), ego->getCarFollowModel().getMaxDecel(), 0, ego->getLateralPositionOnLane()) || (*link)->haveRed()) {
2451  break;
2452  }
2453 #ifdef HAVE_INTERNAL_LANES
2454  // check for link leaders
2455  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(ego, seen);
2456  if (linkLeaders.size() > 0) {
2457  const MSLink::LinkLeader ll = linkLeaders[0];
2458  if (ll.vehAndGap.first != 0) {
2459  // add link leader to all sublanes and return
2460  for (int i = 0; i < result.numSublanes(); ++i) {
2461  MSVehicle* veh = ll.vehAndGap.first;
2462  result.addLeader(veh, ll.vehAndGap.second, 0);
2463  }
2464  return; ;
2465  } // XXX else, deal with pedestrians
2466  }
2467  bool nextInternal = (*link)->getViaLane() != 0;
2468 #endif
2469  nextLane = (*link)->getViaLaneOrLane();
2470  if (nextLane == 0) {
2471  break;
2472  }
2473 
2474  MSLeaderInfo leaders = nextLane->getLastVehicleInformation(0, 0, 0, false);
2475 #ifdef DEBUG_CONTEXT
2476  if (DEBUG_COND2(ego)) {
2477  std::cout << SIMTIME << " getLeadersOnConsecutive lane=" << getID() << " nextLane=" << nextLane->getID() << " leaders=" << leaders.toString() << "\n";
2478  }
2479 #endif
2480  // @todo check alignment issues if the lane width changes
2481  const int iMax = MIN2(leaders.numSublanes(), result.numSublanes());
2482  for (int i = 0; i < iMax; ++i) {
2483  const MSVehicle* veh = leaders[i];
2484  if (veh != 0) {
2485 #ifdef DEBUG_CONTEXT
2486  if (DEBUG_COND2(ego)) std::cout << " lead=" << veh->getID()
2487  << " seen=" << seen
2488  << " minGap=" << ego->getVehicleType().getMinGap()
2489  << " backPos=" << veh->getBackPositionOnLane(nextLane)
2490  << " gap=" << seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane)
2491  << "\n";
2492 #endif
2493  result.addLeader(veh, seen - ego->getVehicleType().getMinGap() + veh->getBackPositionOnLane(nextLane), 0, i);
2494  }
2495  }
2496 
2497  if (nextLane->getVehicleMaxSpeed(ego) < speed) {
2498  dist = ego->getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(ego));
2499  }
2500  seen += nextLane->getLength();
2501  if (seen <= dist) {
2502  // delaying the update of arrivalTime and making it conditional to avoid possible integer overflows
2503  arrivalTime += TIME2STEPS(nextLane->getLength() / MAX2(speed, NUMERICAL_EPS));
2504  }
2505 #ifdef HAVE_INTERNAL_LANES
2506  if (!nextInternal) {
2507  view++;
2508  }
2509 #else
2510  view++;
2511 #endif
2512  }
2513 }
2514 
2515 
2516 
2517 MSVehicle*
2519  for (VehCont::const_reverse_iterator i = myPartialVehicles.rbegin(); i != myPartialVehicles.rend(); ++i) {
2520  MSVehicle* veh = *i;
2521  if (veh->isFrontOnLane(this)
2522  && veh != ego
2523  && veh->getPositionOnLane() <= ego->getPositionOnLane()) {
2524 #ifdef DEBUG_CONTEXT
2525  if (DEBUG_COND2(ego)) {
2526  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " found=" << veh->getID() << "\n";
2527  }
2528 #endif
2529  return veh;
2530  }
2531  }
2532 #ifdef DEBUG_CONTEXT
2533  if (DEBUG_COND2(ego)) {
2534  std::cout << SIMTIME << " getPartialBehind lane=" << getID() << " ego=" << ego->getID() << " nothing found. partials=" << toString(myPartialVehicles) << "\n";
2535  }
2536 #endif
2537  return 0;
2538 }
2539 
2540 
2541 MSLane*
2543  if (myNeighs.size() == 1) {
2544  return dictionary(myNeighs[0]);
2545  }
2546  return 0;
2547 }
2548 
2549 
2550 SUMOReal
2552  MSLane* opposite = getOpposite();
2553  if (opposite == 0) {
2554  assert(false);
2555  throw ProcessError("Lane '" + getID() + "' cannot compute oppositePos as there is no opposite lane.");
2556  }
2557  // XXX transformations for curved geometries
2558  return MAX2((SUMOReal)0, opposite->getLength() - pos);
2559 
2560 }
2561 
2562 std::pair<MSVehicle* const, SUMOReal>
2563 MSLane::getFollower(const MSVehicle* ego, SUMOReal egoPos, SUMOReal dist, bool ignoreMinorLinks) const {
2564  for (AnyVehicleIterator first = anyVehiclesUpstreamBegin(); first != anyVehiclesUpstreamEnd(); ++first) {
2565  // XXX refactor leaderInfo to use a const vehicle all the way through the call hierarchy
2566  MSVehicle* pred = (MSVehicle*)*first;
2567 #ifdef DEBUG_CONTEXT
2568  if (DEBUG_COND2(ego)) {
2569  std::cout << " getFollower lane=" << getID() << " egoPos=" << egoPos << " pred=" << pred->getID() << " predPos=" << pred->getPositionOnLane(this) << "\n";
2570  }
2571 #endif
2572  if (pred->getPositionOnLane(this) < egoPos && pred != ego) {
2573  return std::pair<MSVehicle* const, SUMOReal>(pred, egoPos - pred->getPositionOnLane(this) - ego->getVehicleType().getLength() - pred->getVehicleType().getMinGap());
2574  }
2575  }
2576  return getFollowerOnConsecutive(
2577  egoPos - ego->getVehicleType().getLength(),
2578  ego->getSpeed(), ego->getCarFollowModel().getMaxDecel(), dist, ignoreMinorLinks);
2579 }
2580 
2581 std::pair<MSVehicle* const, SUMOReal>
2582 MSLane::getOppositeLeader(const MSVehicle* ego, SUMOReal dist, bool oppositeDir) const {
2583 #ifdef DEBUG_OPPOSITE
2584  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeLeader lane=" << getID()
2585  << " ego=" << ego->getID()
2586  << " pos=" << ego->getPositionOnLane()
2587  << " posOnOpposite=" << getOppositePos(ego->getPositionOnLane())
2588  << " dist=" << dist
2589  << " oppositeDir=" << oppositeDir
2590  << "\n";
2591 #endif
2592  if (!oppositeDir) {
2593  return getLeader(ego, getOppositePos(ego->getPositionOnLane()), ego->getBestLanesContinuation(this));
2594  } else {
2595  const SUMOReal egoLength = ego->getVehicleType().getLength();
2596  const SUMOReal egoPos = ego->getLaneChangeModel().isOpposite() ? ego->getPositionOnLane() : getOppositePos(ego->getPositionOnLane());
2597  std::pair<MSVehicle* const, SUMOReal> result = getFollower(ego, egoPos + egoLength, dist, true);
2598  result.second -= ego->getVehicleType().getMinGap();
2599  return result;
2600  }
2601 }
2602 
2603 
2604 std::pair<MSVehicle* const, SUMOReal>
2606 #ifdef DEBUG_OPPOSITE
2607  if (DEBUG_COND2(ego)) std::cout << SIMTIME << " getOppositeFollower lane=" << getID()
2608  << " ego=" << ego->getID()
2609  << " backPos=" << ego->getBackPositionOnLane()
2610  << " posOnOpposite=" << getOppositePos(ego->getBackPositionOnLane())
2611  << "\n";
2612 #endif
2613  if (ego->getLaneChangeModel().isOpposite()) {
2614  std::pair<MSVehicle* const, SUMOReal> result = getFollower(ego, getOppositePos(ego->getPositionOnLane()), -1, true);
2615  return result;
2616  } else {
2617  std::pair<MSVehicle* const, SUMOReal> result = getLeader(ego, getOppositePos(ego->getPositionOnLane() - ego->getVehicleType().getLength()), std::vector<MSLane*>());
2618  if (result.second > 0) {
2619  // follower can be safely ignored since it is going the other way
2620  return std::make_pair(static_cast<MSVehicle*>(0), -1);
2621  } else {
2622  return result;
2623  }
2624  }
2625 }
2626 
2627 
2628 void
2630  const std::string action = oc.getString("collision.action");
2631  if (action == "none") {
2633  } else if (action == "warn") {
2635  } else if (action == "teleport") {
2637  } else if (action == "remove") {
2639  } else {
2640  throw ProcessError("Invalid collision.action '" + action + "'.");
2641  }
2642  myCheckJunctionCollisions = oc.getBool("collision.check-junctions");
2643 }
2644 
2645 
2646 void
2647 MSLane::setPermissions(SVCPermissions permissions, long transientID) {
2648  if (transientID == CHANGE_PERMISSIONS_PERMANENT) {
2649  myPermissions = permissions;
2650  myOriginalPermissions = permissions;
2651  } else {
2652  myPermissionChanges[transientID] = permissions;
2654  }
2655 }
2656 
2657 
2658 void
2659 MSLane::resetPermissions(long transientID) {
2660  myPermissionChanges.erase(transientID);
2661  if (myPermissionChanges.empty()) {
2663  } else {
2664  // combine all permission changes
2666  for (std::map<long, SVCPermissions>::iterator it = myPermissionChanges.begin(); it != myPermissionChanges.end(); ++it) {
2667  myPermissions &= it->second;
2668  }
2669  }
2670 }
2671 
2672 /****************************************************************************/
2673 
const std::map< SUMOVehicleClass, SUMOReal > * myRestrictions
The vClass speed restrictions for this lane.
Definition: MSLane.h:1101
void loadState(std::vector< std::string > &vehIDs, MSVehicleControl &vc)
Loads the state of this segment with the given parameters.
Definition: MSLane.cpp:2296
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
std::pair< MSVehicle *const, SUMOReal > getFollowerOnConsecutive(SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel, SUMOReal dist=-1, bool ignoreMinorLinks=false) const
return the follower with the largest missing rear gap among all predecessor lanes (within dist) ...
Definition: MSLane.cpp:1673
SVCPermissions myPermissions
The vClass permissions for this lane.
Definition: MSLane.h:1095
VehCont myVehicles
The lane&#39;s vehicles. This container holds all vehicles that have their front (longitudinally) and the...
Definition: MSLane.h:1059
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:127
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
A free lateral position is chosen.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1427
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1466
The position is given.
long long int SUMOTime
Definition: SUMOTime.h:43
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1494
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
void resetPermissions(long transientID)
Definition: MSLane.cpp:2659
void descheduleDeparture(SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
At the leftmost side of the lane.
virtual std::string toString() const
print a debugging representation
SUMOReal getWaitingSeconds() const
Returns the overall waiting time on this lane.
Definition: MSLane.cpp:2111
static void insertIDs(std::vector< std::string > &into)
Adds the ids of all stored lanes into the given vector.
Definition: MSLane.cpp:1349
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:1306
std::pair< MSVehicle *const, SUMOReal > getFollower(const MSVehicle *ego, SUMOReal egoPos, SUMOReal dist, bool ignoreMinorLinks) const
Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane) ...
Definition: MSLane.cpp:2563
MSVehicle * getFirstAnyVehicle() const
returns the first vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1480
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:407
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:783
int numSublanes() const
Definition: MSLeaderInfo.h:86
begin/end of the description of a single lane
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2247
void setTentativeLaneAndPosition(MSLane *lane, SUMOReal pos, SUMOReal posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:3547
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
Stop & getNextStop()
Definition: MSVehicle.cpp:3899
int myI2
index for myPartialVehicles
Definition: MSLane.h:145
std::pair< MSVehicle *const, SUMOReal > getOppositeFollower(const MSVehicle *ego) const
Definition: MSLane.cpp:2605
void enterLaneAtInsertion(MSLane *enteredLane, SUMOReal pos, SUMOReal speed, SUMOReal posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:2776
bool hasInfluencer() const
Definition: MSVehicle.h:1386
The speed is given.
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
SUMOReal getImpatience() const
Returns this vehicles impatience.
virtual const MSEdge * succEdge(int nSuccs) const =0
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
virtual SUMOReal insertionFollowSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const
Computes the vehicle&#39;s safe speed (no dawdling) This method is used during the insertion stage...
Definition: MSCFModel.cpp:213
#define M_PI
Definition: angles.h:37
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2542
void registerTeleportYield()
register one non-collision-related teleport
const std::map< SUMOVehicleClass, SUMOReal > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:296
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:1357
The vehicle arrived at a junction.
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:536
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:142
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:133
This is an uncontrolled, minor link, has to stop.
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:96
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:480
SUMOReal departSpeed
(optional) The initial speed of the vehicle
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:599
std::vector< IncomingLaneInfo > myIncomingLanes
Definition: MSLane.h:1103
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:60
int SVCPermissions
int myI2End
end index for myPartialVehicles
Definition: MSLane.h:149
void setLength(SUMOReal val)
Sets a new length for the lane (used by TraCI only)
Definition: MSLane.cpp:1558
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:192
int myIndex
The lane index.
Definition: MSLane.h:1046
virtual bool integrateNewVehicle(SUMOTime t)
Insert buffered vehicle into the real lane.
Definition: MSLane.cpp:1393
The lateral position is chosen randomly.
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
SUMOTime myLeaderInfoTime
time step for which myLeaderInfo was last updated
Definition: MSLane.h:1127
MSVehicle * getFirstFullVehicle() const
returns the first vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1457
If a fixed number of random choices fails, a free lateral position is chosen.
SUMOReal xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:130
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
SUMOReal getFuelConsumption() const
Returns the sum of last step fuel consumption.
Definition: MSLane.cpp:2200
A RT-tree for efficient storing of SUMO&#39;s Named objects.
Definition: NamedRTree.h:72
SUMOReal getLength() const
Get vehicle&#39;s length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1576
const MSEdge *const myEdge
Definition: MSLane.h:1220
SUMOReal getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:496
SUMOReal getMaximumBrakeDist() const
compute maximum braking distance on this lane
Definition: MSLane.cpp:1664
This is a dead end link.
void addIncomingLane(MSLane *lane, MSLink *viaLink)
Definition: MSLane.cpp:1600
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
SUMOReal getNettoOccupancy() const
Returns the netto (excluding minGaps) occupancy of this lane during the last step (including minGaps)...
Definition: MSLane.cpp:2096
T MAX2(T a, T b)
Definition: StdDefs.h:70
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:97
by_connections_to_sorter(const MSEdge *const e)
constructor
Definition: MSLane.cpp:2262
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
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:59
The speed is chosen randomly.
static void initCollisionOptions(const OptionsCont &oc)
Definition: MSLane.cpp:2629
virtual void addMoveReminder(MSMoveReminder *rem)
Add a move-reminder to move-reminder container.
Definition: MSLane.cpp:205
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2056
void getLeadersOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal 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:2427
SUMOReal getSecureGap(const SUMOReal speed, const SUMOReal leaderSpeed, const SUMOReal leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:276
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:803
This is an uncontrolled, right-before-left link.
SUMOReal getElectricityConsumption() const
Returns the sum of last step electricity consumption.
Definition: MSLane.cpp:2212
std::map< long, SVCPermissions > myPermissionChanges
Definition: MSLane.h:1143
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1843
int getLaneIndex() const
Definition: MSVehicle.cpp:3540
void addNeigh(const std::string &id)
Adds a neighbor to this lane.
Definition: MSLane.cpp:198
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
bool isInternal() const
Definition: MSLane.cpp:1443
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
int operator()(const MSEdge *const e1, const MSEdge *const e2) const
comparing operator
Definition: MSLane.cpp:2269
const SVCPermissions SVCAll
void gotActive(MSLane *l)
Informs the control that the given lane got active.
std::pair< MSVehicle *const, SUMOReal > getCriticalLeader(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
Definition: MSLane.cpp:1925
const SUMOReal myWidth
Lane width [m].
Definition: MSLane.h:1086
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1126
static SUMOReal angleDiff(const SUMOReal angle1, const SUMOReal angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:178
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
bool freeInsertion(MSVehicle &veh, SUMOReal speed, MSMoveReminder::Notification notification=MSMoveReminder::NOTIFICATION_DEPARTED)
Tries to insert the given vehicle on any place.
Definition: MSLane.cpp:304
VehCont myPartialVehicles
The lane&#39;s partial vehicles. This container holds all vehicles that are partially on this lane but wh...
Definition: MSLane.h:1071
The position is chosen randomly.
static bool myCheckJunctionCollisions
Definition: MSLane.h:1157
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:868
This is an uncontrolled, all-way stop link.
SUMOReal myMaxSpeed
Lane-wide speedlimit [m/s].
Definition: MSLane.h:1092
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:136
int myI1End
end index for myVehicles
Definition: MSLane.h:147
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
int myDirection
index delta
Definition: MSLane.h:153
PositionVector myShape
The shape of the lane.
Definition: MSLane.h:1043
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle *ego, bool allSublanes) const
return the sublane followers with the largest missing rear gap among all predecessor lanes (within di...
Definition: MSLane.cpp:2310
The speed is given.
bool myDownstream
iteration direction
Definition: MSLane.h:151
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2881
SUMOReal getHCEmissions() const
Returns the sum of last step HC emissions.
Definition: MSLane.cpp:2188
#define SIMTIME
Definition: SUMOTime.h:70
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:380
std::vector< std::string > myNeighs
Definition: MSLane.h:1140
void setMaxSpeed(SUMOReal val)
Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
Definition: MSLane.cpp:1551
static CollisionAction myCollisionAction
the action to take on collisions
Definition: MSLane.h:1156
std::map< std::string, MSLane * > DictType
definition of the static dictionary type
Definition: MSLane.h:1146
SUMOReal getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
virtual void incorporateVehicle(MSVehicle *veh, SUMOReal pos, SUMOReal speed, SUMOReal 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:247
MSLinkCont myLinks
Definition: MSLane.h:1115
virtual void detectCollisions(SUMOTime timestep, const std::string &stage)
Check if vehicles are too close.
Definition: MSLane.cpp:999
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSLane.h:1149
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:45
void addApproachingLane(MSLane *lane, bool warnMultiCon)
Definition: MSLane.cpp:1610
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
int operator()(MSVehicle *v1, MSVehicle *v2) const
Comparing operator.
Definition: MSLane.cpp:2252
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:419
int numFreeSublanes() const
Definition: MSLeaderInfo.h:90
SUMOReal myRightSideOnEdge
the combined width of all lanes with lower index on myEdge
Definition: MSLane.h:1135
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1994
#define max(a, b)
Definition: polyfonts.c:65
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time, assuming that during...
Definition: MSCFModel.h:263
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:1075
std::pair< MSVehicle *const, SUMOReal > getLeaderOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:1833
const MSVehicle * operator*()
Definition: MSLane.cpp:114
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:227
LinkState getIncomingLinkState() const
get the state of the link from the logical predecessor to this lane
Definition: MSLane.cpp:2034
SUMOReal getMissingRearGap(SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const
return by how much further the leader must be inserted to avoid rear end collisions ...
Definition: MSLane.cpp:1648
SUMOReal basePos(const MSVehicle &veh) const
departure position where the vehicle fits fully onto the lane (if possible)
Definition: MSLane.cpp:503
Representation of a vehicle.
Definition: SUMOVehicle.h:67
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3716
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
const MSEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of reachable edges.
Definition: MSEdge.h:364
virtual int addLeader(const MSVehicle *veh, bool beyond, SUMOReal latOffset=0)
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
This is an uncontrolled, minor link, has to brake.
SUMOReal getDepartSpeed(const MSVehicle &veh, bool &patchSpeed)
Definition: MSLane.cpp:392
Sorts vehicles by their position (descending)
Definition: MSLane.h:1163
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:3236
SVCPermissions myOriginalPermissions
The original vClass permissions for this lane (before temporary modifications)
Definition: MSLane.h:1098
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:2899
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2063
SUMOReal getMaxSpeedFactor() const
return the maximum speed factor for all vehicles that ever entered the network
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:308
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:1594
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:807
SUMOReal getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:2124
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3729
bool lastInsertion(MSVehicle &veh, SUMOReal mspeed, 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:267
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1102
void markDelayed() const
Definition: MSEdge.h:635
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, SUMOReal latOffset, SUMOReal minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:854
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
The maximum speed is used.
SUMOReal getSafeFollowSpeed(const std::pair< const MSVehicle *, SUMOReal > leaderInfo, const SUMOReal seen, const MSLane *const lane, SUMOReal distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:1801
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:392
T MIN2(T a, T b)
Definition: StdDefs.h:64
void add(const SUMOTime t, MSVehicle *veh)
Adds a vehicle to this transfer object.
#define POSITION_EPS
Definition: config.h:182
SUMOReal getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:472
No information given; use default.
CollisionAction
Definition: MSLane.h:162
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:590
MSLane(const std::string &id, SUMOReal maxSpeed, SUMOReal length, MSEdge *const edge, int numericalID, const PositionVector &shape, SUMOReal width, SVCPermissions permissions, int index)
Constructor.
Definition: MSLane.cpp:162
int myRightmostSublane
the index of the rightmost sublane of this lane on myEdge
Definition: MSLane.h:1137
MSLane * myLogicalPredecessorLane
Definition: MSLane.h:1104
virtual int addLeader(const MSVehicle *veh, SUMOReal gap, SUMOReal latOffset=0, int sublane=-1)
Something on a lane to be noticed about vehicle movement.
SUMOReal myLength
Lane length [m].
Definition: MSLane.h:1083
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:201
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
virtual SUMOReal setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:214
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
virtual void swapAfterLaneChange(SUMOTime t)
moves myTmpVehicles int myVehicles after a lane change procedure
Definition: MSLane.cpp:1565
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:206
void registerTeleportJam()
register one non-collision-related teleport
void handleCollisionBetween(SUMOTime timestep, const std::string &stage, const MSVehicle *collider, const MSVehicle *victim, SUMOReal gap, SUMOReal latGap, std::set< const MSVehicle *, SUMOVehicle::ComparatorIdLess > &toRemove, std::set< const MSVehicle * > &toTeleport) const
take action upon collision
Definition: MSLane.cpp:1168
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
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:1108
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2893
std::map< MSEdge *, std::vector< MSLane * > > myApproachingLanes
Definition: MSLane.h:1117
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:288
int addFollower(const MSVehicle *veh, const MSVehicle *ego, SUMOReal gap, SUMOReal latOffset=0, int sublane=-1)
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
Base class for objects which have an id.
Definition: Named.h:46
int myNumericalID
Unique numerical ID (set on reading by netload)
Definition: MSLane.h:1040
std::vector< MSMoveReminder * > myMoveReminders
This lane&#39;s move reminder.
Definition: MSLane.h:1153
SUMOReal safeInsertionSpeed(const MSVehicle *veh, const MSLeaderInfo &leaders, SUMOReal speed)
return the maximum safe speed for insertion behind leaders (a negative value indicates that safe inse...
Definition: MSLane.cpp:835
const SUMOReal myLengthGeometryFactor
precomputed myShape.length / myLength
Definition: MSLane.h:1132
AnyVehicleIterator & operator++()
Definition: MSLane.cpp:99
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
void leaveLane(const MSMoveReminder::Notification reason)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:2832
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos, MSMoveReminder::Notification notification, SUMOReal posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:826
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void sortPartialVehicles()
sorts myPartialVehicles
Definition: MSLane.cpp:1420
SUMOReal getWidth() const
Get the width which vehicles of this class shall have when being drawn.
void setPermissions(SVCPermissions permissions, long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition: MSLane.cpp:2647
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2045
SUMOReal getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:3601
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1317
SUMOReal getNOxEmissions() const
Returns the sum of last step NOx emissions.
Definition: MSLane.cpp:2176
static SUMOTime gTimeToGridlockHighways
Definition: MSGlobals.h:70
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:238
std::string myID
The name of the object.
Definition: Named.h:136
SUMOReal getPMxEmissions() const
Returns the sum of last step PMx emissions.
Definition: MSLane.cpp:2164
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
The vehicle has departed (was inserted into the network)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3905
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:143
bool detectCollisionBetween(SUMOTime timestep, const std::string &stage, const MSVehicle *collider, const 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:1110
bool operator()(const MSVehicle *cmp, SUMOReal pos) const
compares vehicle position to the detector position
Definition: MSLane.cpp:2241
#define DEBUG_COND
Definition: MSLane.cpp:83
SUMOReal myBruttoVehicleLengthSum
The current length of all vehicles on this lane, including their minGaps.
Definition: MSLane.h:1108
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:284
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:361
static void clear()
Clears the dictionary.
Definition: MSLane.cpp:1340
bool isEmpty() const
Definition: MSLane.cpp:1438
SUMOReal 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:3569
SUMOReal getCO2Emissions() const
Returns the sum of last step CO2 emissions.
Definition: MSLane.cpp:2140
MSEdge *const myEdge
The lane&#39;s edge, for routing only.
Definition: MSLane.h:1089
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:299
SUMOReal getCOEmissions() const
Returns the sum of last step CO emissions.
Definition: MSLane.cpp:2152
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:141
bool checkFailure(MSVehicle *aVehicle, SUMOReal &speed, SUMOReal &dist, const SUMOReal nspeed, const bool patchSpeed, const std::string errorMsg) const
Definition: MSLane.cpp:508
MSVehicle * getPartialBehind(const MSVehicle *ego) const
Definition: MSLane.cpp:2518
A storage for options typed value containers)
Definition: OptionsCont.h:99
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
static SUMOReal gLateralResolution
Definition: MSGlobals.h:89
bool overlapsWith(const AbstractPoly &poly, SUMOReal offset=0) const
Returns the information whether the given polygon overlaps with this.
bool isApproachedFrom(MSEdge *const edge)
Definition: MSLane.cpp:1624
std::pair< MSVehicle *const, SUMOReal > getOppositeLeader(const MSVehicle *ego, SUMOReal dist, bool oppositeDir) const
Definition: MSLane.cpp:2582
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:56
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
static SUMOReal sum(SUMOReal val)
Computes the resulting noise.
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:442
#define LANE_RTREE_QUAL
static SUMOTime gTimeToGridlock
Definition: MSGlobals.h:67
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2419
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOReal getMinDeceleration() const
return the minimum deceleration capability for all vehicles that ever entered the network ...
const MSLeaderInfo & getFirstVehicleInformation(const MSVehicle *ego, SUMOReal latOffset, bool onlyFrontOnLane, SUMOReal maxPos=std::numeric_limits< SUMOReal >::max(), bool allowCached=true) const
analogue to getLastVehicleInformation but in the upstream direction
Definition: MSLane.cpp:905
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:391
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2359
void saveState(OutputDevice &out)
Saves the state of this lane into the given stream.
Definition: MSLane.cpp:2285
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:427
MSLeaderInfo myLeaderInfo
leaders on all sublanes as seen by approaching vehicles (cached)
Definition: MSLane.h:1120
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:819
SUMOReal getOppositePos(SUMOReal pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2551
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool nextIsMyVehicles() const
Definition: MSLane.cpp:128
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:208
#define DEBUG_COND2(obj)
Definition: MSLane.cpp:84
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
void registerCollision()
registers one collision-related teleport
SUMOReal ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:148
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:351
#define NUMERICAL_EPS
Definition: config.h:158
MSLeaderInfo myFollowerInfo
followers on all sublanes as seen by vehicles on consecutive lanes (cached)
Definition: MSLane.h:1122
virtual ~MSLane()
Destructor.
Definition: MSLane.cpp:184
int operator()(const std::pair< const MSVehicle *, SUMOReal > &p1, const std::pair< const MSVehicle *, SUMOReal > &p2) const
Definition: MSLane.cpp:1642
SUMOReal myNettoVehicleLengthSum
The current length of all vehicles on this lane, excluding their minGaps.
Definition: MSLane.h:1111
std::string toString() const
print a debugging representation
bool isInsertionSuccess(MSVehicle *vehicle, SUMOReal speed, SUMOReal pos, SUMOReal posLat, bool recheckNextLanes, MSMoveReminder::Notification notification)
Tries to insert the given vehicle with the given state (speed and pos)
Definition: MSLane.cpp:526
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1545
No information given; use default.
A free position is chosen.
The class responsible for building and deletion of vehicles.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
MSLeaderInfo myLeaderInfoTmp
Definition: MSLane.h:1124
virtual SUMOReal insertionStopSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap) const
Computes the vehicle&#39;s safe speed for approaching an obstacle at insertion without constraints due to...
Definition: MSCFModel.cpp:224
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:1079
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:458
SUMOReal getHarmonoise_NoiseEmissions() const
Returns the sum of last step noise emissions.
Definition: MSLane.cpp:2224
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:988
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:488
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:708
The edge is an internal edge.
Definition: MSEdge.h:97
SUMOReal getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2081
virtual bool executeMovements(SUMOTime t, std::vector< MSLane * > &lanesWithVehiclesToIntegrate)
Executes planned vehicle movements with regards to right-of-way.
Definition: MSLane.cpp:1223
SUMOTime myFollowerInfoTime
time step for which myFollowerInfo was last updated
Definition: MSLane.h:1129
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:1448
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Definition: MSLane.h:386
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void registerTeleportWrongLane()
register one non-collision-related teleport
SUMOReal departPosLat
(optional) The lateral position the vehicle shall depart from
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:401
Back-at-zero position.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:447
int getCrossingIndex() const
return the index of the link to the next crossing if this is walkingArea, else -1 ...
Definition: MSLane.cpp:2070
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, const std::vector< MSLane * > &bestLaneConts, SUMOReal dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1768
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
virtual bool appropriate(const MSVehicle *veh)
Definition: MSLane.cpp:1375
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:957
SUMOReal getRightSideOnEdge() const
Definition: MSLane.h:897
const std::string & getID() const
Returns the name of the vehicle.
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction ...
Definition: MSLane.h:396
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.