Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 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 : /****************************************************************************/
14 : /// @file MSLCM_LC2013.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Friedemann Wesner
18 : /// @author Sascha Krieg
19 : /// @author Michael Behrisch
20 : /// @date Fri, 08.10.2013
21 : ///
22 : // A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013
23 : /****************************************************************************/
24 : #pragma once
25 : #include <config.h>
26 :
27 : #include "MSAbstractLaneChangeModel.h"
28 : #include <vector>
29 :
30 : // INVALID_SPEED should be used when the construction of upper bound for the speed
31 : // leads to no restrictions, e.g. during LC-messaging to followers or leaders.
32 : // Currently either std::numeric_limits<...>.max() or -1 is used for this purpose in many places.
33 : // TODO: implement this everywhere and remove workarounds for ballistic update in cases of possible '-1'-returns. Refs. #2577
34 : #define INVALID_SPEED 299792458 + 1 // nothing can go faster than the speed of light!
35 :
36 :
37 : // ===========================================================================
38 : // class definitions
39 : // ===========================================================================
40 : /**
41 : * @class MSLCM_LC2013
42 : * @brief A lane change model developed by D. Krajzewicz, J. Erdmann
43 : * et al. between 2004 and 2013
44 : */
45 : class MSLCM_LC2013 : public MSAbstractLaneChangeModel {
46 : public:
47 :
48 : MSLCM_LC2013(MSVehicle& v);
49 :
50 : virtual ~MSLCM_LC2013();
51 :
52 : /// @brief Returns the model's id
53 0 : LaneChangeModel getModelID() const override {
54 0 : return LaneChangeModel::LC2013;
55 : }
56 :
57 : /// @brief init cached parameters derived directly from model parameters
58 : void initDerivedParameters();
59 :
60 : bool debugVehicle() const override;
61 :
62 : /** @brief Called to examine whether the vehicle wants to change
63 : * using the given laneOffset.
64 : * This method gets the information about the surrounding vehicles
65 : * and whether another lane may be more preferable
66 : *
67 : * TODO: better documentation, refs #2
68 : *
69 : * */
70 : int wantsChange(
71 : int laneOffset,
72 : MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
73 : const std::pair<MSVehicle*, double>& leader,
74 : const std::pair<MSVehicle*, double>& follower,
75 : const std::pair<MSVehicle*, double>& neighLead,
76 : const std::pair<MSVehicle*, double>& neighFollow,
77 : const MSLane& neighLane,
78 : const std::vector<MSVehicle::LaneQ>& preb,
79 : MSVehicle** lastBlocked,
80 : MSVehicle** firstBlocked) override;
81 :
82 : void* inform(void* info, MSVehicle* sender) override;
83 :
84 : /** @brief Called to adapt the speed in order to allow a lane change.
85 : * It uses information on LC-related desired speed-changes from
86 : * the call to wantsChange() at the end of the previous simulation step
87 : *
88 : * @param min The minimum resulting speed
89 : * @param wanted The aspired speed of the car following model
90 : * @param max The maximum resulting speed
91 : * @param cfModel The model used
92 : * @return the new speed of the vehicle as proposed by the lane changer
93 : */
94 : double patchSpeed(const double min, const double wanted, const double max,
95 : const MSCFModel& cfModel) override;
96 :
97 : void changed() override;
98 :
99 : void resetState() override;
100 :
101 : double getSafetyFactor() const override;
102 :
103 : double getOppositeSafetyFactor() const override;
104 :
105 : void prepareStep() override;
106 :
107 : /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
108 : std::string getParameter(const std::string& key) const override;
109 :
110 : /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
111 : void setParameter(const std::string& key, const std::string& value) override;
112 :
113 : /// @brief decides the next lateral speed (for continuous lane changing)
114 : double computeSpeedLat(double latDist, double& maneuverDist, bool urgent) const override;
115 :
116 : protected:
117 :
118 : /** helper function which contains the actual logic */
119 : double _patchSpeed(double min, const double wanted, double max,
120 : const MSCFModel& cfModel);
121 :
122 : /// @brief helper function for doing the actual work
123 : int _wantsChange(
124 : int laneOffset,
125 : MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
126 : const std::pair<MSVehicle*, double>& leader,
127 : const std::pair<MSVehicle*, double>& follower,
128 : const std::pair<MSVehicle*, double>& neighLead,
129 : const std::pair<MSVehicle*, double>& neighFollow,
130 : const MSLane& neighLane,
131 : const std::vector<MSVehicle::LaneQ>& preb,
132 : MSVehicle* lastBlocked,
133 : MSVehicle* firstBlocked);
134 :
135 : /* @brief decide whether we will overtake or follow a blocking leader
136 : * and inform it accordingly
137 : * If we decide to follow, myVSafes will be extended
138 : * returns the planned speed if following or -1 if overtaking */
139 : double informLeader(MSAbstractLaneChangeModel::MSLCMessager& msgPass,
140 : int blocked, int dir,
141 : const std::pair<MSVehicle*, double>& neighLead,
142 : double remainingSeconds);
143 :
144 : /// @brief decide whether we will try cut in before the follower or allow to be overtaken
145 : void informFollower(MSAbstractLaneChangeModel::MSLCMessager& msgPass,
146 : int blocked, int dir,
147 : const std::pair<MSVehicle*, double>& neighFollow,
148 : double remainingSeconds,
149 : double plannedSpeed);
150 :
151 :
152 : /* @brief compute the distance to cover until a safe gap to the vehicle v in front is reached
153 : * assuming constant velocities
154 : * @param[in] follower the vehicle which overtakes
155 : * @param[in] leader the vehicle to be overtaken
156 : * @param[in] gap initial distance between front of follower and back of leader
157 : * @param[in] leaderSpeed an assumed speed for the leader (default uses the current speed)
158 : * @param[in] followerSpeed an assumed speed for the follower (default uses the current speed)
159 : * @return the distance that the relative positions would have to change.
160 : */
161 : static double overtakeDistance(const MSVehicle* follower, const MSVehicle* leader, const double gap, double followerSpeed = INVALID_SPEED, double leaderSpeed = INVALID_SPEED);
162 :
163 : /// @brief compute useful slowdowns for blocked vehicles
164 : int slowDownForBlocked(MSVehicle* blocked, int state);
165 :
166 : /// @brief anticipate future follow speed for the given leader
167 : double anticipateFollowSpeed(const std::pair<MSVehicle*, double>& leaderDist, double dist, double vMax, bool acceleratingLeader);
168 :
169 : /// @brief react to pedestrians on the given lane
170 : void adaptSpeedToPedestrians(const MSLane* lane, double& v);
171 :
172 : /// @brief reserve space at the end of the lane to avoid dead locks
173 : bool saveBlockerLength(double length, double foeLeftSpace) override;
174 :
175 : inline bool amBlockingLeader() {
176 : return (myOwnState & LCA_AMBLOCKINGLEADER) != 0;
177 : }
178 : inline bool amBlockingFollower() {
179 : return (myOwnState & LCA_AMBLOCKINGFOLLOWER) != 0;
180 : }
181 : inline bool amBlockingFollowerNB() {
182 : return (myOwnState & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0;
183 : }
184 : inline bool amBlockingFollowerPlusNB() {
185 189812305 : return (myOwnState & (LCA_AMBLOCKINGFOLLOWER | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)) != 0;
186 : }
187 : inline bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist) {
188 51061030 : return dist / (abs(laneOffset)) < lookForwardDist;
189 : }
190 : inline bool currentDistAllows(double dist, int laneOffset, double lookForwardDist) {
191 205 : return dist / abs(laneOffset) > lookForwardDist;
192 : }
193 :
194 : /// @brief whether there is a lane beyond laneOffset that can be used to overtake the stopped leader on the neighboring lane
195 : bool hasFreeLane(int laneOffset, const std::pair<MSVehicle*, double>& neighLeadStopped) const;
196 :
197 : protected:
198 :
199 : /// @brief information regarding save velocity (unused) and state flags of the ego vehicle
200 : typedef std::pair<double, int> Info;
201 :
202 : /// @brief a value for tracking the probability that a change to that side is beneficial
203 : double mySpeedGainProbabilityLeft;
204 : double mySpeedGainProbabilityRight;
205 :
206 : /* @brief a value for tracking the probability of following the/"Rechtsfahrgebot"
207 : * A larger negative value indicates higher probability for moving to the
208 : * right (as in mySpeedGainProbability) */
209 : double myKeepRightProbability;
210 :
211 : double myLeadingBlockerLength;
212 : double myLeftSpace;
213 :
214 : /*@brief the speed to use when computing the look-ahead distance for
215 : * determining urgency of strategic lane changes */
216 : double myLookAheadSpeed;
217 :
218 : bool myDontBrake; // XXX: myDontBrake is initialized as false and seems not to be changed anywhere... What's its purpose???
219 :
220 : /// @name user configurable model parameters (can be changed via TraCI)
221 : //@{
222 : double myStrategicParam;
223 : double myCooperativeParam; // in [0,1]
224 : double mySpeedGainParam;
225 : double myKeepRightParam;
226 : double myOppositeParam;
227 :
228 : // @brief the factor by which the lookahead distance to the left differs from the lookahead to the right
229 : double myLookaheadLeft;
230 : // @brief the factor by which the speedGain-threshold for the leftdiffers from the threshold for the right
231 : double mySpeedGainRight;
232 :
233 : // @brief lookahead for speedGain in seconds
234 : double mySpeedGainLookahead;
235 : // @brief the minimum time to spent driving without lane change after a speed-gain change
236 : double mySpeedGainRemainTime;
237 : // @brief the threshold value of mySpeedGainProbability for making a speedGain change urgent
238 : double mySpeedGainUrgency;
239 : // @brief bounus factor staying on the inside of multi-lane roundabout
240 : double myRoundaboutBonus;
241 : // @brief factor for cooperative speed adjustment
242 : double myCooperativeSpeed;
243 :
244 : // time for unrestricted driving on the right to accept keepRight change
245 : double myKeepRightAcceptanceTime;
246 :
247 : // @brief speed difference factor for overtaking the leader on the neighbor lane before changing to that lane
248 : double myOvertakeDeltaSpeedFactor;
249 :
250 : // for feature testing
251 : const double myExperimentalParam1;
252 :
253 : //@}
254 :
255 : /// @name derived parameters
256 : //@{
257 : // @brief willingness to encroach on other vehicles laterally (pushing them around)
258 : double myChangeProbThresholdRight;
259 : double myChangeProbThresholdLeft;
260 : //@}
261 : };
|