SUMO - Simulation of Urban MObility
|
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