SUMO - Simulation of Urban MObility
MSVehicleControl.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // The class responsible for building and deletion of vehicles
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include "MSVehicleControl.h"
00034 #include "MSVehicle.h"
00035 #include "MSLane.h"
00036 #include "MSNet.h"
00037 #include <microsim/devices/MSDevice.h>
00038 #include <utils/common/FileHelpers.h>
00039 #include <utils/common/RGBColor.h>
00040 #include <utils/common/SUMOVTypeParameter.h>
00041 #include <utils/iodevices/BinaryInputDevice.h>
00042 #include <utils/iodevices/OutputDevice.h>
00043 #include <utils/options/OptionsCont.h>
00044 
00045 #ifdef CHECK_MEMORY_LEAKS
00046 #include <foreign/nvwa/debug_new.h>
00047 #endif // CHECK_MEMORY_LEAKS
00048 
00049 
00050 // ===========================================================================
00051 // member method definitions
00052 // ===========================================================================
00053 MSVehicleControl::MSVehicleControl() :
00054     myLoadedVehNo(0),
00055     myRunningVehNo(0),
00056     myEndedVehNo(0),
00057     myDiscarded(0),
00058     myTotalDepartureDelay(0),
00059     myTotalTravelTime(0),
00060     myDefaultVTypeMayBeDeleted(true),
00061     myWaitingForPerson(0) {
00062     SUMOVTypeParameter defType;
00063     myVTypeDict[DEFAULT_VTYPE_ID] = MSVehicleType::build(defType);
00064 }
00065 
00066 
00067 MSVehicleControl::~MSVehicleControl() {
00068     // delete vehicles
00069     for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
00070         delete(*i).second;
00071     }
00072     myVehicleDict.clear();
00073     // delete vehicle type distributions
00074     for (VTypeDistDictType::iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
00075         delete(*i).second;
00076     }
00077     myVTypeDistDict.clear();
00078     // delete vehicle types
00079     for (VTypeDictType::iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
00080         delete(*i).second;
00081     }
00082     myVTypeDict.clear();
00083 }
00084 
00085 
00086 SUMOVehicle*
00087 MSVehicleControl::buildVehicle(SUMOVehicleParameter* defs,
00088                                const MSRoute* route,
00089                                const MSVehicleType* type) {
00090     myLoadedVehNo++;
00091     MSVehicle* built = new MSVehicle(defs, route, type, myLoadedVehNo - 1);
00092     MSNet::getInstance()->informVehicleStateListener(built, MSNet::VEHICLE_STATE_BUILT);
00093     return built;
00094 }
00095 
00096 
00097 void
00098 MSVehicleControl::scheduleVehicleRemoval(SUMOVehicle* veh) {
00099     assert(myRunningVehNo > 0);
00100     for (std::vector<MSDevice*>::const_iterator i = veh->getDevices().begin(); i != veh->getDevices().end(); ++i) {
00101         (*i)->generateOutput();
00102     }
00103     if (OptionsCont::getOptions().isSet("tripinfo-output")) {
00104         OutputDevice::getDeviceByOption("tripinfo-output").closeTag(veh->getDevices().size() == 1);
00105     }
00106     myTotalTravelTime += STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - veh->getDeparture());
00107     myRunningVehNo--;
00108     MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VEHICLE_STATE_ARRIVED);
00109     deleteVehicle(veh);
00110 }
00111 
00112 
00113 void
00114 MSVehicleControl::printMeanWaitingTime(OutputDevice& od) const {
00115     if (getDepartedVehicleNo() == 0) {
00116         od << -1.;
00117     } else {
00118         od << (myTotalDepartureDelay / (SUMOReal) getDepartedVehicleNo());
00119     }
00120 }
00121 
00122 
00123 void
00124 MSVehicleControl::printMeanTravelTime(OutputDevice& od) const {
00125     if (myEndedVehNo == 0) {
00126         od << -1.;
00127     } else {
00128         od << (myTotalTravelTime / (SUMOReal) myEndedVehNo);
00129     }
00130 }
00131 
00132 
00133 void
00134 MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) {
00135     ++myRunningVehNo;
00136     myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart));
00137     MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VEHICLE_STATE_DEPARTED);
00138 }
00139 
00140 
00141 void
00142 MSVehicleControl::saveState(std::ostream& /*os*/) {
00143 }
00144 
00145 
00146 void
00147 MSVehicleControl::loadState(BinaryInputDevice& /*bis*/, const SUMOTime /*offset*/) {
00148 }
00149 
00150 
00151 bool
00152 MSVehicleControl::addVehicle(const std::string& id, SUMOVehicle* v) {
00153     VehicleDictType::iterator it = myVehicleDict.find(id);
00154     if (it == myVehicleDict.end()) {
00155         // id not in myVehicleDict.
00156         myVehicleDict[id] = v;
00157         return true;
00158     }
00159     return false;
00160 }
00161 
00162 
00163 SUMOVehicle*
00164 MSVehicleControl::getVehicle(const std::string& id) const {
00165     VehicleDictType::const_iterator it = myVehicleDict.find(id);
00166     if (it == myVehicleDict.end()) {
00167         return 0;
00168     }
00169     return it->second;
00170 }
00171 
00172 
00173 void
00174 MSVehicleControl::deleteVehicle(SUMOVehicle* veh, bool discard) {
00175     myEndedVehNo++;
00176     if (discard) {
00177         myDiscarded++;
00178     }
00179     myVehicleDict.erase(veh->getID());
00180     delete veh;
00181 }
00182 
00183 
00184 MSVehicleControl::constVehIt
00185 MSVehicleControl::loadedVehBegin() const {
00186     return myVehicleDict.begin();
00187 }
00188 
00189 
00190 MSVehicleControl::constVehIt
00191 MSVehicleControl::loadedVehEnd() const {
00192     return myVehicleDict.end();
00193 }
00194 
00195 
00196 bool
00197 MSVehicleControl::checkVType(const std::string& id) {
00198     if (id == DEFAULT_VTYPE_ID) {
00199         if (myDefaultVTypeMayBeDeleted) {
00200             delete myVTypeDict[id];
00201             myVTypeDict.erase(myVTypeDict.find(id));
00202             myDefaultVTypeMayBeDeleted = false;
00203         } else {
00204             return false;
00205         }
00206     } else {
00207         if (myVTypeDict.find(id) != myVTypeDict.end() || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
00208             return false;
00209         }
00210     }
00211     return true;
00212 }
00213 
00214 bool
00215 MSVehicleControl::addVType(MSVehicleType* vehType) {
00216     if (checkVType(vehType->getID())) {
00217         myVTypeDict[vehType->getID()] = vehType;
00218         return true;
00219     }
00220     return false;
00221 }
00222 
00223 
00224 bool
00225 MSVehicleControl::addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*> *vehTypeDistribution) {
00226     if (checkVType(id)) {
00227         myVTypeDistDict[id] = vehTypeDistribution;
00228         return true;
00229     }
00230     return false;
00231 }
00232 
00233 
00234 bool
00235 MSVehicleControl::hasVTypeDistribution(const std::string& id) const {
00236     return myVTypeDistDict.find(id) != myVTypeDistDict.end();
00237 }
00238 
00239 
00240 MSVehicleType*
00241 MSVehicleControl::getVType(const std::string& id) {
00242     VTypeDictType::iterator it = myVTypeDict.find(id);
00243     if (it == myVTypeDict.end()) {
00244         VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
00245         if (it2 == myVTypeDistDict.end()) {
00246             return 0;
00247         }
00248         return it2->second->get();
00249     }
00250     if (id == DEFAULT_VTYPE_ID) {
00251         myDefaultVTypeMayBeDeleted = false;
00252     }
00253     return it->second;
00254 }
00255 
00256 
00257 void
00258 MSVehicleControl::insertVTypeIDs(std::vector<std::string> &into) const {
00259     into.reserve(into.size() + myVTypeDict.size() + myVTypeDistDict.size());
00260     for (VTypeDictType::const_iterator i = myVTypeDict.begin(); i != myVTypeDict.end(); ++i) {
00261         into.push_back((*i).first);
00262     }
00263     for (VTypeDistDictType::const_iterator i = myVTypeDistDict.begin(); i != myVTypeDistDict.end(); ++i) {
00264         into.push_back((*i).first);
00265     }
00266 }
00267 
00268 
00269 void
00270 MSVehicleControl::addWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
00271     if (myWaiting.find(edge) == myWaiting.end()) {
00272         myWaiting[edge] = std::vector<SUMOVehicle*>();
00273     }
00274     myWaiting[edge].push_back(vehicle);
00275 }
00276 
00277 
00278 void
00279 MSVehicleControl::removeWaiting(const MSEdge* const edge, SUMOVehicle* vehicle) {
00280     if (myWaiting.find(edge) != myWaiting.end()) {
00281         std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting[edge].begin(), myWaiting[edge].end(), vehicle);
00282         if (it != myWaiting[edge].end()) {
00283             myWaiting[edge].erase(it);
00284         }
00285     }
00286 }
00287 
00288 
00289 SUMOVehicle*
00290 MSVehicleControl::getWaitingVehicle(const MSEdge* const edge, const std::set<std::string> &lines) {
00291     if (myWaiting.find(edge) != myWaiting.end()) {
00292         for (std::vector<SUMOVehicle*>::const_iterator it = myWaiting[edge].begin(); it != myWaiting[edge].end(); ++it) {
00293             const std::string& line = (*it)->getParameter().line == "" ? (*it)->getParameter().id : (*it)->getParameter().line;
00294             if (lines.count(line)) {
00295                 return (*it);
00296             }
00297         }
00298     }
00299     return 0;
00300 }
00301 
00302 
00303 void
00304 MSVehicleControl::abortWaiting() {
00305     for (VehicleDictType::iterator i = myVehicleDict.begin(); i != myVehicleDict.end(); ++i) {
00306         WRITE_WARNING("Vehicle " + i->first + " aborted waiting for a person that will never come.");
00307     }
00308 }
00309 
00310 
00311 bool 
00312 MSVehicleControl::isInQuota(const SUMOReal frac) const {
00313     const unsigned int resolution = 1000;
00314     const unsigned int intFrac = (unsigned int)floor(frac * resolution + 0.5);
00315     // the vehicle in question has already been loaded, hence  the '-1'
00316     // apply % twice to avoid integer overflow
00317     return (((myLoadedVehNo - 1) % resolution) * intFrac) % resolution < intFrac;
00318 }
00319 
00320 /****************************************************************************/
00321 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines