LCOV - code coverage report
Current view: top level - src/microsim - MSStoppingPlace.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.3 % 148 141
Test Date: 2024-10-24 15:46:30 Functions: 96.6 % 29 28

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2005-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    MSStoppingPlace.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @author  Johannes Rummel
      18              : /// @date    Mon, 13.12.2005
      19              : ///
      20              : // A lane area vehicles can halt at
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <map>
      26              : #include <utils/vehicle/SUMOVehicle.h>
      27              : #include <utils/geom/Position.h>
      28              : #include <utils/common/RGBColor.h>
      29              : #include <microsim/transportables/MSTransportable.h>
      30              : #include <microsim/MSGlobals.h>
      31              : #include <microsim/MSVehicleType.h>
      32              : #include <microsim/MSNet.h>
      33              : #include <microsim/MSLane.h>
      34              : #include <microsim/MSStop.h>
      35              : #include "MSStoppingPlace.h"
      36              : 
      37              : // ===========================================================================
      38              : // method definitions
      39              : // ===========================================================================
      40        63589 : MSStoppingPlace::MSStoppingPlace(const std::string& id,
      41              :                                  SumoXMLTag element,
      42              :                                  const std::vector<std::string>& lines,
      43              :                                  MSLane& lane,
      44              :                                  double begPos, double endPos, const std::string name,
      45              :                                  int capacity,
      46              :                                  double parkingLength,
      47        63589 :                                  const RGBColor& color) :
      48              :     Named(id),
      49        63589 :     myElement(element),
      50       127178 :     myLines(lines), myLane(lane),
      51        63589 :     myBegPos(begPos), myEndPos(endPos),
      52        63589 :     myLastFreePos(endPos),
      53        63589 :     myLastParking(nullptr),
      54        63589 :     myName(name),
      55        63589 :     myTransportableCapacity(capacity),
      56        63589 :     myParkingFactor(parkingLength <= 0 ? 1 : (endPos - begPos) / parkingLength),
      57        63589 :     myColor(color),
      58              :     // see MSVehicleControl defContainerType
      59       180697 :     myTransportableDepth(element == SUMO_TAG_CONTAINER_STOP ? SUMO_const_waitingContainerDepth : SUMO_const_waitingPersonDepth) {
      60        63589 :     computeLastFreePos();
      61      2994666 :     for (int i = 0; i < capacity; i++) {
      62              :         myWaitingSpots.insert(i);
      63              :     }
      64        63589 : }
      65              : 
      66              : 
      67       227193 : MSStoppingPlace::~MSStoppingPlace() {}
      68              : 
      69              : 
      70              : const MSLane&
      71       778538 : MSStoppingPlace::getLane() const {
      72       778538 :     return myLane;
      73              : }
      74              : 
      75              : 
      76              : double
      77       381053 : MSStoppingPlace::getBeginLanePosition() const {
      78       381053 :     return myBegPos;
      79              : }
      80              : 
      81              : 
      82              : double
      83       202973 : MSStoppingPlace::getEndLanePosition() const {
      84       202973 :     return myEndPos;
      85              : }
      86              : 
      87              : Position
      88         2992 : MSStoppingPlace::getCenterPos() const {
      89         2992 :     return myLane.getShape().positionAtOffset(myLane.interpolateLanePosToGeometryPos((myBegPos + myEndPos) / 2),
      90         2992 :             myLane.getWidth() / 2 + 0.5);
      91              : }
      92              : 
      93              : 
      94              : void
      95        19187 : MSStoppingPlace::enter(SUMOVehicle* veh, bool parking) {
      96        19187 :     double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
      97        19187 :     double end = beg - veh->getVehicleType().getLengthWithGap() * (parking ? myParkingFactor : 1);
      98        19187 :     myEndPositions[veh] = std::make_pair(beg, end);
      99        19187 :     computeLastFreePos();
     100        19187 : }
     101              : 
     102              : 
     103              : double
     104      1381866 : MSStoppingPlace::getLastFreePos(const SUMOVehicle& forVehicle, double /*brakePos*/) const {
     105      1381866 :     if (getStoppedVehicleNumber() > 0) {
     106       544938 :         const double vehGap = forVehicle.getVehicleType().getMinGap();
     107       544938 :         double pos = myLastFreePos - vehGap;
     108          629 :         if (myParkingFactor < 1 && myLastParking != nullptr && forVehicle.hasStops() && (forVehicle.getStops().front().pars.parking == ParkingType::ONROAD)
     109       545029 :                 && myLastParking->remainingStopDuration() < forVehicle.getStops().front().getMinDuration(SIMSTEP)) {
     110              :             // stop far back enough so that the previous vehicle can leave
     111           21 :             pos = myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS;
     112              :         }
     113       544938 :         if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
     114        45293 :             return forVehicle.getPositionOnLane();
     115              :         }
     116       499645 :         if (!fits(pos, forVehicle)) {
     117              :             // try to find a place ahead of the waiting vehicles
     118       486741 :             const double vehLength = forVehicle.getVehicleType().getLength();
     119              :             std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
     120      1440957 :             for (auto it : myEndPositions) {
     121       954216 :                 spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
     122              :             }
     123              :             // sorted from myEndPos towars myBegPos
     124       486741 :             std::sort(spaces.begin(), spaces.end());
     125       486741 :             std::reverse(spaces.begin(), spaces.end());
     126       486741 :             double prev = myEndPos;
     127      1400554 :             for (auto it : spaces) {
     128              :                 //if (forVehicle.isSelected()) {
     129              :                 //    std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
     130              :                 //}
     131       936939 :                 if (prev - it.first + NUMERICAL_EPS >= vehLength && (
     132        13915 :                             it.second.second->isParking()
     133         4976 :                             || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
     134              :                     return prev;
     135              :                 }
     136       913813 :                 prev = it.second.first - vehGap;
     137              :             }
     138       486741 :         }
     139       490434 :         return pos;
     140              :     }
     141       836928 :     return myLastFreePos;
     142              : }
     143              : 
     144              : bool
     145       994616 : MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
     146              :     // always fit at the default position or if at least half the vehicle length
     147              :     // is within the stop range (debatable)
     148       994616 :     return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
     149              : }
     150              : 
     151              : double
     152       111398 : MSStoppingPlace::getWaitingPositionOnLane(MSTransportable* t) const {
     153              :     auto it = myWaitingTransportables.find(t);
     154       111398 :     const double waitingWidth = myElement == SUMO_TAG_CONTAINER_STOP
     155       111398 :                                 ? SUMO_const_waitingContainerWidth
     156              :                                 : SUMO_const_waitingPersonWidth;
     157       111398 :     if (it != myWaitingTransportables.end() && it->second >= 0) {
     158        36037 :         return myEndPos - (0.5 + (it->second) % getTransportablesAbreast()) * waitingWidth;
     159              :     } else {
     160        75361 :         return (myEndPos + myBegPos) / 2;
     161              :     }
     162              : }
     163              : 
     164              : 
     165              : int
     166       107105 : MSStoppingPlace::getTransportablesAbreast(double length, SumoXMLTag element) {
     167       107105 :     return MAX2(1, (int)floor(length / (element == SUMO_TAG_CONTAINER_STOP
     168       107105 :                                         ? SUMO_const_waitingContainerWidth
     169       107105 :                                         : SUMO_const_waitingPersonWidth)));
     170              : }
     171              : 
     172              : int
     173        68482 : MSStoppingPlace::getTransportablesAbreast() const {
     174        68482 :     return getTransportablesAbreast(myEndPos - myBegPos, myElement);
     175              : }
     176              : 
     177              : Position
     178        88025 : MSStoppingPlace::getWaitPosition(MSTransportable* t) const {
     179        88025 :     double lanePos = getWaitingPositionOnLane(t);
     180              :     int row = 0;
     181              :     auto it = myWaitingTransportables.find(t);
     182        88025 :     if (it != myWaitingTransportables.end()) {
     183        30787 :         if (it->second >= 0) {
     184        30787 :             row = int(it->second / getTransportablesAbreast());
     185              :         } else {
     186              :             // invalid position, draw outside bounds
     187            0 :             row = 1 + myTransportableCapacity / getTransportablesAbreast();
     188              :         }
     189              :     }
     190        88025 :     const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
     191        88025 :     return myLane.getShape().positionAtOffset(myLane.interpolateLanePosToGeometryPos(lanePos),
     192        88025 :             lefthandSign * (myLane.getWidth() / 2 + row * myTransportableDepth));
     193              : }
     194              : 
     195              : 
     196              : double
     197            0 : MSStoppingPlace::getStoppingPosition(const SUMOVehicle* veh) const {
     198              :     auto i = myEndPositions.find(veh);
     199            0 :     if (i != myEndPositions.end()) {
     200            0 :         return i->second.second;
     201              :     } else {
     202            0 :         return getLastFreePos(*veh);
     203              :     }
     204              : }
     205              : 
     206              : std::vector<const MSTransportable*>
     207          156 : MSStoppingPlace::getTransportables() const {
     208              :     std::vector<const MSTransportable*> result;
     209          212 :     for (auto item : myWaitingTransportables) {
     210           56 :         result.push_back(item.first);
     211              :     }
     212          156 :     return result;
     213            0 : }
     214              : 
     215              : bool
     216       127204 : MSStoppingPlace::hasSpaceForTransportable() const {
     217       127204 :     return myWaitingSpots.size() > 0;
     218              : }
     219              : 
     220              : bool
     221       127204 : MSStoppingPlace::addTransportable(const MSTransportable* p) {
     222              :     int spot = -1;
     223       127204 :     if (!hasSpaceForTransportable()) {
     224              :         return false;
     225              :     }
     226        87862 :     spot = *myWaitingSpots.begin();
     227              :     myWaitingSpots.erase(myWaitingSpots.begin());
     228        87862 :     myWaitingTransportables[p] = spot;
     229        87862 :     return true;
     230              : }
     231              : 
     232              : 
     233              : void
     234       193935 : MSStoppingPlace::removeTransportable(const MSTransportable* p) {
     235              :     auto i = myWaitingTransportables.find(p);
     236       193935 :     if (i != myWaitingTransportables.end()) {
     237        87695 :         if (i->second >= 0) {
     238        87695 :             myWaitingSpots.insert(i->second);
     239              :         }
     240              :         myWaitingTransportables.erase(i);
     241              :     }
     242       193935 : }
     243              : 
     244              : 
     245              : void
     246        18941 : MSStoppingPlace::leaveFrom(SUMOVehicle* what) {
     247              :     assert(myEndPositions.find(what) != myEndPositions.end());
     248              :     myEndPositions.erase(myEndPositions.find(what));
     249        18941 :     computeLastFreePos();
     250        18941 : }
     251              : 
     252              : 
     253              : void
     254       101767 : MSStoppingPlace::computeLastFreePos() {
     255       101767 :     myLastFreePos = myEndPos;
     256       101767 :     myLastParking = nullptr;
     257       126869 :     for (auto item : myEndPositions) {
     258              :         // vehicle might be stopped beyond myEndPos
     259        25102 :         if (myLastFreePos >= item.second.second || myLastFreePos == myEndPos) {
     260        22579 :             myLastFreePos = item.second.second;
     261        22579 :             if (item.first->isStoppedParking()) {
     262         3430 :                 myLastParking = item.first;
     263              :             }
     264              :         }
     265              :     }
     266       101767 : }
     267              : 
     268              : 
     269              : double
     270        62476 : MSStoppingPlace::getAccessPos(const MSEdge* edge, SumoRNG* rng) const {
     271        62476 :     if (edge == &myLane.getEdge()) {
     272        56244 :         return (myBegPos + myEndPos) / 2.;
     273              :     }
     274         7741 :     for (const auto& access : myAccessPos) {
     275         6495 :         if (edge == &access.lane->getEdge()) {
     276         4986 :             if (rng == nullptr || access.startPos == access.endPos) {
     277         4228 :                 return access.endPos;
     278              :             }
     279          758 :             return RandHelper::rand(access.startPos, access.endPos, rng);
     280              :         }
     281              :     }
     282              :     return -1.;
     283              : }
     284              : 
     285              : 
     286              : const MSStoppingPlace::Access*
     287        57867 : MSStoppingPlace::getAccess(const MSEdge* edge) const {
     288        61055 :     for (const auto& access : myAccessPos) {
     289         7311 :         if (edge == &access.lane->getEdge()) {
     290              :             return &access;
     291              :         }
     292              :     }
     293              :     return nullptr;
     294              : }
     295              : 
     296              : 
     297              : const std::string&
     298         1178 : MSStoppingPlace::getMyName() const {
     299         1178 :     return myName;
     300              : }
     301              : 
     302              : 
     303              : const RGBColor&
     304        51675 : MSStoppingPlace::getColor() const {
     305        51675 :     return myColor;
     306              : }
     307              : 
     308              : 
     309              : bool
     310         2169 : MSStoppingPlace::addAccess(MSLane* const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit) {
     311              :     // prevent multiple accesses on the same lane
     312         4313 :     for (const auto& access : myAccessPos) {
     313         2151 :         if (lane == access.lane) {
     314              :             return false;
     315              :         }
     316              :     }
     317         2162 :     if (length < 0.) {
     318         1087 :         const Position accPos = lane->geometryPositionAtOffset((startPos + endPos) / 2.);
     319         1087 :         const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
     320         1087 :         length = accPos.distanceTo(stopPos);
     321              :     }
     322         2162 :     myAccessPos.push_back({lane, startPos, endPos, length, exit});
     323         2162 :     return true;
     324              : }
     325              : 
     326              : 
     327              : std::vector<const SUMOVehicle*>
     328          602 : MSStoppingPlace::getStoppedVehicles() const {
     329              :     std::vector<const SUMOVehicle*> result;
     330          872 :     for (auto item : myEndPositions) {
     331          270 :         result.push_back(item.first);
     332              :     }
     333          602 :     return result;
     334            0 : }
     335              : 
     336              : 
     337              : void
     338          101 : MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
     339          228 :     for (auto item : myWaitingTransportables) {
     340          127 :         into.push_back(item.first->getID());
     341              :     }
     342          101 :     std::sort(into.begin(), into.end());
     343          101 : }
     344              : 
     345              : 
     346              : void
     347           50 : MSStoppingPlace::clearState() {
     348              :     myEndPositions.clear();
     349              :     myWaitingTransportables.clear();
     350           50 :     computeLastFreePos();
     351           50 : }
     352              : 
     353              : 
     354              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1