SUMO - Simulation of Urban MObility
MSAbstractLaneChangeModel.h
Go to the documentation of this file.
1 /****************************************************************************/
11 // Interface for lane-change models
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 #ifndef MSAbstractLaneChangeModel_h
25 #define MSAbstractLaneChangeModel_h
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #include <microsim/MSVehicle.h>
37 
38 class MSLane;
39 
40 // ===========================================================================
41 // used enumeration
42 // ===========================================================================
43 
44 // ===========================================================================
45 // class definitions
46 // ===========================================================================
52 public:
53 
57  class MSLCMessager {
58  public:
64  MSLCMessager(MSVehicle* leader, MSVehicle* neighLead, MSVehicle* neighFollow)
65  : myLeader(leader), myNeighLeader(neighLead),
66  myNeighFollower(neighFollow) { }
67 
68 
71 
72 
78  void* informLeader(void* info, MSVehicle* sender) {
79  assert(myLeader != 0);
80  return myLeader->getLaneChangeModel().inform(info, sender);
81  }
82 
83 
89  void* informNeighLeader(void* info, MSVehicle* sender) {
90  assert(myNeighLeader != 0);
91  return myNeighLeader->getLaneChangeModel().inform(info, sender);
92  }
93 
94 
100  void* informNeighFollower(void* info, MSVehicle* sender) {
101  assert(myNeighFollower != 0);
102  return myNeighFollower->getLaneChangeModel().inform(info, sender);
103  }
104 
105 
106  private:
113 
114  };
115 
116  struct StateAndDist {
117  // @brief LaneChangeAction flags
118  int state;
119  // @brief lateralDistance
120  double latDist;
121  // @brief direction that was checked
122  int dir;
123 
124  StateAndDist(int _state, double _latDist, int _dir) :
125  state(_state),
126  latDist(_latDist),
127  dir(_dir) {}
128 
129  bool sameDirection(const StateAndDist& other) const {
130  return latDist * other.latDist > 0;
131  }
132  };
133 
135  void static initGlobalOptions(const OptionsCont& oc);
136 
142 
144  static bool haveLCOutput() {
145  return myLCOutput;
146  }
147 
153 
155  virtual ~MSAbstractLaneChangeModel();
156 
157  inline int getOwnState() const {
158  return myOwnState;
159  }
160 
161  virtual void setOwnState(const int state);
162 
163  const std::pair<int, int>& getSavedState(const int dir) const {
164  return mySavedStates.find(dir)->second;
165  }
166 
167  void saveState(const int dir, const int stateWithoutTraCI, const int state) {
168  mySavedStates[dir] = std::make_pair(stateWithoutTraCI, state);
169  }
170 
171  void setFollowerGaps(CLeaderDist follower, double secGap);
172  void setLeaderGaps(CLeaderDist, double secGap);
173  void setFollowerGaps(const MSLeaderDistanceInfo& vehicles);
174  void setLeaderGaps(const MSLeaderDistanceInfo& vehicles);
175 
176  virtual void prepareStep() {
186  myCommittedSpeed = 0;
187  }
188 
193  virtual int wantsChange(
194  int laneOffset,
195  MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
196  const std::pair<MSVehicle*, double>& leader,
197  const std::pair<MSVehicle*, double>& neighLead,
198  const std::pair<MSVehicle*, double>& neighFollow,
199  const MSLane& neighLane,
200  const std::vector<MSVehicle::LaneQ>& preb,
201  MSVehicle** lastBlocked,
202  MSVehicle** firstBlocked) {
203  UNUSED_PARAMETER(laneOffset);
204  UNUSED_PARAMETER(&msgPass);
205  UNUSED_PARAMETER(blocked);
206  UNUSED_PARAMETER(&leader);
207  UNUSED_PARAMETER(&neighLead);
208  UNUSED_PARAMETER(&neighFollow);
209  UNUSED_PARAMETER(&neighLane);
210  UNUSED_PARAMETER(&preb);
211  UNUSED_PARAMETER(lastBlocked);
212  UNUSED_PARAMETER(firstBlocked);
213  throw ProcessError("Method not implemented by model " + toString(myModel));
214  };
215 
216  virtual int wantsChangeSublane(
217  int laneOffset,
218  LaneChangeAction alternatives,
219  const MSLeaderDistanceInfo& leaders,
220  const MSLeaderDistanceInfo& followers,
221  const MSLeaderDistanceInfo& blockers,
222  const MSLeaderDistanceInfo& neighLeaders,
223  const MSLeaderDistanceInfo& neighFollowers,
224  const MSLeaderDistanceInfo& neighBlockers,
225  const MSLane& neighLane,
226  const std::vector<MSVehicle::LaneQ>& preb,
227  MSVehicle** lastBlocked,
228  MSVehicle** firstBlocked,
229  double& latDist, int& blocked) {
230  UNUSED_PARAMETER(laneOffset);
231  UNUSED_PARAMETER(alternatives);
232  UNUSED_PARAMETER(&leaders);
233  UNUSED_PARAMETER(&followers);
234  UNUSED_PARAMETER(&blockers);
235  UNUSED_PARAMETER(&neighLeaders);
236  UNUSED_PARAMETER(&neighFollowers);
237  UNUSED_PARAMETER(&neighBlockers);
238  UNUSED_PARAMETER(&neighLane);
239  UNUSED_PARAMETER(&preb);
240  UNUSED_PARAMETER(lastBlocked);
241  UNUSED_PARAMETER(firstBlocked);
242  UNUSED_PARAMETER(latDist);
243  UNUSED_PARAMETER(blocked);
244  throw ProcessError("Method not implemented by model " + toString(myModel));
245  }
246 
248  virtual void updateExpectedSublaneSpeeds(const MSLeaderInfo& ahead, int sublaneOffset, int laneIndex) {
249  UNUSED_PARAMETER(&ahead);
250  UNUSED_PARAMETER(sublaneOffset);
251  UNUSED_PARAMETER(laneIndex);
252  throw ProcessError("Method not implemented by model " + toString(myModel));
253  }
254 
257  UNUSED_PARAMETER(sd1);
258  UNUSED_PARAMETER(sd2);
259  throw ProcessError("Method not implemented by model " + toString(myModel));
260  }
261 
262  virtual void* inform(void* info, MSVehicle* sender) = 0;
263 
275  virtual double patchSpeed(const double min, const double wanted, const double max,
276  const MSCFModel& cfModel) = 0;
277 
278  /* @brief called once when the primary lane of the vehicle changes (updates
279  * the custom variables of each child implementation */
280  virtual void changed() = 0;
281 
282 
284  virtual bool debugVehicle() const {
285  return false;
286  }
287 
289  void changedToOpposite();
290 
291  void unchanged() {
292  if (myLastLaneChangeOffset > 0) {
294  } else if (myLastLaneChangeOffset < 0) {
296  }
297  }
298 
303  return myShadowLane;
304  }
305 
307  MSLane* getShadowLane(const MSLane* lane) const;
308 
310  MSLane* getShadowLane(const MSLane* lane, double posLat) const;
311 
313  void setShadowLane(MSLane* lane) {
314  myShadowLane = lane;
315  }
316 
317  const std::vector<MSLane*>& getShadowFurtherLanes() const {
318  return myShadowFurtherLanes;
319  }
320 
321  const std::vector<double>& getShadowFurtherLanesPosLat() const {
323  }
324 
326  return myLastLaneChangeOffset;
327  }
328 
329 
331  inline bool pastMidpoint() const {
332  return myLaneChangeCompletion >= 0.5;
333  }
334 
336  SUMOTime remainingTime() const;
337 
339  inline bool isChangingLanes() const {
340  return myLaneChangeCompletion < (1 - NUMERICAL_EPS);
341  }
342 
344  inline int getLaneChangeDirection() const {
345  return myLaneChangeDirection;
346  }
347 
349  int getShadowDirection() const;
350 
352  double getAngleOffset() const;
353 
355  inline bool alreadyChanged() const {
356  return myAlreadyChanged;
357  }
358 
360  void resetChanged() {
361  myAlreadyChanged = false;
362  }
363 
365  bool startLaneChangeManeuver(MSLane* source, MSLane* target, int direction);
366 
367  /* @brief continue the lane change maneuver and return whether the midpoint
368  * was passed in this step
369  */
370  bool updateCompletion();
371 
372  /* @brief update lane change shadow after the vehicle moved to a new lane */
373  void updateShadowLane();
374 
375  /* @brief finish the lane change maneuver
376  */
378 
379  /* @brief clean up all references to the shadow vehicle
380  */
381  void cleanupShadowLane();
382 
384  virtual void saveBlockerLength(double length) {
385  UNUSED_PARAMETER(length);
386  };
387 
389  myPartiallyOccupatedByShadow.push_back(lane);
390  }
391 
393  myNoPartiallyOccupatedByShadow.push_back(lane);
394  }
395 
397  void primaryLaneChanged(MSLane* source, MSLane* target, int direction);
398 
400  void setShadowApproachingInformation(MSLink* link) const;
402 
403  bool isOpposite() const {
404  return myAmOpposite;
405  }
406 
407  double getCommittedSpeed() const {
408  return myCommittedSpeed;
409  }
410 
412  double getSpeedLat() const {
413  return mySpeedLat;
414  }
415 
416  void setSpeedLat(double speedLat) {
417  mySpeedLat = speedLat;
418  }
419 
421  virtual std::string getParameter(const std::string& key) const {
422  throw InvalidArgument("Parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
423  }
424 
426  virtual void setParameter(const std::string& key, const std::string& value) {
427  UNUSED_PARAMETER(value);
428  throw InvalidArgument("Setting parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
429  }
430 
431  static const double NO_NEIGHBOR;
432 
433 protected:
434  virtual bool congested(const MSVehicle* const neighLeader);
435 
436  virtual bool predInteraction(const std::pair<MSVehicle*, double>& leader);
437 
439  bool cancelRequest(int state);
440 
441 
442 protected:
445 
448  std::map<int, std::pair<int, int> > mySavedStates;
449 
451  double mySpeedLat;
452 
455 
458 
461 
464 
467 
468  /* @brief Lanes that are parially (laterally) occupied by the back of the
469  * vehicle (analogue to MSVehicle::myFurtherLanes) */
470  std::vector<MSLane*> myShadowFurtherLanes;
471  std::vector<double> myShadowFurtherLanesPosLat;
472 
475 
478 
480  std::vector<MSLane*> myPartiallyOccupatedByShadow;
481 
482  /* @brief list of lanes where there is no shadow vehicle partial occupator
483  * (when changing to a lane that has no predecessor) */
484  std::vector<MSLane*> myNoPartiallyOccupatedByShadow;
485 
489 
496 
497  /* @brief to be called by derived classes in their changed() method.
498  * If dir=0 is given, the current value remains unchanged */
499  void initLastLaneChangeOffset(int dir);
500 
503 
505  static bool myLCOutput;
506 
507 
508 private:
509  /* @brief information how long ago the vehicle has performed a lane-change,
510  * sign indicates direction of the last change
511  */
513 
515  mutable std::vector<MSLink*> myApproachedByShadow;
516 
519 
520 
521 private:
524 };
525 
526 
527 #endif
528 
529 /****************************************************************************/
530 
std::vector< MSLane * > myPartiallyOccupatedByShadow
list of lanes where the shadow vehicle is partial occupator
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:136
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
#define min(a, b)
Definition: polyfonts.c:66
virtual int wantsChangeSublane(int laneOffset, LaneChangeAction alternatives, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked, double &latDist, int &blocked)
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
virtual void * inform(void *info, MSVehicle *sender)=0
void setLeaderGaps(CLeaderDist, double secGap)
MSVehicle * myNeighLeader
The leader on the lane the vehicle want to change to.
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
bool alreadyChanged() const
reset the flag whether a vehicle already moved to false
double myLastLeaderGap
the actual minimum longitudinal distances to vehicles on the target lane
double myLaneChangeCompletion
progress of the lane change maneuver 0:started, 1:complete
double getSpeedLat() const
return the lateral speed of the current lane change maneuver
The car-following model abstraction.
Definition: MSCFModel.h:60
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
int getShadowDirection() const
return the direction in which the current shadow lane lies
Notification
Definition of a vehicle state.
static bool myLCOutput
whether to record lane-changing
const std::pair< int, int > & getSavedState(const int dir) const
MSLCMessager(MSVehicle *leader, MSVehicle *neighLead, MSVehicle *neighFollow)
Constructor.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
MSLane * myShadowLane
A lane that is partially occupied by the front of the vehicle but that is not the primary lane...
virtual bool predInteraction(const std::pair< MSVehicle *, double > &leader)
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:40
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3144
void saveState(const int dir, const int stateWithoutTraCI, const int state)
std::vector< double > myShadowFurtherLanesPosLat
virtual double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)=0
Called to adapt the speed in order to allow a lane change.
MSVehicle * myNeighFollower
The follower on the lane the vehicle want to change to.
void setFollowerGaps(CLeaderDist follower, double secGap)
const LaneChangeModel myModel
the type of this model
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
A class responsible for exchanging messages between cars involved in lane-change interaction.
LaneChangeModel
The vehicle changes lanes (micro only)
The action has not been determined.
#define max(a, b)
Definition: polyfonts.c:65
bool cancelRequest(int state)
whether the influencer cancels the given request
std::vector< MSLane * > myNoPartiallyOccupatedByShadow
double getAngleOffset() const
return the angle offset during a continuous change maneuver
bool pastMidpoint() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
void setShadowPartialOccupator(MSLane *lane)
void setShadowLane(MSLane *lane)
set the shadow lane
virtual void updateExpectedSublaneSpeeds(const MSLeaderInfo &ahead, int sublaneOffset, int laneIndex)
update expected speeds for each sublane of the current edge
virtual void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
virtual int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
Called to examine whether the vehicle wants to change using the given laneOffset. This method gets th...
std::vector< MSLane * > myShadowFurtherLanes
const std::vector< MSLane * > & getShadowFurtherLanes() const
bool sameDirection(const StateAndDist &other) const
virtual StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const
decide in which direction to move in case both directions are desirable
int myLaneChangeDirection
direction of the lane change maneuver -1 means right, 1 means left
virtual void changed()=0
static void initGlobalOptions(const OptionsCont &oc)
init global model parameters
const std::vector< double > & getShadowFurtherLanesPosLat() const
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
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.
StateAndDist(int _state, double _latDist, int _dir)
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
virtual std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this laneChangeModel. Throw exception for unsupported key ...
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
MSAbstractLaneChangeModel & operator=(const MSAbstractLaneChangeModel &s)
Invalidated assignment operator.
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:42
LaneChangeAction
The state of a vehicle&#39;s lane-change behavior.
virtual void setOwnState(const int state)
SUMOTime remainingTime() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
void setNoShadowPartialOccupator(MSLane *lane)
void * informLeader(void *info, MSVehicle *sender)
Informs the leader on the same lane.
void resetChanged()
reset the flag whether a vehicle already moved to false
A storage for options typed value containers)
Definition: OptionsCont.h:99
double mySpeedLat
the current lateral speed
static bool haveLCOutput()
whether lanechange-output is active
virtual void saveBlockerLength(double length)
reserve space at the end of the lane to avoid dead locks
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
long long int SUMOTime
Definition: TraCIDefs.h:52
double myCommittedSpeed
the speed when committing to a change maneuver
#define NUMERICAL_EPS
Definition: config.h:152
std::vector< MSLink * > myApproachedByShadow
links which are approached by the shadow vehicle
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right ...
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
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.
MSVehicle * myLeader
The leader on the informed vehicle&#39;s lane.
std::map< int, std::pair< int, int > > mySavedStates
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
virtual bool congested(const MSVehicle *const neighLeader)
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
virtual ~MSAbstractLaneChangeModel()
Destructor.