/****************************************************************************/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 MSLeaderInfo.h14/// @author Jakob Erdmann15/// @date Oct 201516///17// Information about vehicles ahead (may be multiple vehicles if18// lateral-resolution is active)19/****************************************************************************/20#pragma once21#include <config.h>2223#include <string>24#include <vector>25#include <utils/common/StdDefs.h>2627// ===========================================================================28// class declarations29// ===========================================================================30class MSVehicle;31class MSLane;323334// ===========================================================================35// type definitions36// ===========================================================================37typedef std::pair<const MSVehicle*, double> CLeaderDist;38typedef std::pair<MSVehicle*, double> LeaderDist;394041// ===========================================================================42// class definitions43// ===========================================================================44/**45* @class MSLeaderInfo46*/47class MSLeaderInfo {48public:49/// Constructor50MSLeaderInfo(const double laneWidth, const MSVehicle* ego = nullptr, const double latOffset = 0.);5152/// Destructor53virtual ~MSLeaderInfo();5455/* @brief adds this vehicle as a leader in the appropriate sublanes56* @param[in] veh The vehicle to add57* @param[in] beyond Whether the vehicle is beyond the existing leaders (and thus may be shadowed by them)58* @param[in] latOffset The lateral offset that must be added to the position of veh59* @return The number of free sublanes60*/61virtual int addLeader(const MSVehicle* veh, bool beyond, double latOffset = 0.);6263/// @brief discard all information64virtual void clear();6566/* @brief returns sublanes occupied by veh67* @param[in] veh The vehicle to check68* @param[in] latOffset The offset value to add to the vehicle position69* @param[out] rightmost The rightmost sublane occupied by veh70* @param[out] leftmost The rightmost sublane occupied by veh71*/72void getSubLanes(const MSVehicle* veh, double latOffset, int& rightmost, int& leftmost) const;7374/* @brief returns the sublane boundaries of the ith sublane75* @param[in] sublane The sublane to check76* @param[in] latOffset The offset value to add to the result77* @param[out] rightSide The right border of the given sublane78* @param[out] leftSide The left border of the given sublane79*/80void getSublaneBorders(int sublane, double latOffset, double& rightSide, double& leftSide) const;8182/// @brief return the vehicle for the given sublane83const MSVehicle* operator[](int sublane) const;8485int numSublanes() const {86return (int)myVehicles.size();87}8889int numFreeSublanes() const {90return myFreeSublanes;91}9293bool hasVehicles() const {94return myHasVehicles;95}9697const std::vector<const MSVehicle*>& getVehicles() const {98return myVehicles;99}100101int getSublaneOffset() const {102return myOffset;103}104105/// @brief set number of sublanes by which to shift positions106void setSublaneOffset(int offset);107108/// @brief whether a stopped vehicle is leader109bool hasStoppedVehicle() const;110111/// @brief whether the given vehicle is part of this leaderInfo112bool hasVehicle(const MSVehicle* veh) const;113114/// @brief remove vehicles that are driving in the opposite direction (fully or partially) on the given lane115void removeOpposite(const MSLane* lane);116117/// @brief print a debugging representation118virtual std::string toString() const;119120protected:121122/// @brief the width of the lane to which this instance applies123// @note: not const to simplify assignment124double myWidth;125126/// @brief an extra offset for shifting the interpretation of sublane borders (default [0,myWidth])127int myOffset;128129std::vector<const MSVehicle*> myVehicles;130131/// @brief the number of free sublanes132// if an ego vehicle is given in the constructor, the number of free133// sublanes of those covered by ego134int myFreeSublanes;135136/// @brief borders of the ego vehicle for filtering of free sublanes137int egoRightMost;138int egoLeftMost;139140bool myHasVehicles;141142};143144145/// @brief saves leader/follower vehicles and their distances relative to an ego vehicle146class MSLeaderDistanceInfo : public MSLeaderInfo {147public:148/// Constructor149MSLeaderDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset);150151/// @brief Construct for the non-sublane-case152MSLeaderDistanceInfo(const CLeaderDist& cLeaderDist, const double laneWidth);153154/// Destructor155virtual ~MSLeaderDistanceInfo();156157/* @brief adds this vehicle as a leader in the appropriate sublanes158* @param[in] veh The vehicle to add159* @param[in] gap The gap between the egoFront+minGap to the back of veh160* or from the back of ego to the front+minGap of veh161* @param[in] latOffset The lateral offset that must be added to the position of veh162* @param[in] sublane The single sublane to which this leader shall be checked (-1 means: check for all)163* @return The number of free sublanes164*/165virtual int addLeader(const MSVehicle* veh, double gap, double latOffset = 0, int sublane = -1);166167virtual int addLeader(const MSVehicle* veh, bool beyond, double latOffset = 0) {168UNUSED_PARAMETER(veh);169UNUSED_PARAMETER(beyond);170UNUSED_PARAMETER(latOffset);171throw ProcessError(TL("Method not supported"));172}173174/// @brief updatd empty sublanes with vehicles and gaps from other175virtual void addLeaders(MSLeaderDistanceInfo& other);176177/// @brief discard all information178virtual void clear();179180/// @brief return the vehicle and its distance for the given sublane181CLeaderDist operator[](int sublane) const;182183/// @brief print a debugging representation184virtual std::string toString() const;185186const std::vector<double>& getDistances() const {187return myDistances;188}189190/// @brief subtract vehicle length from all gaps if the leader vehicle is driving in the opposite direction191void fixOppositeGaps(bool isFollower);192193/// @brief add given value to all gaps194void patchGaps(double amount);195196/// @brief return vehicle with the smalles gap197CLeaderDist getClosest() const;198199void moveSamePosTo(const MSVehicle* ego, MSLeaderDistanceInfo& other);200201/// @brief return minimum distance to a stopped vehicle or max double202double getMinDistToStopped() const;203204205protected:206207std::vector<double> myDistances;208209};210211212/* @brief saves follower vehicles and their distances as well as their required gap relative to an ego vehicle213* when adding new followers, the one with the largest required gap is recored214* (rather than the one with the smallest gap) */215class MSCriticalFollowerDistanceInfo : public MSLeaderDistanceInfo {216public:217/// Constructor218MSCriticalFollowerDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset, const bool haveOppositeLeaders = false);219220/// Destructor221virtual ~MSCriticalFollowerDistanceInfo();222223/* @brief adds this vehicle as a follower in the appropriate sublanes224* @param[in] veh The vehicle to add225* @param[in] ego The vehicle which is being followed226* @param[in] gap The distance from the back of ego to the follower227* @param[in] latOffset The lateral offset that must be added to the position of veh228* @param[in] sublane The single sublane to which this leader shall be checked (-1 means: check for all)229* @return The number of free sublanes230*/231int addFollower(const MSVehicle* veh, const MSVehicle* ego, double gap, double latOffset = 0, int sublane = -1);232233virtual int addLeader(const MSVehicle* veh, double gap, double latOffset = 0, int sublane = -1) {234UNUSED_PARAMETER(veh);235UNUSED_PARAMETER(gap);236UNUSED_PARAMETER(latOffset);237UNUSED_PARAMETER(sublane);238throw ProcessError(TL("Method not supported"));239}240241virtual int addLeader(const MSVehicle* veh, bool beyond, double latOffset = 0) {242UNUSED_PARAMETER(veh);243UNUSED_PARAMETER(beyond);244UNUSED_PARAMETER(latOffset);245throw ProcessError(TL("Method not supported"));246}247248/// @brief discard all information249void clear();250251/// @brief print a debugging representation252std::string toString() const;253254protected:255256// @brief the differences between requriedGap and actual gap for each of the followers257std::vector<double> myMissingGaps;258259// @brief whether this Info objects tracks leaders instead of followers260bool myHaveOppositeLeaders;261262};263264265