|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Main for the DFROUTER 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 #ifdef HAVE_VERSION_H 00031 #include <version.h> 00032 #endif 00033 00034 #include <xercesc/sax/SAXException.hpp> 00035 #include <xercesc/sax/SAXParseException.hpp> 00036 #include <utils/common/TplConvert.h> 00037 #include <iostream> 00038 #include <string> 00039 #include <limits.h> 00040 #include <ctime> 00041 #include <router/ROLoader.h> 00042 #include <router/RONet.h> 00043 #include "RODFEdgeBuilder.h" 00044 #include <router/ROFrame.h> 00045 #include <utils/common/MsgHandler.h> 00046 #include <utils/options/Option.h> 00047 #include <utils/options/OptionsCont.h> 00048 #include <utils/options/OptionsIO.h> 00049 #include <utils/common/UtilExceptions.h> 00050 #include <utils/common/SystemFrame.h> 00051 #include <utils/common/ToString.h> 00052 #include <utils/xml/XMLSubSys.h> 00053 #include "RODFFrame.h" 00054 #include "RODFNet.h" 00055 #include "RODFEdge.h" 00056 #include "RODFDetector.h" 00057 #include "RODFDetectorHandler.h" 00058 #include "RODFRouteCont.h" 00059 #include "RODFDetectorFlow.h" 00060 #include "RODFDetFlowLoader.h" 00061 #include <utils/xml/XMLSubSys.h> 00062 #include <utils/common/FileHelpers.h> 00063 #include <utils/iodevices/OutputDevice.h> 00064 00065 #ifdef CHECK_MEMORY_LEAKS 00066 #include <foreign/nvwa/debug_new.h> 00067 #endif // CHECK_MEMORY_LEAKS 00068 00069 00070 // =========================================================================== 00071 // functions 00072 // =========================================================================== 00073 /* ------------------------------------------------------------------------- 00074 * data processing methods 00075 * ----------------------------------------------------------------------- */ 00076 void 00077 readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) { 00078 if (!oc.isSet("detector-files")) { 00079 throw ProcessError("No detector file given (use --detector-files <FILE>)."); 00080 } 00081 // read definitions stored in XML-format 00082 std::vector<std::string> files = oc.getStringVector("detector-files"); 00083 for (std::vector<std::string>::const_iterator fileIt=files.begin(); fileIt!=files.end(); ++fileIt) { 00084 if (!FileHelpers::exists(*fileIt)) { 00085 throw ProcessError("Could not open detector file '" + *fileIt + "'"); 00086 } 00087 PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'"); 00088 RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt); 00089 if (XMLSubSys::runParser(handler, *fileIt)) { 00090 PROGRESS_DONE_MESSAGE(); 00091 } else { 00092 PROGRESS_FAILED_MESSAGE(); 00093 throw ProcessError(); 00094 } 00095 } 00096 } 00097 00098 00099 void 00100 readDetectorFlows(RODFDetectorFlows& flows, OptionsCont& oc, RODFDetectorCon& dc) { 00101 if (!oc.isSet("measure-files")) { 00102 // ok, not given, return an empty container 00103 return; 00104 } 00105 // check whether the file exists 00106 std::vector<std::string> files = oc.getStringVector("measure-files"); 00107 for (std::vector<std::string>::const_iterator fileIt=files.begin(); fileIt!=files.end(); ++fileIt) { 00108 if (!FileHelpers::exists(*fileIt)) { 00109 throw ProcessError("The measure-file '" + *fileIt + "' can not be opened."); 00110 } 00111 // parse 00112 PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'"); 00113 RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")), 00114 string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor"))); 00115 dfl.read(*fileIt); 00116 PROGRESS_DONE_MESSAGE(); 00117 } 00118 } 00119 00120 00121 void 00122 startComputation(RODFNet* optNet, RODFDetectorFlows& flows, RODFDetectorCon& detectors, OptionsCont& oc) { 00123 if (oc.getBool("print-absolute-flows")) { 00124 flows.printAbsolute(); 00125 } 00126 00127 // if a network was loaded... (mode1) 00128 if (optNet!=0) { 00129 if (oc.getBool("remove-empty-detectors")) { 00130 PROGRESS_BEGIN_MESSAGE("Removing empty detectors"); 00131 optNet->removeEmptyDetectors(detectors, flows); 00132 PROGRESS_DONE_MESSAGE(); 00133 } else if (oc.getBool("report-empty-detectors")) { 00134 PROGRESS_BEGIN_MESSAGE("Scanning for empty detectors"); 00135 optNet->reportEmptyDetectors(detectors, flows); 00136 PROGRESS_DONE_MESSAGE(); 00137 } 00138 // compute the detector types (optionally) 00139 if (!detectors.detectorsHaveCompleteTypes()||oc.getBool("revalidate-detectors")) { 00140 optNet->computeTypes(detectors, oc.getBool("strict-sources")); 00141 } 00142 // compute routes between the detectors (optionally) 00143 if (!detectors.detectorsHaveRoutes()||oc.getBool("revalidate-routes")||oc.getBool("guess-empty-flows")) { 00144 PROGRESS_BEGIN_MESSAGE("Computing routes"); 00145 optNet->buildRoutes(detectors, 00146 oc.getBool("all-end-follower"), oc.getBool("keep-unfinished-routes"), 00147 oc.getBool("routes-for-all"), !oc.getBool("keep-longer-routes"), 00148 oc.getInt("max-search-depth")); 00149 PROGRESS_DONE_MESSAGE(); 00150 } 00151 } 00152 00153 // check 00154 // whether the detectors are valid 00155 if (!detectors.detectorsHaveCompleteTypes()) { 00156 throw ProcessError("The detector types are not defined; use in combination with a network"); 00157 } 00158 // whether the detectors have routes 00159 if (!detectors.detectorsHaveRoutes()) { 00160 throw ProcessError("The emitters have no routes; use in combination with a network"); 00161 } 00162 00163 // save the detectors if wished 00164 if (oc.isSet("detector-output")) { 00165 detectors.save(oc.getString("detector-output")); 00166 } 00167 // save their positions as POIs if wished 00168 if (oc.isSet("detectors-poi-output")) { 00169 detectors.saveAsPOIs(oc.getString("detectors-poi-output")); 00170 } 00171 00172 // save the routes file if it was changed or it's wished 00173 if (detectors.detectorsHaveRoutes()&&oc.isSet("routes-output")) { 00174 detectors.saveRoutes(oc.getString("routes-output")); 00175 } 00176 00177 // guess flows if wished 00178 if (oc.getBool("guess-empty-flows")) { 00179 optNet->buildDetectorDependencies(detectors); 00180 detectors.guessEmptyFlows(flows); 00181 } 00182 00183 const SUMOTime begin = string2time(oc.getString("begin")); 00184 const SUMOTime end = string2time(oc.getString("end")); 00185 const SUMOTime step = string2time(oc.getString("time-step")); 00186 00187 // save emitters if wished 00188 if (oc.isSet("emitters-output")||oc.isSet("emitters-poi-output")) { 00189 optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!! 00190 if (oc.getBool("revalidate-flows")) { 00191 PROGRESS_BEGIN_MESSAGE("Rechecking loaded flows"); 00192 optNet->revalidateFlows(detectors, flows, begin, end, step); 00193 PROGRESS_DONE_MESSAGE(); 00194 } 00195 if (oc.isSet("emitters-output")) { 00196 PROGRESS_BEGIN_MESSAGE("Writing emitters"); 00197 detectors.writeEmitters(oc.getString("emitters-output"), flows, 00198 begin, end, step, 00199 *optNet, 00200 oc.getBool("calibrator-output"), 00201 oc.getBool("include-unused-routes"), 00202 oc.getFloat("scale"), 00203 oc.getInt("max-search-depth"), 00204 oc.getBool("emissions-only")); 00205 PROGRESS_DONE_MESSAGE(); 00206 } 00207 if (oc.isSet("emitters-poi-output")) { 00208 PROGRESS_BEGIN_MESSAGE("Writing emitter pois"); 00209 detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows); 00210 PROGRESS_DONE_MESSAGE(); 00211 } 00212 } 00213 // save end speed trigger if wished 00214 if (oc.isSet("variable-speed-sign-output")) { 00215 PROGRESS_BEGIN_MESSAGE("Writing speed triggers"); 00216 detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows, 00217 begin, end, step); 00218 PROGRESS_DONE_MESSAGE(); 00219 } 00220 // save checking detectors if wished 00221 if (oc.isSet("validation-output")) { 00222 PROGRESS_BEGIN_MESSAGE("Writing validation detectors"); 00223 detectors.writeValidationDetectors(oc.getString("validation-output"), 00224 oc.getBool("validation-output.add-sources"), true, true); // !!! 00225 PROGRESS_DONE_MESSAGE(); 00226 } 00227 // build global rerouter on end if wished 00228 if (oc.isSet("end-reroute-output")) { 00229 PROGRESS_BEGIN_MESSAGE("Writing highway end rerouter"); 00230 detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!! 00231 PROGRESS_DONE_MESSAGE(); 00232 } 00233 /* 00234 // save the insertion definitions 00235 if(oc.isSet("flow-definitions")) { 00236 buildVehicleEmissions(oc.getString("flow-definitions")); 00237 } 00238 */ 00239 // 00240 } 00241 00242 00243 /* ------------------------------------------------------------------------- 00244 * main 00245 * ----------------------------------------------------------------------- */ 00246 int 00247 main(int argc, char** argv) { 00248 OptionsCont& oc = OptionsCont::getOptions(); 00249 // give some application descriptions 00250 oc.setApplicationDescription("Builds vehicle routes for SUMO using detector values."); 00251 oc.setApplicationName("dfrouter", "SUMO dfrouter Version " + (std::string)VERSION_STRING); 00252 int ret = 0; 00253 RODFNet* net = 0; 00254 RODFDetectorCon* detectors = 0; 00255 RODFDetectorFlows* flows = 0; 00256 try { 00257 // initialise the application system (messaging, xml, options) 00258 XMLSubSys::init(false); 00259 RODFFrame::fillOptions(); 00260 OptionsIO::getOptions(true, argc, argv); 00261 if (oc.processMetaOptions(argc < 2)) { 00262 SystemFrame::close(); 00263 return 0; 00264 } 00265 MsgHandler::initOutputOptions(); 00266 if (!RODFFrame::checkOptions()) { 00267 throw ProcessError(); 00268 } 00269 RandHelper::initRandGlobal(); 00270 // load data 00271 ROLoader loader(oc, false); 00272 net = new RODFNet(oc.getBool("highway-mode")); 00273 RODFEdgeBuilder builder; 00274 loader.loadNet(*net, builder); 00275 net->buildApproachList(); 00276 // load detectors 00277 detectors = new RODFDetectorCon(); 00278 readDetectors(*detectors, oc, net); 00279 // load detector values 00280 flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")), 00281 string2time(oc.getString("time-step"))); 00282 readDetectorFlows(*flows, oc, *detectors); 00283 // build routes 00284 startComputation(net, *flows, *detectors, oc); 00285 } catch (ProcessError& e) { 00286 if (std::string(e.what())!=std::string("Process Error") && std::string(e.what())!=std::string("")) { 00287 WRITE_ERROR(e.what()); 00288 } 00289 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false); 00290 ret = 1; 00291 #ifndef _DEBUG 00292 } catch (...) { 00293 MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false); 00294 ret = 1; 00295 #endif 00296 } 00297 delete net; 00298 delete flows; 00299 delete detectors; 00300 OutputDevice::closeAll(); 00301 SystemFrame::close(); 00302 if (ret==0) { 00303 std::cout << "Success." << std::endl; 00304 } 00305 return ret; 00306 } 00307 00308 00309 00310 /****************************************************************************/ 00311