Eclipse SUMO - Simulation of Urban MObility
MSAbstractLaneChangeModel.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
23 // Interface for lane-change models
24 /****************************************************************************/
25 
26 // ===========================================================================
27 // DEBUG
28 // ===========================================================================
29 //#define DEBUG_TARGET_LANE
30 //#define DEBUG_SHADOWLANE
31 //#define DEBUG_OPPOSITE
32 //#define DEBUG_MANEUVER
33 #define DEBUG_COND (myVehicle.isSelected())
34 #include <config.h>
35 
38 #include <microsim/MSNet.h>
39 #include <microsim/MSEdge.h>
40 #include <microsim/MSLane.h>
41 #include <microsim/MSDriverState.h>
42 #include <microsim/MSGlobals.h>
43 #include "MSLCM_DK2008.h"
44 #include "MSLCM_LC2013.h"
45 #include "MSLCM_SL2015.h"
46 
47 /* -------------------------------------------------------------------------
48  * static members
49  * ----------------------------------------------------------------------- */
55 const double MSAbstractLaneChangeModel::NO_NEIGHBOR(std::numeric_limits<double>::max());
56 
57 /* -------------------------------------------------------------------------
58  * MSAbstractLaneChangeModel-methods
59  * ----------------------------------------------------------------------- */
60 
61 void
63  myAllowOvertakingRight = oc.getBool("lanechange.overtake-right");
64  myLCOutput = oc.isSet("lanechange-output");
65  myLCStartedOutput = oc.getBool("lanechange-output.started");
66  myLCEndedOutput = oc.getBool("lanechange-output.ended");
67  myLCXYOutput = oc.getBool("lanechange-output.xy");
68 }
69 
70 
73  if (MSGlobals::gLateralResolution > 0 && lcm != LCM_SL2015 && lcm != LCM_DEFAULT) {
74  throw ProcessError("Lane change model '" + toString(lcm) + "' is not compatible with sublane simulation");
75  }
76  switch (lcm) {
77  case LCM_DK2008:
78  return new MSLCM_DK2008(v);
79  case LCM_LC2013:
80  return new MSLCM_LC2013(v);
81  case LCM_SL2015:
82  return new MSLCM_SL2015(v);
83  case LCM_DEFAULT:
85  return new MSLCM_LC2013(v);
86  } else {
87  return new MSLCM_SL2015(v);
88  }
89  default:
90  throw ProcessError("Lane change model '" + toString(lcm) + "' not implemented");
91  }
92 }
93 
94 
96  myVehicle(v),
97  myOwnState(0),
98  myPreviousState(0),
99  myPreviousState2(0),
100  myCanceledStateRight(LCA_NONE),
101  myCanceledStateCenter(LCA_NONE),
102  myCanceledStateLeft(LCA_NONE),
103  mySpeedLat(0),
104  myAccelerationLat(0),
105  myCommittedSpeed(0),
106  myLaneChangeCompletion(1.0),
107  myLaneChangeDirection(0),
108  myAlreadyChanged(false),
109  myShadowLane(nullptr),
110  myTargetLane(nullptr),
111  myCarFollowModel(v.getCarFollowModel()),
112  myModel(model),
113  myLastLateralGapLeft(0.),
114  myLastLateralGapRight(0.),
115  myLastLeaderGap(0.),
116  myLastFollowerGap(0.),
117  myLastLeaderSecureGap(0.),
118  myLastFollowerSecureGap(0.),
119  myLastOrigLeaderGap(0.),
120  myLastOrigLeaderSecureGap(0.),
121  myLastLeaderSpeed(0),
122  myLastFollowerSpeed(0),
123  myLastOrigLeaderSpeed(0),
124  myDontResetLCGaps(false),
125  myMaxSpeedLatStanding(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING, v.getVehicleType().getMaxSpeedLat())),
126  myMaxSpeedLatFactor(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR, 1)),
127  mySigma(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_SIGMA, 0.0)),
128  myLastLaneChangeOffset(0),
129  myAmOpposite(false),
130  myManeuverDist(0.),
131  myPreviousManeuverDist(0.) {
135 }
136 
137 
139 }
140 
141 void
144  myOwnState = state;
145  myPreviousState = state; // myOwnState is modified in prepareStep so we make a backup
146 }
147 
148 void
149 MSAbstractLaneChangeModel::updateSafeLatDist(const double travelledLatDist) {
150  UNUSED_PARAMETER(travelledLatDist);
151 }
152 
153 
154 void
156 #ifdef DEBUG_MANEUVER
157  if (DEBUG_COND) {
158  std::cout << SIMTIME
159  << " veh=" << myVehicle.getID()
160  << " setManeuverDist() old=" << myManeuverDist << " new=" << dist
161  << std::endl;
162  }
163 #endif
164  myManeuverDist = fabs(dist) < NUMERICAL_EPS ? 0. : dist;
165  // store value which may be modified by the model during the next step
167 }
168 
169 
170 double
172  return myManeuverDist;
173 }
174 
175 double
177  return myPreviousManeuverDist;
178 }
179 
180 void
182  if (dir == -1) {
183  myLeftFollowers = std::make_shared<MSLeaderDistanceInfo>(followers);
184  myLeftLeaders = std::make_shared<MSLeaderDistanceInfo>(leaders);
185  } else if (dir == 1) {
186  myRightFollowers = std::make_shared<MSLeaderDistanceInfo>(followers);
187  myRightLeaders = std::make_shared<MSLeaderDistanceInfo>(leaders);
188  } else {
189  // dir \in {-1,1} !
190  assert(false);
191  }
192 }
193 
194 
195 void
196 MSAbstractLaneChangeModel::saveNeighbors(const int dir, const std::pair<MSVehicle* const, double>& follower, const std::pair<MSVehicle* const, double>& leader) {
197  if (dir == -1) {
198  myLeftFollowers = std::make_shared<MSLeaderDistanceInfo>(follower, myVehicle.getLane());
199  myLeftLeaders = std::make_shared<MSLeaderDistanceInfo>(leader, myVehicle.getLane());
200  } else if (dir == 1) {
201  myRightFollowers = std::make_shared<MSLeaderDistanceInfo>(follower, myVehicle.getLane());
202  myRightLeaders = std::make_shared<MSLeaderDistanceInfo>(leader, myVehicle.getLane());
203  } else {
204  // dir \in {-1,1} !
205  assert(false);
206  }
207 }
208 
209 
210 void
212  myLeftFollowers = nullptr;
213  myLeftLeaders = nullptr;
214  myRightFollowers = nullptr;
215  myRightLeaders = nullptr;
216 }
217 
218 
219 const std::shared_ptr<MSLeaderDistanceInfo>
221  if (dir == -1) {
222  return myLeftFollowers;
223  } else if (dir == 1) {
224  return myRightFollowers;
225  } else {
226  // dir \in {-1,1} !
227  assert(false);
228  }
229  return nullptr;
230 }
231 
232 const std::shared_ptr<MSLeaderDistanceInfo>
234  if (dir == -1) {
235  return myLeftLeaders;
236  } else if (dir == 1) {
237  return myRightLeaders;
238  } else {
239  // dir \in {-1,1} !
240  assert(false);
241  }
242  return nullptr;
243 }
244 
245 
246 bool
248  if (neighLeader == nullptr) {
249  return false;
250  }
251  // Congested situation are relevant only on highways (maxSpeed > 70km/h)
252  // and congested on German Highways means that the vehicles have speeds
253  // below 60km/h. Overtaking on the right is allowed then.
254  if ((myVehicle.getLane()->getSpeedLimit() <= 70.0 / 3.6) || (neighLeader->getLane()->getSpeedLimit() <= 70.0 / 3.6)) {
255 
256  return false;
257  }
258  if (myVehicle.congested() && neighLeader->congested()) {
259  return true;
260  }
261  return false;
262 }
263 
264 
265 
266 bool
267 MSAbstractLaneChangeModel::predInteraction(const std::pair<MSVehicle*, double>& leader) {
268  if (leader.first == 0) {
269  return false;
270  }
271  // let's check it on highways only
272  if (leader.first->getSpeed() < (80.0 / 3.6)) {
273  return false;
274  }
275  return leader.second < myCarFollowModel.interactionGap(&myVehicle, leader.first->getSpeed());
276 }
277 
278 
279 bool
283  myLaneChangeDirection = direction;
284  setManeuverDist((target->getWidth() + source->getWidth()) * 0.5 * direction);
287  if (myLCOutput) {
289  }
290  return true;
291  } else {
292  primaryLaneChanged(source, target, direction);
293  return false;
294  }
295 }
296 
297 void
299  myDontResetLCGaps = true;
300 }
301 
302 void
304  myDontResetLCGaps = false;
305 }
306 
307 void
309  initLastLaneChangeOffset(direction);
311  source->leftByLaneChange(&myVehicle);
312  laneChangeOutput("change", source, target, direction); // record position on the source edge in case of opposite change
313  if (&source->getEdge() != &target->getEdge()) {
315 #ifdef DEBUG_OPPOSITE
316  if (debugVehicle()) {
317  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " primaryLaneChanged nowOpposite=" << myAmOpposite << "\n";
318  }
319 #endif
322  } else {
324  }
325  target->enteredByLaneChange(&myVehicle);
326  // Assure that the drive items are up to date (even if the following step is no actionstep for the vehicle).
327  // This is necessary because the lane advance uses the target lane from the corresponding drive item.
329  changed();
330 }
331 
332 void
333 MSAbstractLaneChangeModel::laneChangeOutput(const std::string& tag, MSLane* source, MSLane* target, int direction, double maneuverDist) {
334  if (myLCOutput) {
335  OutputDevice& of = OutputDevice::getDeviceByOption("lanechange-output");
336  of.openTag(tag);
339  of.writeAttr(SUMO_ATTR_TIME, time2string(MSNet::getInstance()->getCurrentTimeStep()));
340  of.writeAttr(SUMO_ATTR_FROM, source->getID());
341  of.writeAttr(SUMO_ATTR_TO, target->getID());
342  of.writeAttr(SUMO_ATTR_DIR, direction);
345  of.writeAttr("reason", toString((LaneChangeAction)(myOwnState & ~(
350  of.writeAttr("leaderGap", myLastLeaderGap == NO_NEIGHBOR ? "None" : toString(myLastLeaderGap));
351  of.writeAttr("leaderSecureGap", myLastLeaderSecureGap == NO_NEIGHBOR ? "None" : toString(myLastLeaderSecureGap));
352  of.writeAttr("leaderSpeed", myLastLeaderSpeed == NO_NEIGHBOR ? "None" : toString(myLastLeaderSpeed));
353  of.writeAttr("followerGap", myLastFollowerGap == NO_NEIGHBOR ? "None" : toString(myLastFollowerGap));
354  of.writeAttr("followerSecureGap", myLastFollowerSecureGap == NO_NEIGHBOR ? "None" : toString(myLastFollowerSecureGap));
355  of.writeAttr("followerSpeed", myLastFollowerSpeed == NO_NEIGHBOR ? "None" : toString(myLastFollowerSpeed));
356  of.writeAttr("origLeaderGap", myLastOrigLeaderGap == NO_NEIGHBOR ? "None" : toString(myLastOrigLeaderGap));
357  of.writeAttr("origLeaderSecureGap", myLastOrigLeaderSecureGap == NO_NEIGHBOR ? "None" : toString(myLastOrigLeaderSecureGap));
358  of.writeAttr("origLeaderSpeed", myLastOrigLeaderSpeed == NO_NEIGHBOR ? "None" : toString(myLastOrigLeaderSpeed));
360  const double latGap = direction < 0 ? myLastLateralGapRight : myLastLateralGapLeft;
361  of.writeAttr("latGap", latGap == NO_NEIGHBOR ? "None" : toString(latGap));
362  if (maneuverDist != 0) {
363  of.writeAttr("maneuverDistance", toString(maneuverDist));
364  }
365  }
366  if (myLCXYOutput) {
369  }
370  of.closeTag();
373  }
374  }
375 }
376 
377 
378 double
379 MSAbstractLaneChangeModel::computeSpeedLat(double /*latDist*/, double& maneuverDist) const {
381  int stepsToChange = (int)ceil(fabs(maneuverDist) / SPEED2DIST(myVehicle.getVehicleType().getMaxSpeedLat()));
382  return DIST2SPEED(maneuverDist / stepsToChange);
383  } else {
384  return maneuverDist / STEPS2TIME(MSGlobals::gLaneChangeDuration);
385  }
386 }
387 
388 
389 double
391  throw ProcessError("Method getAssumedDecelForLaneChangeDuration() not implemented by model " + toString(myModel));
392 }
393 
394 void
397  mySpeedLat = speedLat;
398 }
399 
400 bool
402  const bool pastBefore = pastMidpoint();
403  // maneuverDist is not updated in the context of continuous lane changing but represents the full LC distance
404  double maneuverDist = getManeuverDist();
405  setSpeedLat(computeSpeedLat(0, maneuverDist));
407  return !pastBefore && pastMidpoint();
408 }
409 
410 
411 void
413  UNUSED_PARAMETER(reason);
421  // aborted maneuver
422 #ifdef DEBUG_OPPOSITE
423  if (debugVehicle()) {
424  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " aborted maneuver (no longer opposite)\n";
425  }
426 #endif
428  }
429 }
430 
431 
432 MSLane*
433 MSAbstractLaneChangeModel::getShadowLane(const MSLane* lane, double posLat) const {
435  // initialize shadow lane
436  const double overlap = myVehicle.getLateralOverlap(posLat);
437 #ifdef DEBUG_SHADOWLANE
438  if (debugVehicle()) {
439  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " posLat=" << posLat << " overlap=" << overlap << "\n";
440  }
441 #endif
442  if (myAmOpposite) {
443  // return the neigh-lane in forward direction
444  return lane->getParallelLane(1);
445  } else if (overlap > NUMERICAL_EPS) {
446  const int shadowDirection = posLat < 0 ? -1 : 1;
447  return lane->getParallelLane(shadowDirection);
448  } else if (isChangingLanes() && myLaneChangeCompletion < 0.5) {
449  // "reserve" target lane even when there is no overlap yet
451  } else {
452  return nullptr;
453  }
454  } else {
455  return nullptr;
456  }
457 }
458 
459 
460 MSLane*
463 }
464 
465 
466 void
468  if (myShadowLane != nullptr) {
469  if (debugVehicle()) {
470  std::cout << SIMTIME << " cleanupShadowLane\n";
471  }
473  myShadowLane = nullptr;
474  }
475  for (std::vector<MSLane*>::const_iterator it = myShadowFurtherLanes.begin(); it != myShadowFurtherLanes.end(); ++it) {
476  if (debugVehicle()) {
477  std::cout << SIMTIME << " cleanupShadowLane2\n";
478  }
479  (*it)->resetPartialOccupation(&myVehicle);
480  }
481  myShadowFurtherLanes.clear();
483 }
484 
485 void
487  if (myTargetLane != nullptr) {
488  if (debugVehicle()) {
489  std::cout << SIMTIME << " cleanupTargetLane\n";
490  }
492  myTargetLane = nullptr;
493  }
494  for (std::vector<MSLane*>::const_iterator it = myFurtherTargetLanes.begin(); it != myFurtherTargetLanes.end(); ++it) {
495  if (debugVehicle()) {
496  std::cout << SIMTIME << " cleanupTargetLane\n";
497  }
498  if (*it != nullptr) {
499  (*it)->resetManeuverReservation(&myVehicle);
500  }
501  }
502  myFurtherTargetLanes.clear();
503 // myNoPartiallyOccupatedByShadow.clear();
504 }
505 
506 
507 bool
508 MSAbstractLaneChangeModel::cancelRequest(int state, int laneOffset) {
509  // store request before canceling
510  getCanceledState(laneOffset) |= state;
511  int ret = myVehicle.influenceChangeDecision(state);
512  return ret != state;
513 }
514 
515 
516 void
518  if (dir > 0) {
520  } else if (dir < 0) {
522  }
523 }
524 
525 void
527  if (!haveLateralDynamics()) {
528  // assume each vehicle drives at the center of its lane and act as if it fits
529  return;
530  }
531  if (myShadowLane != nullptr) {
532 #ifdef DEBUG_SHADOWLANE
533  if (debugVehicle()) {
534  std::cout << SIMTIME << " updateShadowLane()\n";
535  }
536 #endif
538  }
540  std::vector<MSLane*> passed;
541  if (myShadowLane != nullptr) {
543  const std::vector<MSLane*>& further = myVehicle.getFurtherLanes();
544  const std::vector<double>& furtherPosLat = myVehicle.getFurtherLanesPosLat();
545  assert(further.size() == furtherPosLat.size());
546  passed.push_back(myShadowLane);
547  for (int i = 0; i < (int)further.size(); ++i) {
548  MSLane* shadowFurther = getShadowLane(further[i], furtherPosLat[i]);
549 #ifdef DEBUG_SHADOWLANE
550  if (debugVehicle()) {
551  std::cout << SIMTIME << " further=" << further[i]->getID() << " (posLat=" << furtherPosLat[i] << ") shadowFurther=" << Named::getIDSecure(shadowFurther) << "\n";
552  }
553 #endif
554  if (shadowFurther != nullptr && shadowFurther->getLinkTo(passed.back()) != nullptr) {
555  passed.push_back(shadowFurther);
556  }
557  }
558  std::reverse(passed.begin(), passed.end());
559  } else {
560  if (isChangingLanes() && myVehicle.getLateralOverlap() > NUMERICAL_EPS) {
561  WRITE_WARNING("Vehicle '" + myVehicle.getID() + "' could not finish continuous lane change (lane disappeared) time=" +
562  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
564  }
565  }
566 #ifdef DEBUG_SHADOWLANE
567  if (debugVehicle()) {
568  std::cout << SIMTIME << " updateShadowLane() veh=" << myVehicle.getID()
569  << " newShadowLane=" << Named::getIDSecure(myShadowLane)
570  << "\n before:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << " further=" << toString(myVehicle.getFurtherLanes()) << " passed=" << toString(passed);
571  std::cout << std::endl;
572  }
573 #endif
575 #ifdef DEBUG_SHADOWLANE
576  if (debugVehicle()) std::cout
577  << "\n after:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << "\n";
578 #endif
579 }
580 
581 
582 int
584  if (isChangingLanes()) {
585  if (pastMidpoint()) {
586  return -myLaneChangeDirection;
587  } else {
588  return myLaneChangeDirection;
589  }
590  } else if (myShadowLane == nullptr) {
591  return 0;
592  } else if (myAmOpposite) {
593  // return neigh-lane in forward direction
594  return 1;
595  } else {
596  assert(&myShadowLane->getEdge() == &myVehicle.getLane()->getEdge());
598  }
599 }
600 
601 
602 MSLane*
604 #ifdef DEBUG_TARGET_LANE
605  MSLane* oldTarget = myTargetLane;
606  std::vector<MSLane*> oldFurtherTargets = myFurtherTargetLanes;
607  if (debugVehicle()) {
608  std::cout << SIMTIME << " veh '" << myVehicle.getID() << "' (lane=" << myVehicle.getLane()->getID() << ") updateTargetLane()"
609  << "\n oldTarget: " << (oldTarget == nullptr ? "NULL" : oldTarget->getID())
610  << " oldFurtherTargets: " << toString(oldFurtherTargets);
611  }
612 #endif
613  if (myTargetLane != nullptr) {
615  }
616  // Clear old further target lanes
617  for (MSLane* oldTargetLane : myFurtherTargetLanes) {
618  if (oldTargetLane != nullptr) {
619  oldTargetLane->resetManeuverReservation(&myVehicle);
620  }
621  }
622  myFurtherTargetLanes.clear();
623 
624  // Get new target lanes and issue a maneuver reservation.
625  int targetDir;
626  myTargetLane = determineTargetLane(targetDir);
627  if (myTargetLane != nullptr) {
629  // further targets are just the target lanes corresponding to the vehicle's further lanes
630  // @note In a neglectable amount of situations we might add a reservation for a shadow further lane.
631  for (MSLane* furtherLane : myVehicle.getFurtherLanes()) {
632  MSLane* furtherTargetLane = furtherLane->getParallelLane(targetDir);
633  myFurtherTargetLanes.push_back(furtherTargetLane);
634  if (furtherTargetLane != nullptr) {
635  furtherTargetLane->setManeuverReservation(&myVehicle);
636  }
637  }
638  }
639 #ifdef DEBUG_TARGET_LANE
640  if (debugVehicle()) {
641  std::cout << "\n newTarget (offset=" << targetDir << "): " << (myTargetLane == nullptr ? "NULL" : myTargetLane->getID())
642  << " newFurtherTargets: " << toString(myFurtherTargetLanes)
643  << std::endl;
644  }
645 #endif
646  return myTargetLane;
647 }
648 
649 
650 MSLane*
652  targetDir = 0;
653  if (myManeuverDist == 0) {
654  return nullptr;
655  }
656  // Current lateral boundaries of the vehicle
657  const double vehRight = myVehicle.getLateralPositionOnLane() - 0.5 * myVehicle.getWidth();
658  const double vehLeft = myVehicle.getLateralPositionOnLane() + 0.5 * myVehicle.getWidth();
659  const double halfLaneWidth = 0.5 * myVehicle.getLane()->getWidth();
660 
661  if (vehRight + myManeuverDist < -halfLaneWidth) {
662  // Vehicle intends to traverse the right lane boundary
663  targetDir = -1;
664  } else if (vehLeft + myManeuverDist > halfLaneWidth) {
665  // Vehicle intends to traverse the left lane boundary
666  targetDir = 1;
667  }
668  if (targetDir == 0) {
669  // Presently, no maneuvering into another lane is begun.
670  return nullptr;
671  }
672  MSLane* target = myVehicle.getLane()->getParallelLane(targetDir);
673  if (target == nullptr || target == myShadowLane) {
674  return nullptr;
675  } else {
676  return target;
677  }
678 }
679 
680 
681 
682 double
684  const double totalDuration = (myVehicle.getVehicleType().wasSet(VTYPEPARS_MAXSPEED_LAT_SET)
687 
688  const double angleOffset = 60 / totalDuration * (pastMidpoint() ? 1 - myLaneChangeCompletion : myLaneChangeCompletion);
689  return myLaneChangeDirection * angleOffset;
690 }
691 
692 
693 double
694 MSAbstractLaneChangeModel::estimateLCDuration(const double speed, const double remainingManeuverDist, const double decel) const {
695 
697  if (lcParams.find(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING) == lcParams.end() && lcParams.find(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR) == lcParams.end()) {
699  // no dependency of lateral speed on longitudinal speed. (Only called prior to LC initialization to determine whether it could be completed)
701  } else {
702  return remainingManeuverDist / myVehicle.getVehicleType().getMaxSpeedLat();
703  }
704  }
705 
706  if (remainingManeuverDist == 0) {
707  return 0;
708  }
709 
710  // Check argument assumptions
711  assert(speed >= 0);
712  assert(remainingManeuverDist >= 0);
713  assert(decel > 0);
714  assert(myVehicle.getVehicleType().getMaxSpeedLat() > 0);
716  assert(myMaxSpeedLatStanding >= 0);
717 
718  // for brevity
719  const double v0 = speed;
720  const double D = remainingManeuverDist;
721  const double b = decel;
722  const double wmin = myMaxSpeedLatStanding;
723  const double f = myMaxSpeedLatFactor;
724  const double wmax = myVehicle.getVehicleType().getMaxSpeedLat();
725 
726  /* Here's the approach for the calculation of the required time for the LC:
727  * To obtain the maximal LC-duration, for v(t) we assume that v(t)=max(0, v0-b*t),
728  * Where v(t)=0 <=> t >= ts:=v0/b
729  * For the lateral speed w(t) this gives:
730  * w(t) = min(wmax, wmin + f*v(t))
731  * The lateral distance covered until t is
732  * d(t) = int_0^t w(s) ds
733  * We distinguish three possibilities for the solution d(T)=D, where T is the time of the LC completion.
734  * 1) w(T) = wmax, i.e. v(T)>(wmax-wmin)/f
735  * 2) wmin < w(T) < wmax, i.e. (wmax-wmin)/f > v(T) > 0
736  * 3) w(T) = wmin, i.e., v(T)=0
737  */
738  const double vm = (wmax - wmin) / f;
739  double distSoFar = 0.;
740  double timeSoFar = 0.;
741  double v = v0;
742  if (v > vm) {
743  const double wmaxTime = (v0 - vm) / b;
744  const double d1 = wmax * wmaxTime;
745  if (d1 >= D) {
746  return D / wmax;
747  } else {
748  distSoFar += d1;
749  timeSoFar += wmaxTime;
750  v = vm;
751  }
752  }
753  if (v > 0) {
754  /* Here, w(t1+t) = wmin + f*v(t1+t) = wmin + f*(v - b*t)
755  * Thus, the additional lateral distance covered after time t is:
756  * d2 = (wmin + f*v)*t - 0.5*f*b*t^2
757  * and the additional lateral distance covered until v=0 at t=v/b is:
758  * d2 = (wmin + 0.5*f*v)*t
759  */
760  const double t = v / b; // stop time
761  const double d2 = (wmin + 0.5 * f * v) * t; // lateral distance covered until stop
762  assert(d2 > 0);
763  if (distSoFar + d2 >= D) {
764  // LC is completed during this phase
765  const double x = 0.5 * f * b;
766  const double y = wmin + f * v;
767  /* Solve D - distSoFar = y*t - x*t^2.
768  * 0 = x*t^2 - y*t/x + (D - distSoFar)/x
769  */
770  const double p = 0.5 * y / x;
771  const double q = (D - distSoFar) / x;
772  assert(p * p - q > 0);
773  const double t2 = p + sqrt(p * p - q);
774  return timeSoFar + t2;
775  } else {
776  distSoFar += d2;
777  timeSoFar += t;
778  //v = 0;
779  }
780  }
781  // If we didn't return yet this means the LC was not completed until the vehicle stops (if braking with rate b)
782  if (wmin == 0) {
783  // LC won't be completed if vehicle stands
784  double maneuverDist = remainingManeuverDist;
785  const double vModel = computeSpeedLat(maneuverDist, maneuverDist);
786  if (vModel > 0) {
787  // unless the model tells us something different
788  return D / vModel;
789  } else {
790  return -1;
791  }
792  } else {
793  // complete LC with lateral speed wmin
794  return timeSoFar + (D - distSoFar) / wmin;
795  }
796 }
797 
798 SUMOTime
800  assert(isChangingLanes()); // Only to be called during ongoing lane change
802  if (lcParams.find(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING) == lcParams.end() && lcParams.find(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR) == lcParams.end()) {
805  } else {
807  }
808  }
809  // Using maxSpeedLat(Factor/Standing)
811 }
812 
813 
814 void
816  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " set shadow approaching=" << link->getViaLaneOrLane()->getID() << "\n";
817  myApproachedByShadow.push_back(link);
818 }
819 
820 void
822  for (std::vector<MSLink*>::iterator it = myApproachedByShadow.begin(); it != myApproachedByShadow.end(); ++it) {
823  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " remove shadow approaching=" << (*it)->getViaLaneOrLane()->getID() << "\n";
824  (*it)->removeApproaching(&myVehicle);
825  }
826  myApproachedByShadow.clear();
827 }
828 
829 
830 
831 void
834  int oldstate = myVehicle.getLaneChangeModel().getOwnState();
835  if (myOwnState != newstate) {
837  // Calculate and set the lateral maneuver distance corresponding to the change request
838  // to induce a corresponding sublane change.
839  const int dir = (newstate & LCA_RIGHT) != 0 ? -1 : ((newstate & LCA_LEFT) != 0 ? 1 : 0);
840  // minimum distance to move the vehicle fully onto the lane at offset dir
841  const double latLaneDist = myVehicle.lateralDistanceToLane(dir);
842  if ((newstate & LCA_TRACI) != 0) {
843  if ((newstate & LCA_STAY) != 0) {
844  setManeuverDist(0.);
845  } else if (((newstate & LCA_RIGHT) != 0 && dir < 0)
846  || ((newstate & LCA_LEFT) != 0 && dir > 0)) {
847  setManeuverDist(latLaneDist);
848  }
849  }
850  if (myVehicle.hasInfluencer()) {
851  // lane change requests override sublane change requests
853  }
854 
855  }
856  setOwnState(newstate);
857  } else {
858  // Check for sublane change requests
860  const double maneuverDist = myVehicle.getInfluencer().getLatDist();
863  newstate |= LCA_TRACI;
864  if (myOwnState != newstate) {
865  setOwnState(newstate);
866  }
867  if (gDebugFlag2) {
868  std::cout << " traci influenced maneuverDist=" << maneuverDist << "\n";
869  }
870  }
871  }
872  if (gDebugFlag2) {
873  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " stateAfterTraCI=" << toString((LaneChangeAction)newstate) << " original=" << toString((LaneChangeAction)oldstate) << "\n";
874  }
875 }
876 
877 void
880  myAlreadyChanged = true;
881 }
882 
883 void
885  if (follower.first != 0) {
886  myLastFollowerGap = follower.second + follower.first->getVehicleType().getMinGap();
887  myLastFollowerSecureGap = secGap;
888  myLastFollowerSpeed = follower.first->getSpeed();
889  }
890 }
891 
892 void
894  if (leader.first != 0) {
895  myLastLeaderGap = leader.second + myVehicle.getVehicleType().getMinGap();
896  myLastLeaderSecureGap = secGap;
897  myLastLeaderSpeed = leader.first->getSpeed();
898  }
899 }
900 
901 void
903  if (leader.first != 0) {
905  myLastOrigLeaderSecureGap = secGap;
906  myLastOrigLeaderSpeed = leader.first->getSpeed();
907  }
908 }
909 
910 void
920  if (!myDontResetLCGaps) {
930  }
931  myCommittedSpeed = 0;
932 }
933 
934 void
936  int rightmost;
937  int leftmost;
938  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
939  for (int i = rightmost; i <= leftmost; ++i) {
940  CLeaderDist vehDist = vehicles[i];
941  if (vehDist.first != 0) {
942  const MSVehicle* leader = &myVehicle;
943  const MSVehicle* follower = vehDist.first;
944  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
945  if (netGap < myLastFollowerGap && netGap >= 0) {
946  myLastFollowerGap = netGap;
947  myLastFollowerSecureGap = follower->getCarFollowModel().getSecureGap(follower, leader, follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
948  myLastFollowerSpeed = follower->getSpeed();
949  }
950  }
951  }
952 }
953 
954 void
956  int rightmost;
957  int leftmost;
958  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
959  for (int i = rightmost; i <= leftmost; ++i) {
960  CLeaderDist vehDist = vehicles[i];
961  if (vehDist.first != 0) {
962  const MSVehicle* leader = vehDist.first;
963  const MSVehicle* follower = &myVehicle;
964  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
965  if (netGap < myLastLeaderGap && netGap >= 0) {
966  myLastLeaderGap = netGap;
967  myLastLeaderSecureGap = follower->getCarFollowModel().getSecureGap(follower, leader, follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
968  myLastLeaderSpeed = leader->getSpeed();
969  }
970  }
971  }
972 }
973 
974 void
976  int rightmost;
977  int leftmost;
978  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
979  for (int i = rightmost; i <= leftmost; ++i) {
980  CLeaderDist vehDist = vehicles[i];
981  if (vehDist.first != 0) {
982  const MSVehicle* leader = vehDist.first;
983  const MSVehicle* follower = &myVehicle;
984  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
985  if (netGap < myLastOrigLeaderGap && netGap >= 0) {
986  myLastOrigLeaderGap = netGap;
987  myLastOrigLeaderSecureGap = follower->getCarFollowModel().getSecureGap(follower, leader, follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
988  myLastOrigLeaderSpeed = leader->getSpeed();
989  }
990  }
991  }
992 }
993 
994 
995 bool
997  const int stateRight = mySavedStateRight.second;
998  if (
999  (stateRight & LCA_STRATEGIC) != 0
1000  && (stateRight & LCA_RIGHT) != 0
1001  && (stateRight & LCA_BLOCKED) != 0) {
1002  return true;
1003  }
1004  const int stateLeft = mySavedStateLeft.second;
1005  if (
1006  (stateLeft & LCA_STRATEGIC) != 0
1007  && (stateLeft & LCA_LEFT) != 0
1008  && (stateLeft & LCA_BLOCKED) != 0) {
1009  return true;
1010  }
1011  return false;
1012 }
#define DEBUG_COND
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:32
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SPEED2DIST(x)
Definition: SUMOTime.h:43
#define SIMTIME
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
#define DIST2SPEED(x)
Definition: SUMOTime.h:45
long long int SUMOTime
Definition: SUMOTime.h:31
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:51
const int VTYPEPARS_MAXSPEED_LAT_SET
LaneChangeAction
The state of a vehicle's lane-change behavior.
@ LCA_UNKNOWN
The action has not been determined.
@ LCA_BLOCKED
blocked in all directions
@ LCA_NONE
@ LCA_STAY
Needs to stay on the current lane.
@ LCA_AMBACKBLOCKER
@ LCA_AMBLOCKINGLEADER
@ LCA_LEFT
Wants go to the left.
@ LCA_MRIGHT
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
@ LCA_AMBACKBLOCKER_STANDING
@ LCA_TRACI
The action is due to a TraCI request.
@ LCA_RIGHT
Wants go to the right.
@ LCA_MLEFT
@ LCA_AMBLOCKINGFOLLOWER
LaneChangeModel
@ LCM_SL2015
@ LCM_LC2013
@ LCM_DEFAULT
@ LCM_DK2008
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_Y
@ SUMO_ATTR_X
@ SUMO_ATTR_LCA_MAXSPEEDLATFACTOR
@ SUMO_ATTR_LCA_MAXSPEEDLATSTANDING
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_LCA_SIGMA
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_DIR
The abstract direction of a link.
@ SUMO_ATTR_POSITION
@ SUMO_ATTR_TIME
trigger: the time of the step
bool gDebugFlag2
Definition: StdDefs.cpp:32
const double SUMO_const_laneWidth
Definition: StdDefs.h:47
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:29
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
Interface for lane-change models.
void saveLCState(const int dir, const int stateWithoutTraCI, const int state)
double myAccelerationLat
the current lateral acceleration
void setFollowerGaps(CLeaderDist follower, double secGap)
std::vector< MSLane * > myFurtherTargetLanes
bool myAlreadyChanged
whether the vehicle has already moved this step
bool myAmOpposite
whether the vehicle is driving in the opposite direction
std::shared_ptr< MSLeaderDistanceInfo > myRightFollowers
std::shared_ptr< MSLeaderDistanceInfo > myRightLeaders
virtual void setOwnState(const int state)
bool pastMidpoint() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver
virtual double getAssumedDecelForLaneChangeDuration() const
Returns a deceleration value which is used for the estimation of the duration of a lane change.
std::shared_ptr< MSLeaderDistanceInfo > myLeftLeaders
int myPreviousState
lane changing state from the previous simulation step
virtual double estimateLCDuration(const double speed, const double remainingManeuverDist, const double decel) const
Calculates the maximal time needed to complete a lane change maneuver if lcMaxSpeedLatFactor and lcMa...
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model)
int myOwnState
The current state of the vehicle.
double myLastOrigLeaderGap
acutal and secure distance to closest leader vehicle on the original when performing lane change
virtual bool predInteraction(const std::pair< MSVehicle *, double > &leader)
void laneChangeOutput(const std::string &tag, MSLane *source, MSLane *target, int direction, double maneuverDist=0)
called once the vehicle ends a lane change manoeuvre (non-instant)
bool myDontResetLCGaps
Flag to prevent resetting the memorized values for LC relevant gaps until the LC output is triggered ...
int myPreviousState2
lane changing state from step before the previous simulation step
static bool haveLateralDynamics()
whether any kind of lateral dynamics is active
const std::shared_ptr< MSLeaderDistanceInfo > getFollowers(const int dir)
Returns the neighboring, lc-relevant followers for the last step in the requested direction.
double myCommittedSpeed
the speed when committing to a change maneuver
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
std::pair< int, int > mySavedStateLeft
std::shared_ptr< MSLeaderDistanceInfo > myLeftFollowers
Cached info on lc-relevant neighboring vehicles.
static bool myLCOutput
whether to record lane-changing
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
std::pair< int, int > mySavedStateRight
double myLastLeaderSecureGap
the minimum longitudinal distances to vehicles on the target lane that would be necessary for stringe...
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
std::vector< MSLink * > myApproachedByShadow
links which are approached by the shadow vehicle
void setLeaderGaps(CLeaderDist, double secGap)
const std::shared_ptr< MSLeaderDistanceInfo > getLeaders(const int dir)
Returns the neighboring, lc-relevant leaders for the last step in the requested direction.
std::vector< MSLane * > myNoPartiallyOccupatedByShadow
const LaneChangeModel myModel
the type of this model
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
double myLastLeaderGap
the actual minimum longitudinal distances to vehicles on the target lane
SUMOTime remainingTime() const
Compute the remaining time until LC completion.
virtual double computeSpeedLat(double latDist, double &maneuverDist) const
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
void setOrigLeaderGaps(CLeaderDist, double secGap)
void setManeuverDist(const double dist)
Updates the remaining distance for the current maneuver while it is continued within non-action steps...
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
void setSpeedLat(double speedLat)
set the lateral speed and update lateral acceleraton
MSLane * myTargetLane
The target lane for the vehicle's current maneuver.
MSLane * determineTargetLane(int &targetDir) const
double myPreviousManeuverDist
Maneuver distance from the previous simulation step.
std::vector< double > myShadowFurtherLanesPosLat
MSLane * myShadowLane
A lane that is partially occupied by the front of the vehicle but that is not the primary lane.
double mySpeedLat
the current lateral speed
virtual void updateSafeLatDist(const double travelledLatDist)
Updates the value of safe lateral distances (in SL2015) during maneuver continuation in non-action st...
void checkTraCICommands()
Check for commands issued for the vehicle via TraCI and apply the appropriate state changes For the s...
const MSCFModel & myCarFollowModel
The vehicle's car following model.
double myManeuverDist
The complete lateral distance the vehicle wants to travel to finish its maneuver Only used by sublane...
int myLaneChangeDirection
direction of the lane change maneuver -1 means right, 1 means left
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
int getShadowDirection() const
return the direction in which the current shadow lane lies
double myLastLeaderSpeed
speeds of surrounding vehicles at the time of lane change
MSAbstractLaneChangeModel(MSVehicle &v, const LaneChangeModel model)
Constructor.
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right
virtual ~MSAbstractLaneChangeModel()
Destructor.
static void initGlobalOptions(const OptionsCont &oc)
init global model parameters
double getAngleOffset() const
return the angle offset during a continuous change maneuver
void memorizeGapsAtLCInit()
Control for resetting the memorized values for LC relevant gaps until the LC output is triggered in t...
double myLaneChangeCompletion
progress of the lane change maneuver 0:started, 1:complete
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
virtual void changed()=0
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
std::vector< MSLane * > myShadowFurtherLanes
virtual bool congested(const MSVehicle *const neighLeader)
void clearNeighbors()
Clear info on neighboring vehicle from previous step.
void saveNeighbors(const int dir, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &leaders)
Saves the lane change relevant vehicles, which are currently on neighboring lanes in the given direct...
double getWidth() const
Returns the vehicle's width.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
virtual double getSecureGap(const MSVehicle *const, const MSVehicle *const, const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:328
virtual double interactionGap(const MSVehicle *const veh, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel.cpp:222
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:216
static double gLateralResolution
Definition: MSGlobals.h:82
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:79
A lane change model developed by D. Krajzewicz between 2004 and 2010.
Definition: MSLCM_DK2008.h:37
A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013.
Definition: MSLCM_LC2013.h:45
A lane change model developed by J. Erdmann.
Definition: MSLCM_SL2015.h:35
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:2211
virtual void resetManeuverReservation(MSVehicle *v)
Unregisters a vehicle, which previously registered for maneuvering into this lane.
Definition: MSLane.cpp:323
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
Definition: MSLane.cpp:2128
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:1067
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:531
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2675
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:272
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:562
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2668
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3621
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:290
virtual void setManeuverReservation(MSVehicle *v)
Registers the lane change intentions (towards this lane) for the given vehicle.
Definition: MSLane.cpp:312
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:555
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:130
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) const
Notification
Definition of a vehicle state.
@ NOTIFICATION_LANE_CHANGE
The vehicle changes lanes (micro only)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
double getLatDist() const
Definition: MSVehicle.h:1563
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
const std::vector< double > & getFurtherLanesPosLat() const
Definition: MSVehicle.h:815
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:5463
const std::vector< MSLane * > & getFurtherLanes() const
Definition: MSVehicle.h:811
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4699
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:6093
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:5270
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1122
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
Definition: MSVehicle.cpp:5595
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:4634
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1142
@ VEH_SIGNAL_BLINKER_RIGHT
Right blinker lights are switched on.
Definition: MSVehicle.h:1081
@ VEH_SIGNAL_BLINKER_LEFT
Left blinker lights are switched on.
Definition: MSVehicle.h:1083
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:4505
Influencer & getInfluencer()
Definition: MSVehicle.cpp:6059
double updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< double > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:3975
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:411
bool congested() const
Definition: MSVehicle.h:737
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:458
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:374
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:550
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:930
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane
Definition: MSVehicle.cpp:5645
bool hasInfluencer() const
Definition: MSVehicle.h:1651
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1134
void updateDriveItems()
Check whether the drive items (myLFLinkLanes) are up to date, and update them if required.
Definition: MSVehicle.cpp:3172
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:90
bool wasSet(int what) const
Returns whether the given parameter was set.
Definition: MSVehicleType.h:79
const SUMOVTypeParameter & getParameter() const
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:66
const std::string & getID() const
Returns the id.
Definition: Named.h:73
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
double x() const
Returns the x-position.
Definition: Position.h:54
double y() const
Returns the y-position.
Definition: Position.h:59
std::map< SumoXMLAttr, std::string > SubParams
sub-model parameters
const SubParams & getLCParams() const
Returns the LC parameter.