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