LCOV - code coverage report
Current view: top level - src/microsim - MSStoppingPlace.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.3 % 150 143
Test Date: 2024-11-22 15:46:21 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        63723 : 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        63723 :                                  const RGBColor& color) :
      48              :     Named(id),
      49        63723 :     myElement(element),
      50       127446 :     myLines(lines), myLane(lane),
      51        63723 :     myBegPos(begPos), myEndPos(endPos),
      52        63723 :     myLastFreePos(endPos),
      53        63723 :     myLastParking(nullptr),
      54        63723 :     myName(name),
      55        63723 :     myTransportableCapacity(capacity),
      56        63723 :     myParkingFactor(parkingLength <= 0 ? 1 : (endPos - begPos) / parkingLength),
      57        63723 :     myColor(color),
      58              :     // see MSVehicleControl defContainerType
      59       181094 :     myTransportableDepth(element == SUMO_TAG_CONTAINER_STOP ? SUMO_const_waitingContainerDepth : SUMO_const_waitingPersonDepth) {
      60        63723 :     computeLastFreePos();
      61      3000121 :     for (int i = 0; i < capacity; i++) {
      62              :         myWaitingSpots.insert(i);
      63              :     }
      64        63723 : }
      65              : 
      66              : 
      67       227646 : MSStoppingPlace::~MSStoppingPlace() {}
      68              : 
      69              : 
      70              : const MSLane&
      71       786681 : MSStoppingPlace::getLane() const {
      72       786681 :     return myLane;
      73              : }
      74              : 
      75              : 
      76              : double
      77       383448 : MSStoppingPlace::getBeginLanePosition() const {
      78       383448 :     return myBegPos;
      79              : }
      80              : 
      81              : 
      82              : double
      83       204329 : MSStoppingPlace::getEndLanePosition() const {
      84       204329 :     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        19289 : MSStoppingPlace::enter(SUMOVehicle* veh, bool parking) {
      96        19289 :     double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap() * (parking ? myParkingFactor : 1);
      97        19289 :     double end = beg - veh->getVehicleType().getLengthWithGap() * (parking ? myParkingFactor : 1);
      98        19289 :     myEndPositions[veh] = std::make_pair(beg, end);
      99        19289 :     computeLastFreePos();
     100        19289 : }
     101              : 
     102              : 
     103              : double
     104      1385963 : MSStoppingPlace::getLastFreePos(const SUMOVehicle& forVehicle, double /*brakePos*/) const {
     105      1385963 :     if (getStoppedVehicleNumber() > 0) {
     106       544949 :         const double vehGap = forVehicle.getVehicleType().getMinGap();
     107       544949 :         double pos = myLastFreePos - vehGap;
     108         1659 :         if (myParkingFactor < 1 && myLastParking != nullptr && forVehicle.hasStops() && (forVehicle.getStops().front().pars.parking == ParkingType::ONROAD)
     109       545495 :                 && myLastParking->remainingStopDuration() < forVehicle.getStops().front().getMinDuration(SIMSTEP)) {
     110              :             // stop far back enough so that the previous parking vehicle can leave (even if this vehicle fits, it will
     111              :             // be a blocker because it stops on the road)
     112          266 :             pos = MIN2(pos, myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS);
     113              :         }
     114       544949 :         if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
     115        45630 :             return forVehicle.getPositionOnLane();
     116              :         }
     117       499319 :         if (!fits(pos, forVehicle)) {
     118              :             // try to find a place ahead of the waiting vehicles
     119       486317 :             const double vehLength = forVehicle.getVehicleType().getLength() * myParkingFactor;
     120              :             std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
     121      1440219 :             for (auto it : myEndPositions) {
     122       953902 :                 spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
     123              :             }
     124              :             // sorted from myEndPos towars myBegPos
     125       486317 :             std::sort(spaces.begin(), spaces.end());
     126       486317 :             std::reverse(spaces.begin(), spaces.end());
     127       486317 :             double prev = myEndPos;
     128      1399595 :             for (auto it : spaces) {
     129              :                 //if (forVehicle.isSelected()) {
     130              :                 //    std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
     131              :                 //}
     132       936720 :                 if (prev - it.first + NUMERICAL_EPS >= vehLength && (
     133        14103 :                             it.second.second->isParking()
     134         5036 :                             || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
     135              :                     return prev;
     136              :                 }
     137       913278 :                 prev = it.second.first - vehGap;
     138              :             }
     139       476978 :             if (myParkingFactor < 1 && myLastParking != nullptr) {
     140              :                 // stop far back enough so that the previous vehicle can leave
     141          488 :                 pos = MIN2(pos, myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS);
     142              :             }
     143       486317 :         }
     144       489980 :         return pos;
     145              :     }
     146       841014 :     return myLastFreePos;
     147              : }
     148              : 
     149              : bool
     150       995826 : MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
     151              :     // always fit at the default position or if at least half the vehicle length
     152              :     // is within the stop range (debatable)
     153       995826 :     return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
     154              : }
     155              : 
     156              : double
     157       111400 : MSStoppingPlace::getWaitingPositionOnLane(MSTransportable* t) const {
     158              :     auto it = myWaitingTransportables.find(t);
     159       111400 :     const double waitingWidth = myElement == SUMO_TAG_CONTAINER_STOP
     160       111400 :                                 ? SUMO_const_waitingContainerWidth
     161              :                                 : SUMO_const_waitingPersonWidth;
     162       111400 :     if (it != myWaitingTransportables.end() && it->second >= 0) {
     163        36039 :         return myEndPos - (0.5 + (it->second) % getTransportablesAbreast()) * waitingWidth;
     164              :     } else {
     165        75361 :         return (myEndPos + myBegPos) / 2;
     166              :     }
     167              : }
     168              : 
     169              : 
     170              : int
     171       107254 : MSStoppingPlace::getTransportablesAbreast(double length, SumoXMLTag element) {
     172       107254 :     return MAX2(1, (int)floor(length / (element == SUMO_TAG_CONTAINER_STOP
     173       107254 :                                         ? SUMO_const_waitingContainerWidth
     174       107254 :                                         : SUMO_const_waitingPersonWidth)));
     175              : }
     176              : 
     177              : int
     178        68521 : MSStoppingPlace::getTransportablesAbreast() const {
     179        68521 :     return getTransportablesAbreast(myEndPos - myBegPos, myElement);
     180              : }
     181              : 
     182              : Position
     183        88026 : MSStoppingPlace::getWaitPosition(MSTransportable* t) const {
     184        88026 :     double lanePos = getWaitingPositionOnLane(t);
     185              :     int row = 0;
     186              :     auto it = myWaitingTransportables.find(t);
     187        88026 :     if (it != myWaitingTransportables.end()) {
     188        30788 :         if (it->second >= 0) {
     189        30788 :             row = int(it->second / getTransportablesAbreast());
     190              :         } else {
     191              :             // invalid position, draw outside bounds
     192            0 :             row = 1 + myTransportableCapacity / getTransportablesAbreast();
     193              :         }
     194              :     }
     195        88026 :     const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
     196        88026 :     return myLane.getShape().positionAtOffset(myLane.interpolateLanePosToGeometryPos(lanePos),
     197        88026 :             lefthandSign * (myLane.getWidth() / 2 + row * myTransportableDepth));
     198              : }
     199              : 
     200              : 
     201              : double
     202            0 : MSStoppingPlace::getStoppingPosition(const SUMOVehicle* veh) const {
     203              :     auto i = myEndPositions.find(veh);
     204            0 :     if (i != myEndPositions.end()) {
     205            0 :         return i->second.second;
     206              :     } else {
     207            0 :         return getLastFreePos(*veh);
     208              :     }
     209              : }
     210              : 
     211              : std::vector<const MSTransportable*>
     212          156 : MSStoppingPlace::getTransportables() const {
     213              :     std::vector<const MSTransportable*> result;
     214          212 :     for (auto item : myWaitingTransportables) {
     215           56 :         result.push_back(item.first);
     216              :     }
     217          156 :     return result;
     218            0 : }
     219              : 
     220              : bool
     221       127212 : MSStoppingPlace::hasSpaceForTransportable() const {
     222       127212 :     return myWaitingSpots.size() > 0;
     223              : }
     224              : 
     225              : bool
     226       127212 : MSStoppingPlace::addTransportable(const MSTransportable* p) {
     227              :     int spot = -1;
     228       127212 :     if (!hasSpaceForTransportable()) {
     229              :         return false;
     230              :     }
     231        87868 :     spot = *myWaitingSpots.begin();
     232              :     myWaitingSpots.erase(myWaitingSpots.begin());
     233        87868 :     myWaitingTransportables[p] = spot;
     234        87868 :     return true;
     235              : }
     236              : 
     237              : 
     238              : void
     239       193942 : MSStoppingPlace::removeTransportable(const MSTransportable* p) {
     240              :     auto i = myWaitingTransportables.find(p);
     241       193942 :     if (i != myWaitingTransportables.end()) {
     242        87701 :         if (i->second >= 0) {
     243        87701 :             myWaitingSpots.insert(i->second);
     244              :         }
     245              :         myWaitingTransportables.erase(i);
     246              :     }
     247       193942 : }
     248              : 
     249              : 
     250              : void
     251        19049 : MSStoppingPlace::leaveFrom(SUMOVehicle* what) {
     252              :     assert(myEndPositions.find(what) != myEndPositions.end());
     253              :     myEndPositions.erase(myEndPositions.find(what));
     254        19049 :     computeLastFreePos();
     255        19049 : }
     256              : 
     257              : 
     258              : void
     259       102101 : MSStoppingPlace::computeLastFreePos() {
     260       102101 :     myLastFreePos = myEndPos;
     261       102101 :     myLastParking = nullptr;
     262       127317 :     for (auto item : myEndPositions) {
     263              :         // vehicle might be stopped beyond myEndPos
     264        25216 :         if (myLastFreePos >= item.second.second || myLastFreePos == myEndPos) {
     265        22688 :             myLastFreePos = item.second.second;
     266        22688 :             if (item.first->isStoppedParking()) {
     267         3473 :                 myLastParking = item.first;
     268              :             }
     269              :         }
     270              :     }
     271       102101 : }
     272              : 
     273              : 
     274              : double
     275        62478 : MSStoppingPlace::getAccessPos(const MSEdge* edge, SumoRNG* rng) const {
     276        62478 :     if (edge == &myLane.getEdge()) {
     277        56256 :         return (myBegPos + myEndPos) / 2.;
     278              :     }
     279         7719 :     for (const auto& access : myAccessPos) {
     280         6476 :         if (edge == &access.lane->getEdge()) {
     281         4979 :             if (rng == nullptr || access.startPos == access.endPos) {
     282         4221 :                 return access.endPos;
     283              :             }
     284          758 :             return RandHelper::rand(access.startPos, access.endPos, rng);
     285              :         }
     286              :     }
     287              :     return -1.;
     288              : }
     289              : 
     290              : 
     291              : const MSStoppingPlace::Access*
     292        57876 : MSStoppingPlace::getAccess(const MSEdge* edge) const {
     293        61044 :     for (const auto& access : myAccessPos) {
     294         7288 :         if (edge == &access.lane->getEdge()) {
     295              :             return &access;
     296              :         }
     297              :     }
     298              :     return nullptr;
     299              : }
     300              : 
     301              : 
     302              : const std::string&
     303         1183 : MSStoppingPlace::getMyName() const {
     304         1183 :     return myName;
     305              : }
     306              : 
     307              : 
     308              : const RGBColor&
     309        52518 : MSStoppingPlace::getColor() const {
     310        52518 :     return myColor;
     311              : }
     312              : 
     313              : 
     314              : bool
     315         2169 : MSStoppingPlace::addAccess(MSLane* const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit) {
     316              :     // prevent multiple accesses on the same lane
     317         4313 :     for (const auto& access : myAccessPos) {
     318         2151 :         if (lane == access.lane) {
     319              :             return false;
     320              :         }
     321              :     }
     322         2162 :     if (length < 0.) {
     323         1087 :         const Position accPos = lane->geometryPositionAtOffset((startPos + endPos) / 2.);
     324         1087 :         const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
     325         1087 :         length = accPos.distanceTo(stopPos);
     326              :     }
     327         2162 :     myAccessPos.push_back({lane, startPos, endPos, length, exit});
     328         2162 :     return true;
     329              : }
     330              : 
     331              : 
     332              : std::vector<const SUMOVehicle*>
     333          602 : MSStoppingPlace::getStoppedVehicles() const {
     334              :     std::vector<const SUMOVehicle*> result;
     335          872 :     for (auto item : myEndPositions) {
     336          270 :         result.push_back(item.first);
     337              :     }
     338          602 :     return result;
     339            0 : }
     340              : 
     341              : 
     342              : void
     343          101 : MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
     344          228 :     for (auto item : myWaitingTransportables) {
     345          127 :         into.push_back(item.first->getID());
     346              :     }
     347          101 :     std::sort(into.begin(), into.end());
     348          101 : }
     349              : 
     350              : 
     351              : void
     352           40 : MSStoppingPlace::clearState() {
     353              :     myEndPositions.clear();
     354              :     myWaitingTransportables.clear();
     355           40 :     computeLastFreePos();
     356           40 : }
     357              : 
     358              : 
     359              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1