LCOV - code coverage report
Current view: top level - src/microsim/lcmodels - MSLCM_SL2015.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 3 5 60.0 %
Date: 2024-09-16 15:39:55 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2013-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_SL2015.h
      15             : /// @author  Jakob Erdmann
      16             : /// @author  Leonhard Luecken
      17             : /// @date    Tue, 06.10.2015
      18             : ///
      19             : // A lane change model for heterogeneous traffic (based on sub-lanes)
      20             : /****************************************************************************/
      21             : #pragma once
      22             : #include <config.h>
      23             : 
      24             : #include "MSAbstractLaneChangeModel.h"
      25             : #include <vector>
      26             : 
      27             : 
      28             : // ===========================================================================
      29             : // class definitions
      30             : // ===========================================================================
      31             : /**
      32             :  * @class MSLCM_SL2015
      33             :  * @brief A lane change model developed by J. Erdmann
      34             :  */
      35             : class MSLCM_SL2015 : public MSAbstractLaneChangeModel {
      36             : public:
      37             : 
      38             :     MSLCM_SL2015(MSVehicle& v);
      39             : 
      40             :     virtual ~MSLCM_SL2015();
      41             : 
      42             :     /// @brief Returns the model's id
      43           0 :     LaneChangeModel getModelID() const override {
      44           0 :         return LaneChangeModel::SL2015;
      45             :     }
      46             : 
      47             :     /// @brief init cached parameters derived directly from model parameters
      48             :     void initDerivedParameters();
      49             : 
      50             :     /** @brief Called to examine whether the vehicle wants to change
      51             :      * with the given laneOffset (using the sublane model)
      52             :      * This method gets the information about the surrounding vehicles
      53             :      * and whether another lane may be more preferable
      54             :      *
      55             :      * TODO better documentation. Refs #2
      56             :      * A.o.: When is this called (as a wantsChange() exists as well!? What's the difference?)
      57             :      * */
      58             :     int wantsChangeSublane(int laneOffset,
      59             :                            LaneChangeAction alternatives,
      60             :                            const MSLeaderDistanceInfo& leaders,
      61             :                            const MSLeaderDistanceInfo& followers,
      62             :                            const MSLeaderDistanceInfo& blockers,
      63             :                            const MSLeaderDistanceInfo& neighLeaders,
      64             :                            const MSLeaderDistanceInfo& neighFollowers,
      65             :                            const MSLeaderDistanceInfo& neighBlockers,
      66             :                            const MSLane& neighLane,
      67             :                            const std::vector<MSVehicle::LaneQ>& preb,
      68             :                            MSVehicle** lastBlocked,
      69             :                            MSVehicle** firstBlocked,
      70             :                            double& latDist, double& maneuverDist, int& blocked) override;
      71             : 
      72             :     /** @brief Called to examine whether the vehicle wants to change
      73             :      * using the given laneOffset (this is a wrapper around wantsChangeSublane). XXX: no, it wraps _wantsChangeSublane
      74             :      * This method gets the information about the surrounding vehicles
      75             :      * and whether another lane may be more preferable
      76             :      *
      77             :      * TODO: better documentation. Refs #2
      78             :      * */
      79             :     int wantsChange(
      80             :         int laneOffset,
      81             :         MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
      82             :         const std::pair<MSVehicle*, double>& leader,
      83             :         const std::pair<MSVehicle*, double>& follower,
      84             :         const std::pair<MSVehicle*, double>& neighLead,
      85             :         const std::pair<MSVehicle*, double>& neighFollow,
      86             :         const MSLane& neighLane,
      87             :         const std::vector<MSVehicle::LaneQ>& preb,
      88             :         MSVehicle** lastBlocked,
      89             :         MSVehicle** firstBlocked) override;
      90             : 
      91             :     void* inform(void* info, MSVehicle* sender) override;
      92             : 
      93             :     /** @brief Called to adapt the speed in order to allow a lane change.
      94             :      *         It uses information on LC-related desired speed-changes from
      95             :      *         the call to wantsChange() at the end of the previous simulation step
      96             :      *
      97             :      * @param min The minimum resulting speed
      98             :      * @param wanted The aspired speed of the car following model
      99             :      * @param max The maximum resulting speed
     100             :      * @param cfModel The model used
     101             :      * @return the new speed of the vehicle as proposed by the lane changer
     102             :      */
     103             :     double patchSpeed(const double min, const double wanted, const double max,
     104             :                       const MSCFModel& cfModel) override;
     105             : 
     106             :     void changed() override;
     107             : 
     108             :     void resetState() override;
     109             : 
     110             :     double getSafetyFactor() const override;
     111             : 
     112             :     double getOppositeSafetyFactor() const override;
     113             : 
     114             :     void prepareStep() override;
     115             : 
     116             :     double getExtraReservation(int bestLaneOffset) const override;
     117             : 
     118             :     /// @brief whether the current vehicles shall be debugged
     119             :     bool debugVehicle() const override;
     120             : 
     121             :     void setOwnState(const int state) override;
     122             : 
     123             :     /// @brief Updates the value of safe lateral distances (mySafeLatDistLeft and mySafeLatDistRight)
     124             :     ///        during maneuver continuation in non-action steps.
     125             :     virtual void updateSafeLatDist(const double travelledLatDist) override;
     126             : 
     127             :     /// @brief try to retrieve the given parameter from this device. Throw exception for unsupported key
     128             :     std::string getParameter(const std::string& key) const override;
     129             : 
     130             :     /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
     131             :     void setParameter(const std::string& key, const std::string& value) override;
     132             : 
     133             :     /// @brief decides the next lateral speed depending on the remaining lane change distance to be covered
     134             :     ///        and updates maneuverDist according to lateral safety constraints.
     135             :     double computeSpeedLat(double latDist, double& maneuverDist, bool urgent) const override;
     136             : 
     137             :     LatAlignmentDefinition getDesiredAlignment() const override;
     138             : 
     139             : protected:
     140             :     /** helper function which contains the actual logic */
     141             :     double _patchSpeed(double min, const double wanted, double max,
     142             :                        const MSCFModel& cfModel);
     143             : 
     144             :     /// @brief helper function for doing the actual work
     145             :     int _wantsChangeSublane(
     146             :         int laneOffset,
     147             :         LaneChangeAction alternatives,
     148             :         const MSLeaderDistanceInfo& leaders,
     149             :         const MSLeaderDistanceInfo& followers,
     150             :         const MSLeaderDistanceInfo& blockers,
     151             :         const MSLeaderDistanceInfo& neighLeaders,
     152             :         const MSLeaderDistanceInfo& neighFollowers,
     153             :         const MSLeaderDistanceInfo& neighBlockers,
     154             :         const MSLane& neighLane,
     155             :         const std::vector<MSVehicle::LaneQ>& preb,
     156             :         MSVehicle** lastBlocked,
     157             :         MSVehicle** firstBlocked,
     158             :         double& latDist, double& maneuverDist, int& blocked);
     159             : 
     160             : 
     161             :     /* @brief decide whether we will overtake or follow blocking leaders
     162             :      * and inform them accordingly (see informLeader)
     163             :      * If we decide to follow, myVSafes will be extended
     164             :      * returns the planned speed if following or -1 if overtaking */
     165             :     double informLeaders(int blocked, int dir,
     166             :                          const std::vector<CLeaderDist>& blockers,
     167             :                          double remainingSeconds);
     168             : 
     169             :     /// @brief call informFollower for multiple followers
     170             :     void informFollowers(int blocked, int dir,
     171             :                          const std::vector<CLeaderDist>& blockers,
     172             :                          double remainingSeconds,
     173             :                          double plannedSpeed);
     174             : 
     175             :     /* @brief decide whether we will overtake or follow a blocking leader
     176             :      * and inform it accordingly
     177             :      * If we decide to follow, myVSafes will be extended
     178             :      * returns the planned speed if following or -1 if overtaking */
     179             :     double informLeader(int blocked, int dir,
     180             :                         const CLeaderDist& neighLead,
     181             :                         double remainingSeconds);
     182             : 
     183             :     /// @brief decide whether we will try cut in before the follower or allow to be overtaken
     184             :     void informFollower(int blocked, int dir,
     185             :                         const CLeaderDist& neighFollow,
     186             :                         double remainingSeconds,
     187             :                         double plannedSpeed);
     188             : 
     189             : 
     190             :     /// @brief compute useful slowdowns for blocked vehicles
     191             :     int slowDownForBlocked(MSVehicle** blocked, int state);
     192             : 
     193             :     /// @brief reserve space at the end of the lane to avoid dead locks
     194             :     bool saveBlockerLength(double length, double foeLeftSpace) override;
     195             : 
     196             :     /// @brief whether the ego vehicle is driving outside edgebounds
     197             :     bool outsideEdge() const;
     198             : 
     199             :     inline bool amBlockingLeader() {
     200             :         return (myOwnState & LCA_AMBLOCKINGLEADER) != 0;
     201             :     }
     202             :     inline bool amBlockingFollower() {
     203             :         return (myOwnState & LCA_AMBLOCKINGFOLLOWER) != 0;
     204             :     }
     205             :     inline bool amBlockingFollowerNB() {
     206             :         return (myOwnState & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0;
     207             :     }
     208             :     inline bool amBlockingFollowerPlusNB() {
     209    19275973 :         return (myOwnState & (LCA_AMBLOCKINGFOLLOWER | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)) != 0;
     210             :     }
     211             :     inline bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist) {
     212    15979041 :         return dist / (abs(laneOffset)) < lookForwardDist;
     213             :     }
     214             :     inline bool currentDistAllows(double dist, int laneOffset, double lookForwardDist) {
     215         528 :         return dist / abs(laneOffset) > lookForwardDist;
     216             :     }
     217             : 
     218             : 
     219             :     /// @brief information regarding save velocity (unused) and state flags of the ego vehicle
     220             :     typedef std::pair<double, int> Info;
     221             : 
     222             :     /// @brief update expected speeds for each sublane of the current edge
     223             :     void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo& ahead, int sublaneOffset, int laneIndex) override;
     224             : 
     225             :     /// @brief decide in which direction to move in case both directions are desirable
     226             :     StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const override;
     227             : 
     228             :     /// @brief return the most important change reason
     229             :     static int lowest_bit(int changeReason);
     230             : 
     231             : protected:
     232             : 
     233             :     /// @brief send a speed recommendation to the given vehicle
     234             :     void msg(const CLeaderDist& cld, double speed, int state);
     235             : 
     236             :     /// @brief compute shift so that prevSublane + shift = newSublane
     237             :     int computeSublaneShift(const MSEdge* prevEdge, const MSEdge* curEdge);
     238             : 
     239             :     /// @brief get the longest vehicle in the given info
     240             :     CLeaderDist getLongest(const MSLeaderDistanceInfo& ldi) const;
     241             : 
     242             :     bool tieBrakeLeader(const MSVehicle* veh) const;
     243             : 
     244             :     /// @brief get the slowest vehicle in the given info
     245             :     static CLeaderDist getSlowest(const MSLeaderDistanceInfo& ldi);
     246             : 
     247             :     /// @brief restrict latDist to permissible speed and determine blocking state depending on that distance
     248             :     int checkBlocking(const MSLane& neighLane, double& latDist, double maneuverDist, int laneOffset,
     249             :                       const MSLeaderDistanceInfo& leaders,
     250             :                       const MSLeaderDistanceInfo& followers,
     251             :                       const MSLeaderDistanceInfo& blockers,
     252             :                       const MSLeaderDistanceInfo& neighLeaders,
     253             :                       const MSLeaderDistanceInfo& neighFollowers,
     254             :                       const MSLeaderDistanceInfo& neighBlockers,
     255             :                       std::vector<CLeaderDist>* collectLeadBlockers = 0,
     256             :                       std::vector<CLeaderDist>* collectFollowBlockers = 0,
     257             :                       bool keepLatGapManeuver = false,
     258             :                       double gapFactor = 0,
     259             :                       int* retBlockedFully = 0);
     260             : 
     261             :     /// @brief check whether any of the vehicles overlaps with ego
     262             :     int checkBlockingVehicles(const MSVehicle* ego, const MSLeaderDistanceInfo& vehicles,
     263             :                               int laneOffset, double latDist, double foeOffset, bool leaders,
     264             :                               double& safeLatGapRight, double& safeLatGapLeft,
     265             :                               std::vector<CLeaderDist>* collectBlockers = 0) const;
     266             : 
     267             :     /// @brief return whether the given intervals overlap
     268             :     static bool overlap(double right, double left, double right2, double left2);
     269             : 
     270             :     /// @brief compute lane change action from desired lateral distance
     271             :     static LaneChangeAction getLCA(int state, double latDist);
     272             : 
     273             :     /// @brief compute strategic lane change actions
     274             :     /// TODO: Better documentation, refs #2
     275             :     int checkStrategicChange(int ret,
     276             :                              const MSLane& neighLane,
     277             :                              int laneOffset,
     278             :                              const MSLeaderDistanceInfo& leaders,
     279             :                              const MSLeaderDistanceInfo& neighLeaders,
     280             :                              const MSVehicle::LaneQ& curr,
     281             :                              const MSVehicle::LaneQ& neigh,
     282             :                              const MSVehicle::LaneQ& best,
     283             :                              int bestLaneOffset,
     284             :                              bool changeToBest,
     285             :                              double currentDist,
     286             :                              double neighDist,
     287             :                              double laDist,
     288             :                              double roundaboutBonus,
     289             :                              double latLaneDist,
     290             :                              bool checkOpposite,
     291             :                              double& latDist
     292             :                             );
     293             : 
     294             : 
     295             :     bool mustOvertakeStopped(const MSLane& neighLane, const MSLeaderDistanceInfo& leaders, const MSLeaderDistanceInfo& neighLead,
     296             :                              double posOnLane, double neighDist, bool right, double latLaneDist, double& currentDist, double& latDist);
     297             : 
     298             :     /// @brief check whether lateral gap requirements are met override the current maneuver if necessary
     299             :     int keepLatGap(int state,
     300             :                    const MSLeaderDistanceInfo& leaders,
     301             :                    const MSLeaderDistanceInfo& followers,
     302             :                    const MSLeaderDistanceInfo& blockers,
     303             :                    const MSLeaderDistanceInfo& neighLeaders,
     304             :                    const MSLeaderDistanceInfo& neighFollowers,
     305             :                    const MSLeaderDistanceInfo& neighBlockers,
     306             :                    const MSLane& neighLane,
     307             :                    int laneOffset,
     308             :                    double& latDist,
     309             :                    double& maneuverDist,
     310             :                    int& blocked);
     311             : 
     312             : 
     313             :     /// @brief check remaining lateral gaps for the given foe vehicles and optionally update minimum lateral gaps
     314             :     void updateGaps(const MSLeaderDistanceInfo& others, double foeOffset, double oldCenter, double gapFactor,
     315             :                     double& surplusGapRight, double& surplusGapLeft, bool saveMinGap = false, double netOverlap = 0,
     316             :                     double latDist = 0,
     317             :                     std::vector<CLeaderDist>* collectBlockers = 0);
     318             : 
     319             :     /// @brief compute the gap factor for the given state
     320             :     double computeGapFactor(int state) const;
     321             : 
     322             :     /// @brief return the width of this vehicle (padded for numerical stability)
     323             :     double getWidth() const;
     324             : 
     325             :     /// @brief find leaders/followers that are already in a car-following relationship with ego
     326             :     void updateCFRelated(const MSLeaderDistanceInfo& vehicles, double foeOffset, bool leaders);
     327             : 
     328             :     /// @brief return the current sublane width (and return a sensible value when running without sublanes)
     329             :     double getSublaneWidth() {
     330             :         return MSGlobals::gLateralResolution > 0 ? MSGlobals::gLateralResolution : myVehicle.getLane()->getWidth();
     331             :     }
     332             : 
     333             :     /// @brief commit to lane change maneuver potentially overriding safe speed
     334             :     void commitManoeuvre(int blocked, int blockedFully,
     335             :                          const MSLeaderDistanceInfo& leaders,
     336             :                          const MSLeaderDistanceInfo& neighLeaders,
     337             :                          const MSLane& neighLane,
     338             :                          double maneuverDist);
     339             : 
     340             :     /// @brief compute speed when committing to an urgent change that is safe in regard to leading vehicles
     341             :     double commitFollowSpeed(double speed, double latDist, double secondsToLeaveLane, const MSLeaderDistanceInfo& leaders, double foeOffset) const;
     342             : 
     343             :     /// @brief estimate average speed over mySpeedGainLookahead time
     344             :     double forecastAverageSpeed(double vSafe, double vMax, double gap, double vLeader) const;
     345             : 
     346             :     /// @brief compute speedGain when moving by the given amount
     347             :     double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const;
     348             : 
     349             :     /// @brief get lateral position of this vehicle
     350             :     double getPosLat();
     351             : 
     352             :     /// @brief get lateral drift for the current step
     353             :     double getLateralDrift();
     354             : 
     355             :     /// @brief return current edge width optionally extended by opposite direction lane width
     356             :     double getLeftBorder(bool checkOpposite = true) const;
     357             : 
     358             :     /// @brief return vehicle position relative to the current edge (extend by another virtual lane for opposite-direction driving)
     359             :     double getVehicleCenter() const;
     360             : 
     361             :     /// @brief return the right offset of the neighboring lane relative to the current edge
     362             :     double getNeighRight(const MSLane& neighLane) const;
     363             : 
     364             :     /* @brief check whether vehicle speed is appropriate for the intended maneuver distance
     365             :      * (rather than doing an orthogonal slide) */
     366             :     bool preventSliding(double maneuverDist) const;
     367             : 
     368             :     /// @brief check against thresholds
     369             :     inline bool wantsKeepRight(double keepRightProb) const;
     370             : 
     371             :     /// @brief check whether lane is an upcoming bidi lane
     372             :     bool isBidi(const MSLane* lane) const;
     373             : 
     374             :     /// @brief avoid unsafe lateral speed (overruling lcAccelLat)
     375             :     double emergencySpeedLat(double speedLat) const;
     376             : 
     377             : protected:
     378             :     /// @brief a value for tracking the probability that a change to the right is beneficial
     379             :     double mySpeedGainProbabilityRight;
     380             :     /// @brief a value for tracking the probability that a change to the left is beneficial
     381             :     double mySpeedGainProbabilityLeft;
     382             : 
     383             :     /* @brief a value for tracking the probability of following the/"Rechtsfahrgebot"
     384             :      * A larger negative value indicates higher probability for moving to the
     385             :      * right (as in mySpeedGainProbability) */
     386             :     double myKeepRightProbability;
     387             : 
     388             :     double myLeadingBlockerLength;
     389             :     double myLeftSpace;
     390             : 
     391             :     /*@brief the speed to use when computing the look-ahead distance for
     392             :      * determining urgency of strategic lane changes */
     393             :     double myLookAheadSpeed;
     394             : 
     395             :     /// @brief expected travel speeds on all sublanes on the current edge(!)
     396             :     std::vector<double> myExpectedSublaneSpeeds;
     397             : 
     398             :     /// @brief expected travel speeds on all sublanes on the current edge(!)
     399             :     const MSEdge* myLastEdge;
     400             : 
     401             :     /// @brief flag to prevent speed adaptation by slowing down
     402             :     bool myDontBrake;
     403             : 
     404             :     /// @brief whether the current lane changing maneuver can be finished in a single step
     405             :     bool myCanChangeFully;
     406             : 
     407             :     /// @brief the lateral distance the vehicle can safely move in the currently considered direction
     408             :     double mySafeLatDistRight;
     409             :     double mySafeLatDistLeft;
     410             : 
     411             :     /// @brief set of vehicles that are in a car-following relationship with ego (leader of followers)
     412             :     std::set<const MSVehicle*> myCFRelated;
     413             :     bool myCFRelatedReady;
     414             : 
     415             :     /// @name user configurable model parameters (can be changed via TraCI)
     416             :     //@{
     417             :     double myStrategicParam;
     418             :     double myCooperativeParam;
     419             :     double mySpeedGainParam;
     420             :     double myKeepRightParam;
     421             :     double myOppositeParam;
     422             :     double mySublaneParam;
     423             :     // @brief minimum lateral gap
     424             :     double myMinGapLat;
     425             :     // @brief willingness to encroach on other vehicles laterally (pushing them around)
     426             :     double myPushy;
     427             :     // @brief willingness to undercut longitudinal safe gaps
     428             :     double myAssertive;
     429             :     // @brief dynamic component of willingness for longitudinal gap reduction
     430             :     double myImpatience;
     431             :     double myMinImpatience;
     432             :     // @brief time to reach maximum impatience in seconds
     433             :     double myTimeToImpatience;
     434             :     // @brief lateral acceleration
     435             :     double myAccelLat;
     436             :     // @brief distance to turn at which alignment should be adjusted to the turn direction
     437             :     double myTurnAlignmentDist;
     438             :     // @brief the factor by which the lookahead distance to the left differs from the lookahead to the right
     439             :     double myLookaheadLeft;
     440             :     // @brief the factor by which the speedGain-threshold for the leftdiffers from the threshold for the right
     441             :     double mySpeedGainRight;
     442             :     // @brief lane discipline factor
     443             :     double myLaneDiscipline;
     444             :     // @brief lookahead for speedGain in seconds
     445             :     double mySpeedGainLookahead;
     446             :     // @brief bonus factor staying on the inside of multi-lane roundabout
     447             :     double myRoundaboutBonus;
     448             :     // @brief factor for cooperative speed adjustment
     449             :     double myCooperativeSpeed;
     450             :     // time for unrestricted driving on the right to accept keepRight change
     451             :     double myKeepRightAcceptanceTime;
     452             :     // @brief speed difference factor for overtaking the leader on the neighbor lane before changing to that lane
     453             :     double myOvertakeDeltaSpeedFactor;
     454             :     //@}
     455             : 
     456             :     /// @name derived parameters
     457             :     //@{
     458             :     // @brief threshold value for changing to the right
     459             :     double myChangeProbThresholdRight;
     460             :     // @brief threshold value for changing to the left
     461             :     double myChangeProbThresholdLeft;
     462             :     // @brief threshold value for accepting speed loss to achieve desired sublane alignment
     463             :     double mySpeedLossProbThreshold;
     464             : 
     465             :     // @brief state of lane keeping imperfection
     466             :     double mySigmaState;
     467             :     //@}
     468             : 
     469             : };

Generated by: LCOV version 1.14