LCOV - code coverage report
Current view: top level - src/microsim - MSVehicleControl.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 97.7 % 302 295
Test Date: 2026-06-15 15:46:12 Functions: 97.2 % 36 35

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 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    MSVehicleControl.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Wed, 10. Dec 2003
      19              : ///
      20              : // The class responsible for building and deletion of vehicles
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include "MSVehicleControl.h"
      25              : #include "MSVehicle.h"
      26              : #include "MSLane.h"
      27              : #include "MSEdge.h"
      28              : #include "MSNet.h"
      29              : #include "MSRouteHandler.h"
      30              : #include "MSEventControl.h"
      31              : #include "MSStop.h"
      32              : #include <microsim/devices/MSVehicleDevice.h>
      33              : #include <microsim/devices/MSDevice_Tripinfo.h>
      34              : #include <utils/common/FileHelpers.h>
      35              : #include <utils/common/Named.h>
      36              : #include <utils/common/RGBColor.h>
      37              : #include <utils/vehicle/SUMOVTypeParameter.h>
      38              : #include <utils/iodevices/OutputDevice.h>
      39              : #include <utils/options/OptionsCont.h>
      40              : #include <utils/router/IntermodalRouter.h>
      41              : 
      42              : 
      43              : // ===========================================================================
      44              : // member method definitions
      45              : // ===========================================================================
      46        42501 : MSVehicleControl::MSVehicleControl() :
      47        42501 :     myLoadedVehNo(0),
      48        42501 :     myRunningVehNo(0),
      49        42501 :     myEndedVehNo(0),
      50        42501 :     myDiscarded(0),
      51        42501 :     myCollisions(0),
      52        42501 :     myTeleportsCollision(0),
      53        42501 :     myTeleportsJam(0),
      54        42501 :     myTeleportsYield(0),
      55        42501 :     myTeleportsWrongLane(0),
      56        42501 :     myEmergencyStops(0),
      57        42501 :     myEmergencyBrakingCount(0),
      58        42501 :     myStoppedVehicles(0),
      59        42501 :     myTotalDepartureDelay(0),
      60        42501 :     myTotalTravelTime(0),
      61        42501 :     myWaitingForTransportable(0),
      62        42501 :     myMaxSpeedFactor(1),
      63        42501 :     myMinDeceleration(SUMOVTypeParameter::getDefaultDecel(SVC_IGNORING)),
      64        42501 :     myMinDecelerationRail(SUMOVTypeParameter::getDefaultDecel(SVC_RAIL)),
      65        42501 :     myMaxMinGap(0),
      66        85002 :     myPendingRemovals(MSGlobals::gNumSimThreads > 1) {
      67              : 
      68        42501 :     initDefaultTypes();
      69        42501 :     myScale = OptionsCont::getOptions().getFloat("scale");
      70        42501 :     myKeepTime = string2time(OptionsCont::getOptions().getString("keep-after-arrival"));
      71        42501 : }
      72              : 
      73              : 
      74        71230 : MSVehicleControl::~MSVehicleControl() {
      75        41881 :     clearState(false);
      76        71230 : }
      77              : 
      78              : 
      79              : void
      80        42669 : MSVehicleControl::initDefaultTypes() {
      81        42669 :     SUMOVTypeParameter defType(DEFAULT_VTYPE_ID, SVC_PASSENGER);
      82        42669 :     myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
      83              : 
      84        42669 :     SUMOVTypeParameter defPedType(DEFAULT_PEDTYPE_ID, SVC_PEDESTRIAN);
      85        42669 :     defPedType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
      86        42669 :     myVTypeDict[DEFAULT_PEDTYPE_ID] = MSVehicleType::build(defPedType);
      87              : 
      88        42669 :     SUMOVTypeParameter defBikeType(DEFAULT_BIKETYPE_ID, SVC_BICYCLE);
      89        42669 :     defBikeType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
      90        42669 :     myVTypeDict[DEFAULT_BIKETYPE_ID] = MSVehicleType::build(defBikeType);
      91              : 
      92        42669 :     SUMOVTypeParameter defTaxiType(DEFAULT_TAXITYPE_ID, SVC_TAXI);
      93        42669 :     defTaxiType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
      94        42669 :     myVTypeDict[DEFAULT_TAXITYPE_ID] = MSVehicleType::build(defTaxiType);
      95              : 
      96        42669 :     SUMOVTypeParameter defRailType(DEFAULT_RAILTYPE_ID, SVC_RAIL);
      97        42669 :     defRailType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
      98        42669 :     myVTypeDict[DEFAULT_RAILTYPE_ID] = MSVehicleType::build(defRailType);
      99              : 
     100        42669 :     SUMOVTypeParameter defContainerType(DEFAULT_CONTAINERTYPE_ID, SVC_CONTAINER);
     101        42669 :     defContainerType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
     102        42669 :     myVTypeDict[DEFAULT_CONTAINERTYPE_ID] = MSVehicleType::build(defContainerType);
     103              : 
     104              :     myReplaceableDefaultVTypes = DEFAULT_VTYPES;
     105        42669 : }
     106              : 
     107              : 
     108              : SUMOVehicle*
     109      3862093 : MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
     110              :                                ConstMSRoutePtr route, MSVehicleType* type,
     111              :                                const bool ignoreStopErrors, const VehicleDefinitionSource source, bool addRouteStops) {
     112      3967183 :     const double speedFactor = type->computeChosenSpeedDeviation(defs->speedFactor, source == VehicleDefinitionSource::ROUTEFILE ? MSRouteHandler::getParsingRNG() : nullptr);
     113      7724186 :     MSVehicle* built = new MSVehicle(defs, route, type, speedFactor);
     114      3862093 :     initVehicle(built, ignoreStopErrors, addRouteStops, source);
     115      3862037 :     return built;
     116              : }
     117              : 
     118              : 
     119              : void
     120      5256339 : MSVehicleControl::initVehicle(MSBaseVehicle* built, const bool ignoreStopErrors, bool addRouteStops, const VehicleDefinitionSource source) {
     121      5256339 :     myLoadedVehNo++;
     122              :     try {
     123      5256339 :         built->initDevices();
     124      5256300 :         if (source != VehicleDefinitionSource::STATE) {
     125      5251392 :             built->addStops(ignoreStopErrors, nullptr, addRouteStops);
     126              :         }
     127          116 :     } catch (ProcessError&) {
     128          116 :         delete built;
     129          116 :         throw;
     130          116 :     }
     131      5256222 :     MSNet::getInstance()->informVehicleStateListener(built, MSNet::VehicleState::BUILT);
     132      5256222 : }
     133              : 
     134              : 
     135              : void
     136      4017967 : MSVehicleControl::scheduleVehicleRemoval(SUMOVehicle* veh, bool checkDuplicate) {
     137              :     assert(myRunningVehNo > 0);
     138      4017967 :     if (!checkDuplicate || !isPendingRemoval(veh)) {
     139      4017967 :         myPendingRemovals.push_back(veh);
     140              :     }
     141      4017967 : }
     142              : 
     143              : 
     144              : bool
     145        17549 : MSVehicleControl::isPendingRemoval(SUMOVehicle* veh) {
     146              : #ifdef HAVE_FOX
     147        17549 :     return myPendingRemovals.contains(veh);
     148              : #else
     149              :     return std::find(myPendingRemovals.begin(), myPendingRemovals.end(), veh) == myPendingRemovals.end();
     150              : #endif
     151              : }
     152              : 
     153              : 
     154              : void
     155    108861968 : MSVehicleControl::removePending() {
     156    125696916 :     OutputDevice* const tripinfoOut = OptionsCont::getOptions().isSet("tripinfo-output") ? &OutputDevice::getDeviceByOption("tripinfo-output") : nullptr;
     157              : #ifdef HAVE_FOX
     158              :     std::vector<SUMOVehicle*>& vehs = myPendingRemovals.getContainer();
     159              : #else
     160              :     std::vector<SUMOVehicle*>& vehs = myPendingRemovals;
     161              : #endif
     162    108861968 :     std::sort(vehs.begin(), vehs.end(), ComparatorNumericalIdLess());
     163    112879931 :     for (SUMOVehicle* const veh : vehs) {
     164      4017963 :         myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
     165      4017963 :         myRunningVehNo--;
     166      4017963 :         MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VehicleState::ARRIVED);
     167              :         // vehicle is equipped with tripinfo device (not all vehicles are)
     168      4017963 :         const bool hasTripinfo = veh->getDevice(typeid(MSDevice_Tripinfo)) != nullptr;
     169      7074820 :         for (MSVehicleDevice* const dev : veh->getDevices()) {
     170      3772071 :             dev->generateOutput(hasTripinfo ? tripinfoOut : nullptr);
     171              :         }
     172      4017963 :         if (tripinfoOut != nullptr && hasTripinfo) {
     173              :             // close tag after tripinfo (possibly including emissions from another device) have been written
     174       479848 :             tripinfoOut->closeTag();
     175              :         }
     176      4017963 :         if (myKeepTime == 0) {
     177      4017950 :             deleteVehicle(veh);
     178              :         } else {
     179           13 :             deleteKeptVehicle(veh);
     180              :         }
     181              :     }
     182              :     vehs.clear();
     183    108861968 :     if (tripinfoOut != nullptr) {
     184              :         // there seem to be people who think reading an unfinished xml is a good idea ;-)
     185              :         tripinfoOut->flush();
     186              :     }
     187              : #ifdef HAVE_FOX
     188              :     myPendingRemovals.unlock();
     189              : #endif
     190    108861968 : }
     191              : 
     192              : 
     193              : void
     194           16 : MSVehicleControl::deleteKeptVehicle(SUMOVehicle* veh) {
     195           16 :     myEndedVehNo++;
     196           16 :     MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(new DeleteKeptVehicle(veh), SIMSTEP + myKeepTime);
     197           16 : }
     198              : 
     199              : void
     200      4168457 : MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) {
     201      4168457 :     ++myRunningVehNo;
     202      4168457 :     myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart));
     203      4168457 :     MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VehicleState::DEPARTED);
     204      4168457 :     myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor());
     205      4168457 :     myMaxMinGap = MAX2(myMaxMinGap, v.getVehicleType().getMinGap());
     206      4168457 :     const double maxDecel = v.getVehicleType().getCarFollowModel().getMaxDecel();
     207      4168457 :     if ((v.getVClass() & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) {
     208              :         // only  worry about deceleration of road users
     209      8119792 :         myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
     210         8109 :     } else if ((v.getVClass() & SVC_RAIL_CLASSES) != 0) {
     211         7791 :         myMinDecelerationRail = MIN2(myMinDecelerationRail, maxDecel);
     212         7791 :         if ((v.getEdge()->getPermissions() & SVC_ROAD_MOTOR_CLASSES) != 0) {
     213              :             // shared rail/road
     214          946 :             myMinDeceleration = MIN2(myMinDeceleration, maxDecel);
     215              :         }
     216              :     }
     217      4168457 : }
     218              : 
     219              : 
     220              : void
     221          458 : MSVehicleControl::setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime, double maxSpeedFactor, double minDecel) {
     222          458 :     myRunningVehNo = runningVehNo;
     223          458 :     myLoadedVehNo = loadedVehNo;
     224          458 :     myEndedVehNo = endedVehNo;
     225          458 :     myTotalDepartureDelay = totalDepartureDelay;
     226          458 :     myTotalTravelTime = totalTravelTime;
     227          458 :     myMaxSpeedFactor = maxSpeedFactor;
     228          458 :     myMinDeceleration = minDecel;
     229          458 : }
     230              : 
     231              : 
     232              : void
     233          529 : MSVehicleControl::saveState(OutputDevice& out) {
     234          529 :     out.openTag(SUMO_TAG_DELAY);
     235          529 :     out.writeAttr(SUMO_ATTR_NUMBER, myRunningVehNo);
     236          529 :     out.writeAttr(SUMO_ATTR_BEGIN, myLoadedVehNo);
     237          529 :     out.writeAttr(SUMO_ATTR_END, myEndedVehNo);
     238          529 :     out.writeAttr(SUMO_ATTR_DEPART, myTotalDepartureDelay);
     239          529 :     out.writeAttr(SUMO_ATTR_TIME, myTotalTravelTime);
     240          529 :     out.writeAttr(SUMO_ATTR_SPEEDFACTOR, myMaxSpeedFactor);
     241          529 :     out.writeAttr(SUMO_ATTR_DECEL, myMinDeceleration);
     242          529 :     const SUMOTime loaderTime = MSNet::getInstance()->getLoaderTime();
     243          529 :     if (loaderTime > 0 && loaderTime != SUMOTime_MAX) {
     244           34 :         out.writeAttr(SUMO_ATTR_LOADERTIME, MSNet::getInstance()->getLoaderTime());
     245              :     }
     246         1058 :     out.closeTag();
     247              :     // save vehicle types
     248         4500 :     for (const auto& item : myVTypeDict) {
     249         3971 :         if (myReplaceableDefaultVTypes.count(item.first) == 0) {
     250         1061 :             item.second->getParameter().write(out);
     251              :         }
     252              :     }
     253          711 :     for (const auto& item : myVTypeDistDict) {
     254          182 :         out.openTag(SUMO_TAG_VTYPE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, item.first);
     255          182 :         out.writeAttr(SUMO_ATTR_VTYPES, item.second->getVals());
     256          182 :         out.writeAttr(SUMO_ATTR_PROBS, item.second->getProbs());
     257          364 :         out.closeTag();
     258              :     }
     259              :     std::vector<SUMOVehicle*> sortedVehs;
     260         4992 :     for (const auto& item : myVehicleDict) {
     261         4463 :         sortedVehs.push_back(item.second);
     262              :     }
     263          529 :     std::sort(sortedVehs.begin(), sortedVehs.end(), ComparatorNumericalIdLess());
     264         4992 :     for (SUMOVehicle* veh : sortedVehs) {
     265         4463 :         veh->saveState(out);
     266              :     }
     267          529 : }
     268              : 
     269              : 
     270              : void
     271        42049 : MSVehicleControl::clearState(const bool reinit) {
     272       366979 :     for (const auto& item : myVehicleDict) {
     273       324930 :         delete item.second;
     274              :     }
     275              :     myVehicleDict.clear();
     276              :     // delete vehicle type distributions
     277        42502 :     for (const auto& item : myVTypeDistDict) {
     278          906 :         delete item.second;
     279              :     }
     280              :     myVTypeDistDict.clear();
     281              :     // delete vehicle types
     282       345759 :     for (const auto& item : myVTypeDict) {
     283       303710 :         delete item.second;
     284              :     }
     285              :     myVTypeDict.clear();
     286        42049 :     myPendingRemovals.clear(); // could be leftovers from MSVehicleTransfer::checkInsertions (teleport beyond arrival)
     287        42049 :     if (reinit) {
     288          168 :         initDefaultTypes();
     289              :     }
     290        42049 :     myLoadedVehNo = 0;
     291        42049 :     myRunningVehNo = 0;
     292        42049 :     myEndedVehNo = 0;
     293        42049 :     myDiscarded = 0;
     294        42049 :     myCollisions = 0;
     295        42049 :     myTeleportsCollision = 0;
     296        42049 :     myTeleportsJam = 0;
     297        42049 :     myTeleportsYield = 0;
     298        42049 :     myTeleportsWrongLane = 0;
     299        42049 :     myEmergencyStops = 0;
     300        42049 :     myEmergencyBrakingCount = 0;
     301        42049 :     myStoppedVehicles = 0;
     302        42049 :     myTotalDepartureDelay = 0;
     303        42049 :     myTotalTravelTime = 0;
     304        42049 : }
     305              : 
     306              : 
     307              : bool
     308      5151095 : MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
     309              :     VehicleDictType::iterator it = myVehicleDict.find(id);
     310      5151095 :     if (it == myVehicleDict.end()) {
     311              :         // id not in myVehicleDict.
     312      5151095 :         myVehicleDict[id] = v;
     313      5151095 :         handleTriggeredDepart(v, true);
     314      5151095 :         const SUMOVehicleParameter& pars = v->getParameter();
     315      5151095 :         if (v->getVClass() != SVC_TAXI && pars.line != "" && pars.repetitionNumber < 0) {
     316         1154 :             myPTVehicles.push_back(v);
     317              :         }
     318      5151095 :         return true;
     319              :     }
     320              :     return false;
     321              : }
     322              : 
     323              : 
     324              : void
     325      5155592 : MSVehicleControl::handleTriggeredDepart(SUMOVehicle* v, bool add) {
     326      5155592 :     const SUMOVehicleParameter& pars = v->getParameter();
     327      5155592 :     if (pars.departProcedure == DepartDefinition::TRIGGERED || pars.departProcedure == DepartDefinition::CONTAINER_TRIGGERED || pars.departProcedure == DepartDefinition::SPLIT) {
     328         4278 :         const MSEdge* const firstEdge = v->getRoute().getEdges()[pars.departEdge];
     329         4278 :         if (add) {
     330         2204 :             if (!MSGlobals::gUseMesoSim) {
     331              :                 // position will be checked against person position later
     332         1795 :                 static_cast<MSVehicle*>(v)->setTentativeLaneAndPosition(nullptr, v->getParameter().departPos);
     333              :             }
     334         2204 :             if (firstEdge->isTazConnector()) {
     335           78 :                 for (MSEdge* out : firstEdge->getSuccessors()) {
     336           51 :                     out->addWaiting(v);
     337              :                 }
     338              :             } else {
     339         2177 :                 firstEdge->addWaiting(v);
     340              :             }
     341              :             registerOneWaiting();
     342              :         } else {
     343         2074 :             if (firstEdge->isTazConnector()) {
     344           14 :                 for (MSEdge* out : firstEdge->getSuccessors()) {
     345            7 :                     out->removeWaiting(v);
     346              :                 }
     347              :             } else {
     348         2067 :                 firstEdge->removeWaiting(v);
     349              :             }
     350              :             unregisterOneWaiting();
     351              :         }
     352              :     }
     353      5155592 : }
     354              : 
     355              : 
     356              : SUMOVehicle*
     357     22728236 : MSVehicleControl::getVehicle(const std::string& id) const {
     358              :     VehicleDictType::const_iterator it = myVehicleDict.find(id);
     359     22728236 :     if (it == myVehicleDict.end()) {
     360              :         return nullptr;
     361              :     }
     362     17381974 :     return it->second;
     363              : }
     364              : 
     365              : 
     366              : void
     367      4931212 : MSVehicleControl::deleteVehicle(SUMOVehicle* veh, bool discard, bool wasKept) {
     368      4931212 :     if (!wasKept) {
     369      4931199 :         myEndedVehNo++;
     370      4931199 :         if (discard) {
     371       913249 :             myDiscarded++;
     372              :         }
     373              :     }
     374      4931212 :     if (veh != nullptr) {
     375              :         myVehicleDict.erase(veh->getID());
     376              :     }
     377      4931212 :     auto ptVehIt = std::find(myPTVehicles.begin(), myPTVehicles.end(), veh);
     378      4931212 :     if (ptVehIt != myPTVehicles.end()) {
     379          944 :         myPTVehicles.erase(ptVehIt);
     380              :     }
     381      4931212 :     delete veh;
     382      4931212 : }
     383              : 
     384              : 
     385              : bool
     386        63720 : MSVehicleControl::checkVType(const std::string& id) {
     387        63720 :     if (myReplaceableDefaultVTypes.erase(id) > 0) {
     388        10112 :         delete myVTypeDict[id];
     389              :         myVTypeDict.erase(myVTypeDict.find(id));
     390              :     } else {
     391        53608 :         if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
     392          195 :             return false;
     393              :         }
     394              :     }
     395              :     return true;
     396              : }
     397              : 
     398              : 
     399              : bool
     400        63267 : MSVehicleControl::addVType(MSVehicleType* vehType) {
     401        63267 :     if (checkVType(vehType->getID())) {
     402        63072 :         myVTypeDict[vehType->getID()] = vehType;
     403        63072 :         return true;
     404              :     }
     405              :     return false;
     406              : }
     407              : 
     408              : 
     409              : void
     410         1382 : MSVehicleControl::removeVType(const MSVehicleType* vehType) {
     411              :     assert(vehType != nullptr);
     412              :     assert(myVTypeDict.find(vehType->getID()) != myVTypeDict.end());
     413              :     myVTypeDict.erase(vehType->getID());
     414         1382 :     if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
     415              :         myVTypeToDist.erase(vehType->getID());
     416              :     }
     417         1382 :     delete vehType;
     418         1382 : }
     419              : 
     420              : 
     421              : bool
     422          453 : MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution) {
     423          453 :     if (checkVType(id)) {
     424          453 :         myVTypeDistDict[id] = vehTypeDistribution;
     425          453 :         std::vector<MSVehicleType*> vehTypes = vehTypeDistribution->getVals();
     426         1691 :         for (auto vehType : vehTypes) {
     427         1238 :             if (myVTypeToDist.find(vehType->getID()) != myVTypeToDist.end()) {
     428           42 :                 myVTypeToDist[vehType->getID()].insert(id);
     429              :             } else {
     430         3588 :                 myVTypeToDist[vehType->getID()] = { id };
     431              :             }
     432              :         }
     433              :         return true;
     434          453 :     }
     435              :     return false;
     436              : }
     437              : 
     438              : 
     439              : bool
     440        46313 : MSVehicleControl::hasVType(const std::string& id) const {
     441        46313 :     return myVTypeDict.count(id) > 0 || myVTypeDistDict.count(id) > 0;
     442              : }
     443              : 
     444              : 
     445              : bool
     446        19565 : MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
     447        19565 :     return myVTypeDistDict.count(id) > 0;
     448              : }
     449              : 
     450              : 
     451              : MSVehicleType*
     452      9842026 : MSVehicleControl::getVType(const std::string& id, SumoRNG* rng, bool readOnly) {
     453              :     VTypeDictType::iterator it = myVTypeDict.find(id);
     454      9842026 :     if (it == myVTypeDict.end()) {
     455              :         VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
     456      3898773 :         if (it2 == myVTypeDistDict.end()) {
     457              :             return nullptr;
     458              :         }
     459        84566 :         return it2->second->get(rng);
     460              :     }
     461     11861983 :     if (!readOnly && myReplaceableDefaultVTypes.erase(id) > 0) {
     462        20144 :         it->second->check();
     463              :     }
     464      5943253 :     return it->second;
     465              : }
     466              : 
     467              : 
     468              : void
     469          310 : MSVehicleControl::insertVTypeIDs(std::vector<std::string>& into) const {
     470          310 :     into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
     471         2470 :     for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
     472         2160 :         into.push_back((*i).first);
     473              :     }
     474          310 :     for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
     475            0 :         into.push_back((*i).first);
     476              :     }
     477          310 : }
     478              : 
     479              : 
     480              : const std::set<std::string>
     481       145351 : MSVehicleControl::getVTypeDistributionMembership(const std::string& id) const {
     482              :     std::map<std::string, std::set<std::string>>::const_iterator it = myVTypeToDist.find(id);
     483       145351 :     if (it == myVTypeToDist.end()) {
     484        60214 :         return std::set<std::string>();
     485              :     }
     486              :     return it->second;
     487              : }
     488              : 
     489              : 
     490              : const RandomDistributor<MSVehicleType*>*
     491       135596 : MSVehicleControl::getVTypeDistribution(const std::string& typeDistID) const {
     492              :     const auto it = myVTypeDistDict.find(typeDistID);
     493       135596 :     if (it != myVTypeDistDict.end()) {
     494         2192 :         return it->second;
     495              :     }
     496              :     return nullptr;
     497              : }
     498              : 
     499              : 
     500              : const std::vector<MSVehicleType*>
     501            0 : MSVehicleControl::getPedestrianTypes(void) const {
     502              :     std::vector<MSVehicleType*> pedestrianTypes;
     503            0 :     for (auto const& e : myVTypeDict)
     504            0 :         if (e.second->getVehicleClass() == SUMOVehicleClass::SVC_PEDESTRIAN) {
     505            0 :             pedestrianTypes.push_back(e.second);
     506              :         }
     507            0 :     return pedestrianTypes;
     508            0 : }
     509              : 
     510              : 
     511              : void
     512        28118 : MSVehicleControl::abortWaiting() {
     513        30065 :     for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
     514         1947 :         SUMOVehicle* veh = i->second;
     515              :         std::string waitReason;
     516         1947 :         if (veh->isStoppedTriggered()) {
     517         1873 :             const MSStop& stop = veh->getNextStop();
     518         1873 :             if (stop.triggered) {
     519              :                 waitReason = "for a person that will never come";
     520          124 :             } else if (stop.containerTriggered) {
     521              :                 waitReason = "for a container that will never come";
     522           36 :             } else if (stop.joinTriggered) {
     523           36 :                 if (stop.pars.join != "") {
     524           48 :                     waitReason = "to be joined to vehicle '" + stop.pars.join + "'";
     525              :                 } else {
     526              :                     waitReason = "for a joining vehicle that will never come";
     527              :                 }
     528              :             } else {
     529              :                 waitReason = "for an unknown trigger";
     530              :             }
     531           74 :         } else if (!veh->hasDeparted()) {
     532           74 :             if (veh->getParameter().departProcedure == DepartDefinition::SPLIT) {
     533              :                 waitReason = "for a train from which to split";
     534           58 :             } else if (veh->getParameter().departProcedure == DepartDefinition::TRIGGERED) {
     535              :                 waitReason = "at insertion for a person that will never come";
     536           22 :             } else if (veh->getParameter().departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
     537              :                 waitReason = "at insertion for a container that will never come";
     538              :             } else {
     539              :                 waitReason = "for an unknown departure trigger";
     540              :             }
     541              :         } else {
     542              :             waitReason = "for an unknown reason";
     543              :         }
     544         5841 :         WRITE_WARNINGF(TL("Vehicle '%' aborted waiting %."), i->first, waitReason);
     545              :     }
     546        28118 : }
     547              : 
     548              : 
     549              : int
     550       522721 : MSVehicleControl::getHaltingVehicleNo() const {
     551              :     int result = 0;
     552     75575773 :     for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
     553     75053052 :         const SUMOVehicle* veh = it->second;
     554     75053052 :         if ((veh->isOnRoad() || veh->isRemoteControlled()) && veh->getSpeed() < SUMO_const_haltingSpeed)  {
     555     18905441 :             result++;
     556              :         }
     557              :     }
     558       522721 :     return result;
     559              : }
     560              : 
     561              : 
     562              : std::pair<double, double>
     563       522721 : MSVehicleControl::getVehicleMeanSpeeds() const {
     564              :     double speedSum = 0;
     565              :     double relSpeedSum = 0;
     566              :     int count = 0;
     567     75575773 :     for (MSVehicleControl::constVehIt it = loadedVehBegin(); it != loadedVehEnd(); ++it) {
     568     75053052 :         const SUMOVehicle* veh = it->second;
     569     75053052 :         if ((veh->isOnRoad() || veh->isRemoteControlled()) && !veh->isStopped()) {
     570     42243186 :             count++;
     571     42243186 :             speedSum += veh->getSpeed();
     572     42243186 :             relSpeedSum += veh->getEdge()->getSpeedLimit() > 0 ? veh->getSpeed() / veh->getEdge()->getSpeedLimit() : 0;
     573              :         }
     574              :     }
     575       522721 :     if (count > 0) {
     576       427718 :         return std::make_pair(speedSum / count, relSpeedSum / count);
     577              :     } else {
     578        95003 :         return std::make_pair(-1, -1);
     579              :     }
     580              : }
     581              : 
     582              : 
     583              : int
     584      1391065 : MSVehicleControl::getQuota(double frac, int loaded) const {
     585      1391065 :     frac = frac < 0 ? myScale : frac;
     586              :     const int origLoaded = (loaded < 1
     587              :                             // the vehicle in question has already been loaded, hence  the '-1'
     588      1391065 :                             ? frac > 1. ? (int)(myLoadedVehNo / frac) : myLoadedVehNo - 1
     589              :                             // given transportable number reflects only previously loaded
     590       518517 :                             : frac > 1. ? (int)(loaded / frac) : loaded);
     591      1391065 :     return getScalingQuota(frac, origLoaded);
     592              : }
     593              : 
     594              : 
     595              : int
     596       552250 : MSVehicleControl::getTeleportCount() const {
     597       552250 :     return myTeleportsCollision + myTeleportsJam + myTeleportsYield + myTeleportsWrongLane;
     598              : }
     599              : 
     600              : 
     601              : void
     602         4940 : MSVehicleControl::adaptIntermodalRouter(MSTransportableRouter& router) const {
     603         5221 :     for (const SUMOVehicle* const veh : myPTVehicles) {
     604              :         // add single vehicles with line attribute which are not part of a flow
     605          281 :         ConstMSRoutePtr const route = MSRoute::dictionary(veh->getParameter().routeid);
     606          281 :         router.getNetwork()->addSchedule(veh->getParameter(), route == nullptr ? nullptr : &route->getStops());
     607              :     }
     608         4940 : }
     609              : 
     610              : // ===========================================================================
     611              : // MSVehicleControl::DeleteKeptVehicle method definitions
     612              : // ===========================================================================
     613              : 
     614              : SUMOTime
     615           13 : MSVehicleControl::DeleteKeptVehicle::execute(SUMOTime /*currentTime*/) {
     616           13 :     MSNet::getInstance()->getVehicleControl().deleteVehicle(myVehicle, false, true);
     617           13 :     return 0;
     618              : }
     619              : 
     620              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1