Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
emissionsMap_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) 2013-2025 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/****************************************************************************/
19// Main for an emissions map writer
20/****************************************************************************/
21#include <config.h>
22
23#ifdef HAVE_VERSION_H
24#include <version.h>
25#endif
26
27#include <iostream>
28#include <string>
29#include <ctime>
30#include <memory>
31#if __cplusplus >= 201703L
32#if __has_include(<filesystem>)
33#include <filesystem>
34namespace fs = std::filesystem;
35#elif __has_include(<experimental/filesystem>)
36#include <experimental/filesystem>
37namespace fs = std::experimental::filesystem;
38#endif
39#endif
50#include <utils/xml/XMLSubSys.h>
53#include "VTypesHandler.h"
54
55
56// ===========================================================================
57// functions
58// ===========================================================================
59void single(const OptionsCont& oc, const std::string& of, const std::string& className, SUMOEmissionClass c,
60 double vMin, double vMax, double vStep,
61 double aMin, double aMax, double aStep,
62 double sMin, double sMax, double sStep,
63 bool verbose) {
64 if (verbose) {
65 WRITE_MESSAGEF(TL("Writing map of '%' into '%'."), className, of);
66 }
67 std::ofstream o(of.c_str());
68 if (!o.good()) {
69 throw ProcessError(TLF("Could not open file '%' for writing.", of));
70 }
71
72 std::unique_ptr<EnergyParams> energyParams;
73 std::map<std::string, SUMOVTypeParameter*> vTypes;
74 if (oc.isSet("vtype") || oc.isSet("additional-files")) {
75 if (!oc.isSet("additional-files")) {
76 throw ProcessError(TL("Option --vtype requires option --additional-files for loading vehicle types"));
77 }
78 if (!oc.isUsableFileList("additional-files")) {
79 throw ProcessError();
80 }
81 for (const std::string& file : oc.getStringVector("additional-files")) {
82 VTypesHandler typesHandler(file, vTypes);
83 if (!XMLSubSys::runParser(typesHandler, file)) {
84 throw ProcessError(TLF("Loading of % failed.", file));
85 }
86 }
87 if (!oc.isSet("vtype") && vTypes.size() != 1) {
88 throw ProcessError(TL("Vehicle type is not unique."));
89 }
90 const auto vTypeIt = oc.isSet("vtype") ? vTypes.find(oc.getString("vtype")) : vTypes.begin();
91 if (vTypeIt == vTypes.end()) {
92 throw ProcessError(TLF("Vehicle type '%' is not defined.", oc.getString("vtype")));
93 }
94 if (oc.isDefault("emission-class")) {
95 c = vTypeIt->second->emissionClass;
96 }
97 energyParams = std::unique_ptr<EnergyParams>(new EnergyParams(vTypeIt->second));
98 } else {
99 energyParams = std::unique_ptr<EnergyParams>(new EnergyParams());
100 }
101 for (double v = vMin; v <= vMax; v += vStep) {
102 for (double a = aMin; a <= aMax; a += aStep) {
103 for (double s = sMin; s <= sMax; s += sStep) {
104 const PollutantsInterface::Emissions result = PollutantsInterface::computeAll(c, v, a, s, energyParams.get());
105 o << v << ";" << a << ";" << s << ";" << "CO" << ";" << result.CO << std::endl;
106 o << v << ";" << a << ";" << s << ";" << "CO2" << ";" << result.CO2 << std::endl;
107 o << v << ";" << a << ";" << s << ";" << "HC" << ";" << result.HC << std::endl;
108 o << v << ";" << a << ";" << s << ";" << "PMx" << ";" << result.PMx << std::endl;
109 o << v << ";" << a << ";" << s << ";" << "NOx" << ";" << result.NOx << std::endl;
110 o << v << ";" << a << ";" << s << ";" << "fuel" << ";" << result.fuel << std::endl;
111 o << v << ";" << a << ";" << s << ";" << "electricity" << ";" << result.electricity << std::endl;
112 }
113 }
114 }
115}
116
117
118
119
120int
121main(int argc, char** argv) {
123 oc.setApplicationDescription(TL("Builds and writes an emissions map for SUMO's emission models."));
124 oc.setApplicationName("emissionsMap", "Eclipse SUMO emissionsMap " VERSION_STRING);
125 // add options
127 oc.addOptionSubTopic("Input");
128 oc.addOptionSubTopic("Processing");
129 oc.doRegister("iterate", 'i', new Option_Bool(false));
130 oc.addDescription("iterate", "Processing", TL("If set, maps for all available emissions are written."));
131
132 oc.doRegister("emission-class", 'e', new Option_String());
133 oc.addDescription("emission-class", "Processing", TL("Defines the name of the emission class to generate the map for."));
134
135 oc.doRegister("additional-files", new Option_FileName());
136 oc.addDescription("additional-files", "Input", TL("Load emission parameters (vTypes) from FILE(s)"));
137
138 oc.doRegister("vtype", new Option_String());
139 oc.addDescription("vtype", "Input", TL("Defines the vehicle type to use for emission parameters."));
140
141 oc.doRegister("v-min", new Option_Float(0.));
142 oc.addDescription("v-min", "Processing", TL("Defines the minimum velocity boundary of the map to generate (in m/s)."));
143 oc.doRegister("v-max", new Option_Float(50.));
144 oc.addDescription("v-max", "Processing", TL("Defines the maximum velocity boundary of the map to generate (in m/s)."));
145 oc.doRegister("v-step", new Option_Float(2.));
146 oc.addDescription("v-step", "Processing", TL("Defines the velocity step size (in m/s)."));
147 oc.doRegister("a-min", new Option_Float(-4.));
148 oc.addDescription("a-min", "Processing", TL("Defines the minimum acceleration boundary of the map to generate (in m/s^2)."));
149 oc.doRegister("a-max", new Option_Float(4.));
150 oc.addDescription("a-max", "Processing", TL("Defines the maximum acceleration boundary of the map to generate (in m/s^2)."));
151 oc.doRegister("a-step", new Option_Float(.5));
152 oc.addDescription("a-step", "Processing", TL("Defines the acceleration step size (in m/s^2)."));
153 oc.doRegister("s-min", new Option_Float(-10.));
154 oc.addDescription("s-min", "Processing", TL("Defines the minimum slope boundary of the map to generate (in deg)."));
155 oc.doRegister("s-max", new Option_Float(10.));
156 oc.addDescription("s-max", "Processing", TL("Defines the maximum slope boundary of the map to generate (in deg)."));
157 oc.doRegister("s-step", new Option_Float(1.));
158 oc.addDescription("s-step", "Processing", TL("Defines the slope step size (in deg)."));
159
160 oc.addOptionSubTopic("Output");
161 oc.doRegister("output-file", 'o', new Option_String());
162 oc.addSynonyme("output", "output-file");
163 oc.addDescription("output", "Output", TL("Defines the file (or the path if --iterate was set) to write the map(s) into."));
164
165 oc.addOptionSubTopic("Emissions");
166 oc.doRegister("emissions.volumetric-fuel", new Option_Bool(false));
167 oc.addDescription("emissions.volumetric-fuel", "Emissions", TL("Return fuel consumption values in (legacy) unit l instead of mg"));
168
169 oc.doRegister("phemlight-path", new Option_FileName(StringVector({ "./PHEMlight/" })));
170 oc.addDescription("phemlight-path", "Emissions", TL("Determines where to load PHEMlight definitions from"));
171
172 oc.doRegister("phemlight-year", new Option_Integer(0));
173 oc.addDescription("phemlight-year", "Emissions", TL("Enable fleet age modelling with the given reference year in PHEMlight5"));
174
175 oc.doRegister("phemlight-temperature", new Option_Float(INVALID_DOUBLE));
176 oc.addDescription("phemlight-temperature", "Emissions", TL("Set ambient temperature to correct NOx emissions in PHEMlight5"));
177
179
180 // run
181 int ret = 0;
182 try {
183 // initialise the application system (messaging, xml, options)
185 OptionsIO::setArgs(argc, argv);
187 if (oc.processMetaOptions(argc < 2)) {
189 return 0;
190 }
191
192 double vMin = oc.getFloat("v-min");
193 double vMax = oc.getFloat("v-max");
194 double vStep = oc.getFloat("v-step");
195 double aMin = oc.getFloat("a-min");
196 double aMax = oc.getFloat("a-max");
197 double aStep = oc.getFloat("a-step");
198 double sMin = oc.getFloat("s-min");
199 double sMax = oc.getFloat("s-max");
200 double sStep = oc.getFloat("s-step");
201 if (!oc.getBool("iterate")) {
202 if (!oc.isSet("emission-class")) {
203 throw ProcessError(TL("The emission class (-e) must be given."));
204 }
205 if (!oc.isSet("output-file")) {
206 throw ProcessError(TL("The output file (-o) must be given."));
207 }
209 single(oc, oc.getString("output-file"), oc.getString("emission-class"),
210 c, vMin, vMax, vStep, aMin, aMax, aStep, sMin, sMax, sStep, oc.getBool("verbose"));
211 } else {
212 if (!oc.isSet("output-file")) {
213 oc.set("output-file", "./");
214 }
215#if __cplusplus >= 201703L
216 std::vector<std::string> phemPath;
217 phemPath.push_back(OptionsCont::getOptions().getString("phemlight-path") + "/");
218 if (getenv("PHEMLIGHT_PATH") != nullptr) {
219 phemPath.push_back(std::string(getenv("PHEMLIGHT_PATH")) + "/");
220 }
221 if (getenv("SUMO_HOME") != nullptr) {
222 phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight/");
223 phemPath.push_back(std::string(getenv("SUMO_HOME")) + "/data/emissions/PHEMlight5/");
224 }
225 for (const std::string& p : phemPath) {
226 std::error_code ec;
227 for (const auto& entry : fs::directory_iterator(p, ec)) {
228 if (entry.path().extension() == ".veh") {
229 if (entry.path().parent_path().filename().string().back() == '5') {
230 PollutantsInterface::getClassByName("PHEMlight5/" + entry.path().filename().stem().stem().string());
231 } else {
232 PollutantsInterface::getClassByName("PHEMlight/" + entry.path().filename().stem().stem().string());
233 }
234 }
235 }
236 }
237#endif
238 const std::vector<SUMOEmissionClass> classes = PollutantsInterface::getAllClasses();
239 for (std::vector<SUMOEmissionClass>::const_iterator ci = classes.begin(); ci != classes.end(); ++ci) {
240 SUMOEmissionClass c = *ci;
241 single(oc, oc.getString("output-file") + PollutantsInterface::getName(c) + ".csv",
243 c, vMin, vMax, vStep, aMin, aMax, aStep, sMin, sMax, sStep, oc.getBool("verbose"));
244 }
245 }
246 } catch (InvalidArgument& e) {
248 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
249 ret = 1;
250 } catch (ProcessError& e) {
251 if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
253 }
254 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
255 ret = 1;
256#ifndef _DEBUG
257 } catch (...) {
258 MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
259 ret = 1;
260#endif
261 }
263 if (ret == 0) {
264 std::cout << "Success." << std::endl;
265 }
266 return ret;
267}
268
269
270/****************************************************************************/
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:289
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::vector< std::string > StringVector
Definition of a vector of strings.
Definition Option.h:42
int SUMOEmissionClass
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
An upper class for objects with additional parameters.
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
A storage for options typed value containers)
Definition OptionsCont.h:89
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.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
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 addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
bool set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
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.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
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
static std::string getName(const SUMOEmissionClass c)
Checks whether the string describes a known vehicle class.
static const std::vector< SUMOEmissionClass > getAllClasses()
Checks whether the string describes a known vehicle class.
static Emissions computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const EnergyParams *param)
Returns the amount of all emitted pollutants given the vehicle type and state (in mg/s or ml/s for fu...
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
static void close()
Closes all of an applications subsystems.
static void addConfigurationOptions(OptionsCont &oc)
Adds configuration options to the given container.
static void addReportOptions(OptionsCont &oc)
Adds reporting options to the given container.
An XML-Handler for amitran and netstate trajectories.
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 single(const OptionsCont &oc, const std::string &of, const std::string &className, SUMOEmissionClass c, double vMin, double vMax, double vStep, double aMin, double aMax, double aStep, double sMin, double sMax, double sStep, bool verbose)
Storage for collected values of all emission types.