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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
22 // Interface for lane-change models
23 /****************************************************************************/
24 
25 // ===========================================================================
26 // DEBUG
27 // ===========================================================================
28 //#define DEBUG_TARGET_LANE
29 #define DEBUG_COND (myVehicle.isSelected())
30 
31 
32 // ===========================================================================
33 // included modules
34 // ===========================================================================
35 #ifdef _MSC_VER
36 #include <windows_config.h>
37 #else
38 #include <config.h>
39 #endif
40 
43 #include <microsim/MSNet.h>
44 #include <microsim/MSEdge.h>
45 #include <microsim/MSLane.h>
46 #include <microsim/MSGlobals.h>
47 #include "MSLCM_DK2008.h"
48 #include "MSLCM_LC2013.h"
49 #include "MSLCM_SL2015.h"
50 
51 /* -------------------------------------------------------------------------
52  * static members
53  * ----------------------------------------------------------------------- */
58 const double MSAbstractLaneChangeModel::NO_NEIGHBOR(std::numeric_limits<double>::max());
59 
60 /* -------------------------------------------------------------------------
61  * MSAbstractLaneChangeModel-methods
62  * ----------------------------------------------------------------------- */
63 
64 void
66  myAllowOvertakingRight = oc.getBool("lanechange.overtake-right");
67  myLCOutput = oc.isSet("lanechange-output");
68  myLCStartedOutput = oc.getBool("lanechange-output.started");
69  myLCEndedOutput = oc.getBool("lanechange-output.ended");
70 }
71 
72 
75  if (MSGlobals::gLateralResolution > 0 && lcm != LCM_SL2015 && lcm != LCM_DEFAULT) {
76  throw ProcessError("Lane change model '" + toString(lcm) + "' is not compatible with sublane simulation");
77  }
78  switch (lcm) {
79  case LCM_DK2008:
80  return new MSLCM_DK2008(v);
81  case LCM_LC2013:
82  return new MSLCM_LC2013(v);
83  case LCM_SL2015:
84  return new MSLCM_SL2015(v);
85  case LCM_DEFAULT:
87  return new MSLCM_LC2013(v);
88  } else {
89  return new MSLCM_SL2015(v);
90  }
91  default:
92  throw ProcessError("Lane change model '" + toString(lcm) + "' not implemented");
93  }
94 }
95 
96 
98  myVehicle(v),
99  myOwnState(0),
100  myPreviousState(0),
101  myPreviousState2(0),
102  mySpeedLat(0),
103  myCommittedSpeed(0),
106  myManeuverDist(0.),
107  myAlreadyChanged(false),
108  myShadowLane(nullptr),
109  myTargetLane(nullptr),
110  myCarFollowModel(v.getCarFollowModel()),
111  myModel(model),
114  myLastLeaderGap(0.),
115  myLastFollowerGap(0.),
121  myAmOpposite(false) {
122 }
123 
124 
126 }
127 
128 void
131  myOwnState = state;
132  myPreviousState = state; // myOwnState is modified in prepareStep so we make a backup
133 }
134 
135 void
136 MSAbstractLaneChangeModel::updateSafeLatDist(const double travelledLatDist) {
137  UNUSED_PARAMETER(travelledLatDist);
138 }
139 
140 
141 void
143 #ifdef DEBUG_MANEUVER
144  if DEBUG_COND {
145  std::cout << SIMTIME
146  << " veh=" << myVehicle.getID()
147  << " setManeuverDist() old=" << myManeuverDist << " new=" << dist
148  << std::endl;
149  }
150 #endif
151  myManeuverDist = dist;
152 }
153 
154 
155 double
157  return myManeuverDist;
158 }
159 
160 
161 bool
163  if (neighLeader == 0) {
164  return false;
165  }
166  // Congested situation are relevant only on highways (maxSpeed > 70km/h)
167  // and congested on German Highways means that the vehicles have speeds
168  // below 60km/h. Overtaking on the right is allowed then.
169  if ((myVehicle.getLane()->getSpeedLimit() <= 70.0 / 3.6) || (neighLeader->getLane()->getSpeedLimit() <= 70.0 / 3.6)) {
170 
171  return false;
172  }
173  if (myVehicle.congested() && neighLeader->congested()) {
174  return true;
175  }
176  return false;
177 }
178 
179 
180 
181 bool
182 MSAbstractLaneChangeModel::predInteraction(const std::pair<MSVehicle*, double>& leader) {
183  if (leader.first == 0) {
184  return false;
185  }
186  // let's check it on highways only
187  if (leader.first->getSpeed() < (80.0 / 3.6)) {
188  return false;
189  }
190  return leader.second < myCarFollowModel.interactionGap(&myVehicle, leader.first->getSpeed());
191 }
192 
193 
194 bool
196  if (&source->getEdge() != &target->getEdge()) {
198  }
201  myLaneChangeDirection = direction;
202  mySpeedLat = (target->getCenterOnEdge() - source->getCenterOnEdge()) * (double)DELTA_T / (double)MSGlobals::gLaneChangeDuration;
205  return true;
206  } else {
207  primaryLaneChanged(source, target, direction);
208  return false;
209  }
210 }
211 
212 
213 void
215  initLastLaneChangeOffset(direction);
217  source->leftByLaneChange(&myVehicle);
219  target->enteredByLaneChange(&myVehicle);
220  laneChangeOutput("change", source, target, direction);
221  changed();
222 }
223 
224 void
225 MSAbstractLaneChangeModel::laneChangeOutput(const std::string& tag, MSLane* source, MSLane* target, int direction) {
226  if (myLCOutput) {
227  OutputDevice& of = OutputDevice::getDeviceByOption("lanechange-output");
228  of.openTag(tag);
231  of.writeAttr(SUMO_ATTR_TIME, time2string(MSNet::getInstance()->getCurrentTimeStep()));
232  of.writeAttr(SUMO_ATTR_FROM, source->getID());
233  of.writeAttr(SUMO_ATTR_TO, target->getID());
234  of.writeAttr(SUMO_ATTR_DIR, direction);
238  of.writeAttr("leaderGap", myLastLeaderGap == NO_NEIGHBOR ? "None" : toString(myLastLeaderGap));
239  of.writeAttr("leaderSecureGap", myLastLeaderSecureGap == NO_NEIGHBOR ? "None" : toString(myLastLeaderSecureGap));
240  of.writeAttr("followerGap", myLastFollowerGap == NO_NEIGHBOR ? "None" : toString(myLastFollowerGap));
241  of.writeAttr("followerSecureGap", myLastFollowerSecureGap == NO_NEIGHBOR ? "None" : toString(myLastFollowerSecureGap));
242  of.writeAttr("origLeaderGap", myLastOrigLeaderGap == NO_NEIGHBOR ? "None" : toString(myLastOrigLeaderGap));
243  of.writeAttr("origLeaderSecureGap", myLastOrigLeaderSecureGap == NO_NEIGHBOR ? "None" : toString(myLastOrigLeaderSecureGap));
245  const double latGap = direction < 0 ? myLastLateralGapRight : myLastLateralGapLeft;
246  of.writeAttr("latGap", latGap == NO_NEIGHBOR ? "None" : toString(latGap));
247  }
248  of.closeTag();
249  }
250  // Assure that the drive items are up to date (even if the following step is no actionstep for the vehicle).
252 }
253 
254 bool
256  const bool pastBefore = pastMidpoint();
258  return !pastBefore && pastMidpoint();
259 }
260 
261 
262 void
264  UNUSED_PARAMETER(reason);
271  if (myAmOpposite) {
273  }
274 }
275 
276 
277 MSLane*
278 MSAbstractLaneChangeModel::getShadowLane(const MSLane* lane, double posLat) const {
280  // initialize shadow lane
281  const double overlap = myVehicle.getLateralOverlap(posLat);
282  if (debugVehicle()) {
283  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " posLat=" << posLat << " overlap=" << overlap << "\n";
284  }
285  if (overlap > NUMERICAL_EPS ||
286  // "reserve" target lane even when there is no overlap yet
288  const int shadowDirection = posLat < 0 ? -1 : 1;
289  return lane->getParallelLane(shadowDirection);
290  } else {
291  return 0;
292  }
293  } else {
294  return 0;
295  }
296 }
297 
298 
299 MSLane*
302 }
303 
304 
305 void
307  if (myShadowLane != 0) {
308  if (debugVehicle()) {
309  std::cout << SIMTIME << " cleanupShadowLane\n";
310  }
312  myShadowLane = 0;
313  }
314  for (std::vector<MSLane*>::const_iterator it = myShadowFurtherLanes.begin(); it != myShadowFurtherLanes.end(); ++it) {
315  if (debugVehicle()) {
316  std::cout << SIMTIME << " cleanupShadowLane2\n";
317  }
318  (*it)->resetPartialOccupation(&myVehicle);
319  }
320  myShadowFurtherLanes.clear();
322 }
323 
324 void
326  if (myTargetLane != 0) {
327  if (debugVehicle()) {
328  std::cout << SIMTIME << " cleanupTargetLane\n";
329  }
331  myTargetLane = 0;
332  }
333  for (std::vector<MSLane*>::const_iterator it = myFurtherTargetLanes.begin(); it != myFurtherTargetLanes.end(); ++it) {
334  if (debugVehicle()) {
335  std::cout << SIMTIME << " cleanupTargetLane\n";
336  }
337  if (*it != nullptr) {
338  (*it)->resetManeuverReservation(&myVehicle);
339  }
340  }
341  myFurtherTargetLanes.clear();
342 // myNoPartiallyOccupatedByShadow.clear();
343 }
344 
345 
346 bool
348  int ret = myVehicle.influenceChangeDecision(state);
349  return ret != state;
350 }
351 
352 
353 void
355  if (dir > 0) {
357  } else if (dir < 0) {
359  }
360 }
361 
362 void
364  if (myShadowLane != 0) {
365  if (debugVehicle()) {
366  std::cout << SIMTIME << " updateShadowLane()\n";
367  }
369  }
371  std::vector<MSLane*> passed;
372  if (myShadowLane != 0) {
374  const std::vector<MSLane*>& further = myVehicle.getFurtherLanes();
375  const std::vector<double>& furtherPosLat = myVehicle.getFurtherLanesPosLat();
376  assert(further.size() == furtherPosLat.size());
377  passed.push_back(myShadowLane);
378  for (int i = 0; i < (int)further.size(); ++i) {
379  MSLane* shadowFurther = getShadowLane(further[i], furtherPosLat[i]);
380  if (debugVehicle()) {
381  std::cout << SIMTIME << " further=" << further[i]->getID() << " (posLat=" << furtherPosLat[i] << ") shadowFurther=" << Named::getIDSecure(shadowFurther) << "\n";
382  }
383  if (shadowFurther != 0 && MSLinkContHelper::getConnectingLink(*shadowFurther, *passed.back()) != 0) {
384  passed.push_back(shadowFurther);
385  }
386  }
387  std::reverse(passed.begin(), passed.end());
388  } else {
390  WRITE_WARNING("Vehicle '" + myVehicle.getID() + "' could not finish continuous lane change (lane disappeared) time=" +
391  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
393  }
394  }
395  if (debugVehicle()) {
396  std::cout << SIMTIME << " updateShadowLane() veh=" << myVehicle.getID()
397  << " newShadowLane=" << Named::getIDSecure(myShadowLane)
398  << "\n before:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << " further=" << toString(myVehicle.getFurtherLanes()) << " passed=" << toString(passed);
399  std::cout << std::endl;
400  }
402  if (debugVehicle()) std::cout
403  << "\n after:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << "\n";
404 }
405 
406 
407 int
409  if (isChangingLanes()) {
410  if (pastMidpoint()) {
411  return -myLaneChangeDirection;
412  } else {
413  return myLaneChangeDirection;
414  }
415  } else if (myShadowLane == 0) {
416  return 0;
417  } else {
418  assert(&myShadowLane->getEdge() == &myVehicle.getLane()->getEdge());
420  }
421 }
422 
423 
424 void
426 #ifdef DEBUG_TARGET_LANE
427  MSLane* oldTarget = myTargetLane;
428  std::vector<MSLane*> oldFurtherTargets = myFurtherTargetLanes;
429  if (debugVehicle()) {
430  std::cout << SIMTIME << " veh '" << myVehicle.getID() << "' (lane=" << myVehicle.getLane()->getID() << ") updateTargetLane()"
431  << "\n oldTarget: " << (oldTarget == nullptr ? "NULL" : oldTarget->getID())
432  << " oldFurtherTargets: " << toString(oldFurtherTargets);
433  }
434 #endif
435  if (myTargetLane != nullptr) {
437  }
438  // Clear old further target lanes
439  for (MSLane* oldTargetLane : myFurtherTargetLanes) {
440  if (oldTargetLane != nullptr) {
441  oldTargetLane->resetManeuverReservation(&myVehicle);
442  }
443  }
444  myFurtherTargetLanes.clear();
445 
446  // Get new target lanes and issue a maneuver reservation.
447  int targetDir;
448  myTargetLane = determineTargetLane(targetDir);
449  if (myTargetLane != nullptr) {
451  // further targets are just the target lanes corresponding to the vehicle's further lanes
452  // @note In a neglectable amount of situations we might add a reservation for a shadow further lane.
453  for (MSLane* furtherLane : myVehicle.getFurtherLanes()) {
454  MSLane* furtherTargetLane = furtherLane->getParallelLane(targetDir);
455  myFurtherTargetLanes.push_back(furtherTargetLane);
456  if (furtherTargetLane != nullptr) {
457  furtherTargetLane->setManeuverReservation(&myVehicle);
458  }
459  }
460  }
461 #ifdef DEBUG_TARGET_LANE
462  if (debugVehicle()) {
463  std::cout << "\n newTarget (offset=" << targetDir << "): " << (myTargetLane == nullptr ? "NULL" : myTargetLane->getID())
464  << " newFurtherTargets: " << toString(myFurtherTargetLanes)
465  << std::endl;
466  }
467 #endif
468 }
469 
470 
471 MSLane*
473  targetDir = 0;
474  if (myManeuverDist == 0) {
475  return nullptr;
476  }
477  // Current lateral boundaries of the vehicle
478  const double vehRight = myVehicle.getLateralPositionOnLane() - 0.5 * myVehicle.getWidth();
479  const double vehLeft = myVehicle.getLateralPositionOnLane() + 0.5 * myVehicle.getWidth();
480  const double halfLaneWidth = 0.5 * myVehicle.getLane()->getWidth();
481 
482  if (vehRight + myManeuverDist < -halfLaneWidth) {
483  // Vehicle intends to traverse the right lane boundary
484  targetDir = -1;
485  } else if (vehLeft + myManeuverDist > halfLaneWidth) {
486  // Vehicle intends to traverse the left lane boundary
487  targetDir = 1;
488  }
489  if (targetDir == 0) {
490  // Presently, no maneuvering into another lane is begun.
491  return nullptr;
492  }
493  MSLane* target = myVehicle.getLane()->getParallelLane(targetDir);
494  if (target == nullptr || target == myShadowLane) {
495  return nullptr;
496  } else {
497  return target;
498  }
499 }
500 
501 
502 
503 double
506  return myLaneChangeDirection * angleOffset;
507 }
508 
509 
510 SUMOTime
513 }
514 
515 
516 void
518  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " set shadow approaching=" << link->getViaLaneOrLane()->getID() << "\n";
519  myApproachedByShadow.push_back(link);
520 }
521 
522 void
524  for (std::vector<MSLink*>::iterator it = myApproachedByShadow.begin(); it != myApproachedByShadow.end(); ++it) {
525  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " remove shadow approaching=" << (*it)->getViaLaneOrLane()->getID() << "\n";
526  (*it)->removeApproaching(&myVehicle);
527  }
528  myApproachedByShadow.clear();
529 }
530 
531 
532 
533 void
536  int oldstate = myVehicle.getLaneChangeModel().getOwnState();
537  if (myOwnState != newstate) {
539  // Calculate and set the lateral maneuver distance corresponding to the change request
540  // to induce a corresponding sublane change.
541  const int dir = (newstate & LCA_RIGHT) != 0 ? -1 : ((newstate & LCA_LEFT) != 0 ? 1 : 0);
542  // minimum distance to move the vehicle fully onto the lane at offset dir
543  const double latLaneDist = myVehicle.lateralDistanceToLane(dir);
544  if ((newstate & LCA_TRACI) != 0) {
545  if ((newstate & LCA_STAY) != 0) {
546  setManeuverDist(0.);
547  } else if (((newstate & LCA_RIGHT) != 0 && dir < 0)
548  || ((newstate & LCA_LEFT) != 0 && dir > 0)) {
549  setManeuverDist(latLaneDist);
550  }
551  }
552  if (myVehicle.hasInfluencer()) {
553  // lane change requests override sublane change requests
555  }
556 
557  }
558  setOwnState(newstate);
559  } else {
560  // Check for sublane change requests
562  const double maneuverDist = myVehicle.getInfluencer().getLatDist();
565  newstate |= LCA_TRACI;
566  if (myOwnState != newstate) {
567  setOwnState(newstate);
568  }
569  if (gDebugFlag2) {
570  std::cout << " traci influenced maneuverDist=" << maneuverDist << "\n";
571  }
572  }
573  }
574  if (DEBUG_COND) {
575  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " stateAfterTraCI=" << toString((LaneChangeAction)newstate) << " original=" << toString((LaneChangeAction)oldstate) << "\n";
576  }
577 }
578 
579 void
582  myAlreadyChanged = true;
583 }
584 
585 void
587  if (follower.first != 0) {
588  myLastFollowerGap = follower.second + follower.first->getVehicleType().getMinGap();
589  myLastFollowerSecureGap = secGap;
590  }
591 }
592 
593 void
595  if (leader.first != 0) {
596  myLastLeaderGap = leader.second + myVehicle.getVehicleType().getMinGap();
597  myLastLeaderSecureGap = secGap;
598  }
599 }
600 
601 void
603  if (leader.first != 0) {
605  myLastOrigLeaderSecureGap = secGap;
606  }
607 }
608 
609 void
611  int rightmost;
612  int leftmost;
613  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
614  for (int i = rightmost; i <= leftmost; ++i) {
615  CLeaderDist vehDist = vehicles[i];
616  if (vehDist.first != 0) {
617  const MSVehicle* leader = &myVehicle;
618  const MSVehicle* follower = vehDist.first;
619  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
620  if (netGap < myLastFollowerGap && netGap >= 0) {
621  myLastFollowerGap = netGap;
622  myLastFollowerSecureGap = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
623  }
624  }
625  }
626 }
627 
628 void
630  int rightmost;
631  int leftmost;
632  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
633  for (int i = rightmost; i <= leftmost; ++i) {
634  CLeaderDist vehDist = vehicles[i];
635  if (vehDist.first != 0) {
636  const MSVehicle* leader = vehDist.first;
637  const MSVehicle* follower = &myVehicle;
638  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
639  if (netGap < myLastLeaderGap && netGap >= 0) {
640  myLastLeaderGap = netGap;
641  myLastLeaderSecureGap = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
642  }
643  }
644  }
645 }
646 
647 void
649  int rightmost;
650  int leftmost;
651  vehicles.getSubLanes(&myVehicle, 0, rightmost, leftmost);
652  for (int i = rightmost; i <= leftmost; ++i) {
653  CLeaderDist vehDist = vehicles[i];
654  if (vehDist.first != 0) {
655  const MSVehicle* leader = vehDist.first;
656  const MSVehicle* follower = &myVehicle;
657  const double netGap = vehDist.second + follower->getVehicleType().getMinGap();
658  if (netGap < myLastOrigLeaderGap && netGap >= 0) {
659  myLastOrigLeaderGap = netGap;
661  }
662  }
663  }
664 }
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
static double gLateralResolution
Definition: MSGlobals.h:91
A lane change model developed by J. Erdmann.
Definition: MSLCM_SL2015.h:44
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:260
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:135
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
int myPreviousState
lane changing state from the previous simulation step
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:564
void setLeaderGaps(CLeaderDist, double secGap)
double myLastLeaderGap
the actual minimum longitudinal distances to vehicles on the target lane
int getShadowDirection() const
return the direction in which the current shadow lane lies
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model) ...
double myLaneChangeCompletion
progress of the lane change maneuver 0:started, 1:complete
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:402
Notification
Definition of a vehicle state.
virtual void resetManeuverReservation(MSVehicle *v)
Unregisters a vehicle, which previously registered for maneuvering into this lane.
Definition: MSLane.cpp:272
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
Wants go to the right.
static bool myLCOutput
whether to record lane-changing
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
Definition: MSVehicle.cpp:4445
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
double myLastOrigLeaderGap
acutal and secure distance to closest leader vehicle on the original when performing lane change ...
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
double getAngleOffset() const
return the angle offset during a continuous change maneuver
#define DEBUG_COND
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:58
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2358
MSLane * myShadowLane
A lane that is partially occupied by the front of the vehicle but that is not the primary lane...
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
virtual bool predInteraction(const std::pair< MSVehicle *, double > &leader)
virtual double setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:229
Wants go to the left.
MSLane * myTargetLane
The target lane for the vehicle&#39;s current maneuver.
virtual void setManeuverReservation(MSVehicle *v)
Registers the lane change intentions (towards this lane) for the given vehicle.
Definition: MSLane.cpp:261
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:513
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
SUMOTime remainingTime() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:3516
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
void checkTraCICommands()
Check for commands issued for the vehicle via TraCI and apply the appropriate state changes For the s...
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3674
#define SIMTIME
Definition: SUMOTime.h:71
Right blinker lights are switched on.
Definition: MSVehicle.h:1162
std::vector< double > myShadowFurtherLanesPosLat
void setFollowerGaps(CLeaderDist follower, double secGap)
Needs to stay on the current lane.
const LaneChangeModel myModel
the type of this model
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
LaneChangeModel
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:3624
The vehicle changes lanes (micro only)
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:882
A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013...
Definition: MSLCM_LC2013.h:54
int getIndex() const
Returns the lane&#39;s index.
Definition: MSLane.h:520
Left blinker lights are switched on.
Definition: MSVehicle.h:1164
bool cancelRequest(int state)
whether the influencer cancels the given request
std::vector< MSLane * > myNoPartiallyOccupatedByShadow
double myManeuverDist
The complete lateral distance the vehicle wants to travel to finish its maneuver Only used by sublane...
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:242
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it&#39;s primary lane ...
Definition: MSVehicle.cpp:4495
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:3054
double getCenterOnEdge() const
Definition: MSLane.h:968
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2365
std::vector< MSLane * > myShadowFurtherLanes
const std::vector< MSLane * > & getFurtherLanes() const
Definition: MSVehicle.h:780
double getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:489
#define STEPS2TIME(x)
Definition: SUMOTime.h:64
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) const
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:189
int myLaneChangeDirection
direction of the lane change maneuver -1 means right, 1 means left
bool hasInfluencer() const
Definition: MSVehicle.h:1543
bool pastMidpoint() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
double getMinGap() const
Get the free space in front of vehicles of this class.
virtual void changed()=0
static void initGlobalOptions(const OptionsCont &oc)
init global model parameters
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:211
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:4073
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
double myLastLeaderSecureGap
the minimum longitudinal distances to vehicles on the target lane that would be necessary for stringe...
int myOwnState
The current state of the vehicle.
MSLane * determineTargetLane(int &targetDir) const
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:439
void setOrigLeaderGaps(CLeaderDist, double secGap)
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
const std::vector< double > & getFurtherLanesPosLat() const
Definition: MSVehicle.h:784
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:41
trigger: the time of the step
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:4812
LaneChangeAction
The state of a vehicle&#39;s lane-change behavior.
virtual void setOwnState(const int state)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
A storage for options typed value containers)
Definition: OptionsCont.h:98
std::vector< MSLane * > myFurtherTargetLanes
double mySpeedLat
the current lateral speed
const std::string & getID() const
Returns the name of the vehicle type.
The abstract direction of a link.
A lane change model developed by D. Krajzewicz between 2004 and 2010.
Definition: MSLCM_DK2008.h:46
The action is due to a TraCI request.
bool gDebugFlag2
Definition: StdDefs.cpp:33
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:70
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
bool closeTag()
Closes the most recently opened tag.
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1223
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1215
long long int SUMOTime
Definition: TraCIDefs.h:51
double myCommittedSpeed
the speed when committing to a change maneuver
#define NUMERICAL_EPS
Definition: config.h:151
std::vector< MSLink * > myApproachedByShadow
links which are approached by the shadow vehicle
MSLane * getShadowLane() const
Returns the lane the vehicle&#39;s shadow is on during continuous/sublane lane change.
void setManeuverDist(const double dist)
Updates the remaining distance for the current maneuver while it is continued within non-action steps...
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:304
virtual void updateSafeLatDist(const double travelledLatDist)
Updates the value of safe lateral distances (in SL2015) during maneuver continuation in non-action st...
int myPreviousState2
lane changing state from step before the previous simulation step
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:482
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:4836
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right ...
double getLatDist() const
Definition: MSVehicle.h:1459
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:88
void laneChangeOutput(const std::string &tag, MSLane *source, MSLane *target, int direction)
called once the vehicle ends a lane change manoeuvre (non-instant)
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
const std::string & getID() const
Returns the name of the vehicle.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
bool myAlreadyChanged
whether the vehicle has already moved this step
const MSCFModel & myCarFollowModel
The vehicle&#39;s car following model.
bool myAmOpposite
whether the vehicle is driving in the opposite direction
MSAbstractLaneChangeModel(MSVehicle &v, const LaneChangeModel model)
Constructor.
Interface for lane-change models.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
double getWidth() const
Returns the vehicle&#39;s width.
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:1962
virtual bool congested(const MSVehicle *const neighLeader)
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
void updateDriveItems()
Check whether the drive items (myLFLinkLanes) are up to date, and update them if required.
Definition: MSVehicle.cpp:2516
bool congested() const
Definition: MSVehicle.h:714
virtual ~MSAbstractLaneChangeModel()
Destructor.