LCOV - code coverage report
Current view: top level - src/microsim/transportables - MSPModel_Striping.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 97.4 % 39 38
Test Date: 2024-12-21 15:45:41 Functions: 77.8 % 9 7

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2014-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    MSPModel_Striping.h
      15              : /// @author  Jakob Erdmann
      16              : /// @author  Michael Behrisch
      17              : /// @date    Mon, 13 Jan 2014
      18              : ///
      19              : // The pedestrian movement model using stripes on sidewalks
      20              : /****************************************************************************/
      21              : #pragma once
      22              : #include <config.h>
      23              : 
      24              : #include <string>
      25              : #include <limits>
      26              : #include <utils/common/SUMOTime.h>
      27              : #include <utils/common/Command.h>
      28              : #include <utils/options/OptionsCont.h>
      29              : #include <microsim/MSLane.h>
      30              : #include "MSPerson.h"
      31              : #include "MSPModel_Interacting.h"
      32              : 
      33              : // ===========================================================================
      34              : // class declarations
      35              : // ===========================================================================
      36              : class MSNet;
      37              : class MSLink;
      38              : class MSJunction;
      39              : 
      40              : 
      41              : // ===========================================================================
      42              : // class definitions
      43              : // ===========================================================================
      44              : /**
      45              :  * @class MSPModel_Striping
      46              :  * @brief The pedestrian movement model using stripes on sidewalks
      47              :  *
      48              :  */
      49              : class MSPModel_Striping : public MSPModel_Interacting {
      50              : 
      51              :     friend class GUIPerson; // for debugging
      52              : 
      53              : public:
      54              : 
      55       712608 :     struct WalkingAreaPath {
      56       178152 :         WalkingAreaPath(const MSLane* _from, const MSLane* _walkingArea, const MSLane* _to, const PositionVector& _shape, int _dir, double _angleOverride) :
      57       178152 :             from(_from),
      58       178152 :             to(_to),
      59       178152 :             lane(_walkingArea),
      60            0 :             shape(_shape),
      61       178152 :             dir(_dir),
      62       178152 :             angleOverride(_angleOverride),
      63       178152 :             length(_shape.length()) {
      64       178152 :         }
      65              : 
      66              :         const MSLane* const from;
      67              :         const MSLane* const to;
      68              :         const MSLane* const lane; // the walkingArea;
      69              :         const PositionVector shape;
      70              :         const int dir; // the direction when entering this path
      71              :         const double angleOverride;
      72              :         const double length;
      73              : 
      74              :     };
      75              : 
      76              :     typedef std::map<std::pair<const MSLane*, const MSLane*>, const WalkingAreaPath> WalkingAreaPaths;
      77              : 
      78              :     /// @brief Constructor (it should not be necessary to construct more than one instance)
      79              :     MSPModel_Striping(const OptionsCont& oc, MSNet* net);
      80              : 
      81              :     ~MSPModel_Striping();
      82              : 
      83              :     /// @brief register the given person as a pedestrian
      84              :     MSTransportableStateAdapter* add(MSTransportable* transportable, MSStageMoving* stage, SUMOTime now);
      85              : 
      86              :     /// @brief load the state of the given transportable
      87              :     MSTransportableStateAdapter* loadState(MSTransportable* transportable, MSStageMoving* stage, std::istringstream& in);
      88              : 
      89              :     /// @brief model parameters
      90              :     ///@{
      91              : 
      92              :     /// @brief the width of a pedstrian stripe
      93              :     static double stripeWidth;
      94              : 
      95              :     /// @brief the factor for random slow-down
      96              :     static double dawdling;
      97              : 
      98              :     /// @brief the safety buffer to vehicles
      99              :     static double minGapToVehicle;
     100              : 
     101              :     /// @brief intermediate points to smooth out lanes within the walkingarea
     102              :     static int myWalkingAreaDetail;
     103              : 
     104              :     /// @brief the time threshold before becoming jammed
     105              :     static SUMOTime jamTime;
     106              :     static SUMOTime jamTimeCrossing;
     107              :     static SUMOTime jamTimeNarrow;
     108              :     /// @brief the factor on speed when jammed
     109              :     static double jamFactor;
     110              : 
     111              :     /// @brief use old style departPosLat interpretation
     112              :     static bool myLegacyPosLat;
     113              : 
     114              :     /// @brief the distance (in seconds) to look ahead for changing stripes
     115              :     static const double LOOKAHEAD_SAMEDIR;
     116              :     /// @brief the distance (in seconds) to look ahead for changing stripes (regarding oncoming pedestrians)
     117              :     static const double LOOKAHEAD_ONCOMING;
     118              :     /// @brief the distance (in m) to look around for vehicles
     119              :     static const double LOOKAROUND_VEHICLES;
     120              :     /// @brief the distance (in m) to look ahead for obstacles on a subsequent edge
     121              :     static const double LOOKAHEAD_ONCOMING_DIST;
     122              : 
     123              :     /// @brief the utility penalty for moving sideways (corresponds to meters)
     124              :     static const double LATERAL_PENALTY;
     125              : 
     126              :     /// @brief the utility penalty for obstructed (physically blocking me) stripes (corresponds to meters)
     127              :     static const double OBSTRUCTED_PENALTY;
     128              : 
     129              :     /// @brief the utility penalty for inappropriate (reserved for oncoming traffic or may violate my min gap) stripes (corresponds to meters)
     130              :     static const double INAPPROPRIATE_PENALTY;
     131              : 
     132              :     /// @brief the utility penalty for oncoming conflicts on stripes (corresponds to meters)
     133              :     static const double ONCOMING_CONFLICT_PENALTY;
     134              : 
     135              :     /// @brief the minimum utility that indicates obstruction
     136              :     static const double OBSTRUCTION_THRESHOLD;
     137              : 
     138              :     /// @brief the factor by which pedestrian width is reduced when sqeezing past each other
     139              :     static const double SQUEEZE;
     140              : 
     141              :     /// @brief fraction of the leftmost lanes to reserve for oncoming traffic
     142              :     static double RESERVE_FOR_ONCOMING_FACTOR;
     143              :     static double RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS;
     144              :     static double RESERVE_FOR_ONCOMING_MAX;
     145              : 
     146              :     /// @brief whether to use speed limits embedded in the network
     147              :     static bool USE_NET_SPEEDS;
     148              : 
     149              :     /// @brief the time pedestrians take to reach maximum impatience
     150              :     static const double MAX_WAIT_TOLERANCE;
     151              : 
     152              :     /// @brief the fraction of forward speed to be used for lateral movemenk
     153              :     static const double LATERAL_SPEED_FACTOR;
     154              : 
     155              :     /// @brief the minimum distance to the next obstacle in order to start walking after stopped
     156              :     static const double MIN_STARTUP_DIST;
     157              : 
     158              :     ///@}
     159              : 
     160              :     /// @brief Convert the striping to the vehicle lateral position and vice versa.
     161              :     // The striping model uses as lateral position the distance of the center of the pedestrian
     162              :     // to the left boundary of the lane minus a half stripe width, where right is positive.
     163              :     // The vehicle uses the distance to the center of the lane (and left is positive).
     164              :     // The function happens to be self inverse so it can be used to convert in both directions.
     165              :     inline static double posLatConversion(const double posLat, const double laneWidth) {
     166          140 :         return .5 * (laneWidth - stripeWidth) - posLat;
     167              :     }
     168              : 
     169              : 
     170              : protected:
     171              :     static const double DIST_FAR_AWAY;
     172              :     static const double DIST_BEHIND;
     173              :     static const double DIST_OVERLAP;
     174              : 
     175              :     struct Obstacle;
     176              :     class PState;
     177              :     typedef std::vector<Obstacle> Obstacles;
     178              :     typedef std::map<const MSLane*, Obstacles, ComparatorNumericalIdLess> NextLanesObstacles;
     179              :     typedef std::map<const MSLane*, double> MinNextLengths;
     180              : 
     181              :     struct NextLaneInfo {
     182      1528102 :         NextLaneInfo(const MSLane* _lane, const MSLink* _link, int _dir) :
     183      1528102 :             lane(_lane),
     184      1528102 :             link(_link),
     185      1528102 :             dir(_dir) {
     186              :         }
     187              : 
     188       681623 :         NextLaneInfo() :
     189       681623 :             lane(0),
     190       681623 :             link(0),
     191       243773 :             dir(UNDEFINED_DIRECTION) {
     192              :         }
     193              : 
     194              :         /// @brief the next lane to be used
     195              :         const MSLane* lane;
     196              :         /// @brief the link from the current lane to the next lane
     197              :         const MSLink* link;
     198              :         /// @brief the direction on the next lane
     199              :         int dir;
     200              :     };
     201              : 
     202              :     enum ObstacleType {
     203              :         OBSTACLE_NONE = 0,
     204              :         OBSTACLE_PED = 1,
     205              :         OBSTACLE_VEHICLE = 3,
     206              :         OBSTACLE_END = 4,
     207              :         OBSTACLE_NEXTEND = 5,
     208              :         OBSTACLE_LINKCLOSED = 6,
     209              :         OBSTACLE_ARRIVALPOS = 7
     210              :     };
     211              : 
     212              :     /// @brief information regarding surround Pedestrians (and potentially other things)
     213   1853847174 :     struct Obstacle {
     214              :         /// @brief create No-Obstacle
     215              :         Obstacle(int dir, double dist = DIST_FAR_AWAY);
     216              :         /// @brief create an obstacle from ped for ego moving in dir
     217              :         Obstacle(const PState& ped);
     218              :         /// @brief create an obstacle from explicit values
     219              :         Obstacle(double _x, double _speed, ObstacleType _type, const std::string& _description, const double width = 0., const SUMOVehicle* veh = nullptr)
     220      6474125 :             : xFwd(_x + width / 2.), xBack(_x - width / 2.), speed(_speed), type(_type), description(_description), vehicle(veh) {};
     221              : 
     222              :         /// @brief maximal position on the current lane in forward direction
     223              :         double xFwd;
     224              :         /// @brief maximal position on the current lane in backward direction
     225              :         double xBack;
     226              :         /// @brief speed relative to lane direction (positive means in the same direction)
     227              :         double speed;
     228              :         /// @brief whether this obstacle denotes a border, a vehicle or a pedestrian
     229              :         ObstacleType type;
     230              :         /// @brief the id / description of the obstacle
     231              :         std::string description;
     232              :         /// @brief a pointer to the vehicle if this obstacle is one
     233              :         const SUMOVehicle* vehicle = nullptr;
     234              : 
     235              :         bool closer(const Obstacle& o, int dir);
     236              :     };
     237              : 
     238              :     class walkingarea_path_sorter {
     239              :     public:
     240              :         /// comparing operation
     241              :         bool operator()(const WalkingAreaPath* p1, const WalkingAreaPath* p2) const {
     242     14022788 :             if (p1->from->getNumericalID() < p2->from->getNumericalID()) {
     243              :                 return true;
     244              :             }
     245     13877909 :             if (p1->from->getNumericalID() == p2->from->getNumericalID()) {
     246     13780625 :                 if (p1->to->getNumericalID() < p2->to->getNumericalID()) {
     247              :                     return true;
     248              :                 }
     249              :             }
     250              :             return false;
     251              :         }
     252              :     };
     253              : 
     254              : 
     255              :     /**
     256              :      * @class PState
     257              :      * @brief Container for pedestrian state and individual position update function
     258              :      */
     259              :     class PState : public MSPModel_InteractingState {
     260              :     public:
     261              :         PState(MSPerson* person, MSStageMoving* stage, const MSLane* lane);
     262              : 
     263              :         /// @brief constructor for loading state
     264              :         PState(MSPerson* person, MSStageMoving* stage, std::istringstream* in = nullptr);
     265              : 
     266       507030 :         ~PState() {};
     267              :         Position getPosition(const MSStageMoving& stage, SUMOTime now) const;
     268              :         double getAngle(const MSStageMoving& stage, SUMOTime now) const;
     269              :         const MSEdge* getNextEdge(const MSStageMoving& stage) const;
     270              :         void moveTo(MSPerson* p, MSLane* lane, double lanePos, double lanePosLat, SUMOTime t);
     271              :         void moveToXY(MSPerson* p, Position pos, MSLane* lane, double lanePos,
     272              :                       double lanePosLat, double angle, int routeOffset,
     273              :                       const ConstMSEdgeVector& edges, SUMOTime t);
     274              : 
     275              :         /// @brief information about the upcoming lane
     276              :         NextLaneInfo myNLI;
     277              :         /// @brief the current walkingAreaPath or 0
     278              :         const WalkingAreaPath* myWalkingAreaPath;
     279              : 
     280              :         /// @brief return the minimum position on the lane
     281              :         virtual double getMinX(const bool includeMinGap = true) const;
     282              : 
     283              :         /// @brief return the maximum position on the lane
     284              :         virtual double getMaxX(const bool includeMinGap = true) const;
     285              : 
     286              :         /// @brief return the length of the pedestrian
     287              :         double getLength() const;
     288              : 
     289              :         /// @brief return the minimum gap of the pedestrian
     290              :         double getMinGap() const;
     291              : 
     292              :         /// @brief the absolute distance to the end of the lane in walking direction (or to the arrivalPos)
     293              :         double distToLaneEnd() const;
     294              : 
     295              :         /// @brief return whether this pedestrian has passed the end of the current lane and update myRelX if so
     296              :         bool moveToNextLane(SUMOTime currentTime);
     297              : 
     298              :         /// @brief perform position update
     299              :         void walk(const Obstacles& obs, SUMOTime currentTime);
     300              : 
     301              :         /// @brief returns the impatience
     302              :         double getImpatience(SUMOTime now) const;
     303              : 
     304              :         int stripe() const;
     305              :         int otherStripe() const;
     306              : 
     307              :         static int stripe(const double relY);
     308              :         int otherStripe(const double relY) const;
     309              : 
     310              :         /* @brief calculate distance to the given obstacle,
     311              :          * - non-negative values signify an obstacle in front of ego
     312              :          * the special values DIST_OVERLAP and DIST_BEHIND are used to signify
     313              :          * obstacles that overlap and obstacles behind ego respectively
     314              :          * the result is the same regardless of walking direction
     315              :          */
     316              :         double distanceTo(const Obstacle& obs, const bool includeMinGap = true) const;
     317              : 
     318              :         /// @brief replace obstacles in the first vector with obstacles from the second if they are closer to me
     319              :         void mergeObstacles(Obstacles& into, const Obstacles& obs2);
     320              : 
     321              :         /// @brief replace obstacles in the first vector with obstacles from the second if they are closer in the given direction
     322              :         static void mergeObstacles(Obstacles& into, const Obstacles& obs2, int dir, int offset);
     323              : 
     324              :         /// @brief whether the pedestrian may ignore a red light
     325              :         bool ignoreRed(const MSLink* link) const;
     326              : 
     327              :         /// @brief whether the pedestrian should stop at a yellow light
     328              :         bool stopForYellow(const MSLink* link) const;
     329              : 
     330              :         /// @brief return the person width
     331              :         virtual double getWidth() const;
     332              : 
     333    672154397 :         virtual ObstacleType getOType() const {
     334    672154397 :             return OBSTACLE_PED;
     335              :         }
     336              : 
     337              :         /// @brief whether the person is currently being controlled via TraCI
     338              :         bool isRemoteControlled() const;
     339              : 
     340              :         /** @brief Saves the current state into the given stream
     341              :          */
     342              :         void saveState(std::ostringstream& out);
     343              : 
     344              :         const MSLane* getNextCrossing() const;
     345              : 
     346              :         /// @brief return the lateral offset to the lane center
     347     11733401 :         double getLatOffset() const {
     348     11733401 :             return posLatConversion(myPosLat, myLane->getWidth());
     349              :         }
     350              : 
     351              :         inline double getPosLat() const {
     352     11485528 :             return myPosLat;
     353              :         }
     354              : 
     355              :         double getPathLength() const;
     356              :         void reverse(const double pathLength, const double usableWidth);
     357              :         void reset(const double edgePos, const double latPos);
     358              : 
     359              :     protected:
     360              :         /// @brief constructor for PStateVehicle
     361              :         PState();
     362              :     private:
     363              :         /// @brief Invalidated assignment operator.
     364              :         PState& operator=(const PState&) = delete;
     365              :     };
     366              : 
     367              :     class PStateVehicle : public PState {
     368              :     public:
     369              :         PStateVehicle(const MSVehicle* veh, const MSLane* walkingarea, double relX, double relY, double xWidth, double yWidth);
     370              :         const std::string& getID() const;
     371              :         double getMinX(const bool includeMinGap = true) const;
     372              :         double getMaxX(const bool includeMinGap = true) const;
     373              :         double getWidth() const;
     374              : 
     375       463388 :         ObstacleType getOType() const {
     376       463388 :             return OBSTACLE_VEHICLE;
     377              :         }
     378              : 
     379              :         const MSVehicle* getVehicle() const {
     380       463388 :             return myVehicle;
     381              :         }
     382              :     private:
     383              :         const MSVehicle* myVehicle;
     384              :         const double myXWidth;
     385              :         const double myYWidth;
     386              :     };
     387              : 
     388              : 
     389              :     class MovePedestrians : public Command {
     390              :     public:
     391         3885 :         MovePedestrians(MSPModel_Striping* model) : myModel(model) {};
     392         3884 :         ~MovePedestrians() {};
     393              :         SUMOTime execute(SUMOTime currentTime);
     394              :     private:
     395              :         MSPModel_Striping* const myModel;
     396              :     private:
     397              :         /// @brief Invalidated assignment operator.
     398              :         MovePedestrians& operator=(const MovePedestrians&) = delete;
     399              :     };
     400              : 
     401              :     /// @brief sorts the persons by position on the lane. If dir is forward, higher x positions come first.
     402              :     class by_xpos_sorter {
     403              :     public:
     404              :         /// constructor
     405              :         by_xpos_sorter(int dir): myDir(dir) {}
     406              : 
     407              :     public:
     408              :         /// comparing operation
     409   2940167416 :         bool operator()(const MSPModel_InteractingState* p1, const MSPModel_InteractingState* p2) const {
     410   2940167416 :             if (p1->getEdgePos(0) != p2->getEdgePos(0)) {
     411   1410742033 :                 return myDir * p1->getEdgePos(0) > myDir * p2->getEdgePos(0);
     412              :             }
     413   1529425383 :             return p1->getID() < p2->getID();
     414              :         }
     415              : 
     416              :     private:
     417              :         const int myDir;
     418              :     };
     419              : 
     420              : 
     421              :     /// @brief move all pedestrians forward and advance to the next lane if applicable
     422              :     void moveInDirection(SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir);
     423              : 
     424              :     /// @brief move pedestrians forward on one lane
     425              :     void moveInDirectionOnLane(Pedestrians& pedestrians, const MSLane* lane, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir, bool debug);
     426              : 
     427              :     /// @brief handle arrivals and lane advancement
     428              :     void arriveAndAdvance(Pedestrians& pedestrians, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir);
     429              : 
     430              :     const ActiveLanes& getActiveLanes() {
     431              :         return myActiveLanes;
     432              :     }
     433              : 
     434              : private:
     435              :     static void DEBUG_PRINT(const Obstacles& obs);
     436              : 
     437              :     /// @brief returns the direction in which these lanes are connectioned or 0 if they are not
     438              :     static int connectedDirection(const MSLane* from, const MSLane* to);
     439              : 
     440              :     /** @brief computes the successor lane for the given pedestrian and sets the
     441              :      * link as well as the direction to use on the succesor lane
     442              :      * @param[in] currentLane The lane the pedestrian is currently on
     443              :      * @param[in] ped The pedestrian for which to compute the next lane
     444              :      */
     445              :     static NextLaneInfo getNextLane(const PState& ped, const MSLane* currentLane, const MSLane* prevLane);
     446              : 
     447              :     /// @brief return the next walkingArea in the given direction
     448              :     static const MSLane* getNextWalkingArea(const MSLane* currentLane, const int dir, const MSLink*& link);
     449              : 
     450              :     static void initWalkingAreaPaths(const MSNet* net);
     451              : 
     452              :     /// @brief creates and inserts all paths into the given map
     453              :     static void insertWalkArePaths(const MSEdge* edge, WalkingAreaPaths& into);
     454              : 
     455              :     static const WalkingAreaPath* getWalkingAreaPath(const MSEdge* walkingArea, const MSLane* before, const MSLane* after);
     456              : 
     457              :     /// @brief return an arbitrary path across the given walkingArea
     458              :     static const WalkingAreaPath* getArbitraryPath(const MSEdge* walkingArea);
     459              : 
     460              :     static const WalkingAreaPath* guessPath(const MSEdge* walkingArea, const MSEdge* before, const MSEdge* after);
     461              : 
     462              :     /// @brief return the maximum number of pedestrians walking side by side
     463              :     static int numStripes(const MSLane* lane);
     464              : 
     465              :     static Obstacles getNeighboringObstacles(const Pedestrians& pedestrians, int egoIndex, int stripes);
     466              : 
     467              :     const Obstacles& getNextLaneObstacles(NextLanesObstacles& nextLanesObs, const MSLane* lane, const MSLane* nextLane, int stripes,
     468              :                                           int nextDir, double currentLength, int currentDir);
     469              : 
     470              :     static void transformToCurrentLanePositions(Obstacles& o, int currentDir, int nextDir, double currentLength, double nextLength);
     471              : 
     472              :     static void addCloserObstacle(Obstacles& obs, double x, int stripe, int numStripes, const std::string& id, double width, int dir, ObstacleType type);
     473              : 
     474              :     /* @brief compute stripe-offset to transform relY values from a lane with origStripes into a lane wit destStrips
     475              :      * @note this is called once for transforming nextLane peds to into the current system as obstacles and another time
     476              :      * (in reverse) to transform the pedestrian coordinates into the nextLane-coordinates when changing lanes
     477              :      */
     478              :     static int getStripeOffset(int origStripes, int destStripes, bool addRemainder);
     479              : 
     480              :     ///@brief add vehicles driving across
     481              :     static bool addCrossingVehs(const MSLane* crossing, int stripes, double lateral_offset, int dir, Obstacles& crossingVehs, bool prio);
     482              : 
     483              :     ///@brief retrieve vehicle obstacles on the given lane
     484              :     static Obstacles getVehicleObstacles(const MSLane* lane, int dir, PState* ped = 0);
     485              : 
     486              :     static bool addVehicleFoe(const MSVehicle* veh, const MSLane* walkingarea, const Position& relPos, double xWidth, double yWidth, double lateral_offset,
     487              :                               double minY, double maxY, Pedestrians& toDelete, Pedestrians& transformedPeds);
     488              : 
     489              :     static int getReserved(int stripes, double factor);
     490              : 
     491              :     /// @brief register pedestrian approach with the junction model
     492              :     static void registerCrossingApproach(const PState& ped, const MSLane* crossing, const MSLane* beforeWA);
     493              : 
     494              : private:
     495              :     /// @brief store for walkinArea elements
     496              :     static WalkingAreaPaths myWalkingAreaPaths;
     497              :     static std::map<const MSEdge*, std::vector<const MSLane*> > myWalkingAreaFoes;
     498              :     static MinNextLengths myMinNextLengths;
     499              : };
        

Generated by: LCOV version 2.0-1