Eclipse SUMO - Simulation of Urban MObility
MSLaneChanger.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2002-2024 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 /****************************************************************************/
21 // Performs lane changing of vehicles
22 /****************************************************************************/
23 #pragma once
24 #include <config.h>
25 
26 #include "MSLane.h"
27 #include "MSEdge.h"
28 #include "MSVehicle.h"
29 #include <vector>
31 
32 
33 // ===========================================================================
34 // class declarations
35 // ===========================================================================
36 
37 
38 // ===========================================================================
39 // class definitions
40 // ===========================================================================
46 public:
48  MSLaneChanger(const std::vector<MSLane*>* lanes, bool allowChanging);
49 
51  virtual ~MSLaneChanger();
52 
54  void laneChange(SUMOTime t);
55 
56 public:
61  struct ChangeElem {
62 
63  ChangeElem(MSLane* _lane);
64 
66  void registerHop(MSVehicle* vehicle);
67 
80 
81  double dens;
82 
86 
89  std::vector<int> siblings;
90 
93  // the vehicles in front of the current vehicle (only on the current edge, continously updated during change() )
95 
96  // the vehicles in front of the current vehicle (including those on the next edge, contiously update during change() ))
98 
100  std::vector<MSVehicle*> outsideBounds;
102 
103  };
104 
105 public:
108  typedef std::vector< ChangeElem > Changer;
109 
111  typedef Changer::iterator ChangerIt;
112 
114  typedef Changer::const_iterator ConstChangerIt;
115 
118  return myChanger;
119  }
120 
121 
122 protected:
124  virtual void initChanger();
125 
128  bool vehInChanger() const {
129  // If there is at least one valid vehicle under the veh's in myChanger
130  // return true.
131  for (ConstChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
132  if (veh(ce) != 0) {
133  return true;
134  }
135  }
136  return false;
137  }
138 
142  // If ce has a valid vehicle, return it. Otherwise return 0.
143  if (!ce->lane->myVehicles.empty()) {
144  return ce->lane->myVehicles.back();
145  } else {
146  return 0;
147  }
148  }
149 
150 
152  virtual bool change();
153 
154 
156  bool changeOpposite(MSVehicle* vehicle, std::pair<MSVehicle*, double> leader, MSVehicle* lastStopped);
157 
158  std::pair<MSVehicle* const, double> getOncomingVehicle(const MSLane* opposite, std::pair<MSVehicle*,
159  double> neighOncoming, double searchDist, double& vMax, const MSVehicle* overtaken = nullptr,
160  MSLane::MinorLinkMode mLinkMode = MSLane::MinorLinkMode::FOLLOW_NEVER);
161 
162  std::pair<MSVehicle* const, double> getOncomingOppositeVehicle(const MSVehicle* vehicle,
163  std::pair<MSVehicle*, double> overtaken, double searchDist);
164 
166  void registerUnchanged(MSVehicle* vehicle);
167 
170  void checkTraCICommands(MSVehicle* vehicle);
171 
175  bool applyTraCICommands(MSVehicle* vehicle);
176 
178  virtual void updateChanger(bool vehHasChanged);
179 
183  void updateLanes(SUMOTime t);
184 
188 
189  /* @brief check whether lane changing in the given direction is desirable
190  * and possible */
192  int laneOffset,
193  const std::pair<MSVehicle* const, double>& leader,
194  const std::vector<MSVehicle::LaneQ>& preb) const;
195 
196  /* @brief check whether lane changing in the given direction is desirable
197  * and possible */
198  int checkChange(
199  int laneOffset,
200  const MSLane* targetLane,
201  const std::pair<MSVehicle* const, double>& leader,
202  const std::pair<MSVehicle* const, double>& follower,
203  const std::pair<MSVehicle* const, double>& neighLead,
204  const std::pair<MSVehicle* const, double>& neighFollow,
205  const std::vector<MSVehicle::LaneQ>& preb) const;
206 
207  /* @brief call lanechange model to check the merits of an opposite-direction
208  * change and update state accordingly */
209  virtual bool checkChangeOpposite(
210  MSVehicle* vehicle,
211  int laneOffset,
212  MSLane* targetLane,
213  const std::pair<MSVehicle* const, double>& leader,
214  const std::pair<MSVehicle* const, double>& neighLead,
215  const std::pair<MSVehicle* const, double>& neighFollow,
216  const std::vector<MSVehicle::LaneQ>& preb);
217 
218 
219  /* @brief start the lane change maneuver (and finish it instantly if gLaneChangeDuration == 0)
220  * @return False when aborting the change due to being remote controlled*/
221  bool startChange(MSVehicle* vehicle, ChangerIt& from, int direction);
222 
224  bool continueChange(MSVehicle* vehicle, ChangerIt& from);
225 
226  std::pair<MSVehicle* const, double> getRealFollower(const ChangerIt& target) const;
227 
228  std::pair<MSVehicle* const, double> getRealLeader(const ChangerIt& target) const;
229 
231  bool mayChange(int direction) const;
232 
234  static MSVehicle* getCloserFollower(const double maxPos, MSVehicle* follow1, MSVehicle* follow2);
235 
243  static void computeOvertakingTime(const MSVehicle* vehicle, double vMax, const MSVehicle* leader, double gap, double& timeToOvertake, double& spaceToOvertake);
244 
254  static std::pair<MSVehicle*, double> getColumnleader(double& maxSpace, MSVehicle* vehicle, std::pair<MSVehicle*, double> leader, double maxLookAhead = std::numeric_limits<double>::max());
255 
257  static const MSLane* getLaneAfter(const MSLane* lane, const std::vector<MSLane*>& conts, bool allowMinor, bool& contsEnd);
258 
260  static bool hasOppositeStop(MSVehicle* vehicle);
261 
263  bool checkOppositeStop(MSVehicle* vehicle, const MSLane* oncomingLane, const MSLane* opposite, std::pair<MSVehicle*, double> leader);
264 
268  bool avoidDeadlock(MSVehicle* vehicle,
269  std::pair<MSVehicle*, double> neighLead,
270  std::pair<MSVehicle*, double> overtaken,
271  std::pair<MSVehicle*, double> leader);
272 
276  bool resolveDeadlock(MSVehicle* vehicle,
277  std::pair<MSVehicle* const, double> leader,
278  std::pair<MSVehicle*, double> neighLead,
279  std::pair<MSVehicle*, double> overtaken);
280 
282  bool yieldToDeadlockOncoming(const MSVehicle* vehicle, const MSVehicle* stoppedNeigh, double dist);
283 
285  bool yieldToOppositeWaiting(const MSVehicle* vehicle, const MSVehicle* stoppedNeigh, double dist, SUMOTime deltaWait = 0);
286 
288  double computeSafeOppositeLength(MSVehicle* vehicle, double oppositeLength, const MSLane* source, double usableDist,
289  std::pair<MSVehicle*, double> oncoming, double vMax, double oncomingSpeed,
290  std::pair<MSVehicle*, double> neighLead,
291  std::pair<MSVehicle*, double> overtaken,
292  std::pair<MSVehicle*, double> neighFollow,
293  double surplusGap, const MSLane* opposite,
294  bool canOvertake);
295 
296  // @brief compute distance that can safely be driven on the opposite side
297  static double computeSurplusGap(const MSVehicle* vehicle, const MSLane* opposite, std::pair<MSVehicle*, double> oncoming, double timeToOvertake,
298  double spaceToOvertake, double& oncomingSpeed, bool oncomingOpposite = false);
299 
300  // @brief find hilltop within searchDistance
301  static bool foundHilltop(MSVehicle* vehicle, bool foundHill, double searchDist, const std::vector<MSLane*>& bestLanes, int view, double pos, double lastMax, double hilltopThreshold);
302 
304  static std::vector<MSVehicle::LaneQ> getBestLanesOpposite(MSVehicle* vehicle, const MSLane* stopLane, double oppositeLength);
305 
307  static double getMaxOvertakingSpeed(const MSVehicle* vehicle, double maxSpaceToOvertake);
308 
309 protected:
312 
317 
318  /* @brief Whether vehicles may start to change lanes on this edge
319  * (finishing a change in progress is always permitted) */
320  const bool myAllowsChanging;
321 
323  const bool myChangeToOpposite;
324 
325 private:
328 
331 
334 };
long long int SUMOTime
Definition: GUI.h:35
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:45
virtual ~MSLaneChanger()
Destructor.
bool applyTraCICommands(MSVehicle *vehicle)
Execute TraCI LC-commands.
bool continueChange(MSVehicle *vehicle, ChangerIt &from)
continue a lane change maneuver and return whether the vehicle has completely moved onto the new lane...
const bool myChangeToOpposite
whether this edge allows changing to the opposite direction edge
MSLaneChanger(const MSLaneChanger &)
Copy constructor.
bool checkOppositeStop(MSVehicle *vehicle, const MSLane *oncomingLane, const MSLane *opposite, std::pair< MSVehicle *, double > leader)
decide whether to change (back or forth) for an opposite stop
bool changeOpposite(MSVehicle *vehicle, std::pair< MSVehicle *, double > leader, MSVehicle *lastStopped)
MSLaneChanger()
Default constructor.
static bool hasOppositeStop(MSVehicle *vehicle)
whether vehicle has an opposite-direction stop within relevant range
void checkTraCICommands(MSVehicle *vehicle)
Take into account traci LC-commands.
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
virtual void initChanger()
Initialize the changer before looping over all vehicles.
bool vehInChanger() const
Check if there is a single change-candidate in the changer. Returns true if there is one.
std::pair< MSVehicle *const, double > getRealFollower(const ChangerIt &target) const
virtual bool change()
static const MSLane * getLaneAfter(const MSLane *lane, const std::vector< MSLane * > &conts, bool allowMinor, bool &contsEnd)
return the next lane in conts beyond lane or nullptr
std::pair< MSVehicle *const, double > getOncomingOppositeVehicle(const MSVehicle *vehicle, std::pair< MSVehicle *, double > overtaken, double searchDist)
std::vector< ChangeElem > Changer
The list of changers; For each lane, a ChangeElem is being build.
std::pair< MSVehicle *const, double > getOncomingVehicle(const MSLane *opposite, std::pair< MSVehicle *, double > neighOncoming, double searchDist, double &vMax, const MSVehicle *overtaken=nullptr, MSLane::MinorLinkMode mLinkMode=MSLane::MinorLinkMode::FOLLOW_NEVER)
bool startChange(MSVehicle *vehicle, ChangerIt &from, int direction)
const bool myAllowsChanging
double computeSafeOppositeLength(MSVehicle *vehicle, double oppositeLength, const MSLane *source, double usableDist, std::pair< MSVehicle *, double > oncoming, double vMax, double oncomingSpeed, std::pair< MSVehicle *, double > neighLead, std::pair< MSVehicle *, double > overtaken, std::pair< MSVehicle *, double > neighFollow, double surplusGap, const MSLane *opposite, bool canOvertake)
determine for how long the vehicle can drive safely on the opposite side
int checkChangeWithinEdge(int laneOffset, const std::pair< MSVehicle *const, double > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
Changer & getChanger()
return changer (only to be used by MSLaneChangerSublane from another instance)
MSVehicle * veh(ConstChangerIt ce) const
static bool foundHilltop(MSVehicle *vehicle, bool foundHill, double searchDist, const std::vector< MSLane * > &bestLanes, int view, double pos, double lastMax, double hilltopThreshold)
Changer myChanger
Container for ChangeElemements, one for every lane in the edge.
static double computeSurplusGap(const MSVehicle *vehicle, const MSLane *opposite, std::pair< MSVehicle *, double > oncoming, double timeToOvertake, double spaceToOvertake, double &oncomingSpeed, bool oncomingOpposite=false)
ChangerIt findCandidate()
Find current candidate. If there is none, myChanger.end() is returned.
bool mayChange(int direction) const
whether changing to the lane in the given direction should be considered
Changer::const_iterator ConstChangerIt
the iterator moving over the ChangeElems
bool yieldToOppositeWaiting(const MSVehicle *vehicle, const MSVehicle *stoppedNeigh, double dist, SUMOTime deltaWait=0)
check whether to yield for oncoming vehicles that have waited longer for opposite overtaking
static MSVehicle * getCloserFollower(const double maxPos, MSVehicle *follow1, MSVehicle *follow2)
return the closer follower of ego
MSLaneChanger & operator=(const MSLaneChanger &)
Assignment operator.
void registerUnchanged(MSVehicle *vehicle)
void updateLanes(SUMOTime t)
bool avoidDeadlock(MSVehicle *vehicle, std::pair< MSVehicle *, double > neighLead, std::pair< MSVehicle *, double > overtaken, std::pair< MSVehicle *, double > leader)
avoid opposite-diretion deadlock when vehicles are stopped on both sides of the road The method may c...
static std::pair< MSVehicle *, double > getColumnleader(double &maxSpace, MSVehicle *vehicle, std::pair< MSVehicle *, double > leader, double maxLookAhead=std::numeric_limits< double >::max())
return leader vehicle that is to be overtaken
static double getMaxOvertakingSpeed(const MSVehicle *vehicle, double maxSpaceToOvertake)
compute maximum maneuver speed
ChangerIt myCandi
bool resolveDeadlock(MSVehicle *vehicle, std::pair< MSVehicle *const, double > leader, std::pair< MSVehicle *, double > neighLead, std::pair< MSVehicle *, double > overtaken)
keep stopping to resolve opposite-diretion deadlock while there is oncoming traffic The method may ca...
std::pair< MSVehicle *const, double > getRealLeader(const ChangerIt &target) const
bool yieldToDeadlockOncoming(const MSVehicle *vehicle, const MSVehicle *stoppedNeigh, double dist)
check whether to keep stopping for oncoming vehicles in the deadlock zone
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
int checkChange(int laneOffset, const MSLane *targetLane, const std::pair< MSVehicle *const, double > &leader, const std::pair< MSVehicle *const, double > &follower, const std::pair< MSVehicle *const, double > &neighLead, const std::pair< MSVehicle *const, double > &neighFollow, const std::vector< MSVehicle::LaneQ > &preb) const
virtual bool checkChangeOpposite(MSVehicle *vehicle, int laneOffset, MSLane *targetLane, const std::pair< MSVehicle *const, double > &leader, const std::pair< MSVehicle *const, double > &neighLead, const std::pair< MSVehicle *const, double > &neighFollow, const std::vector< MSVehicle::LaneQ > &preb)
static void computeOvertakingTime(const MSVehicle *vehicle, double vMax, const MSVehicle *leader, double gap, double &timeToOvertake, double &spaceToOvertake)
Compute the time and space required for overtaking the given leader.
static std::vector< MSVehicle::LaneQ > getBestLanesOpposite(MSVehicle *vehicle, const MSLane *stopLane, double oppositeLength)
add LaneQ for opposite lanes
virtual void updateChanger(bool vehHasChanged)
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
MinorLinkMode
determine whether/how getFollowers looks upstream beyond minor links
Definition: MSLane.h:965
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:144
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
std::vector< int > siblings
Definition: MSLaneChanger.h:89
std::vector< MSVehicle * > outsideBounds
vehicles that cannot be stored in ahead because they are outside the lane bounds
bool mayChangeRight
whether changing is possible to either direction
Definition: MSLaneChanger.h:84
MSVehicle * lead
the leader vehicle for the current change candidate
Definition: MSLaneChanger.h:69
MSVehicle * lastStopped
the next vehicle downstream of the ego vehicle that is stopped (and thus an obstacle)
Definition: MSLaneChanger.h:79
MSLeaderDistanceInfo aheadNext
Definition: MSLaneChanger.h:97
MSLane * lane
the lane corresponding to this ChangeElem (the current change candidate is on this lane)
Definition: MSLaneChanger.h:71
MSVehicle * lastBlocked
the next vehicle downstream of the ego vehicle that is blocked from changing to this lane
Definition: MSLaneChanger.h:75
MSVehicle * firstBlocked
the farthest downstream vehicle on this edge that is blocked from changing to this lane
Definition: MSLaneChanger.h:77
void registerHop(MSVehicle *vehicle)
Register that vehicle belongs to Changer Item to after LC decisions.
MSVehicle * hoppedVeh
last vehicle that changed into this lane
Definition: MSLaneChanger.h:73