Eclipse SUMO - Simulation of Urban MObility
NLBuilder.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 /****************************************************************************/
17 // The main interface for loading a microsim
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <iostream>
27 #include <vector>
28 #include <string>
29 #include <map>
30 
35 #include <utils/options/Option.h>
40 #include <utils/common/SysUtils.h>
41 #include <utils/common/ToString.h>
44 #include <utils/xml/XMLSubSys.h>
48 #include <microsim/MSNet.h>
50 #include <microsim/MSEdgeControl.h>
51 #include <microsim/MSGlobals.h>
53 #include <microsim/MSFrame.h>
57 
58 #include "NLHandler.h"
59 #include "NLEdgeControlBuilder.h"
61 #include "NLDetectorBuilder.h"
62 #include "NLTriggerBuilder.h"
63 #include "NLBuilder.h"
64 
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
69 // ---------------------------------------------------------------------------
70 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeWeight - methods
71 // ---------------------------------------------------------------------------
72 void
74  double value, double begTime, double endTime) const {
75  MSEdge* edge = MSEdge::dictionary(id);
76  if (edge != nullptr) {
77  myNet.getWeightsStorage().addEffort(edge, begTime, endTime, value);
78  } else {
79  WRITE_ERROR("Trying to set the effort for the unknown edge '" + id + "'.");
80  }
81 }
82 
83 
84 // ---------------------------------------------------------------------------
85 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
86 // ---------------------------------------------------------------------------
87 void
89  double value, double begTime, double endTime) const {
90  MSEdge* edge = MSEdge::dictionary(id);
91  if (edge != nullptr) {
92  myNet.getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
93  } else {
94  WRITE_ERROR("Trying to set the travel time for the unknown edge '" + id + "'.");
95  }
96 }
97 
98 
99 // ---------------------------------------------------------------------------
100 // NLBuilder - methods
101 // ---------------------------------------------------------------------------
103  MSNet& net,
106  NLDetectorBuilder& db,
107  NLHandler& xmlHandler)
108  : myOptions(oc), myEdgeBuilder(eb), myJunctionBuilder(jb),
109  myDetectorBuilder(db),
110  myNet(net), myXMLHandler(xmlHandler) {}
111 
112 
114 
115 
116 bool
118  // try to build the net
119  if (!load("net-file", true)) {
120  return false;
121  }
122  if (myXMLHandler.networkVersion() == 0.) {
123  throw ProcessError("Invalid network, no network version declared.");
124  }
125  // check whether the loaded net agrees with the simulation options
126  if (myOptions.getBool("no-internal-links") && myXMLHandler.haveSeenInternalEdge()) {
127  WRITE_WARNING("Network contains internal links but option --no-internal-links is set. Vehicles will 'jump' across junctions and thus underestimate route lengths and travel times.");
128  }
129  if (myOptions.getString("lanechange.duration") != "0" && myXMLHandler.haveSeenNeighs()) {
130  throw ProcessError("Network contains explicit neigh lanes which do not work together with option --lanechange.duration.");
131  }
132  buildNet();
133  // @note on loading order constraints:
134  // - additional-files before route-files and state-files due to referencing
135  // - additional-files before weight-files since the latter might contain intermodal edge data and the intermodal net depends on the stops and public transport from the additionals
136 
137  // load additional net elements (sources, detectors, ...)
138  if (myOptions.isSet("additional-files")) {
139  if (!load("additional-files")) {
140  return false;
141  }
142  // load shapes with separate handler
144  if (!ShapeHandler::loadFiles(myOptions.getStringVector("additional-files"), sh)) {
145  return false;
146  }
149  }
150  }
151  // load weights if wished
152  if (myOptions.isSet("weight-files")) {
153  if (!myOptions.isUsableFileList("weight-files")) {
154  return false;
155  }
156  // build and prepare the weights handler
157  std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
158  // travel time, first (always used)
160  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", true, ttRetriever));
161  // the measure to use, then
163  std::string measure = myOptions.getString("weight-attribute");
164  if (!myOptions.isDefault("weight-attribute")) {
165  if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel" || measure == "electricity") {
166  measure += "_perVeh";
167  }
168  retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(measure, true, eRetriever));
169  }
170  // set up handler
171  SAXWeightsHandler handler(retrieverDefs, "");
172  // start parsing; for each file in the list
173  std::vector<std::string> files = myOptions.getStringVector("weight-files");
174  for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
175  // report about loading when wished
176  WRITE_MESSAGE("Loading weights from '" + *i + "'...");
177  // parse the file
178  if (!XMLSubSys::runParser(handler, *i)) {
179  return false;
180  }
181  }
182  }
183  // load the previous state if wished
184  if (myOptions.isSet("load-state")) {
185  long before = SysUtils::getCurrentMillis();
186  const std::string& f = myOptions.getString("load-state");
187  PROGRESS_BEGIN_MESSAGE("Loading state from '" + f + "'");
188  MSStateHandler h(f, string2time(myOptions.getString("load-state.offset")));
189  XMLSubSys::runParser(h, f);
190  if (myOptions.isDefault("begin")) {
191  myOptions.set("begin", time2string(h.getTime()));
192  if (TraCIServer::getInstance() != nullptr) {
194  }
195  }
197  return false;
198  }
199  if (h.getTime() != string2time(myOptions.getString("begin"))) {
200  WRITE_WARNING("State was written at a different time " + time2string(h.getTime()) + " than the begin time " + myOptions.getString("begin") + "!");
201  }
202  PROGRESS_TIME_MESSAGE(before);
203  }
204  // load routes
205  if (myOptions.isSet("route-files") && string2time(myOptions.getString("route-steps")) <= 0) {
206  if (!load("route-files")) {
207  return false;
208  }
209  }
210  // optionally switch off traffic lights
211  if (myOptions.getBool("tls.all-off")) {
213  }
214  WRITE_MESSAGE("Loading done.");
215  return true;
216 }
217 
218 
219 MSNet*
222  oc.clear();
225  if (oc.processMetaOptions(OptionsIO::getArgC() < 2)) {
227  return nullptr;
228  }
229  XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
230  if (!MSFrame::checkOptions()) {
231  throw ProcessError();
232  }
234  initRandomness();
236  MSVehicleControl* vc = nullptr;
238  vc = new MEVehicleControl();
239  } else {
240  vc = new MSVehicleControl();
241  }
242  MSNet* net = new MSNet(vc, new MSEventControl(), new MSEventControl(), new MSEventControl());
243  // need to init TraCI-Server before loading routes to catch VEHICLE_STATE_BUILT
244  TraCIServer::openSocket(std::map<int, TraCIServer::CmdExecutor>());
245 
247  NLDetectorBuilder db(*net);
248  NLJunctionControlBuilder jb(*net, db);
249  NLTriggerBuilder tb;
250  NLHandler handler("", *net, db, tb, eb, jb);
251  tb.setHandler(&handler);
252  NLBuilder builder(oc, *net, eb, jb, db, handler);
256  if (builder.build()) {
257  // preload the routes especially for TraCI
258  net->loadRoutes();
259  return net;
260  }
261  delete net;
262  throw ProcessError();
263 }
264 
265 void
271 }
272 
273 void
275  MSEdgeControl* edges = nullptr;
276  MSJunctionControl* junctions = nullptr;
277  SUMORouteLoaderControl* routeLoaders = nullptr;
278  MSTLLogicControl* tlc = nullptr;
279  std::vector<SUMOTime> stateDumpTimes;
280  std::vector<std::string> stateDumpFiles;
281  try {
282  MSFrame::buildStreams(); // ensure streams are ready for output during building
284  junctions = myJunctionBuilder.build();
285  junctions->postloadInitContainer();
286  routeLoaders = buildRouteLoaderControl(myOptions);
288  const std::vector<int> times = myOptions.getIntVector("save-state.times");
289  for (std::vector<int>::const_iterator i = times.begin(); i != times.end(); ++i) {
290  stateDumpTimes.push_back(TIME2STEPS(*i));
291  }
292  if (myOptions.isSet("save-state.files")) {
293  stateDumpFiles = myOptions.getStringVector("save-state.files");
294  if (stateDumpFiles.size() != stateDumpTimes.size()) {
295  WRITE_ERROR("Wrong number of state file names!");
296  }
297  } else {
298  const std::string prefix = myOptions.getString("save-state.prefix");
299  const std::string suffix = myOptions.getString("save-state.suffix");
300  for (std::vector<SUMOTime>::iterator i = stateDumpTimes.begin(); i != stateDumpTimes.end(); ++i) {
301  stateDumpFiles.push_back(prefix + "_" + time2string(*i) + suffix);
302  }
303  }
304  } catch (IOError& e) {
305  delete edges;
306  delete junctions;
307  delete routeLoaders;
308  delete tlc;
309  throw ProcessError(e.what());
310  } catch (ProcessError&) {
311  delete edges;
312  delete junctions;
313  delete routeLoaders;
314  delete tlc;
315  throw;
316  }
317  // if anthing goes wrong after this point, the net is responsible for cleaning up
318  myNet.closeBuilding(myOptions, edges, junctions, routeLoaders, tlc, stateDumpTimes, stateDumpFiles,
323 }
324 
325 
326 bool
327 NLBuilder::load(const std::string& mmlWhat, const bool isNet) {
328  if (!myOptions.isUsableFileList(mmlWhat)) {
329  return false;
330  }
331  std::vector<std::string> files = myOptions.getStringVector(mmlWhat);
332  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
333  PROGRESS_BEGIN_MESSAGE("Loading " + mmlWhat + " from '" + *fileIt + "'");
334  long before = SysUtils::getCurrentMillis();
335  if (!XMLSubSys::runParser(myXMLHandler, *fileIt, isNet)) {
336  WRITE_MESSAGE("Loading of " + mmlWhat + " failed.");
337  return false;
338  }
339  PROGRESS_TIME_MESSAGE(before);
340  }
341  return true;
342 }
343 
344 
347  // build the loaders
348  SUMORouteLoaderControl* loaders = new SUMORouteLoaderControl(string2time(oc.getString("route-steps")));
349  // check whether a list is existing
350  if (oc.isSet("route-files") && string2time(oc.getString("route-steps")) > 0) {
351  std::vector<std::string> files = oc.getStringVector("route-files");
352  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
353  if (!FileHelpers::isReadable(*fileIt)) {
354  throw ProcessError("The route file '" + *fileIt + "' is not accessible.");
355  }
356  }
357  // open files for reading
358  for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
359  loaders->add(new SUMORouteLoader(new MSRouteHandler(*fileIt, false)));
360  }
361  }
362  return loaders;
363 }
364 
365 
366 /****************************************************************************/
void setHandler(NLHandler *handler)
Sets the parent handler to use for nested parsing.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:72
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:81
Builds detectors for microsim.
SUMOTime getTime() const
get time
void switchOffAll()
switch all logic variants to &#39;off&#39;
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition: OptionsIO.cpp:76
Obtains edge efforts from a weights handler and stores them within the edges.
Definition: NLBuilder.h:177
void buildNet()
Closes the net building process.
Definition: NLBuilder.cpp:274
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:49
static void initRNGs(const OptionsCont &oc)
initialize rngs
Definition: MSLane.cpp:3672
void addEdgeWeight(const std::string &id, double val, double beg, double end) const
Adds an effort for a given edge and time period.
Definition: NLBuilder.cpp:73
The main interface for loading a microsim.
Definition: NLBuilder.h:61
static void buildStreams()
Builds the streams used possibly by the simulation.
Definition: MSFrame.cpp:527
Parser and output filter for routes and vehicles state saving and loading.
static void setValidation(const std::string &validationScheme, const std::string &netValidationScheme)
Enables or disables validation.
Definition: XMLSubSys.cpp:59
static bool loadFiles(const std::vector< std::string > &files, ShapeHandler &sh)
loads all of the given files
An XML-handler for network weights.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
MSNet & myNet
The network edges shall be obtained from.
Definition: NLBuilder.h:167
void add(SUMORouteLoader *loader)
add another loader
OptionsCont & myOptions
The options to get the names of the files to load and further information from.
Definition: NLBuilder.h:205
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:804
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool wasInformed() const
Returns the information whether any messages were added.
Definition: MsgHandler.cpp:270
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:113
static void close()
Closes all of an applications subsystems.
void setAdditionalRestrictions()
apply additional restrictions
static std::mt19937 * getEquipmentRNG()
Definition: MSDevice.h:91
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
The simulated network and simulation perfomer.
Definition: MSNet.h:92
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Container for junctions; performs operations on all stored junctions.
static std::mt19937 * getParsingRNG()
get parsing RNG
static void fillOptions()
Inserts options used by the simulation into the OptionsCont-singleton.
Definition: MSFrame.cpp:61
A class that stores and controls tls and switching of their programs.
NLJunctionControlBuilder & myJunctionBuilder
The junction control builder to use.
Definition: NLBuilder.h:211
A road/street connecting two junctions.
Definition: MSEdge.h:76
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:243
bool lefthand() const
Definition: NLHandler.h:117
void clear()
Removes all information from the container.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
Builder of microsim-junctions and tls.
ShapeContainer & getShapeContainer()
Returns the shapes container.
Definition: MSNet.h:460
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:410
void addTravelTime(const MSEdge *const e, double begin, double end, double value)
Adds a travel time information for an edge and a time span.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
Stores edges and lanes, performs moving of vehicle.
Definition: MSEdgeControl.h:73
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
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) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:241
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:59
static int getArgC()
Return the number of command line arguments.
Definition: OptionsIO.h:66
MSNet & myNet
The net to fill.
Definition: NLBuilder.h:217
The class responsible for building and deletion of vehicles (gui-version)
NLBuilder(OptionsCont &oc, MSNet &net, NLEdgeControlBuilder &eb, NLJunctionControlBuilder &jb, NLDetectorBuilder &db, NLHandler &xmlHandler)
Constructor.
Definition: NLBuilder.cpp:102
void postloadInitContainer()
Closes building of junctions.
double networkVersion() const
Definition: NLHandler.h:121
void closeBuilding(const OptionsCont &oc, MSEdgeControl *edges, MSJunctionControl *junctions, SUMORouteLoaderControl *routeLoaders, MSTLLogicControl *tlc, std::vector< SUMOTime > stateDumpTimes, std::vector< std::string > stateDumpFiles, bool hasInternalLinks, bool hasNeighs, bool lefthand, double version)
Closes the network&#39;s building process.
Definition: MSNet.cpp:241
The XML-Handler for network loading.
Definition: NLHandler.h:81
static bool checkOptions()
Checks the set options.
Definition: MSFrame.cpp:559
virtual bool build()
Builds and initialises the simulation.
Definition: NLBuilder.cpp:117
static void initRandomness()
initializes all RNGs
Definition: NLBuilder.cpp:266
Complete definition about what shall be retrieved and where to store it.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
bool haveSeenAdditionalSpeedRestrictions() const
Definition: NLHandler.h:113
static void openSocket(const std::map< int, CmdExecutor > &execs)
Initialises the server.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
The XML-Handler for shapes loading network loading.
Definition: NLHandler.h:57
const IntVector & getIntVector(const std::string &name) const
Returns the list of integer-value of the named option (only for Option_IntVector) ...
void setTargetTime(SUMOTime targetTime)
Sets myTargetTime on server and sockets to the given value.
static TraCIServer * getInstance()
Definition: TraCIServer.h:71
A storage for options typed value containers)
Definition: OptionsCont.h:90
SUMORouteLoaderControl * buildRouteLoaderControl(const OptionsCont &oc)
Builds the route loader control.
Definition: NLBuilder.cpp:346
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
bool haveSeenInternalEdge() const
Definition: NLHandler.h:105
bool load(const std::string &mmlWhat, const bool isNet=false)
Loads a described subpart form the given list of files.
Definition: NLBuilder.cpp:327
static void setMSGlobals(OptionsCont &oc)
Sets the global microsim-options.
Definition: MSFrame.cpp:683
void addEdgeWeight(const std::string &id, double val, double beg, double end) const
Adds a travel time for a given edge and time period.
Definition: NLBuilder.cpp:88
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:380
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
The class responsible for building and deletion of vehicles.
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:39
Builds trigger objects for microsim.
virtual ~NLBuilder()
Destructor.
Definition: NLBuilder.cpp:113
void loadRoutes()
loads routes for the next few steps
Definition: MSNet.cpp:375
static MSNet * init()
Definition: NLBuilder.cpp:220
virtual void clear()
Clears information whether an error occurred previously.
Definition: MsgHandler.cpp:160
bool haveSeenNeighs() const
Definition: NLHandler.h:109
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:240
static void initOutputOptions()
init output options
Definition: MsgHandler.cpp:208
MSTLLogicControl * buildTLLogics()
Returns the built tls-logic control.
static bool gUseMesoSim
Definition: MSGlobals.h:91
NLDetectorBuilder & myDetectorBuilder
The detector control builder to use.
Definition: NLBuilder.h:214
Stores time-dependant events and executes them at the proper time.
NLHandler & myXMLHandler
The handler used to parse the net.
Definition: NLBuilder.h:220
Parser and container for routes during their loading.
Interface for building edges.
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net&#39;s internal edge travel times/efforts container.
Definition: MSNet.cpp:820
void addEffort(const MSEdge *const e, double begin, double end, double value)
Adds an effort information for an edge and a time span.
NLEdgeControlBuilder & myEdgeBuilder
The edge control builder to use.
Definition: NLBuilder.h:208
MSEdgeControl * build(double networkVersion)
builds the MSEdgeControl-class which holds all edges