/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2002-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file MSLaneChangerSublane.h14/// @author Jakob Erdmann15/// @author Leonhard Luecken16/// @date Oct 201517///18// Performs sub-lane changing of vehicles19/****************************************************************************/20#pragma once21#include <config.h>2223#include <microsim/lcmodels/MSAbstractLaneChangeModel.h>24#include "MSLaneChanger.h"252627// ===========================================================================28// class declarations29// ===========================================================================303132// ===========================================================================33// class definitions34// ===========================================================================35/**36* @class MSLaneChangerSublane37* @brief Performs lane changing of vehicles38*/39class MSLaneChangerSublane : public MSLaneChanger {40public:41/// Constructor42MSLaneChangerSublane(const std::vector<MSLane*>* lanes, bool allowChanging);4344/// Destructor.45~MSLaneChangerSublane();4647protected:4849/** Find a new candidate and try to change it. */50virtual bool change();5152/// @brief Initialize the changer before looping over all vehicles.53virtual void initChanger();5455/** After the possible change, update the changer. */56virtual void updateChanger(bool vehHasChanged);5758/** @brief check whether sub-lane changing in the given direction is desirable59* and possible60* @param[in] laneOffset The direction in which changing should be checked61* @param[in] leaders The candidate vehicle's leaders62* @param[in] preb The bestLanse of the candidaet vehicle63* @param[out] latDist The distance by which the vehicle changes laterally64* @param[out] maneuverDist The lateral distance for the complete envisioned maneuver65* (used for maneuver continuation in non-actionsteps).66*/67int checkChangeSublane(68int laneOffset,69LaneChangeAction alternatives,70const std::vector<MSVehicle::LaneQ>& preb,71double& latDist,72double& maneuverDist) const;7374/* @brief call lanechange model to check the merits of an opposite-direction75* change and update state accordingly */76bool checkChangeOpposite(77MSVehicle* vehicle,78int laneOffset,79MSLane* targetLane,80const std::pair<MSVehicle* const, double>& leader,81const std::pair<MSVehicle* const, double>& neighLead,82const std::pair<MSVehicle* const, double>& neighFollow,83const std::vector<MSVehicle::LaneQ>& preb);848586/// @brief Continue a sublane-lane change maneuver and return whether the midpoint was passed in this step87// (used to continue sublane changing in non-action steps).88bool continueChangeSublane(MSVehicle* vehicle, ChangerIt& from);8990/// @brief change by the specified amount and return whether a new lane was entered91bool startChangeSublane(MSVehicle* vehicle, ChangerIt& from, double latDist, double maneuverDist);9293/// @brief check whether the given vehicle has entered the new lane 'to->lane' during a sublane LC-step94bool checkChangeToNewLane(MSVehicle* vehicle, const int direction, ChangerIt from, ChangerIt to);9596/// @brief get leaders for ego on the given lane97MSLeaderDistanceInfo getLeaders(const ChangerIt& target, const MSVehicle* ego) const;9899/// @brief immediately stop lane-changing and register vehicle as unchanged100void abortLCManeuver(MSVehicle* vehicle);101102typedef MSAbstractLaneChangeModel::StateAndDist StateAndDist;103/// @brief helper function that calls checkChangeSublane and sets blocker information104StateAndDist checkChangeHelper(MSVehicle* vehicle, int laneOffset, LaneChangeAction alternatives);105106/// @brief find the closest leader that prevents ego vehicle from passing on the current lane107static std::pair<MSVehicle*, double> findClosestLeader(const MSLeaderDistanceInfo& leaders, const MSVehicle* vehicle);108109/// @brief optional output for start of lane-change maneuvre110void outputLCStarted(MSVehicle* vehicle, ChangerIt& from, ChangerIt& to, int direction, double maneuverDist);111/// @brief optional output for end of lane-change maneuvre112void outputLCEnded(MSVehicle* vehicle, ChangerIt& from, ChangerIt& to, int direction);113114void addOutsideLeaders(const MSVehicle* vehicle, MSLeaderDistanceInfo& leaders) const;115116/// @brief whether checkChangeOpposite was called for the current vehicle117bool myCheckedChangeOpposite;118119private:120/// Default constructor.121MSLaneChangerSublane();122123/// Copy constructor.124MSLaneChangerSublane(const MSLaneChangerSublane&);125126/// Assignment operator.127MSLaneChangerSublane& operator=(const MSLaneChangerSublane&);128};129130131