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-11-21 15:56:26 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       706320 :     struct WalkingAreaPath {
      56       176580 :         WalkingAreaPath(const MSLane* _from, const MSLane* _walkingArea, const MSLane* _to, const PositionVector& _shape, int _dir, double _angleOverride) :
      57       176580 :             from(_from),
      58       176580 :             to(_to),
      59       176580 :             lane(_walkingArea),
      60            0 :             shape(_shape),
      61       176580 :             dir(_dir),
      62       176580 :             angleOverride(_angleOverride),
      63       176580 :             length(_shape.length()) {
      64       176580 :         }
      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 the time pedestrians take to reach maximum impatience
     147              :     static const double MAX_WAIT_TOLERANCE;
     148              : 
     149              :     /// @brief the fraction of forward speed to be used for lateral movemenk
     150              :     static const double LATERAL_SPEED_FACTOR;
     151              : 
     152              :     /// @brief the minimum distance to the next obstacle in order to start walking after stopped
     153              :     static const double MIN_STARTUP_DIST;
     154              : 
     155              :     ///@}
     156              : 
     157              :     /// @brief Convert the striping to the vehicle lateral position and vice versa.
     158              :     // The striping model uses as lateral position the distance of the center of the pedestrian
     159              :     // to the left boundary of the lane minus a half stripe width, where right is positive.
     160              :     // The vehicle uses the distance to the center of the lane (and left is positive).
     161              :     // The function happens to be self inverse so it can be used to convert in both directions.
     162              :     inline static double posLatConversion(const double posLat, const double laneWidth) {
     163          140 :         return .5 * (laneWidth - stripeWidth) - posLat;
     164              :     }
     165              : 
     166              : 
     167              : protected:
     168              :     static const double DIST_FAR_AWAY;
     169              :     static const double DIST_BEHIND;
     170              :     static const double DIST_OVERLAP;
     171              : 
     172              :     struct Obstacle;
     173              :     class PState;
     174              :     typedef std::vector<Obstacle> Obstacles;
     175              :     typedef std::map<const MSLane*, Obstacles, ComparatorNumericalIdLess> NextLanesObstacles;
     176              :     typedef std::map<const MSLane*, double> MinNextLengths;
     177              : 
     178              :     struct NextLaneInfo {
     179      1396452 :         NextLaneInfo(const MSLane* _lane, const MSLink* _link, int _dir) :
     180      1396452 :             lane(_lane),
     181      1396452 :             link(_link),
     182      1396452 :             dir(_dir) {
     183              :         }
     184              : 
     185       653168 :         NextLaneInfo() :
     186       653168 :             lane(0),
     187       653168 :             link(0),
     188       214226 :             dir(UNDEFINED_DIRECTION) {
     189              :         }
     190              : 
     191              :         /// @brief the next lane to be used
     192              :         const MSLane* lane;
     193              :         /// @brief the link from the current lane to the next lane
     194              :         const MSLink* link;
     195              :         /// @brief the direction on the next lane
     196              :         int dir;
     197              :     };
     198              : 
     199              :     enum ObstacleType {
     200              :         OBSTACLE_NONE = 0,
     201              :         OBSTACLE_PED = 1,
     202              :         OBSTACLE_VEHICLE = 3,
     203              :         OBSTACLE_END = 4,
     204              :         OBSTACLE_NEXTEND = 5,
     205              :         OBSTACLE_LINKCLOSED = 6,
     206              :         OBSTACLE_ARRIVALPOS = 7
     207              :     };
     208              : 
     209              :     /// @brief information regarding surround Pedestrians (and potentially other things)
     210   1391565215 :     struct Obstacle {
     211              :         /// @brief create No-Obstacle
     212              :         Obstacle(int dir, double dist = DIST_FAR_AWAY);
     213              :         /// @brief create an obstacle from ped for ego moving in dir
     214              :         Obstacle(const PState& ped);
     215              :         /// @brief create an obstacle from explicit values
     216              :         Obstacle(double _x, double _speed, ObstacleType _type, const std::string& _description, const double width = 0., const SUMOVehicle* veh = nullptr)
     217      6090003 :             : xFwd(_x + width / 2.), xBack(_x - width / 2.), speed(_speed), type(_type), description(_description), vehicle(veh) {};
     218              : 
     219              :         /// @brief maximal position on the current lane in forward direction
     220              :         double xFwd;
     221              :         /// @brief maximal position on the current lane in backward direction
     222              :         double xBack;
     223              :         /// @brief speed relative to lane direction (positive means in the same direction)
     224              :         double speed;
     225              :         /// @brief whether this obstacle denotes a border, a vehicle or a pedestrian
     226              :         ObstacleType type;
     227              :         /// @brief the id / description of the obstacle
     228              :         std::string description;
     229              :         /// @brief a pointer to the vehicle if this obstacle is one
     230              :         const SUMOVehicle* vehicle = nullptr;
     231              : 
     232              :         bool closer(const Obstacle& o, int dir);
     233              :     };
     234              : 
     235              :     class walkingarea_path_sorter {
     236              :     public:
     237              :         /// comparing operation
     238              :         bool operator()(const WalkingAreaPath* p1, const WalkingAreaPath* p2) const {
     239      9850766 :             if (p1->from->getNumericalID() < p2->from->getNumericalID()) {
     240              :                 return true;
     241              :             }
     242      9706089 :             if (p1->from->getNumericalID() == p2->from->getNumericalID()) {
     243      9608627 :                 if (p1->to->getNumericalID() < p2->to->getNumericalID()) {
     244              :                     return true;
     245              :                 }
     246              :             }
     247              :             return false;
     248              :         }
     249              :     };
     250              : 
     251              : 
     252              :     /**
     253              :      * @class PState
     254              :      * @brief Container for pedestrian state and individual position update function
     255              :      */
     256              :     class PState : public MSPModel_InteractingState {
     257              :     public:
     258              :         PState(MSPerson* person, MSStageMoving* stage, const MSLane* lane);
     259              : 
     260              :         /// @brief constructor for loading state
     261              :         PState(MSPerson* person, MSStageMoving* stage, std::istringstream* in = nullptr);
     262              : 
     263       477330 :         ~PState() {};
     264              :         Position getPosition(const MSStageMoving& stage, SUMOTime now) const;
     265              :         double getAngle(const MSStageMoving& stage, SUMOTime now) const;
     266              :         const MSEdge* getNextEdge(const MSStageMoving& stage) const;
     267              :         void moveTo(MSPerson* p, MSLane* lane, double lanePos, double lanePosLat, SUMOTime t);
     268              :         void moveToXY(MSPerson* p, Position pos, MSLane* lane, double lanePos,
     269              :                       double lanePosLat, double angle, int routeOffset,
     270              :                       const ConstMSEdgeVector& edges, SUMOTime t);
     271              : 
     272              :         /// @brief information about the upcoming lane
     273              :         NextLaneInfo myNLI;
     274              :         /// @brief the current walkingAreaPath or 0
     275              :         const WalkingAreaPath* myWalkingAreaPath;
     276              : 
     277              :         /// @brief return the minimum position on the lane
     278              :         virtual double getMinX(const bool includeMinGap = true) const;
     279              : 
     280              :         /// @brief return the maximum position on the lane
     281              :         virtual double getMaxX(const bool includeMinGap = true) const;
     282              : 
     283              :         /// @brief return the length of the pedestrian
     284              :         double getLength() const;
     285              : 
     286              :         /// @brief return the minimum gap of the pedestrian
     287              :         double getMinGap() const;
     288              : 
     289              :         /// @brief the absolute distance to the end of the lane in walking direction (or to the arrivalPos)
     290              :         double distToLaneEnd() const;
     291              : 
     292              :         /// @brief return whether this pedestrian has passed the end of the current lane and update myRelX if so
     293              :         bool moveToNextLane(SUMOTime currentTime);
     294              : 
     295              :         /// @brief perform position update
     296              :         void walk(const Obstacles& obs, SUMOTime currentTime);
     297              : 
     298              :         /// @brief returns the impatience
     299              :         double getImpatience(SUMOTime now) const;
     300              : 
     301              :         int stripe() const;
     302              :         int otherStripe() const;
     303              : 
     304              :         static int stripe(const double relY);
     305              :         int otherStripe(const double relY) const;
     306              : 
     307              :         /* @brief calculate distance to the given obstacle,
     308              :          * - non-negative values signify an obstacle in front of ego
     309              :          * the special values DIST_OVERLAP and DIST_BEHIND are used to signify
     310              :          * obstacles that overlap and obstacles behind ego respectively
     311              :          * the result is the same regardless of walking direction
     312              :          */
     313              :         double distanceTo(const Obstacle& obs, const bool includeMinGap = true) const;
     314              : 
     315              :         /// @brief replace obstacles in the first vector with obstacles from the second if they are closer to me
     316              :         void mergeObstacles(Obstacles& into, const Obstacles& obs2);
     317              : 
     318              :         /// @brief replace obstacles in the first vector with obstacles from the second if they are closer in the given direction
     319              :         static void mergeObstacles(Obstacles& into, const Obstacles& obs2, int dir, int offset);
     320              : 
     321              :         /// @brief whether the pedestrian may ignore a red light
     322              :         bool ignoreRed(const MSLink* link) const;
     323              : 
     324              :         /// @brief return the person width
     325              :         virtual double getWidth() const;
     326              : 
     327    471161654 :         virtual ObstacleType getOType() const {
     328    471161654 :             return OBSTACLE_PED;
     329              :         }
     330              : 
     331              :         /// @brief whether the person is currently being controlled via TraCI
     332              :         bool isRemoteControlled() const;
     333              : 
     334              :         /** @brief Saves the current state into the given stream
     335              :          */
     336              :         void saveState(std::ostringstream& out);
     337              : 
     338              :         const MSLane* getNextCrossing() const;
     339              : 
     340              :         /// @brief return the lateral offset to the lane center
     341     11472244 :         double getLatOffset() const {
     342     11472244 :             return posLatConversion(myPosLat, myLane->getWidth());
     343              :         }
     344              : 
     345              :         inline double getPosLat() const {
     346     10056707 :             return myPosLat;
     347              :         }
     348              : 
     349              :         double getPathLength() const;
     350              :         void reverse(const double pathLength, const double usableWidth);
     351              :         void reset(const double edgePos, const double latPos);
     352              : 
     353              :     protected:
     354              :         /// @brief constructor for PStateVehicle
     355              :         PState();
     356              :     private:
     357              :         /// @brief Invalidated assignment operator.
     358              :         PState& operator=(const PState&) = delete;
     359              :     };
     360              : 
     361              :     class PStateVehicle : public PState {
     362              :     public:
     363              :         PStateVehicle(const MSVehicle* veh, const MSLane* walkingarea, double relX, double relY, double xWidth, double yWidth);
     364              :         const std::string& getID() const;
     365              :         double getMinX(const bool includeMinGap = true) const;
     366              :         double getMaxX(const bool includeMinGap = true) const;
     367              :         double getWidth() const;
     368              : 
     369       464765 :         ObstacleType getOType() const {
     370       464765 :             return OBSTACLE_VEHICLE;
     371              :         }
     372              : 
     373              :         const MSVehicle* getVehicle() const {
     374       464765 :             return myVehicle;
     375              :         }
     376              :     private:
     377              :         const MSVehicle* myVehicle;
     378              :         const double myXWidth;
     379              :         const double myYWidth;
     380              :     };
     381              : 
     382              : 
     383              :     class MovePedestrians : public Command {
     384              :     public:
     385         3839 :         MovePedestrians(MSPModel_Striping* model) : myModel(model) {};
     386         3838 :         ~MovePedestrians() {};
     387              :         SUMOTime execute(SUMOTime currentTime);
     388              :     private:
     389              :         MSPModel_Striping* const myModel;
     390              :     private:
     391              :         /// @brief Invalidated assignment operator.
     392              :         MovePedestrians& operator=(const MovePedestrians&) = delete;
     393              :     };
     394              : 
     395              :     /// @brief sorts the persons by position on the lane. If dir is forward, higher x positions come first.
     396              :     class by_xpos_sorter {
     397              :     public:
     398              :         /// constructor
     399              :         by_xpos_sorter(int dir): myDir(dir) {}
     400              : 
     401              :     public:
     402              :         /// comparing operation
     403   1806953222 :         bool operator()(const MSPModel_InteractingState* p1, const MSPModel_InteractingState* p2) const {
     404   1806953222 :             if (p1->getEdgePos(0) != p2->getEdgePos(0)) {
     405    857878105 :                 return myDir * p1->getEdgePos(0) > myDir * p2->getEdgePos(0);
     406              :             }
     407    949075117 :             return p1->getID() < p2->getID();
     408              :         }
     409              : 
     410              :     private:
     411              :         const int myDir;
     412              :     };
     413              : 
     414              : 
     415              :     /// @brief move all pedestrians forward and advance to the next lane if applicable
     416              :     void moveInDirection(SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir);
     417              : 
     418              :     /// @brief move pedestrians forward on one lane
     419              :     void moveInDirectionOnLane(Pedestrians& pedestrians, const MSLane* lane, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir, bool debug);
     420              : 
     421              :     /// @brief handle arrivals and lane advancement
     422              :     void arriveAndAdvance(Pedestrians& pedestrians, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir);
     423              : 
     424              :     const ActiveLanes& getActiveLanes() {
     425              :         return myActiveLanes;
     426              :     }
     427              : 
     428              : private:
     429              :     static void DEBUG_PRINT(const Obstacles& obs);
     430              : 
     431              :     /// @brief returns the direction in which these lanes are connectioned or 0 if they are not
     432              :     static int connectedDirection(const MSLane* from, const MSLane* to);
     433              : 
     434              :     /** @brief computes the successor lane for the given pedestrian and sets the
     435              :      * link as well as the direction to use on the succesor lane
     436              :      * @param[in] currentLane The lane the pedestrian is currently on
     437              :      * @param[in] ped The pedestrian for which to compute the next lane
     438              :      */
     439              :     static NextLaneInfo getNextLane(const PState& ped, const MSLane* currentLane, const MSLane* prevLane);
     440              : 
     441              :     /// @brief return the next walkingArea in the given direction
     442              :     static const MSLane* getNextWalkingArea(const MSLane* currentLane, const int dir, const MSLink*& link);
     443              : 
     444              :     static void initWalkingAreaPaths(const MSNet* net);
     445              : 
     446              :     /// @brief creates and inserts all paths into the given map
     447              :     static void insertWalkArePaths(const MSEdge* edge, WalkingAreaPaths& into);
     448              : 
     449              :     static const WalkingAreaPath* getWalkingAreaPath(const MSEdge* walkingArea, const MSLane* before, const MSLane* after);
     450              : 
     451              :     /// @brief return an arbitrary path across the given walkingArea
     452              :     static const WalkingAreaPath* getArbitraryPath(const MSEdge* walkingArea);
     453              : 
     454              :     static const WalkingAreaPath* guessPath(const MSEdge* walkingArea, const MSEdge* before, const MSEdge* after);
     455              : 
     456              :     /// @brief return the maximum number of pedestrians walking side by side
     457              :     static int numStripes(const MSLane* lane);
     458              : 
     459              :     static Obstacles getNeighboringObstacles(const Pedestrians& pedestrians, int egoIndex, int stripes);
     460              : 
     461              :     const Obstacles& getNextLaneObstacles(NextLanesObstacles& nextLanesObs, const MSLane* lane, const MSLane* nextLane, int stripes,
     462              :                                           int nextDir, double currentLength, int currentDir);
     463              : 
     464              :     static void transformToCurrentLanePositions(Obstacles& o, int currentDir, int nextDir, double currentLength, double nextLength);
     465              : 
     466              :     static void addCloserObstacle(Obstacles& obs, double x, int stripe, int numStripes, const std::string& id, double width, int dir, ObstacleType type);
     467              : 
     468              :     /* @brief compute stripe-offset to transform relY values from a lane with origStripes into a lane wit destStrips
     469              :      * @note this is called once for transforming nextLane peds to into the current system as obstacles and another time
     470              :      * (in reverse) to transform the pedestrian coordinates into the nextLane-coordinates when changing lanes
     471              :      */
     472              :     static int getStripeOffset(int origStripes, int destStripes, bool addRemainder);
     473              : 
     474              :     ///@brief add vehicles driving across
     475              :     static bool addCrossingVehs(const MSLane* crossing, int stripes, double lateral_offset, int dir, Obstacles& crossingVehs, bool prio);
     476              : 
     477              :     ///@brief retrieve vehicle obstacles on the given lane
     478              :     static Obstacles getVehicleObstacles(const MSLane* lane, int dir, PState* ped = 0);
     479              : 
     480              :     static bool addVehicleFoe(const MSVehicle* veh, const MSLane* walkingarea, const Position& relPos, double xWidth, double yWidth, double lateral_offset,
     481              :                               double minY, double maxY, Pedestrians& toDelete, Pedestrians& transformedPeds);
     482              : 
     483              :     static int getReserved(int stripes, double factor);
     484              : 
     485              :     /// @brief register pedestrian approach with the junction model
     486              :     static void registerCrossingApproach(const PState& ped, const MSLane* crossing, const MSLane* beforeWA);
     487              : 
     488              : private:
     489              :     /// @brief store for walkinArea elements
     490              :     static WalkingAreaPaths myWalkingAreaPaths;
     491              :     static std::map<const MSEdge*, std::vector<const MSLane*> > myWalkingAreaFoes;
     492              :     static MinNextLengths myMinNextLengths;
     493              : };
        

Generated by: LCOV version 2.0-1