SUMO - Simulation of Urban MObility
emissionsDrivingCycle_main.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // Main for an emissions calculator
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2013-2015 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #ifdef HAVE_VERSION_H
33 #include <version.h>
34 #endif
35 
37 #include <iostream>
38 #include <string>
39 #include <ctime>
41 #include <utils/options/Option.h>
46 #include <utils/common/ToString.h>
47 #include <utils/xml/XMLSubSys.h>
55 #include "TrajectoriesHandler.h"
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // functions
64 // ===========================================================================
65 
66 
67 /* -------------------------------------------------------------------------
68  * main
69  * ----------------------------------------------------------------------- */
70 int
71 main(int argc, char** argv) {
72  // build options
74  // give some application descriptions
75  oc.setApplicationDescription("Computes emissions by driving a time line.");
76  oc.setApplicationName("emissionsDrivingCycle", "SUMO emissionsDrivingCycle Version " + getBuildName(VERSION_STRING));
77  // add options
78 
80  oc.addOptionSubTopic("Input");
81  oc.doRegister("timeline-file", 't', new Option_FileName());
82  oc.addSynonyme("timeline", "timeline-file");
83  oc.addDescription("timeline-file", "Input", "Defines the file to read the driving cycle from.");
84 
85  oc.doRegister("netstate-file", 'n', new Option_FileName());
86  oc.addSynonyme("netstate", "netstate-file");
87  oc.addSynonyme("amitran", "netstate-file");
88  oc.addDescription("netstate-file", "Input", "Defines the netstate, route and trajectory files to read the driving cycles from.");
89 
90  oc.doRegister("emission-class", 'e', new Option_String("unknown"));
91  oc.addDescription("emission-class", "Input", "Defines for which emission class the emissions shall be generated. ");
92 
93 
94  oc.addOptionSubTopic("Processing");
95  oc.doRegister("compute-a", 'a', new Option_Bool(false));
96  oc.addDescription("compute-a", "Processing", "If set, the acceleration is computed instead of being read from the file. ");
97 
98  oc.doRegister("skip-first", 's', new Option_Bool(false));
99  oc.addDescription("skip-first", "Processing", "If set, the first line of the read file is skipped.");
100 
101  oc.doRegister("kmh", new Option_Bool(false));
102  oc.addDescription("kmh", "Processing", "If set, the given speed is interpreted as being given in km/h.");
103 
104  oc.doRegister("have-slope", new Option_Bool(false));
105  oc.addDescription("have-slope", "Processing", "If set, the fourth column is read and used as slope (in deg).");
106 
107  oc.doRegister("slope", new Option_Float(0));
108  oc.addDescription("slope", "Processing", "Sets a global slope (in deg) that is used if the file does not contain slope information.");
109 
110  oc.addOptionSubTopic("Output");
111  oc.doRegister("output-file", 'o', new Option_String());
112  oc.addSynonyme("output", "output-file");
113  oc.addDescription("output", "Output", "Defines the file to write the emission cycle results into. ");
114 
115  oc.doRegister("emission-output", new Option_FileName());
116  oc.addDescription("emission-output", "Output", "Save the emission values of each vehicle in XML");
117 
118  oc.addOptionSubTopic("Emissions");
119  oc.doRegister("phemlight-path", new Option_FileName("./PHEMlight/"));
120  oc.addDescription("phemlight-path", "Emissions", "Determines where to load PHEMlight definitions from.");
121 
123  oc.doRegister("quiet", 'q', new Option_Bool(false));
124  oc.addDescription("quiet", "Report", "Not writing anything.");
125 
126  // run
127  int ret = 0;
128  bool quiet = false;
129  try {
130  // initialise the application system (messaging, xml, options)
131  XMLSubSys::init();
132  OptionsIO::getOptions(true, argc, argv);
134  if (oc.processMetaOptions(argc < 2)) {
136  return 0;
137  }
138 
139  quiet = oc.getBool("quiet");
140  if (!oc.isSet("timeline-file") && !oc.isSet("netstate-file")) {
141  throw ProcessError("Either a timeline or a netstate / amitran file must be given.");
142  }
143  if (!oc.isSet("output-file") && (oc.isSet("timeline-file") || !oc.isSet("emission-output"))) {
144  throw ProcessError("The output file must be given.");
145  }
146  std::ostream* out = 0;
147  if (oc.isSet("output-file")) {
148  out = new std::ofstream(oc.getString("output-file").c_str());
149  }
150  OutputDevice::createDeviceByOption("emission-output", "emission-export", "emission_file.xsd");
151  OutputDevice* xmlOut = 0;
152  if (oc.isSet("emission-output")) {
153  xmlOut = &OutputDevice::getDeviceByOption("emission-output");
154  } else if (out == 0) {
155  out = &std::cout;
156  }
157 
158  const SUMOEmissionClass defaultClass = PollutantsInterface::getClassByName(oc.getString("emission-class"));
159  TrajectoriesHandler handler(oc.getBool("compute-a"), defaultClass, oc.getFloat("slope"), out, xmlOut);
160 
161  if (oc.isSet("timeline-file")) {
162  bool skipFirst = oc.getBool("skip-first");
163  const bool computeA = oc.getBool("compute-a");
164  const bool inKMH = oc.getBool("kmh");
165  const bool haveSlope = oc.getBool("have-slope");
166  SUMOReal l = 0;
167 
168  LineReader lr(oc.getString("timeline-file"));
169  while (lr.hasMore()) {
170  std::string line = lr.readLine();
171  if (skipFirst) {
172  skipFirst = false;
173  continue;
174  }
175  StringTokenizer st(StringUtils::prune(line), ";");
176  if (st.size() < 2) {
177  throw ProcessError("Each line must at least include the time and the speed.");
178  }
179  try {
180  const SUMOReal t = TplConvert::_2SUMOReal<char>(st.next().c_str());
181  SUMOReal v = TplConvert::_2SUMOReal<char>(st.next().c_str());
182  if (inKMH) {
183  v /= 3.6;
184  }
185  l += v;
186  const SUMOReal a = !computeA && st.hasNext() ? TplConvert::_2SUMOReal<char>(st.next().c_str()) : TrajectoriesHandler::INVALID_VALUE;
187  const SUMOReal s = haveSlope ? TplConvert::_2SUMOReal<char>(st.next().c_str()) : TrajectoriesHandler::INVALID_VALUE;
188  handler.writeEmissions(*out, "", defaultClass, t, v, a, s);
189  } catch (EmptyData&) {
190  throw ProcessError("Missing an entry in line '" + line + "'.");
191  } catch (NumberFormatException&) {
192  throw ProcessError("Not numeric entry in line '" + line + "'.");
193  }
194  }
195  if (!quiet) {
196  std::cout << "sums" << std::endl
197  << "length:" << l << std::endl;
198  }
199  }
200  if (oc.isSet("netstate-file")) {
201  XMLSubSys::runParser(handler, oc.getString("netstate-file"));
202  }
203  if (!quiet) {
204  handler.writeSums(std::cout, "");
205  }
206  } catch (InvalidArgument& e) {
208  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
209  ret = 1;
210  } catch (ProcessError& e) {
211  if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
213  }
214  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
215  ret = 1;
216 #ifndef _DEBUG
217  } catch (...) {
218  MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
219  ret = 1;
220 #endif
221  }
223  if (ret == 0 && !quiet) {
224  std::cout << "Success." << std::endl;
225  }
226  return ret;
227 }
228 
229 
230 
231 /****************************************************************************/
232 
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
Definition: OptionsCont.cpp:84
static void init()
Initialises the xml-subsystem.
Definition: XMLSubSys.cpp:58
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
static void addReportOptions(OptionsCont &oc)
Adds reporting options to the given container.
Definition: SystemFrame.cpp:74
std::string next()
static void getOptions(bool loadConfig, int argc=0, char **argv=0)
Parses the command line arguments and loads the configuration optionally.
Definition: OptionsIO.cpp:64
bool readLine(LineHandler &lh)
Reads a single (the next) line from the file and reports it to the given LineHandler.
Definition: LineReader.cpp:80
Retrieves a file linewise and reports the lines to a handler.
Definition: LineReader.h:58
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)
int main(int argc, char **argv)
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
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:114
static void close()
Closes all of an applications subsystems.
static void addConfigurationOptions(OptionsCont &oc)
Adds configuration options to the given container.
Definition: SystemFrame.cpp:50
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
static const int INVALID_VALUE
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
int SUMOEmissionClass
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
const std::string getBuildName(const std::string &version)
attach some build flags to the version string
Definition: StdDefs.cpp:88
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
size_t size() const
#define VERSION_STRING
Definition: config.h:230
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
Definition: StringUtils.cpp:56
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
An XML-Handler for amitran and netstate trajectories.
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:89
A storage for options typed value containers)
Definition: OptionsCont.h:108
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:218
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.