LCOV - code coverage report
Current view: top level - src/microsim/lcmodels - MSAbstractLaneChangeModel.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.0 % 87 60
Test Date: 2024-12-21 15:45:41 Functions: 22.2 % 18 4

            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    191115031 :             : myLeader(leader), myNeighLeader(neighLead),
      62    191115031 :               myNeighFollower(neighFollow) { }
      63              : 
      64              : 
      65              :         /// @brief Destructor
      66    191115031 :         ~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      2059511 :         void* informNeighLeader(void* info, MSVehicle* sender) {
      86              :             assert(myNeighLeader != 0);
      87      2059511 :             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      1729607 :         void* informNeighFollower(void* info, MSVehicle* sender) {
      97              :             assert(myNeighFollower != 0);
      98      1729607 :             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    220573209 :         StateAndDist(int _state, double _latDist, double _targetDist, int _dir) :
     123    220573209 :             state(_state),
     124    220573209 :             latDist(_latDist),
     125    220573209 :             maneuverDist(_targetDist),
     126    220573209 :             dir(_dir) {}
     127              : 
     128              :         bool sameDirection(const StateAndDist& other) const {
     129      3850861 :             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       667689 :     virtual int checkChangeBeforeCommitting(const MSVehicle* veh, int state) const {
     156              :         UNUSED_PARAMETER(veh);
     157              :         UNUSED_PARAMETER(state);
     158       667689 :         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      5823924 :         return myLCOutput;
     174              :     }
     175              : 
     176              :     /// @brief whether start of maneuvers shall be recorede
     177              :     static bool outputLCStarted() {
     178       394832 :         return myLCStartedOutput;
     179              :     }
     180              : 
     181              :     /// @brief whether start of maneuvers shall be recorede
     182              :     static bool outputLCEnded() {
     183       135218 :         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    784533084 :         return myOwnState;
     197              :     }
     198              : 
     199              :     inline int getPrevState() const {
     200              :         /// at the time of this call myPreviousState already holds the new value
     201     74305555 :         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        16059 :         if (dir == -1) {
     217         5482 :             return mySavedStateRight;
     218        10577 :         } else if (dir == 0) {
     219         5095 :             return mySavedStateCenter;
     220              :         } else {
     221         5482 :             return mySavedStateLeft;
     222              :         }
     223              :     }
     224              : 
     225              :     void saveLCState(const int dir, int stateWithoutTraCI, const int state) {
     226    309490467 :         int canceledStrategic = getCanceledState(dir);
     227              :         // avoid conflicting directions
     228    300697785 :         if ((canceledStrategic & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
     229              :             stateWithoutTraCI = canceledStrategic;
     230              :         }
     231              :         const auto pair = std::make_pair(stateWithoutTraCI, state);
     232    296301444 :         if (dir == -1) {
     233              :             mySavedStateRight = pair;
     234    191036149 :         } 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    697796168 :         if (dir == -1) {
     260    254461274 :             return myCanceledStateRight;
     261    443334894 :         } else if (dir == 0) {
     262    153940840 :             return myCanceledStateCenter;
     263              :         } else {
     264    289394054 :             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    310309703 :         if (myLastLaneChangeOffset > 0) {
     402     49670920 :             myLastLaneChangeOffset += DELTA_T;
     403    260638783 :         } else if (myLastLaneChangeOffset < 0) {
     404     34968825 :             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  10286878402 :         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   3884054207 :         return myTargetLane;
     434              :     }
     435              : 
     436              :     const std::vector<MSLane*>& getFurtherTargetLanes() const {
     437            0 :         return myFurtherTargetLanes;
     438              :     }
     439              : 
     440              :     inline SUMOTime getLastLaneChangeOffset() const {
     441        24762 :         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       565862 :         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   3583346421 :         return myLaneChangeCompletion < (1 - NUMERICAL_EPS);
     469              :     }
     470              : 
     471              :     /// @brief Get the current lane change completion ratio
     472              :     inline double getLaneChangeCompletion() const {
     473       187910 :         return myLaneChangeCompletion;
     474              :     }
     475              : 
     476              :     /// @brief return the direction of the current lane change maneuver
     477              :     inline int getLaneChangeDirection() const {
     478       808532 :         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    620489452 :         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    620489452 :         myPreviousAngleOffset = angleOffset;
     500              :     }
     501              : 
     502              :     /// @brief reset the flag whether a vehicle already moved to false
     503              :     inline bool alreadyChanged() const {
     504    311695717 :         return myAlreadyChanged;
     505              :     }
     506              : 
     507              :     /// @brief reset the flag whether a vehicle already moved to false
     508              :     void resetChanged() {
     509    551248047 :         myAlreadyChanged = false;
     510    551248047 :     }
     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  39823431342 :         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      7522288 :         return myCommittedSpeed;
     585              :     }
     586              : 
     587              :     /// @brief return the lateral speed of the current lane change maneuver
     588            0 :     double getSpeedLat() const {
     589    542274393 :         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        54588 :         return myAccelerationLat;
     599              :     }
     600              : 
     601              :     double getStrategicLookahead() const {
     602     14413021 :         return myStrategicLookahead;
     603              :     }
     604              : 
     605              :     /// @brief set the lateral speed and update lateral acceleraton
     606              :     void setSpeedLat(double speedLat);
     607              : 
     608              :     /// @brief decides the next lateral speed depending on the remaining lane change distance to be covered
     609              :     ///        and updates maneuverDist according to lateral safety constraints.
     610              :     virtual double computeSpeedLat(double latDist, double& maneuverDist, bool urgent) const;
     611              : 
     612              :     /// @brief Returns a deceleration value which is used for the estimation of the duration of a lane change.
     613              :     /// @note  Effective only for continuous lane-changing when using attributes myMaxSpeedLatFactor and myMaxSpeedLatStanding. See #3771
     614              :     virtual double getAssumedDecelForLaneChangeDuration() const;
     615              : 
     616              :     /// @brief try to retrieve the given parameter from this laneChangeModel. Throw exception for unsupported key
     617            0 :     virtual std::string getParameter(const std::string& key) const {
     618            0 :         throw InvalidArgument("Parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
     619              :     }
     620              : 
     621              :     /// @brief try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
     622            0 :     virtual void setParameter(const std::string& key, const std::string& value) {
     623              :         UNUSED_PARAMETER(value);
     624            0 :         throw InvalidArgument("Setting parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
     625              :     }
     626              : 
     627              :     /// reserve extra space for unseen blockers when more tnan one lane change is required
     628            8 :     virtual double getExtraReservation(int /*bestLaneOffset*/) const {
     629            8 :         return 0;
     630              :     }
     631              : 
     632              :     /// @brief Check for commands issued for the vehicle via TraCI and apply the appropriate state changes
     633              :     ///        For the sublane case, this includes setting a new maneuver distance if appropriate.
     634              :     void checkTraCICommands();
     635              : 
     636              :     /// @brief get vehicle position relative to the forward direction lane
     637              :     double getForwardPos() const;
     638              : 
     639              :     bool hasBlueLight() const {
     640    108101737 :         return myHaveBlueLight;
     641              :     }
     642              : 
     643            0 :     virtual LatAlignmentDefinition getDesiredAlignment() const {
     644     89324593 :         return myVehicle.getVehicleType().getPreferredLateralAlignment();
     645              :     }
     646              : 
     647              :     static const double NO_NEIGHBOR;
     648              :     static const double UNDEFINED_LOOKAHEAD;
     649              : 
     650              : protected:
     651              :     virtual bool congested(const MSVehicle* const neighLeader);
     652              : 
     653              :     virtual bool predInteraction(const std::pair<MSVehicle*, double>& leader);
     654              : 
     655              :     virtual bool avoidOvertakeRight() const;
     656              : 
     657              :     /// @brief whether the influencer cancels the given request
     658              :     bool cancelRequest(int state, int laneOffset);
     659              : 
     660              :     /// @brief return the max of maxSpeedLat and lcMaxSpeedLatStanding
     661              :     double getMaxSpeedLat2() const;
     662              : 
     663              :     /** @brief Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration
     664              :      *         and stores it into myLCAccelerationAdvices.
     665              :      *  @note  This construction was introduced to deal with action step lengths,
     666              :      *         where operation on the speed in the next sim step had to be replaced by acceleration
     667              :      *         throughout the next action step.
     668              :      */
     669              :     void addLCSpeedAdvice(const double vSafe, bool ownAdvice = true);
     670              : 
     671              : 
     672              : protected:
     673              :     /// @brief The vehicle this lane-changer belongs to
     674              :     MSVehicle& myVehicle;
     675              : 
     676              :     /// @brief The current state of the vehicle
     677              :     int myOwnState;
     678              :     /// @brief lane changing state from the previous simulation step
     679              :     int myPreviousState;
     680              :     /// @brief lane changing state from step before the previous simulation step
     681              :     int myPreviousState2;
     682              : 
     683              :     std::pair<int, int> mySavedStateRight;
     684              :     std::pair<int, int> mySavedStateCenter;
     685              :     std::pair<int, int> mySavedStateLeft;
     686              :     int myCanceledStateRight;
     687              :     int myCanceledStateCenter;
     688              :     int myCanceledStateLeft;
     689              : 
     690              :     /// @brief Cached info on lc-relevant neighboring vehicles
     691              :     /// @{
     692              :     std::shared_ptr<MSLeaderDistanceInfo> myLeftFollowers;
     693              :     std::shared_ptr<MSLeaderDistanceInfo> myLeftLeaders;
     694              :     std::shared_ptr<MSLeaderDistanceInfo> myRightFollowers;
     695              :     std::shared_ptr<MSLeaderDistanceInfo> myRightLeaders;
     696              :     /// @}
     697              : 
     698              :     /// @brief the current lateral speed
     699              :     double mySpeedLat;
     700              : 
     701              :     /// @brief the current lateral acceleration
     702              :     double myAccelerationLat;
     703              : 
     704              :     /// @brief the current angle offset resulting from lane change and sigma
     705              :     double myAngleOffset;
     706              : 
     707              :     /// @brief the angle offset of the previous time step resulting from lane change and sigma
     708              :     double myPreviousAngleOffset;
     709              : 
     710              :     /// @brief the speed when committing to a change maneuver
     711              :     double myCommittedSpeed;
     712              : 
     713              :     /// @brief progress of the lane change maneuver 0:started, 1:complete
     714              :     double myLaneChangeCompletion;
     715              : 
     716              :     /// @brief direction of the lane change maneuver -1 means right, 1 means left
     717              :     int myLaneChangeDirection;
     718              : 
     719              :     /// @brief whether the vehicle has already moved this step
     720              :     bool myAlreadyChanged;
     721              : 
     722              :     /// @brief A lane that is partially occupied by the front of the vehicle but that is not the primary lane
     723              :     MSLane* myShadowLane;
     724              :     /* @brief Lanes that are partially (laterally) occupied by the back of the
     725              :      * vehicle (analogue to MSVehicle::myFurtherLanes) */
     726              :     std::vector<MSLane*> myShadowFurtherLanes;
     727              :     std::vector<double> myShadowFurtherLanesPosLat;
     728              : 
     729              : 
     730              :     /// @brief The target lane for the vehicle's current maneuver
     731              :     /// @note  This is used by the sublane model to register the vehicle at lanes,
     732              :     ///        it will reach within the current action step, so vehicles on that lane
     733              :     ///        may react to the started lc-maneuver during the car-following process.
     734              :     ///        If the shadow lane is the same as the lc maneuver target, myTargetLane is
     735              :     ///        set to nullptr.
     736              :     ///        The current shadow lanes and further lanes should always be updated before updating the target lane.
     737              :     MSLane* myTargetLane;
     738              : 
     739              :     /* @brief Further upstream lanes that are affected by the vehicle's maneuver (analogue to MSVehicle::myFurtherLanes)
     740              :      * @note  If myTargetLane==nullptr, we may assume myFurtherTargetLanes.size()==0, otherwise we have
     741              :      *        myFurtherTargetLanes.size() == myVehicle.getFurtherLanes.size()
     742              :      *        Here it may occur that an element myFurtherTargetLanes[i]==nullptr if myFurtherLanes[i] has
     743              :      *        no parallel lane in the change direction.
     744              :      *  */
     745              :     std::vector<MSLane*> myFurtherTargetLanes;
     746              : 
     747              :     /// @brief The vehicle's car following model
     748              :     inline const MSCFModel& getCarFollowModel() const {
     749    558933937 :         return myVehicle.getCarFollowModel();
     750              :     }
     751              : 
     752              :     /// @brief the type of this model
     753              :     const LaneChangeModel myModel;
     754              : 
     755              :     /// @brief list of lanes where the shadow vehicle is partial occupator
     756              :     std::vector<MSLane*> myPartiallyOccupatedByShadow;
     757              : 
     758              :     /* @brief list of lanes where there is no shadow vehicle partial occupator
     759              :      * (when changing to a lane that has no predecessor) */
     760              :     std::vector<MSLane*> myNoPartiallyOccupatedByShadow;
     761              : 
     762              :     /// @brief the minimum lateral gaps to other vehicles that were found when last changing to the left and right
     763              :     double myLastLateralGapLeft;
     764              :     double myLastLateralGapRight;
     765              : 
     766              :     /// @brief the actual minimum longitudinal distances to vehicles on the target lane
     767              :     double myLastLeaderGap;
     768              :     double myLastFollowerGap;
     769              :     /// @brief the minimum longitudinal distances to vehicles on the target lane that would be necessary for stringent security
     770              :     double myLastLeaderSecureGap;
     771              :     double myLastFollowerSecureGap;
     772              :     /// @brief acutal and secure distance to closest leader vehicle on the original when performing lane change
     773              :     double myLastOrigLeaderGap;
     774              :     double myLastOrigLeaderSecureGap;
     775              :     /// @brief speeds of surrounding vehicles at the time of lane change
     776              :     double myLastLeaderSpeed;
     777              :     double myLastFollowerSpeed;
     778              :     double myLastOrigLeaderSpeed;
     779              : 
     780              :     /// @brief Flag to prevent resetting the memorized values for LC relevant gaps until the LC output is triggered
     781              :     ///        in the case of continuous LC.
     782              :     bool myDontResetLCGaps;
     783              : 
     784              :     double myStrategicLookahead;
     785              :     // @brief the maximum lateral speed for non-strategic changes when standing
     786              :     double myMaxSpeedLatStanding;
     787              :     // @brief the factor of maximum lateral speed to longitudinal speed for non-strategic changes
     788              :     double myMaxSpeedLatFactor;
     789              :     // @brief the maximum lateral maneuver distance when standing
     790              :     double myMaxDistLatStanding;
     791              :     // @brief factor for lane keeping imperfection
     792              :     double mySigma;
     793              :     // allow overtaking right even though it is prohibited
     794              :     double myOvertakeRightParam;
     795              : 
     796              :     /// @brief whether this vehicle is driving with special permissions and behavior
     797              :     bool myHaveBlueLight;
     798              : 
     799              :     /* @brief to be called by derived classes in their changed() method.
     800              :      * If dir=0 is given, the current value remains unchanged */
     801              :     void initLastLaneChangeOffset(int dir);
     802              : 
     803              :     /* @brief vector of LC-related acceleration recommendations combined with a
     804              :      * boolean to indicate whether the advice is from ego or someone else.
     805              :      * Filled in wantsChange() and applied in patchSpeed() */
     806              :     std::vector<std::pair<double, bool> > myLCAccelerationAdvices;
     807              : 
     808              :     /// @brief whether overtaking on the right is permitted
     809              :     static bool myAllowOvertakingRight;
     810              : 
     811              :     /// @brief whether to record lane-changing
     812              :     static bool myLCOutput;
     813              :     static bool myLCStartedOutput;
     814              :     static bool myLCEndedOutput;
     815              :     static bool myLCXYOutput;
     816              : 
     817              : 
     818              : private:
     819              :     /* @brief information how long ago the vehicle has performed a lane-change,
     820              :      * sign indicates direction of the last change
     821              :      */
     822              :     SUMOTime myLastLaneChangeOffset;
     823              : 
     824              :     /// @brief links which are approached by the shadow vehicle
     825              :     mutable std::vector<MSLink*> myApproachedByShadow;
     826              : 
     827              :     /// @brief whether the vehicle is driving in the opposite direction
     828              :     bool myAmOpposite;
     829              : 
     830              :     /// @brief The complete lateral distance the vehicle wants to travel to finish its maneuver
     831              :     ///        Only used by sublane model, currently.
     832              :     double myManeuverDist;
     833              : 
     834              :     /// @brief Maneuver distance from the previous simulation step
     835              :     double myPreviousManeuverDist;
     836              : 
     837              : 
     838              : private:
     839              :     /// @brief Invalidated assignment operator
     840              :     MSAbstractLaneChangeModel& operator=(const MSAbstractLaneChangeModel& s);
     841              : };
        

Generated by: LCOV version 2.0-1