SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // The main interface for loading a microsim 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 "NLBuilder.h" 00034 #include <microsim/MSNet.h> 00035 #include <microsim/MSEdgeControl.h> 00036 #include <microsim/MSGlobals.h> 00037 #include <iostream> 00038 #include <vector> 00039 #include <xercesc/parsers/SAXParser.hpp> 00040 #include <xercesc/sax2/SAX2XMLReader.hpp> 00041 #include <string> 00042 #include <map> 00043 #include "NLHandler.h" 00044 #include "NLEdgeControlBuilder.h" 00045 #include "NLJunctionControlBuilder.h" 00046 #include "NLDetectorBuilder.h" 00047 #include "NLTriggerBuilder.h" 00048 #include <microsim/MSVehicleControl.h> 00049 #include <microsim/MSVehicleTransfer.h> 00050 #include <microsim/MSRouteLoaderControl.h> 00051 #include <microsim/MSRouteLoader.h> 00052 #include <utils/common/MsgHandler.h> 00053 #include <utils/common/StringTokenizer.h> 00054 #include <utils/options/Option.h> 00055 #include <utils/options/OptionsCont.h> 00056 #include <utils/common/TplConvert.h> 00057 #include <utils/common/FileHelpers.h> 00058 #include <utils/common/SysUtils.h> 00059 #include <utils/common/ToString.h> 00060 #include <utils/xml/XMLSubSys.h> 00061 #include <microsim/output/MSDetectorControl.h> 00062 #include <microsim/MSFrame.h> 00063 #include <microsim/MSEdgeWeightsStorage.h> 00064 #include <utils/iodevices/BinaryInputDevice.h> 00065 00066 #ifdef CHECK_MEMORY_LEAKS 00067 #include <foreign/nvwa/debug_new.h> 00068 #endif // CHECK_MEMORY_LEAKS 00069 00070 00071 // =========================================================================== 00072 // method definitions 00073 // =========================================================================== 00074 // --------------------------------------------------------------------------- 00075 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeWeight - methods 00076 // --------------------------------------------------------------------------- 00077 void 00078 NLBuilder::EdgeFloatTimeLineRetriever_EdgeEffort::addEdgeWeight(const std::string& id, 00079 SUMOReal value, SUMOReal begTime, SUMOReal endTime) const { 00080 MSEdge* edge = MSEdge::dictionary(id); 00081 if (edge != 0) { 00082 myNet.getWeightsStorage().addEffort(edge, begTime, endTime, value); 00083 } else { 00084 WRITE_ERROR("Trying to set the effort for the unknown edge '" + id + "'."); 00085 } 00086 } 00087 00088 00089 // --------------------------------------------------------------------------- 00090 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods 00091 // --------------------------------------------------------------------------- 00092 void 00093 NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id, 00094 SUMOReal value, SUMOReal begTime, SUMOReal endTime) const { 00095 MSEdge* edge = MSEdge::dictionary(id); 00096 if (edge != 0) { 00097 myNet.getWeightsStorage().addTravelTime(edge, begTime, endTime, value); 00098 } else { 00099 WRITE_ERROR("Trying to set the travel time for the unknown edge '" + id + "'."); 00100 } 00101 } 00102 00103 00104 // --------------------------------------------------------------------------- 00105 // NLBuilder - methods 00106 // --------------------------------------------------------------------------- 00107 NLBuilder::NLBuilder(OptionsCont& oc, 00108 MSNet& net, 00109 NLEdgeControlBuilder& eb, 00110 NLJunctionControlBuilder& jb, 00111 NLDetectorBuilder& db, 00112 NLHandler& xmlHandler) 00113 : myOptions(oc), myEdgeBuilder(eb), myJunctionBuilder(jb), 00114 myDetectorBuilder(db), 00115 myNet(net), myXMLHandler(xmlHandler) {} 00116 00117 00118 NLBuilder::~NLBuilder() {} 00119 00120 00121 bool 00122 NLBuilder::build() { 00123 // try to build the net 00124 if (!load("net-file")) { 00125 return false; 00126 } 00127 buildNet(); 00128 #ifdef HAVE_MESOSIM 00129 // load the previous state if wished 00130 if (myOptions.isSet("load-state")) { 00131 long before = SysUtils::getCurrentMillis(); 00132 BinaryInputDevice strm(myOptions.getString("load-state")); 00133 if (!strm.good()) { 00134 WRITE_ERROR("Could not read state from '" + myOptions.getString("load-state") + "'!"); 00135 } else { 00136 PROGRESS_BEGIN_MESSAGE("Loading state from '" + myOptions.getString("load-state") + "'"); 00137 unsigned int step = myNet.loadState(strm); 00138 if (myOptions.isDefault("begin")) { 00139 myOptions.set("begin", time2string(step)); 00140 } 00141 if (step != string2time(myOptions.getString("begin"))) { 00142 WRITE_WARNING("State was written at a different time " + time2string(step) + " than the begin time " + myOptions.getString("begin") + "!"); 00143 } 00144 } 00145 if (MsgHandler::getErrorInstance()->wasInformed()) { 00146 return false; 00147 } 00148 MsgHandler::getMessageInstance()->endProcessMsg("done (" + toString(SysUtils::getCurrentMillis() - before) + "ms)."); 00149 } 00150 #endif 00151 // load weights if wished 00152 if (myOptions.isSet("weight-files")) { 00153 if (!myOptions.isUsableFileList("weight-files")) { 00154 return false; 00155 } 00156 // build and prepare the weights handler 00157 std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs; 00158 // travel time, first (always used) 00159 EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(myNet); 00160 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", true, ttRetriever)); 00161 // the measure to use, then 00162 EdgeFloatTimeLineRetriever_EdgeEffort eRetriever(myNet); 00163 std::string measure = myOptions.getString("weight-attribute"); 00164 if (measure != "traveltime") { 00165 if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel") { 00166 measure += "_perVeh"; 00167 } 00168 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(measure, true, eRetriever)); 00169 } 00170 // set up handler 00171 SAXWeightsHandler handler(retrieverDefs, ""); 00172 // start parsing; for each file in the list 00173 std::vector<std::string> files = myOptions.getStringVector("weight-files"); 00174 for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) { 00175 // report about loading when wished 00176 WRITE_MESSAGE("Loading weights from '" + *i + "'..."); 00177 // parse the file 00178 if (!XMLSubSys::runParser(handler, *i)) { 00179 return false; 00180 } 00181 } 00182 } 00183 // load routes 00184 if (myOptions.isSet("route-files") && string2time(myOptions.getString("route-steps")) <= 0) { 00185 if (!load("route-files")) { 00186 return false; 00187 } 00188 } 00189 // load additional net elements (sources, detectors, ...) 00190 if (myOptions.isSet("additional-files")) { 00191 if (!load("additional-files")) { 00192 return false; 00193 } 00194 } 00195 WRITE_MESSAGE("Loading done."); 00196 return true; 00197 } 00198 00199 00200 void 00201 NLBuilder::buildNet() { 00202 MSEdgeControl* edges = 0; 00203 MSJunctionControl* junctions = 0; 00204 MSRouteLoaderControl* routeLoaders = 0; 00205 MSTLLogicControl* tlc = 0; 00206 try { 00207 edges = myEdgeBuilder.build(); 00208 junctions = myJunctionBuilder.build(); 00209 routeLoaders = buildRouteLoaderControl(myOptions); 00210 tlc = myJunctionBuilder.buildTLLogics(); 00211 MSFrame::buildStreams(); 00212 std::vector<SUMOTime> stateDumpTimes; 00213 std::vector<std::string> stateDumpFiles; 00214 #ifdef HAVE_MESOSIM 00215 const std::vector<int> times = myOptions.getIntVector("save-state.times"); 00216 for (std::vector<int>::const_iterator i = times.begin(); i != times.end(); ++i) { 00217 stateDumpTimes.push_back(TIME2STEPS(*i)); 00218 } 00219 if (!myOptions.isDefault("save-state.prefix")) { 00220 const std::string prefix = myOptions.getString("save-state.prefix"); 00221 for (std::vector<SUMOTime>::iterator i = stateDumpTimes.begin(); i != stateDumpTimes.end(); ++i) { 00222 stateDumpFiles.push_back(prefix + "_" + time2string(*i) + ".bin"); 00223 } 00224 } else { 00225 stateDumpFiles = StringTokenizer(myOptions.getString("save-state.files")).getVector() ; 00226 } 00227 #endif 00228 myNet.closeBuilding(edges, junctions, routeLoaders, tlc, stateDumpTimes, stateDumpFiles); 00229 } catch (IOError& e) { 00230 delete edges; 00231 delete junctions; 00232 delete routeLoaders; 00233 delete tlc; 00234 throw ProcessError(e.what()); 00235 } catch (ProcessError&) { 00236 delete edges; 00237 delete junctions; 00238 delete routeLoaders; 00239 delete tlc; 00240 throw; 00241 } 00242 } 00243 00244 00245 bool 00246 NLBuilder::load(const std::string& mmlWhat) { 00247 if (!OptionsCont::getOptions().isUsableFileList(mmlWhat)) { 00248 return false; 00249 } 00250 std::vector<std::string> files = OptionsCont::getOptions().getStringVector(mmlWhat); 00251 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { 00252 PROGRESS_BEGIN_MESSAGE("Loading " + mmlWhat + " from '" + *fileIt + "'"); 00253 long before = SysUtils::getCurrentMillis(); 00254 if (!XMLSubSys::runParser(myXMLHandler, *fileIt)) { 00255 WRITE_MESSAGE("Loading of " + mmlWhat + " failed."); 00256 return false; 00257 } 00258 MsgHandler::getMessageInstance()->endProcessMsg(" done (" + toString(SysUtils::getCurrentMillis() - before) + "ms)."); 00259 } 00260 return true; 00261 } 00262 00263 00264 MSRouteLoaderControl* 00265 NLBuilder::buildRouteLoaderControl(const OptionsCont& oc) { 00266 // build the loaders 00267 MSRouteLoaderControl::LoaderVector loaders; 00268 // check whether a list is existing 00269 if (oc.isSet("route-files") && string2time(oc.getString("route-steps")) > 0) { 00270 std::vector<std::string> files = oc.getStringVector("route-files"); 00271 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { 00272 if (!FileHelpers::exists(*fileIt)) { 00273 throw ProcessError("The route file '" + *fileIt + "' does not exist."); 00274 } 00275 } 00276 // open files for reading 00277 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) { 00278 loaders.push_back(new MSRouteLoader(myNet, new MSRouteHandler(*fileIt, false))); 00279 } 00280 } 00281 // build the route control 00282 return new MSRouteLoaderControl(myNet, string2time(oc.getString("route-steps")), loaders); 00283 } 00284 00285 00286 /****************************************************************************/ 00287