Eclipse SUMO - Simulation of Urban MObility
TrajectoriesHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2014-2022 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 /****************************************************************************/
18 // An XML-Handler for amitran and netstate trajectories
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <string>
23 #include <utility>
24 #include <iostream>
27 #include <utils/common/ToString.h>
30 #include <utils/geom/GeomHelper.h>
34 #include "TrajectoriesHandler.h"
35 
36 
37 // ===========================================================================
38 // method definitions
39 // ===========================================================================
40 TrajectoriesHandler::TrajectoriesHandler(const bool computeA, const bool computeAForward,
41  const bool accelZeroCorrection, const SUMOEmissionClass defaultClass, EnergyParams* params,
42  const double defaultSlope, std::ostream* stdOut, OutputDevice* xmlOut) :
43  SUMOSAXHandler(""),
44  myComputeA(computeA),
45  myComputeAForward(computeAForward),
46  myAccelZeroCorrection(accelZeroCorrection),
47  myDefaultClass(defaultClass),
48  myParams(params),
49  myDefaultSlope(defaultSlope), myStdOut(stdOut), myXMLOut(xmlOut), myCurrentTime(-1), myStepSize(TS) {}
50 
51 
53 
54 
55 void
57  const SUMOSAXAttributes& attrs) {
58  bool ok = true;
59  switch (element) {
61  myStepSize = attrs.getFloat("timeStepSize") / 1000.;
62  break;
63  case SUMO_TAG_TIMESTEP:
65  break;
66  case SUMO_TAG_VEHICLE:
67  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
68  double v = attrs.getFloat(SUMO_ATTR_SPEED);
69  double a = INVALID_VALUE;
70  double s = INVALID_VALUE;
72  } else {
73  const std::string acId = attrs.getString(SUMO_ATTR_ACTORCONFIG);
74  const std::string id = attrs.getString(SUMO_ATTR_ID);
75  if (myEmissionClassByType.count(acId) == 0) {
76  WRITE_WARNING("Unknown actor configuration '" + acId + "' for vehicle '" + id + "'!");
77  } else {
79  }
80  }
81  break;
82  case SUMO_TAG_ACTORCONFIG: {
83  const std::string id = attrs.getString(SUMO_ATTR_ID);
84  const std::string vClass = attrs.getString(SUMO_ATTR_VEHICLECLASS);
85  const std::string fuel = attrs.getString(SUMO_ATTR_FUEL);
86  const std::string eClass = attrs.getString(SUMO_ATTR_EMISSIONCLASS);
87  const double weight = attrs.getOpt<double>(SUMO_ATTR_WEIGHT, id.c_str(), ok, 0.) * 10.;
88  myEmissionClassByType[id] = PollutantsInterface::getClass(myDefaultClass, vClass, fuel, eClass, weight);
89  break;
90  }
91  case SUMO_TAG_MOTIONSTATE: {
92  const std::string id = attrs.getString(SUMO_ATTR_VEHICLE);
93  if (myEmissionClassByVehicle.count(id) == 0) {
94  WRITE_WARNING("Motion state for unknown vehicle '" + id + "'!");
96  }
98  double v = attrs.getFloat(SUMO_ATTR_SPEED) / 100.;
99  double a = attrs.hasAttribute(SUMO_ATTR_ACCELERATION) ? attrs.get<double>(SUMO_ATTR_ACCELERATION, id.c_str(), ok) / 1000. : INVALID_VALUE;
100  double s = attrs.hasAttribute(SUMO_ATTR_SLOPE) ? RAD2DEG(asin(attrs.get<double>(SUMO_ATTR_SLOPE, id.c_str(), ok) / 10000.)) : INVALID_VALUE;
101  const SUMOTime time = attrs.getOpt<int>(SUMO_ATTR_TIME, id.c_str(), ok, INVALID_VALUE);
102  if (myXMLOut != nullptr) {
103  writeXMLEmissions(id, c, nullptr, time, v, a, s);
104  }
105  if (myStdOut != nullptr) {
106  writeEmissions(*myStdOut, id, c, nullptr, STEPS2TIME(time), v, a, s);
107  }
108  break;
109  }
110  default:
111  break;
112  }
113 }
114 
115 
118  EnergyParams* params,
119  double& v, double& a, double& s) {
120 
121  if (myComputeA) {
122  if (myLastV.count(id) == 0) {
123  a = 0.;
124  } else {
125  a = v - myLastV[id];
126  }
127  myLastV[id] = v;
128  if (myComputeAForward) {
129  v -= a;
130  }
131  }
132  if (myAccelZeroCorrection) {
134  }
135  if (a == INVALID_VALUE) {
136  throw ProcessError("Acceleration information is missing; try running with --compute-a.");
137  }
138  if (s == INVALID_VALUE) {
139  s = myDefaultSlope;
140  }
141  const PollutantsInterface::Emissions result = PollutantsInterface::computeAll(c, v, a, s, params);
142  mySums[id].addScaled(result, myStepSize);
143  if (id != "") {
144  mySums[""].addScaled(result, myStepSize);
145  }
146  return result;
147 }
148 
149 
150 bool
151 TrajectoriesHandler::writeEmissions(std::ostream& o, const std::string id,
152  const SUMOEmissionClass c,
153  EnergyParams* params,
154  double t, double& v,
155  double& a, double& s) {
156  if (myComputeA && myLastV.count(id) == 0) {
157  myLastV[id] = v;
158  myLastSlope[id] = s;
159  return false;
160  }
161  if (myComputeAForward) {
162  t -= TS;
163  const double nextS = s;
164  s = myLastSlope[id];
165  myLastSlope[id] = nextS;
166  }
167  const PollutantsInterface::Emissions e = computeEmissions(id, c, params, v, a, s);
168  o << t << ";" << v << ";" << a << ";" << s << ";"
169  << e.CO << ";" << e.CO2 << ";" << e.HC << ";" << e.PMx << ";"
170  << e.NOx << ";" << e.fuel << ";" << e.electricity << std::endl;
171  return true;
172 }
173 
174 
175 bool
177  const SUMOEmissionClass c,
178  EnergyParams* params,
179  SUMOTime t, double& v,
180  double a, double s) {
181  if (myComputeA && myLastV.count(id) == 0) {
182  myLastV[id] = v;
183  return false;
184  }
185  if (myCurrentTime != t) {
186  if (myCurrentTime != -1) {
187  myXMLOut->closeTag();
188  }
189  myCurrentTime = t;
191  }
192  const PollutantsInterface::Emissions e = computeEmissions(id, c, params, v, a, s);
193  myXMLOut->openTag("vehicle").writeAttr("id", id).writeAttr("eclass", PollutantsInterface::getName(c));
194  myXMLOut->writeAttr("CO2", e.CO2).writeAttr("CO", e.CO).writeAttr("HC", e.HC).writeAttr("NOx", e.NOx);
195  myXMLOut->writeAttr("PMx", e.PMx).writeAttr("fuel", e.fuel).writeAttr("electricity", e.electricity);
196  myXMLOut->writeAttr("speed", v).closeTag();
197  return true;
198 }
199 
200 
201 void
202 TrajectoriesHandler::writeSums(std::ostream& o, const std::string id) {
203  o << "CO:" << mySums[id].CO << std::endl
204  << "CO2:" << mySums[id].CO2 << std::endl
205  << "HC:" << mySums[id].HC << std::endl
206  << "NOx:" << mySums[id].NOx << std::endl
207  << "PMx:" << mySums[id].PMx << std::endl
208  << "fuel:" << mySums[id].fuel << std::endl
209  << "electricity:" << mySums[id].electricity << std::endl;
210 }
211 
212 
213 void
214 TrajectoriesHandler::writeNormedSums(std::ostream& o, const std::string id, const double factor) {
215  o << mySums[id].fuel / factor << ","
216  << mySums[id].electricity / factor << ","
217  << mySums[id].CO2 / factor << ","
218  << mySums[id].NOx / factor << ","
219  << mySums[id].CO / factor << ","
220  << mySums[id].HC / factor << ","
221  << mySums[id].PMx / factor << std::endl;
222 }
223 
224 
225 /****************************************************************************/
#define RAD2DEG(x)
Definition: GeomHelper.h:36
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define TS
Definition: SUMOTime.h:40
long long int SUMOTime
Definition: SUMOTime.h:32
int SUMOEmissionClass
@ SUMO_TAG_TIMESTEP
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_TRAJECTORIES
@ SUMO_TAG_MOTIONSTATE
@ SUMO_TAG_ACTORCONFIG
@ SUMO_ATTR_EMISSIONCLASS
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_FUEL
@ SUMO_ATTR_WEIGHT
@ SUMO_ATTR_VEHICLECLASS
@ SUMO_ATTR_ACTORCONFIG
@ SUMO_ATTR_SLOPE
@ SUMO_ATTR_ACCELERATION
@ SUMO_ATTR_VEHICLE
@ SUMO_ATTR_ID
@ SUMO_ATTR_TIME
trigger: the time of the step
An upper class for objects with additional parameters.
Definition: EnergyParams.h:41
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double getModifiedAccel(const SUMOEmissionClass c, const double v, const double a, const double slope)
Returns the adapted acceleration value, useful for comparing with external PHEMlight references.
static std::string getName(const SUMOEmissionClass c)
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=0)
Returns the amount of all emitted pollutants given the vehicle type and state (in mg/s or ml/s for fu...
static SUMOEmissionClass getClass(const SUMOEmissionClass base, const std::string &vClass, const std::string &fuel, const std::string &eClass, const double weight)
Returns the emission class fittig the given parameters.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual double getFloat(int id) const =0
Returns the double-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
SAX-handler base for SUMO-files.
std::map< std::string, double > myLastSlope
const SUMOEmissionClass myDefaultClass
void writeNormedSums(std::ostream &o, const std::string id, const double factor)
std::map< std::string, PollutantsInterface::Emissions > mySums
void writeSums(std::ostream &o, const std::string id)
static const int INVALID_VALUE
bool writeXMLEmissions(const std::string id, const SUMOEmissionClass c, EnergyParams *params, SUMOTime t, double &v, double a=INVALID_VALUE, double s=INVALID_VALUE)
std::map< std::string, SUMOEmissionClass > myEmissionClassByVehicle
const bool myAccelZeroCorrection
bool writeEmissions(std::ostream &o, const std::string id, const SUMOEmissionClass c, EnergyParams *params, double t, double &v, double &a, double &s)
std::map< std::string, SUMOEmissionClass > myEmissionClassByType
TrajectoriesHandler(const bool computeA, const bool computeAForward, const bool accelZeroCorrection, const SUMOEmissionClass defaultClass, EnergyParams *params, const double defaultSlope, std::ostream *stdOut, OutputDevice *xmlOut)
Constructor.
std::map< std::string, double > myLastV
const PollutantsInterface::Emissions computeEmissions(const std::string id, const SUMOEmissionClass c, EnergyParams *params, double &v, double &a, double &s)
~TrajectoriesHandler()
Destructor.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called when an opening-tag occurs.
Storage for collected values of all emission types.