Eclipse SUMO - Simulation of Urban MObility
dfrouter_main.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
20 // Main for the DFROUTER
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #ifdef HAVE_VERSION_H
30 #include <version.h>
31 #endif
32 
33 #include <iostream>
34 #include <string>
35 #include <limits.h>
36 #include <ctime>
37 #include <xercesc/sax/SAXException.hpp>
38 #include <xercesc/sax/SAXParseException.hpp>
43 #include <utils/common/ToString.h>
45 #include <utils/options/Option.h>
49 #include <utils/xml/XMLSubSys.h>
50 #include <router/ROLoader.h>
51 #include <router/RONet.h>
52 #include <router/ROFrame.h>
53 #include "RODFEdgeBuilder.h"
54 #include "RODFFrame.h"
55 #include "RODFNet.h"
56 #include "RODFEdge.h"
57 #include "RODFDetector.h"
58 #include "RODFDetectorHandler.h"
59 #include "RODFRouteCont.h"
60 #include "RODFDetectorFlow.h"
61 #include "RODFDetFlowLoader.h"
62 
63 
64 // ===========================================================================
65 // functions
66 // ===========================================================================
67 /* -------------------------------------------------------------------------
68  * data processing methods
69  * ----------------------------------------------------------------------- */
70 void
71 readDetectors(RODFDetectorCon& detectors, OptionsCont& oc, RODFNet* optNet) {
72  if (!oc.isSet("detector-files")) {
73  throw ProcessError("No detector file given (use --detector-files <FILE>).");
74  }
75  // read definitions stored in XML-format
76  std::vector<std::string> files = oc.getStringVector("detector-files");
77  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
78  if (!FileHelpers::isReadable(*fileIt)) {
79  throw ProcessError("Could not open detector file '" + *fileIt + "'");
80  }
81  PROGRESS_BEGIN_MESSAGE("Loading detector definitions from '" + *fileIt + "'");
82  RODFDetectorHandler handler(optNet, oc.getBool("ignore-invalid-detectors"), detectors, *fileIt);
83  if (XMLSubSys::runParser(handler, *fileIt)) {
85  } else {
87  throw ProcessError();
88  }
89  }
90  if (detectors.getDetectors().empty()) {
91  throw ProcessError("No detectors found.");
92  }
93 }
94 
95 
96 void
98  if (!oc.isSet("measure-files")) {
99  // ok, not given, return an empty container
100  return;
101  }
102  // check whether the file exists
103  std::vector<std::string> files = oc.getStringVector("measure-files");
104  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
105  if (!FileHelpers::isReadable(*fileIt)) {
106  throw ProcessError("The measure-file '" + *fileIt + "' can not be opened.");
107  }
108  // parse
109  PROGRESS_BEGIN_MESSAGE("Loading flows from '" + *fileIt + "'");
110  RODFDetFlowLoader dfl(dc, flows, string2time(oc.getString("begin")), string2time(oc.getString("end")),
111  string2time(oc.getString("time-offset")), string2time(oc.getString("time-factor")));
112  dfl.read(*fileIt);
114  }
115 }
116 
117 
118 void
120  if (oc.getBool("print-absolute-flows")) {
121  flows.printAbsolute();
122  }
123 
124  // if a network was loaded... (mode1)
125  if (optNet != nullptr) {
126  if (oc.getBool("remove-empty-detectors")) {
127  PROGRESS_BEGIN_MESSAGE("Removing empty detectors");
128  optNet->removeEmptyDetectors(detectors, flows);
130  } else if (oc.getBool("report-empty-detectors")) {
131  PROGRESS_BEGIN_MESSAGE("Scanning for empty detectors");
132  optNet->reportEmptyDetectors(detectors, flows);
134  }
135  // compute the detector types (optionally)
136  if (!detectors.detectorsHaveCompleteTypes() || oc.getBool("revalidate-detectors")) {
137  optNet->computeTypes(detectors, oc.getBool("strict-sources"));
138  }
139  std::vector<RODFDetector*>::const_iterator i = detectors.getDetectors().begin();
140  for (; i != detectors.getDetectors().end(); ++i) {
141  if ((*i)->getType() == SOURCE_DETECTOR) {
142  break;
143  }
144  }
145  if (i == detectors.getDetectors().end() && !oc.getBool("routes-for-all")) {
146  throw ProcessError("No source detectors found.");
147  }
148  // compute routes between the detectors (optionally)
149  if (!detectors.detectorsHaveRoutes() || oc.getBool("revalidate-routes") || oc.getBool("guess-empty-flows")) {
150  PROGRESS_BEGIN_MESSAGE("Computing routes");
151  optNet->buildRoutes(detectors,
152  oc.getBool("keep-unfinished-routes"), oc.getBool("routes-for-all"),
153  !oc.getBool("keep-longer-routes"), oc.getInt("max-search-depth"));
155  }
156  }
157 
158  // check
159  // whether the detectors are valid
160  if (!detectors.detectorsHaveCompleteTypes()) {
161  throw ProcessError("The detector types are not defined; use in combination with a network");
162  }
163  // whether the detectors have routes
164  if (!detectors.detectorsHaveRoutes()) {
165  throw ProcessError("The emitters have no routes; use in combination with a network");
166  }
167 
168  // save the detectors if wished
169  if (oc.isSet("detector-output")) {
170  detectors.save(oc.getString("detector-output"));
171  }
172  // save their positions as POIs if wished
173  if (oc.isSet("detectors-poi-output")) {
174  detectors.saveAsPOIs(oc.getString("detectors-poi-output"));
175  }
176 
177  // save the routes file if it was changed or it's wished
178  if (detectors.detectorsHaveRoutes() && oc.isSet("routes-output")) {
179  detectors.saveRoutes(oc.getString("routes-output"));
180  }
181 
182  // guess flows if wished
183  if (oc.getBool("guess-empty-flows")) {
184  optNet->buildDetectorDependencies(detectors);
185  detectors.guessEmptyFlows(flows);
186  }
187 
188  const SUMOTime begin = string2time(oc.getString("begin"));
189  const SUMOTime end = string2time(oc.getString("end"));
190  const SUMOTime step = string2time(oc.getString("time-step"));
191 
192  // save emitters if wished
193  if (oc.isSet("emitters-output") || oc.isSet("emitters-poi-output")) {
194  optNet->buildEdgeFlowMap(flows, detectors, begin, end, step); // !!!
195  if (oc.getBool("revalidate-flows")) {
196  PROGRESS_BEGIN_MESSAGE("Rechecking loaded flows");
197  optNet->revalidateFlows(detectors, flows, begin, end, step);
199  }
200  if (oc.isSet("emitters-output")) {
201  PROGRESS_BEGIN_MESSAGE("Writing emitters");
202  detectors.writeEmitters(oc.getString("emitters-output"), flows,
203  begin, end, step,
204  *optNet,
205  oc.getBool("calibrator-output"),
206  oc.getBool("include-unused-routes"),
207  oc.getFloat("scale"),
208 // oc.getInt("max-search-depth"),
209  oc.getBool("emissions-only"));
211  }
212  if (oc.isSet("emitters-poi-output")) {
213  PROGRESS_BEGIN_MESSAGE("Writing emitter pois");
214  detectors.writeEmitterPOIs(oc.getString("emitters-poi-output"), flows);
216  }
217  }
218  // save end speed trigger if wished
219  if (oc.isSet("variable-speed-sign-output")) {
220  PROGRESS_BEGIN_MESSAGE("Writing speed triggers");
221  detectors.writeSpeedTrigger(optNet, oc.getString("variable-speed-sign-output"), flows,
222  begin, end, step);
224  }
225  // save checking detectors if wished
226  if (oc.isSet("validation-output")) {
227  PROGRESS_BEGIN_MESSAGE("Writing validation detectors");
228  detectors.writeValidationDetectors(oc.getString("validation-output"),
229  oc.getBool("validation-output.add-sources"), true, true); // !!!
231  }
232  // build global rerouter on end if wished
233  if (oc.isSet("end-reroute-output")) {
234  PROGRESS_BEGIN_MESSAGE("Writing highway end rerouter");
235  detectors.writeEndRerouterDetectors(oc.getString("end-reroute-output")); // !!!
237  }
238  /*
239  // save the insertion definitions
240  if(oc.isSet("flow-definitions")) {
241  buildVehicleEmissions(oc.getString("flow-definitions"));
242  }
243  */
244  //
245 }
246 
247 
248 /* -------------------------------------------------------------------------
249  * main
250  * ----------------------------------------------------------------------- */
251 int
252 main(int argc, char** argv) {
254  // give some application descriptions
255  oc.setApplicationDescription("Builds vehicle routes for SUMO using detector values.");
256  oc.setApplicationName("dfrouter", "Eclipse SUMO dfrouter Version " VERSION_STRING);
257  int ret = 0;
258  RODFNet* net = nullptr;
259  RODFDetectorCon* detectors = nullptr;
260  RODFDetectorFlows* flows = nullptr;
261  try {
262  // initialise the application system (messaging, xml, options)
263  XMLSubSys::init();
265  OptionsIO::setArgs(argc, argv);
267  if (oc.processMetaOptions(argc < 2)) {
269  return 0;
270  }
271  XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
274  throw ProcessError();
275  }
277  // load data
278  ROLoader loader(oc, false, !oc.getBool("no-step-log"));
279  net = new RODFNet(oc.getBool("highway-mode"));
280  RODFEdgeBuilder builder;
281  loader.loadNet(*net, builder);
282  net->buildApproachList();
283  // load detectors
284  detectors = new RODFDetectorCon();
285  readDetectors(*detectors, oc, net);
286  // load detector values
287  flows = new RODFDetectorFlows(string2time(oc.getString("begin")), string2time(oc.getString("end")),
288  string2time(oc.getString("time-step")));
289  readDetectorFlows(*flows, oc, *detectors);
290  // build routes
291  startComputation(net, *flows, *detectors, oc);
292  } catch (const ProcessError& e) {
293  if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
294  WRITE_ERROR(e.what());
295  }
296  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
297  ret = 1;
298 #ifndef _DEBUG
299  } catch (const std::exception& e) {
300  if (std::string(e.what()) != std::string("")) {
301  WRITE_ERROR(e.what());
302  }
303  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
304  ret = 1;
305  } catch (...) {
306  MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
307  ret = 1;
308 #endif
309  }
310  delete net;
311  delete flows;
312  delete detectors;
314  if (ret == 0) {
315  std::cout << "Success." << std::endl;
316  }
317  return ret;
318 }
319 
320 
321 
322 /****************************************************************************/
323 
startComputation
void startComputation(RODFNet *optNet, RODFDetectorFlows &flows, RODFDetectorCon &detectors, OptionsCont &oc)
Definition: dfrouter_main.cpp:119
RODFDetectorHandler.h
RODFDetectorFlows
A container for flows.
Definition: RODFDetectorFlow.h:68
OptionsCont::isSet
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
Definition: OptionsCont.cpp:136
ROLoader
The data loader.
Definition: ROLoader.h:56
RODFDetectorCon::detectorsHaveRoutes
bool detectorsHaveRoutes() const
Definition: RODFDetector.cpp:513
OptionsCont::getInt
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
Definition: OptionsCont.cpp:216
OptionsCont::processMetaOptions
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
Definition: OptionsCont.cpp:561
ToString.h
XMLSubSys::runParser
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:113
RODFDetectorHandler
SAX2-Handler for loading DFROUTER-detector definitions.
Definition: RODFDetectorHandler.h:42
SystemFrame::close
static void close()
Closes all of an applications subsystems.
Definition: SystemFrame.cpp:131
MsgHandler::initOutputOptions
static void initOutputOptions()
init output options
Definition: MsgHandler.cpp:208
RODFFrame::checkOptions
static bool checkOptions()
Checks set options from the OptionsCont-singleton for being valid for usage within dfrouter.
Definition: RODFFrame.cpp:252
PROGRESS_FAILED_MESSAGE
#define PROGRESS_FAILED_MESSAGE()
Definition: MsgHandler.h:244
OptionsCont.h
RODFDetectorCon::writeSpeedTrigger
void writeSpeedTrigger(const RODFNet *const net, const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
Definition: RODFDetector.cpp:804
RODFDetectorCon::saveRoutes
void saveRoutes(const std::string &file) const
Definition: RODFDetector.cpp:586
RODFDetFlowLoader
A loader for detector flows.
Definition: RODFDetFlowLoader.h:43
RODFDetectorFlows::printAbsolute
void printAbsolute() const
Definition: RODFDetectorFlow.cpp:173
MsgHandler.h
RODFNet::revalidateFlows
void revalidateFlows(const RODFDetectorCon &detectors, RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
Definition: RODFNet.cpp:571
OptionsCont::getString
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:202
FileHelpers.h
RODFNet::buildRoutes
void buildRoutes(RODFDetectorCon &det, bool keepUnfoundEnds, bool includeInBetween, bool keepShortestOnly, int maxFollowingLength) const
Definition: RODFNet.cpp:341
MsgHandler::inform
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:118
RODFEdge.h
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:223
RODFDetector.h
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
readDetectorFlows
void readDetectorFlows(RODFDetectorFlows &flows, OptionsCont &oc, RODFDetectorCon &dc)
Definition: dfrouter_main.cpp:97
ROFrame.h
RODFDetectorCon
A container for RODFDetectors.
Definition: RODFDetector.h:221
ROLoader.h
RODFDetectorCon::writeEmitters
void writeEmitters(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, bool writeCalibrators, bool includeUnusedRoutes, double scale, bool insertionsOnly)
Definition: RODFDetector.cpp:626
RODFNet::buildDetectorDependencies
void buildDetectorDependencies(RODFDetectorCon &detectors)
Definition: RODFNet.cpp:1026
main
int main(int argc, char **argv)
Definition: dfrouter_main.cpp:252
RODFNet::computeTypes
void computeTypes(RODFDetectorCon &dets, bool sourcesStrict) const
Definition: RODFNet.cpp:109
OptionsCont::setApplicationName
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.
Definition: OptionsCont.cpp:485
RODFDetectorCon::writeEmitterPOIs
void writeEmitterPOIs(const std::string &file, const RODFDetectorFlows &flows)
Definition: RODFDetector.cpp:728
SystemFrame.h
XMLSubSys::setValidation
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:59
RONet.h
RODFEdgeBuilder
Interface for building instances of dfrouter-edges.
Definition: RODFEdgeBuilder.h:50
OutputDevice.h
ProcessError
Definition: UtilExceptions.h:40
RODFDetectorCon::detectorsHaveCompleteTypes
bool detectorsHaveCompleteTypes() const
Definition: RODFDetector.cpp:502
UtilExceptions.h
XMLSubSys::init
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:48
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:90
readDetectors
void readDetectors(RODFDetectorCon &detectors, OptionsCont &oc, RODFNet *optNet)
Definition: dfrouter_main.cpp:71
string2time
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
RODFEdgeBuilder.h
RandHelper::initRandGlobal
static void initRandGlobal(std::mt19937 *which=0)
Reads the given random number options and initialises the random number generator in accordance.
Definition: RandHelper.cpp:72
RODFFrame::fillOptions
static void fillOptions()
Inserts options used by dfrouter into the OptionsCont-singleton.
Definition: RODFFrame.cpp:47
RODFNet::reportEmptyDetectors
void reportEmptyDetectors(RODFDetectorCon &detectors, RODFDetectorFlows &flows)
Definition: RODFNet.cpp:608
OptionsIO::getOptions
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition: OptionsIO.cpp:76
OptionsCont::setApplicationDescription
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
Definition: OptionsCont.cpp:493
OptionsCont::getFloat
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Definition: OptionsCont.cpp:209
RODFFrame.h
RODFDetectorCon::getDetectors
const std::vector< RODFDetector * > & getDetectors() const
Definition: RODFDetector.cpp:524
StringUtils.h
RODFNet::removeEmptyDetectors
void removeEmptyDetectors(RODFDetectorCon &detectors, RODFDetectorFlows &flows)
Definition: RODFNet.cpp:585
PROGRESS_BEGIN_MESSAGE
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:241
RODFDetectorFlow.h
Option.h
RODFDetFlowLoader.h
PROGRESS_DONE_MESSAGE
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:242
RODFNet
A DFROUTER-network.
Definition: RODFNet.h:45
OptionsIO::setArgs
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:55
RODFDetectorCon::guessEmptyFlows
void guessEmptyFlows(RODFDetectorFlows &flows)
Definition: RODFDetector.cpp:900
SOURCE_DETECTOR
A source detector.
Definition: RODFDetector.h:70
FileHelpers::isReadable
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:49
config.h
RODFDetectorCon::saveAsPOIs
void saveAsPOIs(const std::string &file) const
Definition: RODFDetector.cpp:558
SystemFrame::checkOptions
static bool checkOptions()
checks shared options and sets StdDefs
Definition: SystemFrame.cpp:118
RODFNet.h
MsgHandler::getErrorInstance
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:81
RODFDetectorCon::writeEndRerouterDetectors
void writeEndRerouterDetectors(const std::string &file)
Definition: RODFDetector.cpp:826
VERSION_STRING
#define VERSION_STRING
Definition: config.h:207
RODFDetectorCon::save
void save(const std::string &file) const
Definition: RODFDetector.cpp:530
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
RODFNet::buildEdgeFlowMap
void buildEdgeFlowMap(const RODFDetectorFlows &flows, const RODFDetectorCon &detectors, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
Definition: RODFNet.cpp:928
RODFRouteCont.h
OptionsCont::getStringVector
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:921
OptionsIO.h
RODFDetFlowLoader::read
void read(const std::string &file)
Reads the given file assuming it contains detector values.
Definition: RODFDetFlowLoader.cpp:55
RODFDetectorCon::writeValidationDetectors
void writeValidationDetectors(const std::string &file, bool includeSources, bool singleFile, bool friendly)
Definition: RODFDetector.cpp:842
XMLSubSys.h