SUMO - Simulation of Urban MObility

RORDGenerator_ODAmounts.cpp

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