Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 : /****************************************************************************/
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 : double getExtraReservation(int bestLaneOffset) const override;
108 :
109 : /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
110 : std::string getParameter(const std::string& key) const override;
111 :
112 : /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
113 : void setParameter(const std::string& key, const std::string& value) override;
114 :
115 : /// @brief decides the next lateral speed (for continuous lane changing)
116 : double computeSpeedLat(double latDist, double& maneuverDist, bool urgent) const override;
117 :
118 : protected:
119 :
120 : /** helper function which contains the actual logic */
121 : double _patchSpeed(double min, const double wanted, double max,
122 : const MSCFModel& cfModel);
123 :
124 : /// @brief helper function for doing the actual work
125 : int _wantsChange(
126 : int laneOffset,
127 : MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
128 : const std::pair<MSVehicle*, double>& leader,
129 : const std::pair<MSVehicle*, double>& follower,
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 : /// @brief anticipate future follow speed for the given leader
169 : double anticipateFollowSpeed(const std::pair<MSVehicle*, double>& leaderDist, double dist, double vMax, bool acceleratingLeader);
170 :
171 : /// @brief react to pedestrians on the given lane
172 : void adaptSpeedToPedestrians(const MSLane* lane, double& v);
173 :
174 : /// @brief reserve space at the end of the lane to avoid dead locks
175 : bool saveBlockerLength(double length, double foeLeftSpace) override;
176 :
177 : inline bool amBlockingLeader() {
178 : return (myOwnState & LCA_AMBLOCKINGLEADER) != 0;
179 : }
180 : inline bool amBlockingFollower() {
181 : return (myOwnState & LCA_AMBLOCKINGFOLLOWER) != 0;
182 : }
183 : inline bool amBlockingFollowerNB() {
184 : return (myOwnState & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0;
185 : }
186 : inline bool amBlockingFollowerPlusNB() {
187 144631145 : return (myOwnState & (LCA_AMBLOCKINGFOLLOWER | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)) != 0;
188 : }
189 : inline bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist) {
190 46284214 : return dist / (abs(laneOffset)) < lookForwardDist;
191 : }
192 : inline bool currentDistAllows(double dist, int laneOffset, double lookForwardDist) {
193 136 : return dist / abs(laneOffset) > lookForwardDist;
194 : }
195 :
196 : protected:
197 :
198 : /// @brief information regarding save velocity (unused) and state flags of the ego vehicle
199 : typedef std::pair<double, int> Info;
200 :
201 : /// @brief a value for tracking the probability that a change to the offset with the same sign is beneficial
202 : double mySpeedGainProbability;
203 : /* @brief a value for tracking the probability of following the/"Rechtsfahrgebot"
204 : * A larger negative value indicates higher probability for moving to the
205 : * right (as in mySpeedGainProbability) */
206 : double myKeepRightProbability;
207 :
208 : double myLeadingBlockerLength;
209 : double myLeftSpace;
210 :
211 : /*@brief the speed to use when computing the look-ahead distance for
212 : * determining urgency of strategic lane changes */
213 : double myLookAheadSpeed;
214 :
215 : bool myDontBrake; // XXX: myDontBrake is initialized as false and seems not to be changed anywhere... What's its purpose???
216 :
217 : /// @name user configurable model parameters (can be changed via TraCI)
218 : //@{
219 : double myStrategicParam;
220 : double myCooperativeParam; // in [0,1]
221 : double mySpeedGainParam;
222 : double myKeepRightParam;
223 : double myOppositeParam;
224 :
225 : // @brief the factor by which the lookahead distance to the left differs from the lookahead to the right
226 : double myLookaheadLeft;
227 : // @brief the factor by which the speedGain-threshold for the leftdiffers from the threshold for the right
228 : double mySpeedGainRight;
229 :
230 : // @brief willingness to undercut longitudinal safe gaps
231 : double myAssertive;
232 : // @brief lookahead for speedGain in seconds
233 : double mySpeedGainLookahead;
234 : // @brief bounus factor staying on the inside of multi-lane roundabout
235 : double myRoundaboutBonus;
236 : // @brief factor for cooperative speed adjustment
237 : double myCooperativeSpeed;
238 :
239 : // time for unrestricted driving on the right to accept keepRight change
240 : double myKeepRightAcceptanceTime;
241 :
242 : // @brief speed difference factor for overtaking the leader on the neighbor lane before changing to that lane
243 : double myOvertakeDeltaSpeedFactor;
244 :
245 : // for feature testing
246 : const double myExperimentalParam1;
247 :
248 : //@}
249 :
250 : /// @name derived parameters
251 : //@{
252 : // @brief willingness to encroach on other vehicles laterally (pushing them around)
253 : double myChangeProbThresholdRight;
254 : double myChangeProbThresholdLeft;
255 : //@}
256 : };
|