1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2002-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file MSLaneChanger.h 11 /// @author Christian Roessel 12 /// @author Daniel Krajzewicz 13 /// @author Michael Behrisch 14 /// @author Jakob Erdmann 15 /// @date Fri, 01 Feb 2002 16 /// @version $Id$ 17 /// 18 // Performs lane changing of vehicles 19 /****************************************************************************/ 20 #ifndef MSLaneChanger_h 21 #define MSLaneChanger_h 22 23 24 // =========================================================================== 25 // included modules 26 // =========================================================================== 27 #include <config.h> 28 29 #include "MSLane.h" 30 #include "MSEdge.h" 31 #include "MSVehicle.h" 32 #include <vector> 33 #include <utils/iodevices/OutputDevice.h> 34 35 36 // =========================================================================== 37 // class declarations 38 // =========================================================================== 39 40 41 // =========================================================================== 42 // class definitions 43 // =========================================================================== 44 /** 45 * @class MSLaneChanger 46 * @brief Performs lane changing of vehicles 47 */ 48 class MSLaneChanger { 49 public: 50 /// Constructor 51 MSLaneChanger(const std::vector<MSLane*>* lanes, bool allowChanging); 52 53 /// Destructor. 54 virtual ~MSLaneChanger(); 55 56 /// Start lane-change-process for all vehicles on the edge'e lanes. 57 void laneChange(SUMOTime t); 58 59 public: 60 /** Structure used for lane-change. For every lane you have to 61 know four vehicles, the change-candidate veh and it's follower 62 and leader. Further, information about the last vehicle that changed 63 into this lane is needed */ 64 struct ChangeElem { 65 66 ChangeElem(MSLane* _lane); 67 68 /// @brief Register that vehicle belongs to Changer Item to after LC decisions 69 void registerHop(MSVehicle* vehicle); 70 71 ///@brief the leader vehicle for the current change candidate 72 MSVehicle* lead; 73 ///@brief the lane corresponding to this ChangeElem (the current change candidate is on this lane) 74 MSLane* lane; 75 ///@brief last vehicle that changed into this lane 76 MSVehicle* hoppedVeh; 77 /// @brief the next vehicle downstream of the ego vehicle that is blocked from changing to this lane 78 MSVehicle* lastBlocked; 79 /// @brief the farthest downstream vehicle on this edge that is blocked from changing to this lane 80 MSVehicle* firstBlocked; 81 82 double dens; 83 84 /// @brief whether changing is possible to either direction 85 bool mayChangeRight; 86 bool mayChangeLeft; 87 88 /// relative indices of internal lanes with the same origin lane (siblings) 89 /// only used for changes on internal edges 90 std::vector<int> siblings; 91 92 /// @name Members which are used only by MSLaneChangerSublane 93 /// @{ 94 // the vehicles in from of the current vehicle (only on the current edge, continously updated during change() ) 95 MSLeaderInfo ahead; 96 97 // the vehicles in from of the current vehicle (including those on the next edge, contiously update during change() )) 98 MSLeaderDistanceInfo aheadNext; 99 ///@} 100 101 }; 102 103 public: 104 /** @brief The list of changers; 105 For each lane, a ChangeElem is being build */ 106 typedef std::vector< ChangeElem > Changer; 107 108 /// the iterator moving over the ChangeElems 109 typedef Changer::iterator ChangerIt; 110 111 /// the iterator moving over the ChangeElems 112 typedef Changer::const_iterator ConstChangerIt; 113 114 protected: 115 /// Initialize the changer before looping over all vehicles. 116 virtual void initChanger(); 117 118 /** @brief Check if there is a single change-candidate in the changer. 119 Returns true if there is one. */ vehInChanger()120 bool vehInChanger() const { 121 // If there is at least one valid vehicle under the veh's in myChanger 122 // return true. 123 for (ConstChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { 124 if (veh(ce) != 0) { 125 return true; 126 } 127 } 128 return false; 129 } 130 131 /** Returns the furthes unhandled vehicle on this change-elements lane 132 or 0 if there is none. */ veh(ConstChangerIt ce)133 MSVehicle* veh(ConstChangerIt ce) const { 134 // If ce has a valid vehicle, return it. Otherwise return 0. 135 if (!ce->lane->myVehicles.empty()) { 136 return ce->lane->myVehicles.back(); 137 } else { 138 return 0; 139 } 140 } 141 142 143 /** Find a new candidate and try to change it. */ 144 virtual bool change(); 145 146 147 /** try changing to the opposite direction edge. */ 148 virtual bool changeOpposite(std::pair<MSVehicle*, double> leader); 149 150 /** Update changer for vehicles that did not change */ 151 void registerUnchanged(MSVehicle* vehicle); 152 153 /// @brief Take into account traci LC-commands. 154 /// @note This is currently only used within non-actionsteps. 155 void checkTraCICommands(MSVehicle* vehicle); 156 157 /// @brief Execute TraCI LC-commands. 158 /// @note This is currently only used within non-actionsteps for the non-sublane model. 159 /// @return whether lane was changed 160 bool applyTraCICommands(MSVehicle* vehicle); 161 162 /** After the possible change, update the changer. */ 163 virtual void updateChanger(bool vehHasChanged); 164 165 /** During lane-change a temporary vehicle container is filled within 166 the lanes (bad practice to modify foreign members, I know). Swap 167 this container with the real one. */ 168 void updateLanes(SUMOTime t); 169 170 /** @brief Find current candidate. 171 If there is none, myChanger.end() is returned. */ 172 ChangerIt findCandidate(); 173 174 /* @brief check whether lane changing in the given direction is desirable 175 * and possible */ 176 int checkChangeWithinEdge( 177 int laneOffset, 178 const std::pair<MSVehicle* const, double>& leader, 179 const std::vector<MSVehicle::LaneQ>& preb) const; 180 181 /* @brief check whether lane changing in the given direction is desirable 182 * and possible */ 183 int checkChange( 184 int laneOffset, 185 const MSLane* targetLane, 186 const std::pair<MSVehicle* const, double>& leader, 187 const std::pair<MSVehicle* const, double>& neighLead, 188 const std::pair<MSVehicle* const, double>& neighFollow, 189 const std::vector<MSVehicle::LaneQ>& preb) const; 190 191 /* @brief start the lane change maneuver (and finish it instantly if gLaneChangeDuration == 0) 192 * @return False when aborting the change due to being remote controlled*/ 193 bool startChange(MSVehicle* vehicle, ChangerIt& from, int direction); 194 195 /// @brief continue a lane change maneuver and return whether the vehicle has completely moved onto the new lane (used if gLaneChangeDuration > 0) 196 bool continueChange(MSVehicle* vehicle, ChangerIt& from); 197 198 std::pair<MSVehicle* const, double> getRealFollower(const ChangerIt& target) const; 199 200 std::pair<MSVehicle* const, double> getRealLeader(const ChangerIt& target) const; 201 202 /// @brief whether changing to the lane in the given direction should be considered 203 bool mayChange(int direction) const; 204 205 /// @brief return the closer follower of ego 206 static MSVehicle* getCloserFollower(const double maxPos, MSVehicle* follow1, MSVehicle* follow2); 207 208 /** @brief Compute the time and space required for overtaking the given leader 209 * @param[in] vehicle The vehicle that wants to overtake 210 * @param[in] leader The vehicle to be overtaken 211 * @param[in] gap The gap between vehicle and leader 212 * @param[out] timeToOvertake The time for overtaking 213 * @param[out] spaceToOvertake The space for overtaking 214 */ 215 static void computeOvertakingTime(const MSVehicle* vehicle, const MSVehicle* leader, double gap, double& timeToOvertake, double& spaceToOvertake); 216 217 // @brief return leader vehicle that is to be overtaken 218 static std::pair<MSVehicle*, double> getColumnleader(MSVehicle* vehicle, std::pair<MSVehicle*, double> leader, double maxLookAhead = std::numeric_limits<double>::max()); 219 220 /// @brief return the next lane in conts beyond lane or nullptr 221 static MSLane* getLaneAfter(MSLane* lane, const std::vector<MSLane*>& conts); 222 223 protected: 224 /// Container for ChangeElemements, one for every lane in the edge. 225 Changer myChanger; 226 227 /** Change-candidate. Last of the vehicles in changer. Only this one 228 will try to change. Every vehicle on the edge will be a candidate 229 once in the change-process. */ 230 ChangerIt myCandi; 231 232 /* @brief Whether vehicles may start to change lanes on this edge 233 * (finishing a change in progress is always permitted) */ 234 const bool myAllowsChanging; 235 236 /// @brief whether this edge allows changing to the opposite direction edge 237 const bool myChangeToOpposite; 238 239 private: 240 /// Default constructor. 241 MSLaneChanger(); 242 243 /// Copy constructor. 244 MSLaneChanger(const MSLaneChanger&); 245 246 /// Assignment operator. 247 MSLaneChanger& operator=(const MSLaneChanger&); 248 }; 249 250 251 #endif 252 253 /****************************************************************************/ 254 255