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