SUMO - Simulation of Urban MObility
dfrouter_main.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines