Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2013-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 : /****************************************************************************/
14 : /// @file emissionsMap_main.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @date Wed, 21.08.2013
18 : ///
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 <utils/common/MsgHandler.h>
31 : #include <utils/common/StringUtils.h>
32 : #include <utils/options/Option.h>
33 : #include <utils/options/OptionsCont.h>
34 : #include <utils/options/OptionsIO.h>
35 : #include <utils/common/UtilExceptions.h>
36 : #include <utils/emissions/EnergyParams.h>
37 : #include <utils/emissions/PollutantsInterface.h>
38 : #include <utils/common/SystemFrame.h>
39 : #include <utils/common/ToString.h>
40 : #include <utils/xml/XMLSubSys.h>
41 : #include <utils/common/FileHelpers.h>
42 : #include <utils/iodevices/OutputDevice.h>
43 :
44 :
45 : // ===========================================================================
46 : // functions
47 : // ===========================================================================
48 949 : void single(const std::string& of, const std::string& className, SUMOEmissionClass c,
49 : double vMin, double vMax, double vStep,
50 : double aMin, double aMax, double aStep,
51 : double sMin, double sMax, double sStep,
52 : bool verbose) {
53 949 : if (verbose) {
54 0 : WRITE_MESSAGEF(TL("Writing map of '%' into '%'."), className, of);
55 : }
56 949 : std::ofstream o(of.c_str());
57 949 : if (!o.good()) {
58 0 : throw ProcessError(TLF("Could not open file '%' for writing.", of));
59 : }
60 949 : EnergyParams energyParams(c);
61 7592 : for (double v = vMin; v <= vMax; v += vStep) {
62 66430 : for (double a = aMin; a <= aMax; a += aStep) {
63 119574 : for (double s = sMin; s <= sMax; s += sStep) {
64 59787 : const PollutantsInterface::Emissions result = PollutantsInterface::computeAll(c, v, a, s, &energyParams);
65 59787 : o << v << ";" << a << ";" << s << ";" << "CO" << ";" << result.CO << std::endl;
66 59787 : o << v << ";" << a << ";" << s << ";" << "CO2" << ";" << result.CO2 << std::endl;
67 59787 : o << v << ";" << a << ";" << s << ";" << "HC" << ";" << result.HC << std::endl;
68 59787 : o << v << ";" << a << ";" << s << ";" << "PMx" << ";" << result.PMx << std::endl;
69 59787 : o << v << ";" << a << ";" << s << ";" << "NOx" << ";" << result.NOx << std::endl;
70 59787 : o << v << ";" << a << ";" << s << ";" << "fuel" << ";" << result.fuel << std::endl;
71 59787 : o << v << ";" << a << ";" << s << ";" << "electricity" << ";" << result.electricity << std::endl;
72 : }
73 : }
74 : }
75 949 : }
76 :
77 :
78 :
79 :
80 : int
81 949 : main(int argc, char** argv) {
82 949 : OptionsCont& oc = OptionsCont::getOptions();
83 949 : oc.setApplicationDescription(TL("Builds and writes an emissions map for SUMO's emission models."));
84 1898 : oc.setApplicationName("emissionsMap", "Eclipse SUMO emissionsMap Version " VERSION_STRING);
85 : // add options
86 949 : SystemFrame::addConfigurationOptions(oc);
87 949 : oc.addOptionSubTopic("Processing");
88 949 : oc.doRegister("iterate", 'i', new Option_Bool(false));
89 1898 : oc.addDescription("iterate", "Processing", TL("If set, maps for all available emissions are written."));
90 :
91 949 : oc.doRegister("emission-class", 'e', new Option_String());
92 1898 : oc.addDescription("emission-class", "Processing", TL("Defines the name of the emission class to generate the map for."));
93 :
94 949 : oc.doRegister("v-min", new Option_Float(0.));
95 1898 : oc.addDescription("v-min", "Processing", TL("Defines the minimum velocity boundary of the map to generate (in m/s)."));
96 949 : oc.doRegister("v-max", new Option_Float(50.));
97 1898 : oc.addDescription("v-max", "Processing", TL("Defines the maximum velocity boundary of the map to generate (in m/s)."));
98 949 : oc.doRegister("v-step", new Option_Float(2.));
99 1898 : oc.addDescription("v-step", "Processing", TL("Defines the velocity step size (in m/s)."));
100 949 : oc.doRegister("a-min", new Option_Float(-4.));
101 1898 : oc.addDescription("a-min", "Processing", TL("Defines the minimum acceleration boundary of the map to generate (in m/s^2)."));
102 949 : oc.doRegister("a-max", new Option_Float(4.));
103 1898 : oc.addDescription("a-max", "Processing", TL("Defines the maximum acceleration boundary of the map to generate (in m/s^2)."));
104 949 : oc.doRegister("a-step", new Option_Float(.5));
105 1898 : oc.addDescription("a-step", "Processing", TL("Defines the acceleration step size (in m/s^2)."));
106 949 : oc.doRegister("s-min", new Option_Float(-10.));
107 1898 : oc.addDescription("s-min", "Processing", TL("Defines the minimum slope boundary of the map to generate (in deg)."));
108 949 : oc.doRegister("s-max", new Option_Float(10.));
109 1898 : oc.addDescription("s-max", "Processing", TL("Defines the maximum slope boundary of the map to generate (in deg)."));
110 949 : oc.doRegister("s-step", new Option_Float(1.));
111 1898 : oc.addDescription("s-step", "Processing", TL("Defines the slope step size (in deg)."));
112 :
113 949 : oc.addOptionSubTopic("Output");
114 949 : oc.doRegister("output-file", 'o', new Option_String());
115 1898 : oc.addSynonyme("output", "output-file");
116 1898 : oc.addDescription("output", "Output", TL("Defines the file (or the path if --iterate was set) to write the map(s) into."));
117 :
118 949 : oc.addOptionSubTopic("Emissions");
119 949 : oc.doRegister("emissions.volumetric-fuel", new Option_Bool(false));
120 1898 : oc.addDescription("emissions.volumetric-fuel", "Emissions", TL("Return fuel consumption values in (legacy) unit l instead of mg"));
121 :
122 3796 : oc.doRegister("phemlight-path", new Option_FileName(StringVector({ "./PHEMlight/" })));
123 1898 : oc.addDescription("phemlight-path", "Emissions", TL("Determines where to load PHEMlight definitions from"));
124 :
125 949 : oc.doRegister("phemlight-year", new Option_Integer(0));
126 1898 : oc.addDescription("phemlight-year", "Emissions", TL("Enable fleet age modelling with the given reference year in PHEMlight5"));
127 :
128 949 : oc.doRegister("phemlight-temperature", new Option_Float(INVALID_DOUBLE));
129 1898 : oc.addDescription("phemlight-temperature", "Emissions", TL("Set ambient temperature to correct NOx emissions in PHEMlight5"));
130 :
131 949 : SystemFrame::addReportOptions(oc);
132 :
133 : // run
134 : int ret = 0;
135 : try {
136 : // initialise the application system (messaging, xml, options)
137 949 : XMLSubSys::init();
138 949 : OptionsIO::setArgs(argc, argv);
139 949 : OptionsIO::getOptions();
140 949 : if (oc.processMetaOptions(argc < 2)) {
141 0 : SystemFrame::close();
142 : return 0;
143 : }
144 :
145 949 : double vMin = oc.getFloat("v-min");
146 949 : double vMax = oc.getFloat("v-max");
147 949 : double vStep = oc.getFloat("v-step");
148 949 : double aMin = oc.getFloat("a-min");
149 949 : double aMax = oc.getFloat("a-max");
150 949 : double aStep = oc.getFloat("a-step");
151 949 : double sMin = oc.getFloat("s-min");
152 949 : double sMax = oc.getFloat("s-max");
153 949 : double sStep = oc.getFloat("s-step");
154 1898 : if (!oc.getBool("iterate")) {
155 1898 : if (!oc.isSet("emission-class")) {
156 0 : throw ProcessError(TL("The emission class (-e) must be given."));
157 : }
158 1898 : if (!oc.isSet("output-file")) {
159 0 : throw ProcessError(TL("The output file (-o) must be given."));
160 : }
161 949 : const SUMOEmissionClass c = PollutantsInterface::getClassByName(oc.getString("emission-class"));
162 2847 : single(oc.getString("output-file"), oc.getString("emission-class"),
163 949 : c, vMin, vMax, vStep, aMin, aMax, aStep, sMin, sMax, sStep, oc.getBool("verbose"));
164 : } else {
165 0 : if (!oc.isSet("output-file")) {
166 0 : oc.set("output-file", "./");
167 : }
168 0 : const std::vector<SUMOEmissionClass> classes = PollutantsInterface::getAllClasses();
169 0 : for (std::vector<SUMOEmissionClass>::const_iterator ci = classes.begin(); ci != classes.end(); ++ci) {
170 0 : SUMOEmissionClass c = *ci;
171 0 : single(oc.getString("output-file") + PollutantsInterface::getName(c) + ".csv", PollutantsInterface::getName(c),
172 0 : c, vMin, vMax, vStep, aMin, aMax, aStep, sMin, sMax, sStep, oc.getBool("verbose"));
173 : }
174 0 : }
175 0 : } catch (InvalidArgument& e) {
176 0 : MsgHandler::getErrorInstance()->inform(e.what());
177 0 : MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
178 : ret = 1;
179 0 : } catch (ProcessError& e) {
180 0 : if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
181 0 : MsgHandler::getErrorInstance()->inform(e.what());
182 : }
183 0 : MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
184 : ret = 1;
185 : #ifndef _DEBUG
186 0 : } catch (...) {
187 0 : MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
188 : ret = 1;
189 : #endif
190 0 : }
191 949 : SystemFrame::close();
192 : if (ret == 0) {
193 : std::cout << "Success." << std::endl;
194 : }
195 : return ret;
196 1898 : }
197 :
198 :
199 : /****************************************************************************/
|