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