LCOV - code coverage report
Current view: top level - src/microsim/lcmodels - MSLCM_SL2015.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 60.0 % 5 3
Test Date: 2024-11-21 15:56:26 Functions: 0.0 % 1 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     19667382 :         return (myOwnState & (LCA_AMBLOCKINGFOLLOWER | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)) != 0;
     210              :     }
     211              :     inline bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist) {
     212     15884378 :         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 2.0-1