SUMO - Simulation of Urban MObility
RORDGenerator_ODAmounts.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Class for loading trip amount definitions and route generation
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 <cassert>
00034 #include <string>
00035 #include <algorithm>
00036 #include <utils/options/OptionsCont.h>
00037 #include <utils/common/UtilExceptions.h>
00038 #include <utils/common/StringTokenizer.h>
00039 #include <utils/common/MsgHandler.h>
00040 #include <utils/common/ToString.h>
00041 #include <utils/common/RandHelper.h>
00042 #include <utils/common/StringUtils.h>
00043 #include "RORouteDef.h"
00044 #include "RONet.h"
00045 #include "RORouteDef_OrigDest.h"
00046 #include "RORDGenerator_ODAmounts.h"
00047 #include "ROVehicle.h"
00048 #include "RORouteDef_Complete.h"
00049 #include <utils/xml/SUMOVehicleParserHelper.h>
00050 
00051 #ifdef CHECK_MEMORY_LEAKS
00052 #include <foreign/nvwa/debug_new.h>
00053 #endif // CHECK_MEMORY_LEAKS
00054 
00055 
00056 // ===========================================================================
00057 // method definitions
00058 // ===========================================================================
00059 /* -------------------------------------------------------------------------
00060  * RORDGenerator_ODAmounts::FlowDef - methods
00061  * ----------------------------------------------------------------------- */
00062 RORDGenerator_ODAmounts::FlowDef::FlowDef(ROVehicle* vehicle,
00063         SUMOVTypeParameter* type,
00064         RORouteDef* route,
00065         SUMOTime intBegin,
00066         SUMOTime intEnd,
00067         unsigned int vehicles2insert,
00068         bool randomize)
00069     : myVehicle(vehicle), myVehicleType(type), myRoute(route),
00070       myIntervalBegin(intBegin), myIntervalEnd(intEnd),
00071       myVehicle2InsertNumber(vehicles2insert), myInserted(0), myRandom(randomize) {
00072     assert(myIntervalBegin < myIntervalEnd);
00073     if (myRandom) {
00074         SUMOTime period = myIntervalEnd - myIntervalBegin;
00075         myDepartures.reserve(myVehicle2InsertNumber);
00076         for (size_t i = 0; i < myVehicle2InsertNumber; ++i) {
00077             SUMOTime departure = myIntervalBegin + ((int)(RandHelper::rand(period) / DELTA_T)) * DELTA_T;
00078             myDepartures.push_back(departure);
00079         }
00080         sort(myDepartures.begin(), myDepartures.end());
00081         reverse(myDepartures.begin(), myDepartures.end());
00082     }
00083 }
00084 
00085 
00086 RORDGenerator_ODAmounts::FlowDef::~FlowDef() {
00087     delete myVehicle;
00088 }
00089 
00090 
00091 bool
00092 RORDGenerator_ODAmounts::FlowDef::applicableForTime(SUMOTime t) const {
00093     return myIntervalBegin <= t && myIntervalEnd > t;
00094 }
00095 
00096 
00097 void
00098 RORDGenerator_ODAmounts::FlowDef::addRoutes(RONet& net, SUMOTime t) {
00099     assert(myIntervalBegin <= t && myIntervalEnd >= t);
00100     if (!myRandom) {
00101         unsigned int absPerEachStep = myVehicle2InsertNumber / ((myIntervalEnd - myIntervalBegin) / DELTA_T);
00102         for (unsigned int i = 0; i < absPerEachStep; i++) {
00103             addSingleRoute(net, t);
00104         }
00105         // fraction
00106         SUMOReal toInsert = (SUMOReal) myVehicle2InsertNumber / (SUMOReal)(myIntervalEnd - myIntervalBegin) * (SUMOReal)(t - myIntervalBegin + (SUMOReal)DELTA_T / 2.);
00107         if (toInsert > myInserted) {
00108             addSingleRoute(net, t);
00109         }
00110     } else {
00111         while (myDepartures.size() > 0 && myDepartures.back() < t + DELTA_T) {
00112             addSingleRoute(net, myDepartures.back());
00113             myDepartures.pop_back();
00114         }
00115     }
00116 }
00117 
00118 
00119 void
00120 RORDGenerator_ODAmounts::FlowDef::addSingleRoute(RONet& net, SUMOTime t) {
00121     std::string id = myVehicle->getID() + "_" + toString<unsigned int>(myInserted);
00122     RORouteDef* rd = myRoute->copy(id);
00123     net.addRouteDef(rd);
00124     ROVehicle* veh = myVehicle->copy(id, t, rd);
00125     net.addVehicle(id, veh);
00126     ++myInserted;
00127 }
00128 
00129 
00130 SUMOTime
00131 RORDGenerator_ODAmounts::FlowDef::getIntervalEnd() const {
00132     return myIntervalEnd;
00133 }
00134 
00135 
00136 /* -------------------------------------------------------------------------
00137  * RORDGenerator_ODAmounts - methods
00138  * ----------------------------------------------------------------------- */
00139 RORDGenerator_ODAmounts::RORDGenerator_ODAmounts(RONet& net,
00140         SUMOTime begin,
00141         SUMOTime end,
00142         bool emptyDestinationsAllowed,
00143         bool randomize,
00144         const std::string& fileName)
00145     : RORDLoader_TripDefs(net, begin, end, emptyDestinationsAllowed, false, fileName),
00146       myRandom(randomize),
00147       myHaveWarnedAboutDeprecatedNumber(false) {
00148     // read the complete file on initialisation
00149     myParser->parseReset(myToken);
00150     myParser->parse(getFileName().c_str());
00151     myCurrentDepart = begin;
00152 }
00153 
00154 
00155 RORDGenerator_ODAmounts::~RORDGenerator_ODAmounts() {
00156     for (FlowDefV::const_iterator i = myFlows.begin(); i != myFlows.end(); i++) {
00157         delete(*i);
00158     }
00159 }
00160 
00161 
00162 bool
00163 RORDGenerator_ODAmounts::readRoutesAtLeastUntil(SUMOTime until) {
00164     // skip routes before begin
00165     if (until < myBegin) {
00166         myCurrentDepart = until;
00167         return true;
00168     }
00169     // build route definitions for the given timestep
00170     SUMOTime t;
00171     for (t = myCurrentDepart; t < until + 1; t += DELTA_T) {
00172         buildForTimeStep(t);
00173     }
00174     myCurrentDepart = t;
00175     return true;
00176 }
00177 
00178 
00179 void
00180 RORDGenerator_ODAmounts::buildForTimeStep(SUMOTime time) {
00181     if (time < myBegin || time >= myEnd) {
00182         return;
00183     }
00184     myEnded = true;
00185     for (FlowDefV::const_iterator i = myFlows.begin(); i != myFlows.end(); i++) {
00186         FlowDef* fd = *i;
00187         // skip flow definitions not valid for the current time
00188         if (fd->applicableForTime(time)) {
00189             fd->addRoutes(myNet, time);
00190         }
00191         // check whether any further exists
00192         if (fd->getIntervalEnd() > time) {
00193             myEnded = false;
00194         }
00195     }
00196 }
00197 
00198 
00199 void
00200 RORDGenerator_ODAmounts::myStartElement(int element,
00201                                         const SUMOSAXAttributes& attrs) {
00202     RORDLoader_TripDefs::myStartElement(element, attrs);
00203     if (element == SUMO_TAG_FLOW) {
00204         parseFlowAmountDef(attrs);
00205     } else if (element == SUMO_TAG_INTERVAL) {
00206         bool ok = true;
00207         myUpperIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, 0, ok, -1); // !!!really optional ?
00208         myUpperIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, 0, ok, -1); // !!!really optional ?
00209     }
00210 }
00211 
00212 
00213 void
00214 RORDGenerator_ODAmounts::parseFlowAmountDef(const SUMOSAXAttributes& attrs) {
00215     // get the vehicle id, the edges, the speed and position and
00216     //  the departure time and other information
00217     std::string id = getVehicleID(attrs);
00218     if (myKnownIDs.find(id) != myKnownIDs.end()) {
00219         throw ProcessError("The id '" + id + "' appears twice within the flow descriptions.'");
00220     }
00221     myKnownIDs.insert(id); // !!! a local storage is not save
00222     myBeginEdge = getEdge(attrs, "origin", SUMO_ATTR_FROM, id, false);
00223     myEndEdge = getEdge(attrs, "destination",
00224                         SUMO_ATTR_TO, id, myEmptyDestinationsAllowed);
00225     try {
00226         myParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs, true, true);
00227     } catch (ProcessError& e) {
00228         throw ProcessError(StringUtils::replace(e.what(), "''", id.c_str()));
00229     }
00230     myParameter->id = id;
00231     bool ok = true;
00232     myIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, myUpperIntervalBegin);
00233     myIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, myUpperIntervalEnd);
00234     if (attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
00235         myVehicle2InsertNumber = attrs.getIntReporting(SUMO_ATTR_NUMBER, id.c_str(), ok);
00236     } else if (attrs.hasAttribute(SUMO_ATTR_NO__DEPRECATED)) {
00237         if (!myHaveWarnedAboutDeprecatedNumber) {
00238             myHaveWarnedAboutDeprecatedNumber = true;
00239             WRITE_WARNING("'" + toString(SUMO_ATTR_NO__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_NUMBER) + "' instead.");
00240         }
00241         myVehicle2InsertNumber = attrs.getIntReporting(SUMO_ATTR_NO__DEPRECATED, id.c_str(), ok);
00242     } else {
00243         throw ProcessError("Flow '" + id + "' has no vehicle number.");
00244     }
00245     if (!ok) {
00246         throw ProcessError();
00247     }
00248     if (myIntervalEnd <= myIntervalBegin) {
00249         throw ProcessError("The interval must be larger than 0.\n The current values are: begin=" + toString<unsigned int>(myIntervalBegin) + " end=" + toString<unsigned int>(myIntervalEnd));
00250     }
00251 }
00252 
00253 
00254 void
00255 RORDGenerator_ODAmounts::myEndElement(int element) {
00256     RORDLoader_TripDefs::myEndElement(element);
00257     if (element == SUMO_TAG_FLOW) {
00258         myEndFlowAmountDef();
00259     } else if (element == SUMO_TAG_INTERVAL) {
00260         myUpperIntervalBegin = 0; // !!! was -1
00261         myUpperIntervalEnd = 0; // !!! was: -1
00262     }
00263 }
00264 
00265 
00266 void
00267 RORDGenerator_ODAmounts::myEndFlowAmountDef() {
00268     if (!MsgHandler::getErrorInstance()->wasInformed()) {
00269 
00270         if (myIntervalEnd < myBegin) {
00271             return;
00272         }
00273         // add the vehicle type, the vehicle and the route to the net
00274         RGBColor* col = myParameter->wasSet(VEHPARS_COLOR_SET) ? new RGBColor(myParameter->color) : 0;
00275         RORouteDef* route = new RORouteDef_OrigDest(myParameter->id, col, myBeginEdge, myEndEdge);
00276         SUMOVTypeParameter* type = myNet.getVehicleTypeSecure(myParameter->vtypeid);
00277         // check whether any errors occured
00278         if (MsgHandler::getErrorInstance()->wasInformed()) {
00279             return;
00280         }
00281         // build the vehicle
00282         if (myNet.addRouteDef(route)) {
00283             myNextRouteRead = true;
00284             ROVehicle* vehicle = new ROVehicle(*myParameter, route, type);
00285             // add to the container
00286             FlowDef* fd = new FlowDef(vehicle, type, route, myIntervalBegin, myIntervalEnd, myVehicle2InsertNumber, myRandom);
00287             myFlows.push_back(fd);
00288         } else {
00289             WRITE_ERROR("The vehicle '" + myParameter->id + "' occurs at least twice.");
00290             delete route;
00291         }
00292         delete myParameter;
00293         myParameter = 0;
00294     }
00295 }
00296 
00297 
00298 /****************************************************************************/
00299 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines