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