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