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 2001-2010 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 vehicles2Emit,
00066         bool randomize)
00067         : myVehicle(vehicle), myVehicleType(type), myRoute(route),
00068         myIntervalBegin(intBegin), myIntervalEnd(intEnd),
00069         myVehicle2EmitNumber(vehicles2Emit), myEmitted(0), myRandom(randomize) {
00070     assert(myIntervalBegin<myIntervalEnd);
00071     if (myRandom) {
00072         SUMOTime period = myIntervalEnd - myIntervalBegin;
00073         myDepartures.reserve(myVehicle2EmitNumber);
00074         for (size_t i=0; i<myVehicle2EmitNumber; ++i) {
00075             SUMOTime departure = ((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     //
00099     if (!myRandom) {
00100         unsigned int absPerEachStep = myVehicle2EmitNumber / ((myIntervalEnd-myIntervalBegin) / DELTA_T);
00101         for (unsigned int i=0; i<absPerEachStep; i++) {
00102             addSingleRoute(net, t);
00103         }
00104         // fraction
00105         SUMOReal toEmit = (SUMOReal) myVehicle2EmitNumber / (SUMOReal)(myIntervalEnd-myIntervalBegin) * (SUMOReal)(t-myIntervalBegin+(SUMOReal)DELTA_T/2.);
00106         if (toEmit>myEmitted) {
00107             addSingleRoute(net, t);
00108         }
00109     } else {
00110         while (myDepartures.size()>0&&*(myDepartures.end()-1)<t+DELTA_T) {
00111             addSingleRoute(net, t);
00112             myDepartures.pop_back();
00113         }
00114     }
00115 }
00116 
00117 
00118 void
00119 RORDGenerator_ODAmounts::FlowDef::addSingleRoute(RONet &net, SUMOTime t) {
00120     std::string id = myVehicle->getID() + "_" + toString<unsigned int>(myEmitted);
00121     RORouteDef *rd = myRoute->copy(id);
00122     net.addRouteDef(rd);
00123     ROVehicle *veh = myVehicle->copy(id, t, rd);
00124     net.addVehicle(id, veh);
00125     myEmitted++;
00126 }
00127 
00128 
00129 SUMOTime
00130 RORDGenerator_ODAmounts::FlowDef::getIntervalEnd() const {
00131     return myIntervalEnd;
00132 }
00133 
00134 
00135 /* -------------------------------------------------------------------------
00136  * RORDGenerator_ODAmounts - methods
00137  * ----------------------------------------------------------------------- */
00138 RORDGenerator_ODAmounts::RORDGenerator_ODAmounts(RONet &net,
00139         SUMOTime begin,
00140         SUMOTime end,
00141         bool emptyDestinationsAllowed,
00142         bool randomize,
00143         const std::string &fileName) throw(ProcessError)
00144         : RORDLoader_TripDefs(net, begin, end, emptyDestinationsAllowed, false, fileName),
00145         myRandom(randomize) {
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     // skip routes before begin
00163     if (until<myBegin) {
00164         myDepartureTime = until;
00165         return true;
00166     }
00167     // build route definitions for the given timestep
00168     buildRoutes(until);
00169     return true;
00170 }
00171 
00172 
00173 void
00174 RORDGenerator_ODAmounts::buildRoutes(SUMOTime until) throw() {
00175     SUMOTime t;
00176     for (t=myDepartureTime; t<until+1; t+=DELTA_T) {
00177         buildForTimeStep(t);
00178     }
00179     myDepartureTime = t;
00180 }
00181 
00182 
00183 void
00184 RORDGenerator_ODAmounts::buildForTimeStep(SUMOTime time) throw() {
00185     if (time<myBegin||time>=myEnd) {
00186         return;
00187     }
00188     myEnded = true;
00189     for (FlowDefV::const_iterator i=myFlows.begin(); i!=myFlows.end(); i++) {
00190         FlowDef *fd = *i;
00191         // skip flow definitions not valid for the current time
00192         if (fd->applicableForTime(time)) {
00193             fd->addRoutes(myNet, time);
00194         }
00195         // check whether any further exists
00196         if (fd->getIntervalEnd()>time) {
00197             myEnded = false;
00198         }
00199     }
00200 }
00201 
00202 
00203 void
00204 RORDGenerator_ODAmounts::myStartElement(SumoXMLTag element,
00205                                         const SUMOSAXAttributes &attrs) throw(ProcessError) {
00206     RORDLoader_TripDefs::myStartElement(element, attrs);
00207     if (element == SUMO_TAG_FLOW) {
00208         parseFlowAmountDef(attrs);
00209     } else if (element == SUMO_TAG_INTERVAL) {
00210         parseInterval(attrs);
00211     }
00212 }
00213 
00214 
00215 void
00216 RORDGenerator_ODAmounts::parseFlowAmountDef(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00217     // get the vehicle id, the edges, the speed and position and
00218     //  the departure time and other information
00219     std::string id = getVehicleID(attrs);
00220     if (myKnownIDs.find(id)!=myKnownIDs.end()) {
00221         throw ProcessError("The id '" + id + "' appears twice within the flow descriptions.'");
00222     }
00223     myKnownIDs.insert(id); // !!! a local storage is not save
00224     myBeginEdge = getEdge(attrs, "origin", SUMO_ATTR_FROM, id, false);
00225     myEndEdge = getEdge(attrs, "destination",
00226                         SUMO_ATTR_TO, id, myEmptyDestinationsAllowed);
00227     try {
00228         myParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs, true, true);
00229     } catch (ProcessError &e) {
00230         throw ProcessError(StringUtils::replace(e.what(), "''", id.c_str()));
00231     }
00232     myParameter->id = id;
00233     bool ok = true;
00234     myIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "flow", id.c_str(), ok, myUpperIntervalBegin);
00235     myIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "flow", id.c_str(), ok, myUpperIntervalEnd);
00236     myVehicle2EmitNumber = attrs.getIntReporting(SUMO_ATTR_NO, "flow", id.c_str(), ok); // !!! no real error handling
00237     if (!ok) {
00238         throw ProcessError();
00239     }
00240     if (myIntervalEnd<=myIntervalBegin) {
00241         throw ProcessError("The interval must be larger than 0.\n The current values are: begin=" + toString<unsigned int>(myIntervalBegin) + " end=" + toString<unsigned int>(myIntervalEnd));
00242     }
00243 }
00244 
00245 
00246 void
00247 RORDGenerator_ODAmounts::parseInterval(const SUMOSAXAttributes &attrs) {
00248     bool ok = true;
00249     myUpperIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "interval", 0, ok, -1); // !!!really optional ?
00250     myUpperIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "interval", 0, ok, -1); // !!!really optional ?
00251 }
00252 
00253 
00254 void
00255 RORDGenerator_ODAmounts::myEndElement(SumoXMLTag element) throw(ProcessError) {
00256     RORDLoader_TripDefs::myEndElement(element);
00257     if (element == SUMO_TAG_FLOW) {
00258         myEndFlowAmountDef();
00259     } else if (element == SUMO_TAG_INTERVAL) {
00260         myEndInterval();
00261     }
00262 }
00263 
00264 
00265 void
00266 RORDGenerator_ODAmounts::myEndInterval() {
00267     myUpperIntervalBegin = 0; // !!! was -1
00268     myUpperIntervalEnd = 0; // !!! was: -1
00269 }
00270 
00271 
00272 void
00273 RORDGenerator_ODAmounts::myEndFlowAmountDef() {
00274     if (!MsgHandler::getErrorInstance()->wasInformed()) {
00275 
00276         if (myIntervalEnd<myBegin) {
00277             return;
00278         }
00279         // add the vehicle type, the vehicle and the route to the net
00280         RGBColor *col = myParameter->wasSet(VEHPARS_COLOR_SET) ? new RGBColor(myParameter->color) : 0;
00281         RORouteDef *route = new RORouteDef_OrigDest(myParameter->id, col, myBeginEdge, myEndEdge);
00282         SUMOVTypeParameter *type = myNet.getVehicleTypeSecure(myParameter->vtypeid);
00283         // check whether any errors occured
00284         if (MsgHandler::getErrorInstance()->wasInformed()) {
00285             return;
00286         }
00287         // build the vehicle
00288         myNet.addRouteDef(route);
00289         myNextRouteRead = true;
00290         ROVehicle *vehicle = new ROVehicle(*myParameter, route, type);
00291         // add to the container
00292         FlowDef *fd = new FlowDef(vehicle, type, route, myIntervalBegin, myIntervalEnd, myVehicle2EmitNumber, myRandom);
00293         myFlows.push_back(fd);
00294         delete myParameter;
00295         myParameter = 0;
00296     }
00297 }
00298 
00299 
00300 /****************************************************************************/
00301 

Generated on Wed May 5 00:06:36 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6