1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-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 MSLCM_LC2013.h 11 /// @author Daniel Krajzewicz 12 /// @author Jakob Erdmann 13 /// @author Friedemann Wesner 14 /// @author Sascha Krieg 15 /// @author Michael Behrisch 16 /// @date Fri, 08.10.2013 17 /// @version $Id$ 18 /// 19 // A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013 20 /****************************************************************************/ 21 #ifndef MSLCM_LC2013_h 22 #define MSLCM_LC2013_h 23 24 25 // =========================================================================== 26 // included modules 27 // =========================================================================== 28 #include <config.h> 29 30 #include "MSAbstractLaneChangeModel.h" 31 #include <vector> 32 33 // INVALID_SPEED should be used when the construction of upper bound for the speed 34 // leads to no restrictions, e.g. during LC-messaging to followers or leaders. 35 // Currently either std::numeric_limits<...>.max() or -1 is used for this purpose in many places. 36 // TODO: implement this everywhere and remove workarounds for ballistic update in cases of possible '-1'-returns. Refs. #2577 37 #define INVALID_SPEED 299792458 + 1 // nothing can go faster than the speed of light! 38 39 40 // =========================================================================== 41 // class definitions 42 // =========================================================================== 43 /** 44 * @class MSLCM_LC2013 45 * @brief A lane change model developed by D. Krajzewicz, J. Erdmann 46 * et al. between 2004 and 2013 47 */ 48 class MSLCM_LC2013 : public MSAbstractLaneChangeModel { 49 public: 50 51 MSLCM_LC2013(MSVehicle& v); 52 53 virtual ~MSLCM_LC2013(); 54 55 /// @brief Returns the model's id getModelID()56 LaneChangeModel getModelID() const { 57 return LCM_LC2013; 58 } 59 60 /// @brief init cached parameters derived directly from model parameters 61 void initDerivedParameters(); 62 63 bool debugVehicle() const; 64 65 /** @brief Called to examine whether the vehicle wants to change 66 * using the given laneOffset. 67 * This method gets the information about the surrounding vehicles 68 * and whether another lane may be more preferable 69 * 70 * TODO: better documentation, refs #2 71 * 72 * */ 73 int wantsChange( 74 int laneOffset, 75 MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked, 76 const std::pair<MSVehicle*, double>& leader, 77 const std::pair<MSVehicle*, double>& neighLead, 78 const std::pair<MSVehicle*, double>& neighFollow, 79 const MSLane& neighLane, 80 const std::vector<MSVehicle::LaneQ>& preb, 81 MSVehicle** lastBlocked, 82 MSVehicle** firstBlocked); 83 84 void* inform(void* info, MSVehicle* sender); 85 86 /** @brief Called to adapt the speed in order to allow a lane change. 87 * It uses information on LC-related desired speed-changes from 88 * the call to wantsChange() at the end of the previous simulation step 89 * 90 * @param min The minimum resulting speed 91 * @param wanted The aspired speed of the car following model 92 * @param max The maximum resulting speed 93 * @param cfModel The model used 94 * @return the new speed of the vehicle as proposed by the lane changer 95 */ 96 double patchSpeed(const double min, const double wanted, const double max, 97 const MSCFModel& cfModel); 98 /** helper function which contains the actual logic */ 99 double _patchSpeed(const double min, const double wanted, const double max, 100 const MSCFModel& cfModel); 101 102 void changed(); 103 104 double getSafetyFactor() const; 105 106 double getOppositeSafetyFactor() const; 107 108 void prepareStep(); 109 110 /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key 111 std::string getParameter(const std::string& key) const; 112 113 /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key 114 void setParameter(const std::string& key, const std::string& value); 115 116 /// @brief decides the next lateral speed (for continuous lane changing) 117 double computeSpeedLat(double latDist, double& maneuverDist); 118 119 /// @brief Returns a deceleration value which is used for the estimation of the duration of a lane change. 120 /// @note Effective only for continuous lane-changing when using attributes myMaxSpeedLatFactor and myMaxSpeedLatStanding. See #3771 121 double getAssumedDecelForLaneChangeDuration() const; 122 123 protected: 124 125 /// @brief helper function for doing the actual work 126 int _wantsChange( 127 int laneOffset, 128 MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked, 129 const std::pair<MSVehicle*, double>& leader, 130 const std::pair<MSVehicle*, double>& neighLead, 131 const std::pair<MSVehicle*, double>& neighFollow, 132 const MSLane& neighLane, 133 const std::vector<MSVehicle::LaneQ>& preb, 134 MSVehicle** lastBlocked, 135 MSVehicle** firstBlocked); 136 137 /* @brief decide whether we will overtake or follow a blocking leader 138 * and inform it accordingly 139 * If we decide to follow, myVSafes will be extended 140 * returns the planned speed if following or -1 if overtaking */ 141 double informLeader(MSAbstractLaneChangeModel::MSLCMessager& msgPass, 142 int blocked, int dir, 143 const std::pair<MSVehicle*, double>& neighLead, 144 double remainingSeconds); 145 146 /// @brief decide whether we will try cut in before the follower or allow to be overtaken 147 void informFollower(MSAbstractLaneChangeModel::MSLCMessager& msgPass, 148 int blocked, int dir, 149 const std::pair<MSVehicle*, double>& neighFollow, 150 double remainingSeconds, 151 double plannedSpeed); 152 153 154 /* @brief compute the distance to cover until a safe gap to the vehicle v in front is reached 155 * assuming constant velocities 156 * @param[in] follower the vehicle which overtakes 157 * @param[in] leader the vehicle to be overtaken 158 * @param[in] gap initial distance between front of follower and back of leader 159 * @param[in] leaderSpeed an assumed speed for the leader (default uses the current speed) 160 * @param[in] followerSpeed an assumed speed for the follower (default uses the current speed) 161 * @return the distance that the relative positions would have to change. 162 */ 163 static double overtakeDistance(const MSVehicle* follower, const MSVehicle* leader, const double gap, double followerSpeed = INVALID_SPEED, double leaderSpeed = INVALID_SPEED); 164 165 /// @brief compute useful slowdowns for blocked vehicles 166 int slowDownForBlocked(MSVehicle** blocked, int state); 167 168 169 // XXX: consider relocation of the roundabout functions (perhaps to MSVehicle or the abstract LC Model...) (Leo) 170 /// @brief computes the distance and number of edges in the next upcoming 171 /// roundabout along the lane continuations given in curr and neigh 172 /// @param[in] veh The considered ego Vehicle 173 /// @param[in] curr continuation info along veh's current lane 174 /// @param[in] neigh continuation info along a neighboring lane (in MSLCM_2013::_wantsChange() the considered lane for a lanechange) 175 /// @param[out] roundaboutDistanceAhead Accumulated length of lanes in the next oncoming roundabout in curr 176 /// @param[out] roundaboutDistanceAheadNeigh Accumulated length of lanes in the next oncoming roundabout in neigh 177 /// @param[out] roundaboutEdgesAhead Number of lanes in the next oncoming roundabout in curr 178 /// @param[out] roundaboutEdgesAheadNeigh Number of lanes in the next oncoming roundabout in neigh 179 static void 180 getRoundaboutAheadInfo(const MSLCM_LC2013* lcm, const MSVehicle::LaneQ& curr, const MSVehicle::LaneQ& neigh, 181 double& roundaboutDistanceAhead, double& roundaboutDistanceAheadNeigh, int& roundaboutEdgesAhead, int& roundaboutEdgesAheadNeigh); 182 183 /// @brief Computes the artificial bonus distance for roundabout lanes 184 /// this additional distance reduces the sense of urgency within 185 /// roundabouts and thereby promotes the use of the inner roundabout 186 /// lane in multi-lane roundabouts. 187 /// @param[in] roundaboutDistAhead Distance on roundabout 188 /// @param[in] roundaboutEdgesAhead number of edges on roundabout 189 double 190 roundaboutDistBonus(double roundaboutDistAhead, int roundaboutEdgesAhead) const; 191 192 /// @brief compute the distance on the next upcoming roundabout along a given sequence of lanes. 193 /// @param[in] position position of the vehicle on the initial lane 194 /// @param[in] initialLane starting lane for the computation (may be internal) 195 /// @param[in] continuationLanes sequence of lanes along which the roundabout distance is to be computed (only containing non-internal lanes) 196 /// @return distance along next upcoming roundabout on the given sequence of lanes continuationLanes 197 static double 198 distanceAlongNextRoundabout(double position, const MSLane* initialLane, const std::vector<MSLane*>& continuationLanes); 199 200 /// @brief save space for vehicles which need to counter-lane-change 201 void saveBlockerLength(MSVehicle* blocker, int lcaCounter); 202 203 /// @brief react to pedestrians on the given lane 204 void adaptSpeedToPedestrians(const MSLane* lane, double& v); 205 206 /// @brief reserve space at the end of the lane to avoid dead locks saveBlockerLength(double length)207 inline void saveBlockerLength(double length) { 208 myLeadingBlockerLength = MAX2(length, myLeadingBlockerLength); 209 }; 210 amBlockingLeader()211 inline bool amBlockingLeader() { 212 return (myOwnState & LCA_AMBLOCKINGLEADER) != 0; 213 } amBlockingFollower()214 inline bool amBlockingFollower() { 215 return (myOwnState & LCA_AMBLOCKINGFOLLOWER) != 0; 216 } amBlockingFollowerNB()217 inline bool amBlockingFollowerNB() { 218 return (myOwnState & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0; 219 } amBlockingFollowerPlusNB()220 inline bool amBlockingFollowerPlusNB() { 221 return (myOwnState & (LCA_AMBLOCKINGFOLLOWER | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)) != 0; 222 } currentDistDisallows(double dist,int laneOffset,double lookForwardDist)223 inline bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist) { 224 return dist / (abs(laneOffset)) < lookForwardDist; 225 } currentDistAllows(double dist,int laneOffset,double lookForwardDist)226 inline bool currentDistAllows(double dist, int laneOffset, double lookForwardDist) { 227 return dist / abs(laneOffset) > lookForwardDist; 228 } 229 230 /** @brief Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration 231 * and stores it into myLCAccelerationAdvices. 232 * @note This construction was introduced to deal with action step lengths, 233 * where operation on the speed in the next sim step had to be replaced by acceleration 234 * throughout the next action step. 235 */ 236 void addLCSpeedAdvice(const double vSafe); 237 238 protected: 239 240 /// @brief information regarding save velocity (unused) and state flags of the ego vehicle 241 typedef std::pair<double, int> Info; 242 243 /// @brief a value for tracking the probability that a change to the offset with the same sign is beneficial 244 double mySpeedGainProbability; 245 /* @brief a value for tracking the probability of following the/"Rechtsfahrgebot" 246 * A larger negative value indicates higher probability for moving to the 247 * right (as in mySpeedGainProbability) */ 248 double myKeepRightProbability; 249 250 double myLeadingBlockerLength; 251 double myLeftSpace; 252 253 /*@brief the speed to use when computing the look-ahead distance for 254 * determining urgency of strategic lane changes */ 255 double myLookAheadSpeed; 256 257 /// @brief vector of LC-related acceleration recommendations 258 /// Filled in wantsChange() and applied in patchSpeed() 259 std::vector<double> myLCAccelerationAdvices; 260 261 bool myDontBrake; // XXX: myDontBrake is initialized as false and seems not to be changed anywhere... What's its purpose??? 262 263 /// @name user configurable model parameters (can be changed via TraCI) 264 //@{ 265 double myStrategicParam; 266 double myCooperativeParam; // in [0,1] 267 double mySpeedGainParam; 268 double myKeepRightParam; 269 double myOppositeParam; 270 271 // @brief the factor by which the lookahead distance to the left differs from the lookahead to the right 272 double myLookaheadLeft; 273 // @brief the factor by which the speedGain-threshold for the leftdiffers from the threshold for the right 274 double mySpeedGainRight; 275 276 // @brief willingness to undercut longitudinal safe gaps 277 double myAssertive; 278 279 const double myExperimentalParam1; // for feature testing 280 //@} 281 282 /// @name derived parameters 283 //@{ 284 // @brief willingness to encroach on other vehicles laterally (pushing them around) 285 double myChangeProbThresholdRight; 286 double myChangeProbThresholdLeft; 287 //@} 288 }; 289 290 291 #endif 292 293 /****************************************************************************/ 294 295