LCOV - code coverage report
Current view: top level - src/microsim/lcmodels - MSAbstractLaneChangeModel.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 59 85 69.4 %
Date: 2024-09-16 15:39:55 Functions: 4 18 22.2 %

          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    MSAbstractLaneChangeModel.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Friedemann Wesner
      17             : /// @author  Sascha Krieg
      18             : /// @author  Michael Behrisch
      19             : /// @author  Jakob Erdmann
      20             : /// @author  Leonhard Luecken
      21             : /// @date    Fri, 29.04.2005
      22             : ///
      23             : // Interface for lane-change models
      24             : /****************************************************************************/
      25             : #pragma once
      26             : #include <config.h>
      27             : 
      28             : #include <microsim/MSGlobals.h>
      29             : #include <microsim/MSLeaderInfo.h>
      30             : #include <microsim/MSVehicle.h>
      31             : 
      32             : 
      33             : // ===========================================================================
      34             : // class declarations
      35             : // ===========================================================================
      36             : class MSLane;
      37             : class SUMOSAXAttributes;
      38             : 
      39             : 
      40             : // ===========================================================================
      41             : // class definitions
      42             : // ===========================================================================
      43             : /**
      44             :  * @class MSAbstractLaneChangeModel
      45             :  * @brief Interface for lane-change models
      46             :  */
      47             : class MSAbstractLaneChangeModel {
      48             : public:
      49             : 
      50             :     /** @class MSLCMessager
      51             :      * @brief A class responsible for exchanging messages between cars involved in lane-change interaction
      52             :      */
      53             :     class MSLCMessager {
      54             :     public:
      55             :         /** @brief Constructor
      56             :          * @param[in] leader The leader on the informed vehicle's lane
      57             :          * @param[in] neighLead The leader on the lane the vehicle want to change to
      58             :          * @param[in] neighFollow The follower on the lane the vehicle want to change to
      59             :          */
      60             :         MSLCMessager(MSVehicle* leader,  MSVehicle* neighLead, MSVehicle* neighFollow)
      61   110186708 :             : myLeader(leader), myNeighLeader(neighLead),
      62   110186708 :               myNeighFollower(neighFollow) { }
      63             : 
      64             : 
      65             :         /// @brief Destructor
      66   110186708 :         ~MSLCMessager() { }
      67             : 
      68             : 
      69             :         /** @brief Informs the leader on the same lane
      70             :          * @param[in] info The information to pass
      71             :          * @param[in] sender The sending vehicle (the lane changing vehicle)
      72             :          * @return Something!?
      73             :          */
      74             :         void* informLeader(void* info, MSVehicle* sender) {
      75             :             assert(myLeader != 0);
      76             :             return myLeader->getLaneChangeModel().inform(info, sender);
      77             :         }
      78             : 
      79             : 
      80             :         /** @brief Informs the leader on the desired lane
      81             :          * @param[in] info The information to pass
      82             :          * @param[in] sender The sending vehicle (the lane changing vehicle)
      83             :          * @return Something!?
      84             :          */
      85     3659753 :         void* informNeighLeader(void* info, MSVehicle* sender) {
      86             :             assert(myNeighLeader != 0);
      87     3659753 :             return myNeighLeader->getLaneChangeModel().inform(info, sender);
      88             :         }
      89             : 
      90             : 
      91             :         /** @brief Informs the follower on the desired lane
      92             :          * @param[in] info The information to pass
      93             :          * @param[in] sender The sending vehicle (the lane changing vehicle)
      94             :          * @return Something!?
      95             :          */
      96     1755353 :         void* informNeighFollower(void* info, MSVehicle* sender) {
      97             :             assert(myNeighFollower != 0);
      98     1755353 :             return myNeighFollower->getLaneChangeModel().inform(info, sender);
      99             :         }
     100             : 
     101             : 
     102             :     private:
     103             :         /// @brief The leader on the informed vehicle's lane
     104             :         MSVehicle* myLeader;
     105             :         /// @brief The leader on the lane the vehicle want to change to
     106             :         MSVehicle* myNeighLeader;
     107             :         /// @brief The follower on the lane the vehicle want to change to
     108             :         MSVehicle* myNeighFollower;
     109             : 
     110             :     };
     111             : 
     112             :     struct StateAndDist {
     113             :         // @brief LaneChangeAction flags
     114             :         int state;
     115             :         // @brief Lateral distance to be completed in the next step
     116             :         double latDist;
     117             :         // @brief Full lateral distance required for the completion of the envisioned maneuver
     118             :         double maneuverDist;
     119             :         // @brief direction that was checked
     120             :         int dir;
     121             : 
     122   220355688 :         StateAndDist(int _state, double _latDist, double _targetDist, int _dir) :
     123   220355688 :             state(_state),
     124   220355688 :             latDist(_latDist),
     125   220355688 :             maneuverDist(_targetDist),
     126   220355688 :             dir(_dir) {}
     127             : 
     128             :         bool sameDirection(const StateAndDist& other) const {
     129     3753693 :             return latDist * other.latDist > 0;
     130             :         }
     131             :     };
     132             : 
     133             :     /// @brief init global model parameters
     134             :     void static initGlobalOptions(const OptionsCont& oc);
     135             : 
     136             :     /** @brief Factory method for instantiating new lane changing models
     137             :      * @param[in] lcm The type of model to build
     138             :      * @param[in] vehicle The vehicle for which this model shall be built
     139             :      */
     140             :     static MSAbstractLaneChangeModel* build(LaneChangeModel lcm, MSVehicle& vehicle);
     141             : 
     142             :     /** @brief Returns the model's ID;
     143             :      * @return The model's ID
     144             :      */
     145             :     virtual LaneChangeModel getModelID() const = 0;
     146             : 
     147             :     /** @brief Informs the vehicle that it is about to be moved on an adjacent lane.
     148             :      * The method can be used to re-evaluate the state of the vehicle and potentially abort the lane change.
     149             :      * By default, if the method is not overridden by the lane change model implementation, nothing is altered and the vehicle will perform the lane change.
     150             :      * @param veh the lane changing vehicle
     151             :      * @param state current lane change state
     152             :      * @return the blocked status of the vehicle. If the vehicle should perform the lane change, the method should return 0, corresponding to non-blocked.
     153             :      * Otherwise the method should return a non-zero state, corresponding to the type of blockage.
     154             :      */
     155      653782 :     virtual int checkChangeBeforeCommitting(const MSVehicle* veh, int state) const {
     156             :         UNUSED_PARAMETER(veh);
     157             :         UNUSED_PARAMETER(state);
     158      653782 :         return 0;
     159             :     }
     160             : 
     161             :     /** @brief Save the state of the laneChangeModel
     162             :      * @param[in] out The OutputDevice to write the information into
     163             :      */
     164             :     virtual void saveState(OutputDevice& out) const;
     165             : 
     166             :     /** @brief Loads the state of the laneChangeModel from the given attributes
     167             :      * @param[in] attrs XML attributes describing the current state
     168             :      */
     169             :     virtual void loadState(const SUMOSAXAttributes& attrs);
     170             : 
     171             :     /// @brief whether lanechange-output is active
     172             :     static bool haveLCOutput() {
     173     5628652 :         return myLCOutput;
     174             :     }
     175             : 
     176             :     /// @brief whether start of maneuvers shall be recorede
     177             :     static bool outputLCStarted() {
     178      394970 :         return myLCStartedOutput;
     179             :     }
     180             : 
     181             :     /// @brief whether start of maneuvers shall be recorede
     182             :     static bool outputLCEnded() {
     183      135239 :         return myLCEndedOutput;
     184             :     }
     185             : 
     186             :     /** @brief Constructor
     187             :      * @param[in] v The vehicle this lane-changer belongs to
     188             :      * @param[in] model The type of lane change model
     189             :      */
     190             :     MSAbstractLaneChangeModel(MSVehicle& v, const LaneChangeModel model);
     191             : 
     192             :     /// @brief Destructor
     193             :     virtual ~MSAbstractLaneChangeModel();
     194             : 
     195             :     inline int getOwnState() const {
     196   851457640 :         return myOwnState;
     197             :     }
     198             : 
     199             :     inline int getPrevState() const {
     200             :         /// at the time of this call myPreviousState already holds the new value
     201    74233098 :         return myPreviousState2;
     202             :     }
     203             : 
     204             :     virtual void setOwnState(const int state);
     205             : 
     206             :     /// @brief Updates the remaining distance for the current maneuver while it is continued within non-action steps (only used by sublane model)
     207             :     void setManeuverDist(const double dist);
     208             :     /// @brief Returns the remaining unblocked distance for the current maneuver. (only used by sublane model)
     209             :     double getManeuverDist() const;
     210             :     double getPreviousManeuverDist() const;
     211             : 
     212             :     /// @brief Updates the value of safe lateral distances (in SL2015) during maneuver continuation in non-action steps
     213             :     virtual void updateSafeLatDist(const double travelledLatDist);
     214             : 
     215             :     const std::pair<int, int>& getSavedState(const int dir) const {
     216       19466 :         if (dir == -1) {
     217        6641 :             return mySavedStateRight;
     218       12825 :         } else if (dir == 0) {
     219        6184 :             return mySavedStateCenter;
     220             :         } else {
     221        6641 :             return mySavedStateLeft;
     222             :         }
     223             :     }
     224             : 
     225             :     void saveLCState(const int dir, int stateWithoutTraCI, const int state) {
     226   227602264 :         int canceledStrategic = getCanceledState(dir);
     227             :         // avoid conflicting directions
     228   219022962 :         if ((canceledStrategic & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
     229             :             stateWithoutTraCI = canceledStrategic;
     230             :         }
     231             :         const auto pair = std::make_pair(stateWithoutTraCI, state);
     232   214733311 :         if (dir == -1) {
     233             :             mySavedStateRight = pair;
     234   147886511 :         } else if (dir == 0) {
     235             :             mySavedStateCenter = pair;
     236             :         } else {
     237             :             mySavedStateLeft = pair;
     238             :         }
     239             :     }
     240             : 
     241             :     /// @brief Saves the lane change relevant vehicles, which are currently on neighboring lanes in the given direction
     242             :     ///        (as detected in wantsChangeSublane()). -> SL2015 case
     243             :     void saveNeighbors(const int dir, const MSLeaderDistanceInfo& followers, const MSLeaderDistanceInfo& leaders);
     244             : 
     245             :     /// @brief Saves the lane change relevant vehicles, which are currently on neighboring lanes in the given direction
     246             :     ///        (as detected in wantsChange()). -> LC2013 case
     247             :     void saveNeighbors(const int dir, const std::pair<MSVehicle* const, double>& follower, const std::pair<MSVehicle* const, double>& leader);
     248             : 
     249             :     /// @brief Clear info on neighboring vehicle from previous step
     250             :     void clearNeighbors();
     251             : 
     252             :     /// @brief Returns the neighboring, lc-relevant followers for the last step in the requested direction
     253             :     const std::shared_ptr<MSLeaderDistanceInfo> getFollowers(const int dir);
     254             : 
     255             :     /// @brief Returns the neighboring, lc-relevant leaders for the last step in the requested direction
     256             :     const std::shared_ptr<MSLeaderDistanceInfo> getLeaders(const int dir);
     257             : 
     258             :     int& getCanceledState(const int dir) {
     259   432700825 :         if (dir == -1) {
     260   166551370 :             return myCanceledStateRight;
     261   266149455 :         } else if (dir == 0) {
     262    80183913 :             return myCanceledStateCenter;
     263             :         } else {
     264   185965542 :             return myCanceledStateLeft;
     265             :         }
     266             :     }
     267             : 
     268             :     /// @return whether this vehicle is blocked from performing a strategic change
     269             :     bool isStrategicBlocked() const;
     270             : 
     271             :     void setFollowerGaps(CLeaderDist follower, double secGap);
     272             :     void setLeaderGaps(CLeaderDist, double secGap);
     273             :     void setOrigLeaderGaps(CLeaderDist, double secGap);
     274             :     void setFollowerGaps(const MSLeaderDistanceInfo& vehicles);
     275             :     void setLeaderGaps(const MSLeaderDistanceInfo& vehicles);
     276             :     void setOrigLeaderGaps(const MSLeaderDistanceInfo& vehicles);
     277             : 
     278             :     virtual void prepareStep();
     279             : 
     280             :     /** @brief Called to examine whether the vehicle wants to change
     281             :      * using the given laneOffset.
     282             :      * This method gets the information about the surrounding vehicles
     283             :      * and whether another lane may be more preferable */
     284           0 :     virtual int wantsChange(
     285             :         int laneOffset,
     286             :         MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
     287             :         const std::pair<MSVehicle*, double>& leader,
     288             :         const std::pair<MSVehicle*, double>& follower,
     289             :         const std::pair<MSVehicle*, double>& neighLead,
     290             :         const std::pair<MSVehicle*, double>& neighFollow,
     291             :         const MSLane& neighLane,
     292             :         const std::vector<MSVehicle::LaneQ>& preb,
     293             :         MSVehicle** lastBlocked,
     294             :         MSVehicle** firstBlocked) {
     295             :         UNUSED_PARAMETER(laneOffset);
     296             :         UNUSED_PARAMETER(&msgPass);
     297             :         UNUSED_PARAMETER(blocked);
     298             :         UNUSED_PARAMETER(&leader);
     299             :         UNUSED_PARAMETER(&follower);
     300             :         UNUSED_PARAMETER(&neighLead);
     301             :         UNUSED_PARAMETER(&neighFollow);
     302             :         UNUSED_PARAMETER(&neighLane);
     303             :         UNUSED_PARAMETER(&preb);
     304             :         UNUSED_PARAMETER(lastBlocked);
     305             :         UNUSED_PARAMETER(firstBlocked);
     306           0 :         throw ProcessError("Method not implemented by model " + toString(myModel));
     307             :     };
     308             : 
     309           0 :     virtual int wantsChangeSublane(
     310             :         int laneOffset,
     311             :         LaneChangeAction alternatives,
     312             :         const MSLeaderDistanceInfo& leaders,
     313             :         const MSLeaderDistanceInfo& followers,
     314             :         const MSLeaderDistanceInfo& blockers,
     315             :         const MSLeaderDistanceInfo& neighLeaders,
     316             :         const MSLeaderDistanceInfo& neighFollowers,
     317             :         const MSLeaderDistanceInfo& neighBlockers,
     318             :         const MSLane& neighLane,
     319             :         const std::vector<MSVehicle::LaneQ>& preb,
     320             :         MSVehicle** lastBlocked,
     321             :         MSVehicle** firstBlocked,
     322             :         double& latDist, double& targetDistLat, int& blocked) {
     323             :         UNUSED_PARAMETER(laneOffset);
     324             :         UNUSED_PARAMETER(alternatives);
     325             :         UNUSED_PARAMETER(&leaders);
     326             :         UNUSED_PARAMETER(&followers);
     327             :         UNUSED_PARAMETER(&blockers);
     328             :         UNUSED_PARAMETER(&neighLeaders);
     329             :         UNUSED_PARAMETER(&neighFollowers);
     330             :         UNUSED_PARAMETER(&neighBlockers);
     331             :         UNUSED_PARAMETER(&neighLane);
     332             :         UNUSED_PARAMETER(&preb);
     333             :         UNUSED_PARAMETER(lastBlocked);
     334             :         UNUSED_PARAMETER(firstBlocked);
     335             :         UNUSED_PARAMETER(latDist);
     336             :         UNUSED_PARAMETER(targetDistLat);
     337             :         UNUSED_PARAMETER(blocked);
     338           0 :         throw ProcessError("Method not implemented by model " + toString(myModel));
     339             :     }
     340             : 
     341             :     /// @brief update expected speeds for each sublane of the current edge
     342           0 :     virtual void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo& ahead, int sublaneOffset, int laneIndex) {
     343             :         UNUSED_PARAMETER(&ahead);
     344             :         UNUSED_PARAMETER(sublaneOffset);
     345             :         UNUSED_PARAMETER(laneIndex);
     346           0 :         throw ProcessError("Method not implemented by model " + toString(myModel));
     347             :     }
     348             : 
     349             :     /// @brief decide in which direction to move in case both directions are desirable
     350           0 :     virtual StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const {
     351             :         UNUSED_PARAMETER(sd1);
     352             :         UNUSED_PARAMETER(sd2);
     353           0 :         throw ProcessError("Method not implemented by model " + toString(myModel));
     354             :     }
     355             : 
     356             :     virtual void* inform(void* info, MSVehicle* sender) = 0;
     357             : 
     358             :     /** @brief Called to adapt the speed in order to allow a lane change.
     359             :      *         It uses information on LC-related desired speed-changes from
     360             :      *         the call to wantsChange() at the end of the previous simulation step
     361             :      *
     362             :      * It is guaranteed that min<=wanted<=max, but the implementation needs
     363             :      * to make sure that the return value is between min and max.
     364             :      *
     365             :      * @param min The minimum resulting speed
     366             :      * @param wanted The aspired speed of the car following model
     367             :      * @param max The maximum resulting speed
     368             :      * @param cfModel The model used
     369             :      * @return the new speed of the vehicle as proposed by the lane changer
     370             :      */
     371             :     virtual double patchSpeed(const double min, const double wanted, const double max,
     372             :                               const MSCFModel& cfModel) = 0;
     373             : 
     374             :     /* @brief called once when the primary lane of the vehicle changes (updates
     375             :      * the custom variables of each child implementation */
     376             :     virtual void changed() = 0;
     377             : 
     378             :     /* @brief called once when the vehicle moves to a new lane in an "irregular"  way (i.e. by teleporting)
     379             :      * resets custom variables of each child implementation */
     380           0 :     virtual void resetState() {};
     381             : 
     382             :     /// @brief return factor for modifying the safety constraints of the car-following model
     383           0 :     virtual double getSafetyFactor() const {
     384           0 :         return 1.0;
     385             :     }
     386             : 
     387             :     /// @brief return factor for modifying the safety constraints for opposite-diretction overtaking of the car-following model
     388           0 :     virtual double getOppositeSafetyFactor() const {
     389           0 :         return 1.0;
     390             :     }
     391             : 
     392             :     /// @brief whether the current vehicles shall be debugged
     393           0 :     virtual bool debugVehicle() const {
     394           0 :         return false;
     395             :     }
     396             : 
     397             :     /// @brief called when a vehicle changes between lanes in opposite directions
     398             :     void changedToOpposite();
     399             : 
     400             :     void unchanged() {
     401   240235602 :         if (myLastLaneChangeOffset > 0) {
     402    46983156 :             myLastLaneChangeOffset += DELTA_T;
     403   193252446 :         } else if (myLastLaneChangeOffset < 0) {
     404    35697940 :             myLastLaneChangeOffset -= DELTA_T;
     405             :         }
     406             :     }
     407             : 
     408             :     /** @brief Returns the lane the vehicle's shadow is on during continuous/sublane lane change
     409             :      * @return The vehicle's shadow lane
     410             :      */
     411             :     MSLane* getShadowLane() const {
     412 10873843260 :         return myShadowLane;
     413             :     }
     414             : 
     415             :     /// @brief return the shadow lane for the given lane
     416             :     MSLane* getShadowLane(const MSLane* lane) const;
     417             : 
     418             :     /// @brief return the shadow lane for the given lane and lateral offset
     419             :     MSLane* getShadowLane(const MSLane* lane, double posLat) const;
     420             : 
     421             :     const std::vector<MSLane*>& getShadowFurtherLanes() const {
     422             :         return myShadowFurtherLanes;
     423             :     }
     424             : 
     425             :     const std::vector<double>& getShadowFurtherLanesPosLat() const {
     426             :         return myShadowFurtherLanesPosLat;
     427             :     }
     428             : 
     429             :     /** @brief Returns the lane the vehicle has committed to enter during a sublane lane change
     430             :      *  @return The vehicle's target lane.
     431             :      */
     432             :     MSLane* getTargetLane() const {
     433  4113479618 :         return myTargetLane;
     434             :     }
     435             : 
     436             :     const std::vector<MSLane*>& getFurtherTargetLanes() const {
     437           4 :         return myFurtherTargetLanes;
     438             :     }
     439             : 
     440             :     inline SUMOTime getLastLaneChangeOffset() const {
     441       24743 :         return myLastLaneChangeOffset;
     442             :     }
     443             : 
     444             : 
     445             :     /// @brief return whether the vehicle passed the midpoint of a continuous lane change maneuver
     446             :     inline bool pastMidpoint() const {
     447             :         return myLaneChangeCompletion >= 0.5;
     448             :     }
     449             : 
     450             :     /// @brief Compute the remaining time until LC completion
     451             :     SUMOTime remainingTime() const;
     452             : 
     453             :     /// @brief Calculates the maximal time needed to complete a lane change maneuver
     454             :     ///        if lcMaxSpeedLatFactor and lcMaxSpeedStanding are set and the vehicle breaks not harder than decel.
     455             :     ///        LC when the vehicle starts breaking now. If lcMaxSpeedStanding==0 the completion may be impossible,
     456             :     /// @param[in] speed Current longitudinal speed of the changing vehicle.
     457             :     /// @param[in] remainingManeuverDist dist which is still to be covered until LC is completed
     458             :     /// @param[in] decel Maximal assumed deceleration rate applied during the LC.
     459             :     /// @return maximal LC duration (or -1) if it is possible that it can't be completed.
     460             :     /// @note 1) For the calculation it is assumed that the vehicle starts breaking with decel (>=0) immediately.
     461             :     ///       If lcMaxSpeedStanding==0 the completion may be impossible, and -1 is returned.
     462             :     ///       2) In case that no maxSpeedLat is used to control lane changing, this is only called prior to a lane change,
     463             :     ///          and the duration is MSGlobals::gLaneChangeDuration.
     464             :     virtual double estimateLCDuration(const double speed, const double remainingManeuverDist, const double decel, bool urgent) const;
     465             : 
     466             :     /// @brief return true if the vehicle currently performs a lane change maneuver
     467             :     inline bool isChangingLanes() const {
     468  3995317049 :         return myLaneChangeCompletion < (1 - NUMERICAL_EPS);
     469             :     }
     470             : 
     471             :     /// @brief Get the current lane change completion ratio
     472             :     inline double getLaneChangeCompletion() const {
     473      187933 :         return myLaneChangeCompletion;
     474             :     }
     475             : 
     476             :     /// @brief return the direction of the current lane change maneuver
     477             :     inline int getLaneChangeDirection() const {
     478      808568 :         return myLaneChangeDirection;
     479             :     }
     480             : 
     481             :     /// @brief return the direction in which the current shadow lane lies
     482             :     int getShadowDirection() const;
     483             : 
     484             :     /// @brief return the angle offset during a continuous change maneuver
     485             :     double calcAngleOffset();
     486             : 
     487             :     /// @brief return the angle offset resulting from lane change and sigma
     488             :     inline double getAngleOffset() const {
     489   686791776 :         return myAngleOffset;
     490             :     }
     491             : 
     492             :     /// @brief set the angle offset resulting from lane change and sigma
     493             :     inline void setAngleOffset(const double angleOffset) {
     494             :         myAngleOffset = angleOffset;
     495             :     }
     496             : 
     497             :     /// @brief set the angle offset of the previous time step
     498             :     inline void setPreviousAngleOffset(const double angleOffset) {
     499   686791776 :         myPreviousAngleOffset = angleOffset;
     500             :     }
     501             : 
     502             :     /// @brief reset the flag whether a vehicle already moved to false
     503             :     inline bool alreadyChanged() const {
     504   241560557 :         return myAlreadyChanged;
     505             :     }
     506             : 
     507             :     /// @brief reset the flag whether a vehicle already moved to false
     508             :     void resetChanged() {
     509   617392824 :         myAlreadyChanged = false;
     510   617392824 :     }
     511             : 
     512             :     /// @brief start the lane change maneuver and return whether it continues
     513             :     bool startLaneChangeManeuver(MSLane* source, MSLane* target, int direction);
     514             : 
     515             :     /// @brief Control for resetting the memorized values for LC relevant gaps until the LC output is triggered in the case of continuous LC.
     516             :     void memorizeGapsAtLCInit();
     517             :     void clearGapsAtLCInit();
     518             : 
     519             :     /* @brief continue the lane change maneuver and return whether the midpoint
     520             :      * was passed in this step
     521             :      */
     522             :     bool updateCompletion();
     523             : 
     524             :     /* @brief update lane change shadow after the vehicle moved to a new lane */
     525             :     void updateShadowLane();
     526             : 
     527             :     /* @brief update lane change reservations after the vehicle moved to a new lane
     528             :      * @note  The shadow lane should always be updated before updating the target lane. */
     529             :     MSLane* updateTargetLane();
     530             : 
     531             :     /* @brief Determines the lane which the vehicle intends to enter during its current action step.
     532             :      *        targetDir is set to the offset of the returned lane with respect to the vehicle'a current lane. */
     533             :     MSLane* determineTargetLane(int& targetDir) const;
     534             : 
     535             :     /* @brief finish the lane change maneuver
     536             :      */
     537             :     void endLaneChangeManeuver(const MSMoveReminder::Notification reason = MSMoveReminder::NOTIFICATION_LANE_CHANGE);
     538             : 
     539             :     /* @brief clean up all references to the shadow vehicle
     540             :      */
     541             :     void cleanupShadowLane();
     542             : 
     543             :     /* @brief clean up all references to the vehicle on its target lanes
     544             :      */
     545             :     void cleanupTargetLane();
     546             : 
     547             :     /// @brief reserve space at the end of the lane to avoid dead locks
     548           0 :     virtual bool saveBlockerLength(double /* length */, double /* foeLeftSpace */) {
     549           0 :         return true;
     550             :     }
     551             : 
     552             :     void setShadowPartialOccupator(MSLane* lane) {
     553             :         myPartiallyOccupatedByShadow.push_back(lane);
     554             :     }
     555             : 
     556             :     void setNoShadowPartialOccupator(MSLane* lane) {
     557           0 :         myNoPartiallyOccupatedByShadow.push_back(lane);
     558             :     }
     559             : 
     560             :     /// @brief called once when the vehicles primary lane changes
     561             :     void primaryLaneChanged(MSLane* source, MSLane* target, int direction);
     562             : 
     563             :     /// @brief called once the vehicle ends a lane change manoeuvre (non-instant)
     564             :     void laneChangeOutput(const std::string& tag, MSLane* source, MSLane* target, int direction, double maneuverDist = 0);
     565             : 
     566             :     /// @brief whether the current change completes the manoeuvre
     567           0 :     virtual bool sublaneChangeCompleted(const double latDist) const {
     568             :         UNUSED_PARAMETER(latDist);
     569           0 :         throw ProcessError("Method not implemented by model " + toString(myModel));
     570             :     }
     571             : 
     572             :     /// @brief set approach information for the shadow vehicle
     573             :     void setShadowApproachingInformation(MSLink* link) const;
     574             :     void removeShadowApproachingInformation() const;
     575             : 
     576             :     bool isOpposite() const {
     577 40761231009 :         return myAmOpposite;
     578             :     }
     579             : 
     580             :     /// brief return lane index that treats opposite lanes like normal lanes to the left of the forward lanes
     581             :     int getNormalizedLaneIndex();
     582             : 
     583             :     double getCommittedSpeed() const {
     584     7629645 :         return myCommittedSpeed;
     585             :     }
     586             : 
     587             :     /// @brief return the lateral speed of the current lane change maneuver
     588           0 :     double getSpeedLat() const {
     589   542169087 :         return mySpeedLat;
     590             :     }
     591             : 
     592             :     /* @brief reset the angle (in case no lane changing happens in this step
     593             :      * and the maneuver was finished in the previous step) */
     594             :     virtual void resetSpeedLat();
     595             : 
     596             :     /// @brief return the lateral speed of the current lane change maneuver
     597             :     double getAccelerationLat() const {
     598       43188 :         return myAccelerationLat;
     599             :     }
     600             : 
     601             :     /// @brief set the lateral speed and update lateral acceleraton
     602             :     void setSpeedLat(double speedLat);
     603             : 
     604             :     /// @brief decides the next lateral speed depending on the remaining lane change distance to be covered
     605             :     ///        and updates maneuverDist according to lateral safety constraints.
     606             :     virtual double computeSpeedLat(double latDist, double& maneuverDist, bool urgent) const;
     607             : 
     608             :     /// @brief Returns a deceleration value which is used for the estimation of the duration of a lane change.
     609             :     /// @note  Effective only for continuous lane-changing when using attributes myMaxSpeedLatFactor and myMaxSpeedLatStanding. See #3771
     610             :     virtual double getAssumedDecelForLaneChangeDuration() const;
     611             : 
     612             :     /// @brief try to retrieve the given parameter from this laneChangeModel. Throw exception for unsupported key
     613           0 :     virtual std::string getParameter(const std::string& key) const {
     614           0 :         throw InvalidArgument("Parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
     615             :     }
     616             : 
     617             :     /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
     618           0 :     virtual void setParameter(const std::string& key, const std::string& value) {
     619             :         UNUSED_PARAMETER(value);
     620           0 :         throw InvalidArgument("Setting parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
     621             :     }
     622             : 
     623             :     /// reserve extra space for unseen blockers when more tnan one lane change is required
     624           8 :     virtual double getExtraReservation(int /*bestLaneOffset*/) const {
     625           8 :         return 0;
     626             :     }
     627             : 
     628             :     /// @brief Check for commands issued for the vehicle via TraCI and apply the appropriate state changes
     629             :     ///        For the sublane case, this includes setting a new maneuver distance if appropriate.
     630             :     void checkTraCICommands();
     631             : 
     632             :     /// @brief get vehicle position relative to the forward direction lane
     633             :     double getForwardPos() const;
     634             : 
     635             :     bool hasBlueLight() const {
     636   103332175 :         return myHaveBlueLight;
     637             :     }
     638             : 
     639           0 :     virtual LatAlignmentDefinition getDesiredAlignment() const {
     640    88937645 :         return myVehicle.getVehicleType().getPreferredLateralAlignment();
     641             :     }
     642             : 
     643             :     static const double NO_NEIGHBOR;
     644             : 
     645             : protected:
     646             :     virtual bool congested(const MSVehicle* const neighLeader);
     647             : 
     648             :     virtual bool predInteraction(const std::pair<MSVehicle*, double>& leader);
     649             : 
     650             :     virtual bool avoidOvertakeRight() const;
     651             : 
     652             :     /// @brief whether the influencer cancels the given request
     653             :     bool cancelRequest(int state, int laneOffset);
     654             : 
     655             :     /// @brief return the max of maxSpeedLat and lcMaxSpeedLatStanding
     656             :     double getMaxSpeedLat2() const;
     657             : 
     658             :     /** @brief Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration
     659             :      *         and stores it into myLCAccelerationAdvices.
     660             :      *  @note  This construction was introduced to deal with action step lengths,
     661             :      *         where operation on the speed in the next sim step had to be replaced by acceleration
     662             :      *         throughout the next action step.
     663             :      */
     664             :     void addLCSpeedAdvice(const double vSafe, bool ownAdvice = true);
     665             : 
     666             : 
     667             : protected:
     668             :     /// @brief The vehicle this lane-changer belongs to
     669             :     MSVehicle& myVehicle;
     670             : 
     671             :     /// @brief The current state of the vehicle
     672             :     int myOwnState;
     673             :     /// @brief lane changing state from the previous simulation step
     674             :     int myPreviousState;
     675             :     /// @brief lane changing state from step before the previous simulation step
     676             :     int myPreviousState2;
     677             : 
     678             :     std::pair<int, int> mySavedStateRight;
     679             :     std::pair<int, int> mySavedStateCenter;
     680             :     std::pair<int, int> mySavedStateLeft;
     681             :     int myCanceledStateRight;
     682             :     int myCanceledStateCenter;
     683             :     int myCanceledStateLeft;
     684             : 
     685             :     /// @brief Cached info on lc-relevant neighboring vehicles
     686             :     /// @{
     687             :     std::shared_ptr<MSLeaderDistanceInfo> myLeftFollowers;
     688             :     std::shared_ptr<MSLeaderDistanceInfo> myLeftLeaders;
     689             :     std::shared_ptr<MSLeaderDistanceInfo> myRightFollowers;
     690             :     std::shared_ptr<MSLeaderDistanceInfo> myRightLeaders;
     691             :     /// @}
     692             : 
     693             :     /// @brief the current lateral speed
     694             :     double mySpeedLat;
     695             : 
     696             :     /// @brief the current lateral acceleration
     697             :     double myAccelerationLat;
     698             : 
     699             :     /// @brief the current angle offset resulting from lane change and sigma
     700             :     double myAngleOffset;
     701             : 
     702             :     /// @brief the angle offset of the previous time step resulting from lane change and sigma
     703             :     double myPreviousAngleOffset;
     704             : 
     705             :     /// @brief the speed when committing to a change maneuver
     706             :     double myCommittedSpeed;
     707             : 
     708             :     /// @brief progress of the lane change maneuver 0:started, 1:complete
     709             :     double myLaneChangeCompletion;
     710             : 
     711             :     /// @brief direction of the lane change maneuver -1 means right, 1 means left
     712             :     int myLaneChangeDirection;
     713             : 
     714             :     /// @brief whether the vehicle has already moved this step
     715             :     bool myAlreadyChanged;
     716             : 
     717             :     /// @brief A lane that is partially occupied by the front of the vehicle but that is not the primary lane
     718             :     MSLane* myShadowLane;
     719             :     /* @brief Lanes that are partially (laterally) occupied by the back of the
     720             :      * vehicle (analogue to MSVehicle::myFurtherLanes) */
     721             :     std::vector<MSLane*> myShadowFurtherLanes;
     722             :     std::vector<double> myShadowFurtherLanesPosLat;
     723             : 
     724             : 
     725             :     /// @brief The target lane for the vehicle's current maneuver
     726             :     /// @note  This is used by the sublane model to register the vehicle at lanes,
     727             :     ///        it will reach within the current action step, so vehicles on that lane
     728             :     ///        may react to the started lc-maneuver during the car-following process.
     729             :     ///        If the shadow lane is the same as the lc maneuver target, myTargetLane is
     730             :     ///        set to nullptr.
     731             :     ///        The current shadow lanes and further lanes should always be updated before updating the target lane.
     732             :     MSLane* myTargetLane;
     733             : 
     734             :     /* @brief Further upstream lanes that are affected by the vehicle's maneuver (analogue to MSVehicle::myFurtherLanes)
     735             :      * @note  If myTargetLane==nullptr, we may assume myFurtherTargetLanes.size()==0, otherwise we have
     736             :      *        myFurtherTargetLanes.size() == myVehicle.getFurtherLanes.size()
     737             :      *        Here it may occur that an element myFurtherTargetLanes[i]==nullptr if myFurtherLanes[i] has
     738             :      *        no parallel lane in the change direction.
     739             :      *  */
     740             :     std::vector<MSLane*> myFurtherTargetLanes;
     741             : 
     742             :     /// @brief The vehicle's car following model
     743             :     inline const MSCFModel& getCarFollowModel() const {
     744   511206547 :         return myVehicle.getCarFollowModel();
     745             :     }
     746             : 
     747             :     /// @brief the type of this model
     748             :     const LaneChangeModel myModel;
     749             : 
     750             :     /// @brief list of lanes where the shadow vehicle is partial occupator
     751             :     std::vector<MSLane*> myPartiallyOccupatedByShadow;
     752             : 
     753             :     /* @brief list of lanes where there is no shadow vehicle partial occupator
     754             :      * (when changing to a lane that has no predecessor) */
     755             :     std::vector<MSLane*> myNoPartiallyOccupatedByShadow;
     756             : 
     757             :     /// @brief the minimum lateral gaps to other vehicles that were found when last changing to the left and right
     758             :     double myLastLateralGapLeft;
     759             :     double myLastLateralGapRight;
     760             : 
     761             :     /// @brief the actual minimum longitudinal distances to vehicles on the target lane
     762             :     double myLastLeaderGap;
     763             :     double myLastFollowerGap;
     764             :     /// @brief the minimum longitudinal distances to vehicles on the target lane that would be necessary for stringent security
     765             :     double myLastLeaderSecureGap;
     766             :     double myLastFollowerSecureGap;
     767             :     /// @brief acutal and secure distance to closest leader vehicle on the original when performing lane change
     768             :     double myLastOrigLeaderGap;
     769             :     double myLastOrigLeaderSecureGap;
     770             :     /// @brief speeds of surrounding vehicles at the time of lane change
     771             :     double myLastLeaderSpeed;
     772             :     double myLastFollowerSpeed;
     773             :     double myLastOrigLeaderSpeed;
     774             : 
     775             :     /// @brief Flag to prevent resetting the memorized values for LC relevant gaps until the LC output is triggered
     776             :     ///        in the case of continuous LC.
     777             :     bool myDontResetLCGaps;
     778             : 
     779             :     // @brief the maximum lateral speed for non-strategic changes when standing
     780             :     double myMaxSpeedLatStanding;
     781             :     // @brief the factor of maximum lateral speed to longitudinal speed for non-strategic changes
     782             :     double myMaxSpeedLatFactor;
     783             :     // @brief the maximum lateral maneuver distance when standing
     784             :     double myMaxDistLatStanding;
     785             :     // @brief factor for lane keeping imperfection
     786             :     double mySigma;
     787             :     // allow overtaking right even though it is prohibited
     788             :     double myOvertakeRightParam;
     789             : 
     790             :     /// @brief whether this vehicle is driving with special permissions and behavior
     791             :     bool myHaveBlueLight;
     792             : 
     793             :     /* @brief to be called by derived classes in their changed() method.
     794             :      * If dir=0 is given, the current value remains unchanged */
     795             :     void initLastLaneChangeOffset(int dir);
     796             : 
     797             :     /* @brief vector of LC-related acceleration recommendations combined with a
     798             :      * boolean to indicate whether the advice is from ego or someone else.
     799             :      * Filled in wantsChange() and applied in patchSpeed() */
     800             :     std::vector<std::pair<double, bool> > myLCAccelerationAdvices;
     801             : 
     802             :     /// @brief whether overtaking on the right is permitted
     803             :     static bool myAllowOvertakingRight;
     804             : 
     805             :     /// @brief whether to record lane-changing
     806             :     static bool myLCOutput;
     807             :     static bool myLCStartedOutput;
     808             :     static bool myLCEndedOutput;
     809             :     static bool myLCXYOutput;
     810             : 
     811             : 
     812             : private:
     813             :     /* @brief information how long ago the vehicle has performed a lane-change,
     814             :      * sign indicates direction of the last change
     815             :      */
     816             :     SUMOTime myLastLaneChangeOffset;
     817             : 
     818             :     /// @brief links which are approached by the shadow vehicle
     819             :     mutable std::vector<MSLink*> myApproachedByShadow;
     820             : 
     821             :     /// @brief whether the vehicle is driving in the opposite direction
     822             :     bool myAmOpposite;
     823             : 
     824             :     /// @brief The complete lateral distance the vehicle wants to travel to finish its maneuver
     825             :     ///        Only used by sublane model, currently.
     826             :     double myManeuverDist;
     827             : 
     828             :     /// @brief Maneuver distance from the previous simulation step
     829             :     double myPreviousManeuverDist;
     830             : 
     831             : 
     832             : private:
     833             :     /// @brief Invalidated assignment operator
     834             :     MSAbstractLaneChangeModel& operator=(const MSAbstractLaneChangeModel& s);
     835             : };

Generated by: LCOV version 1.14