LCOV - code coverage report
Current view: top level - src/microsim - MSParkingArea.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 88.3 % 256 226
Test Date: 2024-10-24 15:46:30 Functions: 86.5 % 37 32

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2015-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    MSParkingArea.cpp
      15              : /// @author  Mirco Sturari
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Mirko Barthauer
      18              : /// @date    Tue, 19.01.2016
      19              : ///
      20              : // A area where vehicles can park next to the road
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <utils/common/WrappingCommand.h>
      26              : #include <utils/vehicle/SUMOVehicle.h>
      27              : #include <utils/geom/Position.h>
      28              : #include <utils/geom/GeomHelper.h>
      29              : #include <microsim/MSEventControl.h>
      30              : #include <microsim/MSNet.h>
      31              : #include <microsim/MSVehicle.h>
      32              : #include <microsim/MSVehicleType.h>
      33              : #include "MSLane.h"
      34              : #include <microsim/transportables/MSTransportable.h>
      35              : #include "MSParkingArea.h"
      36              : #include "MSGlobals.h"
      37              : 
      38              : //#define DEBUG_RESERVATIONS
      39              : //#define DEBUG_GET_LAST_FREE_POS
      40              : //#define DEBUG_COND2(obj) (obj.getID() == "v.3")
      41              : #define DEBUG_COND2(obj) (obj.isSelected())
      42              : 
      43              : 
      44              : // ===========================================================================
      45              : // method definitions
      46              : // ===========================================================================
      47        13278 : MSParkingArea::MSParkingArea(const std::string& id, const std::vector<std::string>& lines,
      48              :                              const std::vector<std::string>& badges, MSLane& lane,
      49              :                              double begPos, double endPos, int capacity, double width, double length,
      50              :                              double angle, const std::string& name, bool onRoad,
      51        13278 :                              const std::string& departPos, bool lefthand) :
      52              :     MSStoppingPlace(id, SUMO_TAG_PARKING_AREA, lines, lane, begPos, endPos, name),
      53        13278 :     myRoadSideCapacity(capacity),
      54        13278 :     myCapacity(0),
      55        13278 :     myOnRoad(onRoad),
      56        13278 :     myWidth(width),
      57        13278 :     myLength(length),
      58        13278 :     myAngle(lefthand ? -angle : angle),
      59        13278 :     myAcceptedBadges(badges.begin(), badges.end()),
      60        13278 :     myEgressBlocked(false),
      61        13278 :     myReservationTime(-1),
      62        13278 :     myReservations(0),
      63        13278 :     myReservationMaxLength(0),
      64        13278 :     myNumAlternatives(0),
      65        13278 :     myLastStepOccupancy(0),
      66        13278 :     myDepartPos(-1),
      67        13278 :     myDepartPosDefinition(DepartPosDefinition::DEFAULT),
      68        26570 :     myUpdateEvent(nullptr) {
      69              :     // initialize unspecified defaults
      70        13278 :     if (myWidth == 0) {
      71        11319 :         myWidth = SUMO_const_laneWidth;
      72              :     }
      73              : 
      74        13278 :     if (departPos != "") {
      75              :         std::string error;
      76           58 :         if (!SUMOVehicleParameter::parseDepartPos(departPos, toString(myElement), getID(), myDepartPos, myDepartPosDefinition, error)) {
      77            0 :             throw ProcessError(error);
      78              :         }
      79           29 :         if (myDepartPosDefinition != DepartPosDefinition::GIVEN) {
      80              :             // maybe allow other methods at a later time
      81            0 :             throw ProcessError("Only a numerical departPos is supported for " + toString(myElement) + " '" + getID() + "'");
      82           29 :         } else if (myDepartPos < 0 || myDepartPos > lane.getLength()) {
      83            0 :             throw ProcessError("Invalid departPos for " + toString(myElement) + " '" + getID() + "'");
      84              :         }
      85              :     }
      86              : 
      87        13278 :     const double offset = (MSGlobals::gLefthand != lefthand) ? -1 : 1;
      88        26556 :     myShape = lane.getShape().getSubpart(
      89              :                   lane.interpolateLanePosToGeometryPos(begPos),
      90              :                   lane.interpolateLanePosToGeometryPos(endPos));
      91        13278 :     if (!myOnRoad) {
      92        13217 :         myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset);
      93              :     }
      94        13278 :     setRoadsideCapacity(capacity);
      95        13278 : }
      96              : 
      97              : 
      98        25831 : MSParkingArea::~MSParkingArea() {}
      99              : 
     100              : 
     101              : void
     102        48519 : MSParkingArea::addLotEntry(double x, double y, double z, double width, double length, double angle, double slope) {
     103              :     // create LotSpaceDefinition
     104        48519 :     LotSpaceDefinition lsd((int)mySpaceOccupancies.size(), nullptr, x, y, z, angle, slope, width, length);
     105              :     // If we are modelling parking set the end position to the lot position relative to the lane
     106              :     // rather than the end of the parking area - this results in vehicles stopping nearer the space
     107              :     // and re-entering the lane nearer the space. (If we are not modelling parking the vehicle will usually
     108              :     // enter the space and re-enter at the end of the parking area.)
     109        48519 :     if (MSGlobals::gModelParkingManoeuver) {
     110           30 :         const double offset = this->getLane().getShape().nearest_offset_to_point2D(lsd.position);
     111           30 :         if (offset <  getBeginLanePosition()) {
     112            0 :             lsd.endPos =  getBeginLanePosition() + POSITION_EPS;
     113              :         } else {
     114           30 :             if (this->getLane().getLength() > offset) {
     115           30 :                 lsd.endPos = offset;
     116              :             } else {
     117            0 :                 lsd.endPos = this->getLane().getLength() - POSITION_EPS;
     118              :             }
     119              :         }
     120              :         // Work out the angle of the lot relative to the lane  (-90 adjusts for the way the bay is drawn )
     121           30 :         double relativeAngle = fmod(lsd.rotation - 90., 360) - fmod(RAD2DEG(this->getLane().getShape().rotationAtOffset(lsd.endPos)), 360) + 0.5;
     122           30 :         if (relativeAngle < 0.) {
     123           10 :             relativeAngle += 360.;
     124              :         }
     125           30 :         lsd.manoeuverAngle = relativeAngle;
     126              : 
     127              :         // if p2.y is -ve the lot is on LHS of lane relative to lane direction
     128              :         // we need to know this because it inverts the complexity of the parking manoeuver
     129           30 :         Position p2 = this->getLane().getShape().transformToVectorCoordinates(lsd.position);
     130           30 :         if (p2.y() < (0. + POSITION_EPS)) {
     131           30 :             lsd.sideIsLHS = true;
     132              :         } else {
     133            0 :             lsd.sideIsLHS = false;
     134              :         }
     135              :     } else {
     136        48489 :         lsd.endPos = myEndPos;
     137        48489 :         lsd.manoeuverAngle = int(angle); // unused unless gModelParkingManoeuver is true
     138        48489 :         lsd.sideIsLHS = true;
     139              :     }
     140        48519 :     mySpaceOccupancies.push_back(lsd);
     141        48519 :     myCapacity++;
     142        48519 :     computeLastFreePos();
     143        48519 : }
     144              : 
     145              : int
     146           30 : MSParkingArea::getLastFreeLotAngle() const {
     147              :     assert(myLastFreeLot >= 0);
     148              :     assert(myLastFreeLot < (int)mySpaceOccupancies.size());
     149              : 
     150           30 :     const LotSpaceDefinition& lsd = mySpaceOccupancies[myLastFreeLot];
     151           30 :     if (lsd.sideIsLHS) {
     152           30 :         return abs(int(lsd.manoeuverAngle)) % 180;
     153              :     } else {
     154            0 :         return abs(abs(int(lsd.manoeuverAngle)) % 180 - 180) % 180;
     155              :     }
     156              : }
     157              : 
     158              : double
     159           30 : MSParkingArea::getLastFreeLotGUIAngle() const {
     160              :     assert(myLastFreeLot >= 0);
     161              :     assert(myLastFreeLot < (int)mySpaceOccupancies.size());
     162              : 
     163           30 :     const LotSpaceDefinition& lsd = mySpaceOccupancies[myLastFreeLot];
     164           30 :     if (lsd.manoeuverAngle > 180.) {
     165           15 :         return DEG2RAD(lsd.manoeuverAngle - 360.);
     166              :     } else {
     167           15 :         return DEG2RAD(lsd.manoeuverAngle);
     168              :     }
     169              : }
     170              : 
     171              : 
     172              : double
     173      1323719 : MSParkingArea::getLastFreePos(const SUMOVehicle& forVehicle, double brakePos) const {
     174      1323719 :     if (myCapacity == (int)myEndPositions.size()) {
     175              :         // keep enough space so that  parking vehicles can leave
     176              : #ifdef DEBUG_GET_LAST_FREE_POS
     177              :         if (DEBUG_COND2(forVehicle)) {
     178              :             std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " allOccupied\n";
     179              :         }
     180              : #endif
     181       763575 :         return myLastFreePos - forVehicle.getVehicleType().getMinGap() - POSITION_EPS;
     182              :     } else {
     183       560144 :         const double minPos = MIN2(myEndPos, brakePos);
     184       560144 :         if (myLastFreePos >= minPos) {
     185              : #ifdef DEBUG_GET_LAST_FREE_POS
     186              :             if (DEBUG_COND2(forVehicle)) {
     187              :                 std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " using myLastFreePos=" << myLastFreePos << "\n";
     188              :             }
     189              : #endif
     190              :             return myLastFreePos;
     191              :         } else {
     192              :             // find free pos after minPos
     193        39490 :             for (const auto& lsd : mySpaceOccupancies) {
     194        38773 :                 if (lsd.vehicle == nullptr && lsd.endPos >= minPos) {
     195              : #ifdef DEBUG_GET_LAST_FREE_POS
     196              :                     if (DEBUG_COND2(forVehicle)) {
     197              :                         std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " nextFreePos=" << lsd.endPos << "\n";
     198              :                     }
     199              : #endif
     200              :                     return lsd.endPos;
     201              :                 }
     202              :             }
     203              :             // shouldn't happen. No good solution seems possible
     204              : #ifdef DEBUG_GET_LAST_FREE_POS
     205              :             if (DEBUG_COND2(forVehicle)) {
     206              :                 std::cout << SIMTIME << " getLastFreePos veh=" << forVehicle.getID() << " brakePos=" << brakePos << " myEndPos=" << myEndPos << " noGoodFreePos blockedAt=" << brakePos << "\n";
     207              :             }
     208              : #endif
     209              :             return brakePos;
     210              :         }
     211              :     }
     212              : }
     213              : 
     214              : Position
     215        14432 : MSParkingArea::getVehiclePosition(const SUMOVehicle& forVehicle) const {
     216        35336 :     for (const auto& lsd : mySpaceOccupancies) {
     217        35336 :         if (lsd.vehicle == &forVehicle) {
     218        14432 :             return lsd.position;
     219              :         }
     220              :     }
     221            0 :     return Position::INVALID;
     222              : }
     223              : 
     224              : 
     225              : double
     226        69056 : MSParkingArea::getInsertionPosition(const SUMOVehicle& forVehicle) const {
     227        69056 :     if (myDepartPosDefinition == DepartPosDefinition::GIVEN) {
     228          250 :         return myDepartPos;
     229              :     }
     230       193988 :     for (const auto& lsd : mySpaceOccupancies) {
     231       193980 :         if (lsd.vehicle == &forVehicle) {
     232        68798 :             return lsd.endPos;
     233              :         }
     234              :     }
     235              :     return -1;
     236              : }
     237              : 
     238              : 
     239              : double
     240        12635 : MSParkingArea::getVehicleAngle(const SUMOVehicle& forVehicle) const {
     241        34434 :     for (const auto& lsd : mySpaceOccupancies) {
     242        34417 :         if (lsd.vehicle == &forVehicle) {
     243        12618 :             return (lsd.rotation - 90.) * (double) M_PI / (double) 180.0;
     244              :         }
     245              :     }
     246              :     return 0;
     247              : }
     248              : 
     249              : double
     250         3621 : MSParkingArea::getVehicleSlope(const SUMOVehicle& forVehicle) const {
     251        12171 :     for (const auto& lsd : mySpaceOccupancies) {
     252        12171 :         if (lsd.vehicle == &forVehicle) {
     253         3621 :             return lsd.slope;
     254              :         }
     255              :     }
     256              :     return 0;
     257              : }
     258              : 
     259              : double
     260           30 : MSParkingArea::getGUIAngle(const SUMOVehicle& forVehicle) const {
     261           60 :     for (const auto& lsd : mySpaceOccupancies) {
     262           60 :         if (lsd.vehicle == &forVehicle) {
     263           30 :             if (lsd.manoeuverAngle > 180.) {
     264           15 :                 return DEG2RAD(lsd.manoeuverAngle - 360.);
     265              :             } else {
     266           15 :                 return DEG2RAD(lsd.manoeuverAngle);
     267              :             }
     268              :         }
     269              :     }
     270              :     return 0.;
     271              : }
     272              : 
     273              : int
     274           30 : MSParkingArea::getManoeuverAngle(const SUMOVehicle& forVehicle) const {
     275           60 :     for (const auto& lsd : mySpaceOccupancies) {
     276           60 :         if (lsd.vehicle == &forVehicle) {
     277           30 :             if (lsd.sideIsLHS) {
     278           30 :                 return abs(int(lsd.manoeuverAngle)) % 180;
     279              :             } else {
     280            0 :                 return abs(abs(int(lsd.manoeuverAngle)) % 180 - 180) % 180;
     281              :             }
     282              :         }
     283              :     }
     284              :     return 0;
     285              : }
     286              : 
     287              : int
     288        46662 : MSParkingArea::getLotIndex(const SUMOVehicle* veh) const {
     289        46662 :     if (veh->getPositionOnLane() > myLastFreePos) {
     290              :         // vehicle has gone past myLastFreePos and we need to find the actual lot
     291              :         int closestLot = -1;
     292        10022 :         for (int i = 0; i < (int)mySpaceOccupancies.size(); i++) {
     293         9686 :             const LotSpaceDefinition lsd = mySpaceOccupancies[i];
     294         9686 :             if (lsd.vehicle == nullptr) {
     295              :                 closestLot = i;
     296         3766 :                 if (lsd.endPos >= veh->getPositionOnLane()) {
     297              :                     return i;
     298              :                 }
     299              :             }
     300              :         }
     301          336 :         return closestLot;
     302              :     }
     303        44942 :     if (myOnRoad && myLastFreePos - veh->getPositionOnLane() > POSITION_EPS) {
     304              :         // for on-road parking we need to be precise
     305              :         return -1;
     306              :     }
     307         7182 :     return myLastFreeLot;
     308              : }
     309              : 
     310              : void
     311         7362 : MSParkingArea::enter(SUMOVehicle* veh) {
     312         7362 :     double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
     313         7362 :     double end = veh->getPositionOnLane() - veh->getVehicleType().getLength();
     314         7362 :     if (myUpdateEvent == nullptr) {
     315         6961 :         myUpdateEvent = new WrappingCommand<MSParkingArea>(this, &MSParkingArea::updateOccupancy);
     316         6961 :         MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myUpdateEvent);
     317              :     }
     318         7362 :     int lotIndex = getLotIndex(veh);
     319         7362 :     if (lotIndex < 0) {
     320            0 :         WRITE_WARNING("Unsuitable parking position for vehicle '" + veh->getID() + "' at parkingArea '" + getID() + "' time=" + time2string(SIMSTEP));
     321            0 :         lotIndex = myLastFreeLot;
     322              :     }
     323              : #ifdef DEBUG_GET_LAST_FREE_POS
     324              :     ((SUMOVehicleParameter&)veh->getParameter()).setParameter("lotIndex", toString(lotIndex));
     325              : #endif
     326              :     assert(myLastFreePos >= 0);
     327              :     assert(lotIndex < (int)mySpaceOccupancies.size());
     328         7362 :     mySpaceOccupancies[lotIndex].vehicle = veh;
     329         7362 :     myEndPositions[veh] = std::pair<double, double>(beg, end);
     330         7362 :     computeLastFreePos();
     331              :     // current search ends here
     332         7362 :     veh->setNumberParkingReroutes(0);
     333         7362 : }
     334              : 
     335              : 
     336              : void
     337         6068 : MSParkingArea::leaveFrom(SUMOVehicle* what) {
     338              :     assert(myEndPositions.find(what) != myEndPositions.end());
     339         6068 :     if (myUpdateEvent == nullptr) {
     340         5993 :         myUpdateEvent = new WrappingCommand<MSParkingArea>(this, &MSParkingArea::updateOccupancy);
     341         5993 :         MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myUpdateEvent);
     342              :     }
     343        17869 :     for (auto& lsd : mySpaceOccupancies) {
     344        17869 :         if (lsd.vehicle == what) {
     345         6068 :             lsd.vehicle = nullptr;
     346         6068 :             break;
     347              :         }
     348              :     }
     349              :     myEndPositions.erase(myEndPositions.find(what));
     350         6068 :     computeLastFreePos();
     351         6068 : }
     352              : 
     353              : 
     354              : SUMOTime
     355        12954 : MSParkingArea::updateOccupancy(SUMOTime /* currentTime */) {
     356        12954 :     myLastStepOccupancy = getOccupancy();
     357        12954 :     myUpdateEvent = nullptr;
     358        12954 :     return 0;
     359              : }
     360              : 
     361              : 
     362            0 : MSParkingArea::LotSpaceDefinition::LotSpaceDefinition() :
     363            0 :     index(-1),
     364            0 :     vehicle(nullptr),
     365            0 :     rotation(0),
     366            0 :     slope(0),
     367            0 :     width(0),
     368            0 :     length(0),
     369            0 :     endPos(0),
     370            0 :     manoeuverAngle(0),
     371            0 :     sideIsLHS(false) {
     372            0 : }
     373              : 
     374              : 
     375        48519 : MSParkingArea::LotSpaceDefinition::LotSpaceDefinition(int index_, SUMOVehicle* vehicle_, double x, double y, double z, double rotation_, double slope_, double width_, double length_) :
     376        48519 :     index(index_),
     377        48519 :     vehicle(vehicle_),
     378              :     position(Position(x, y, z)),
     379        48519 :     rotation(rotation_),
     380        48519 :     slope(slope_),
     381        48519 :     width(width_),
     382        48519 :     length(length_),
     383        48519 :     endPos(0),
     384        48519 :     manoeuverAngle(0),
     385        48519 :     sideIsLHS(false) {
     386        48519 : }
     387              : 
     388              : 
     389              : void
     390        63062 : MSParkingArea::computeLastFreePos() {
     391        63062 :     myLastFreeLot = -1;
     392        63062 :     myLastFreePos = myBegPos;
     393        63062 :     myEgressBlocked = false;
     394        89806 :     for (auto& lsd : mySpaceOccupancies) {
     395        87294 :         if (lsd.vehicle == nullptr
     396        87294 :                 || (getOccupancy() == getCapacity()
     397         8199 :                     && lsd.vehicle->remainingStopDuration() <= 0
     398          961 :                     && !lsd.vehicle->isStoppedTriggered())) {
     399        60550 :             if (lsd.vehicle == nullptr) {
     400        59692 :                 myLastFreeLot = lsd.index;
     401        59692 :                 myLastFreePos = lsd.endPos;
     402              :             } else {
     403              :                 // vehicle wants to exit the parking area
     404          858 :                 myLastFreeLot = lsd.index;
     405          858 :                 myLastFreePos = lsd.endPos - lsd.vehicle->getVehicleType().getLength() - POSITION_EPS;
     406          858 :                 myEgressBlocked = true;
     407              :             }
     408              :             break;
     409              :         } else {
     410        26744 :             myLastFreePos = MIN2(myLastFreePos,
     411        26744 :                                  lsd.endPos - lsd.vehicle->getVehicleType().getLength() - NUMERICAL_EPS);
     412              :         }
     413              :     }
     414        63062 : }
     415              : 
     416              : 
     417              : double
     418       732815 : MSParkingArea::getLastFreePosWithReservation(SUMOTime t, const SUMOVehicle& forVehicle, double brakePos) {
     419       732815 :     if (forVehicle.getLane() != &myLane) {
     420              :         // for different lanes, do not consider reservations to avoid lane-order
     421              :         // dependency in parallel simulation
     422              : #ifdef DEBUG_RESERVATIONS
     423              :         if (DEBUG_COND2(forVehicle)) {
     424              :             std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " other lane\n";
     425              :         }
     426              : #endif
     427       560478 :         if (myNumAlternatives > 0 && getOccupancy() == getCapacity()) {
     428              :             // ensure that the vehicle reaches the rerouter lane
     429       155650 :             return MAX2(myBegPos, MIN2(POSITION_EPS, myEndPos));
     430              :         } else {
     431       404828 :             return getLastFreePos(forVehicle, brakePos);
     432              :         }
     433              :     }
     434       172337 :     if (t > myReservationTime) {
     435              : #ifdef DEBUG_RESERVATIONS
     436              :         if (DEBUG_COND2(forVehicle)) {
     437              :             std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " first reservation\n";
     438              :         }
     439              : #endif
     440        91698 :         myReservationTime = t;
     441        91698 :         myReservations = 1;
     442        91698 :         myReservationMaxLength = forVehicle.getVehicleType().getLength();
     443       868484 :         for (const auto& lsd : mySpaceOccupancies) {
     444       776786 :             if (lsd.vehicle != nullptr) {
     445       456140 :                 myReservationMaxLength = MAX2(myReservationMaxLength, lsd.vehicle->getVehicleType().getLength());
     446              :             }
     447              :         }
     448        91698 :         return getLastFreePos(forVehicle, brakePos);
     449              :     } else {
     450        80639 :         if (myCapacity > getOccupancy() + myReservations) {
     451              : #ifdef DEBUG_RESERVATIONS
     452              :             if (DEBUG_COND2(forVehicle)) {
     453              :                 std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " res=" << myReservations << " enough space\n";
     454              :             }
     455              : #endif
     456        34823 :             myReservations++;
     457        34823 :             myReservationMaxLength = MAX2(myReservationMaxLength, forVehicle.getVehicleType().getLength());
     458        34823 :             return getLastFreePos(forVehicle, brakePos);
     459              :         } else {
     460        45816 :             if (myCapacity == 0) {
     461          620 :                 return getLastFreePos(forVehicle, brakePos);
     462              :             } else {
     463              : #ifdef DEBUG_RESERVATIONS
     464              :                 if (DEBUG_COND2(forVehicle)) std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID()
     465              :                                                            << " res=" << myReservations << " resTime=" << myReservationTime << " reserved full, maxLen=" << myReservationMaxLength << " endPos=" << mySpaceOccupancies[0].endPos << "\n";
     466              : #endif
     467        45196 :                 return (mySpaceOccupancies[0].endPos
     468        45196 :                         - myReservationMaxLength
     469        45196 :                         - forVehicle.getVehicleType().getMinGap()
     470        45196 :                         - NUMERICAL_EPS);
     471              :             }
     472              :         }
     473              :     }
     474              : }
     475              : 
     476              : 
     477              : double
     478          600 : MSParkingArea::getWidth() const {
     479          600 :     return myWidth;
     480              : }
     481              : 
     482              : 
     483              : double
     484          600 : MSParkingArea::getLength() const {
     485          600 :     return myLength;
     486              : }
     487              : 
     488              : 
     489              : double
     490          600 : MSParkingArea::getAngle() const {
     491          600 :     return myAngle;
     492              : }
     493              : 
     494              : 
     495              : int
     496       743671 : MSParkingArea::getCapacity() const {
     497       743671 :     return myCapacity;
     498              : }
     499              : 
     500              : 
     501              : bool
     502       381358 : MSParkingArea::parkOnRoad() const {
     503       381358 :     return myOnRoad;
     504              : }
     505              : 
     506              : 
     507              : int
     508       584566 : MSParkingArea::getOccupancy() const {
     509       584566 :     return (int)myEndPositions.size() - (myEgressBlocked ? 1 : 0);
     510              : }
     511              : 
     512              : 
     513              : int
     514       139483 : MSParkingArea::getOccupancyIncludingBlocked() const {
     515       139483 :     return (int)myEndPositions.size();
     516              : }
     517              : 
     518              : 
     519              : int
     520        49436 : MSParkingArea::getLastStepOccupancy() const {
     521        49436 :     return myLastStepOccupancy;
     522              : }
     523              : 
     524              : 
     525              : void
     526            0 : MSParkingArea::accept(std::string badge) {
     527              :     myAcceptedBadges.insert(badge);
     528            0 : }
     529              : 
     530              : 
     531              : void
     532            0 : MSParkingArea::accept(std::vector<std::string> badges) {
     533              :     myAcceptedBadges.insert(badges.begin(), badges.end());
     534            0 : }
     535              : 
     536              : 
     537              : void
     538            0 : MSParkingArea::refuse(std::string badge) {
     539              :     myAcceptedBadges.erase(badge);
     540            0 : }
     541              : 
     542              : 
     543              : bool
     544        16379 : MSParkingArea::accepts(MSBaseVehicle* veh) const {
     545        16379 :     if (myAcceptedBadges.size() == 0) {
     546              :         return true;
     547              :     } else {
     548           21 :         std::vector<std::string> vehicleBadges = veh->getParkingBadges();
     549           21 :         for (auto badge : vehicleBadges) {
     550              :             if (myAcceptedBadges.count(badge) != 0) {
     551              :                 return true;
     552              :             }
     553              :         }
     554            7 :         return false;
     555           21 :     }
     556              : }
     557              : 
     558              : 
     559              : void
     560         1113 : MSParkingArea::notifyEgressBlocked() {
     561         1113 :     computeLastFreePos();
     562         1113 : }
     563              : 
     564              : 
     565              : int
     566            0 : MSParkingArea::getNumAlternatives() const {
     567            0 :     return myNumAlternatives;
     568              : }
     569              : 
     570              : 
     571              : void
     572        12590 : MSParkingArea::setNumAlternatives(int alternatives) {
     573        12590 :     myNumAlternatives = MAX2(myNumAlternatives, alternatives);
     574        12590 : }
     575              : 
     576              : 
     577              : void
     578        22898 : MSParkingArea::setRoadsideCapacity(int capacity) {
     579              :     // reinit parking lot generation process
     580        22898 :     myRoadSideCapacity = capacity;
     581              : 
     582              :     // Initialize space occupancies if there is a road-side capacity
     583              :     // The overall number of lots is fixed and each lot accepts one vehicle regardless of size
     584        22898 :     const double spaceDim = myRoadSideCapacity > 0 ? myLane.interpolateLanePosToGeometryPos((myEndPos - myBegPos) / myRoadSideCapacity) : 7.5;
     585        22898 :     if (myLength == 0) {
     586        10542 :         myLength = spaceDim;
     587              :     }
     588              :     mySpaceOccupancies.clear();
     589        22898 :     myCapacity = 0;
     590        70817 :     for (int i = 0; i < myRoadSideCapacity; ++i) {
     591              :         // calculate pos, angle and slope of parking lot space
     592        47919 :         const Position pos = GeomHelper::calculateLotSpacePosition(myShape, i, spaceDim, myAngle, myWidth, myLength);
     593        47919 :         double spaceAngle = GeomHelper::calculateLotSpaceAngle(myShape, i, spaceDim, myAngle);
     594        47919 :         double spaceSlope = GeomHelper::calculateLotSpaceSlope(myShape, i, spaceDim);
     595              :         // add lotEntry
     596        47919 :         addLotEntry(pos.x(), pos.y(), pos.z(), myWidth, myLength, spaceAngle, spaceSlope);
     597              :         // update endPos
     598       141743 :         mySpaceOccupancies.back().endPos = MIN2(myEndPos, myBegPos + MAX2(POSITION_EPS, spaceDim * (i + 1)));
     599              :     }
     600        22898 : }
     601              : 
     602              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1