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-2020 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>
29 #include <utils/geom/GeomHelper.h>
33 #include "TrajectoriesHandler.h"
34 
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 TrajectoriesHandler::TrajectoriesHandler(const bool computeA, const bool computeAForward,
40  const bool accelZeroCorrection, const SUMOEmissionClass defaultClass,
41  const double defaultSlope, std::ostream* stdOut, OutputDevice* xmlOut)
42  : SUMOSAXHandler(""), myComputeA(computeA), myComputeAForward(computeAForward), myAccelZeroCorrection(accelZeroCorrection), myDefaultClass(defaultClass),
43  myDefaultSlope(defaultSlope), myStdOut(stdOut), myXMLOut(xmlOut), myCurrentTime(-1), myStepSize(TS) {}
44 
45 
47 
48 
49 void
51  const SUMOSAXAttributes& attrs) {
52  bool ok = true;
53  switch (element) {
55  myStepSize = attrs.getFloat("timeStepSize") / 1000.;
56  break;
57  case SUMO_TAG_TIMESTEP:
59  break;
60  case SUMO_TAG_VEHICLE:
61  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
62  double v = attrs.getFloat(SUMO_ATTR_SPEED);
63  double a = INVALID_VALUE;
64  double s = INVALID_VALUE;
66  } else {
67  const std::string acId = attrs.getString(SUMO_ATTR_ACTORCONFIG);
68  const std::string id = attrs.getString(SUMO_ATTR_ID);
69  if (myEmissionClassByType.count(acId) == 0) {
70  WRITE_WARNING("Unknown actor configuration '" + acId + "' for vehicle '" + id + "'!");
71  } else {
73  }
74  }
75  break;
76  case SUMO_TAG_ACTORCONFIG: {
77  const std::string id = attrs.getString(SUMO_ATTR_ID);
78  const std::string vClass = attrs.getString(SUMO_ATTR_VEHICLECLASS);
79  const std::string fuel = attrs.getString(SUMO_ATTR_FUEL);
80  const std::string eClass = attrs.getString(SUMO_ATTR_EMISSIONCLASS);
81  const double weight = attrs.getOpt<double>(SUMO_ATTR_WEIGHT, id.c_str(), ok, 0.) * 10.;
82  myEmissionClassByType[id] = PollutantsInterface::getClass(myDefaultClass, vClass, fuel, eClass, weight);
83  break;
84  }
85  case SUMO_TAG_MOTIONSTATE: {
86  const std::string id = attrs.getString(SUMO_ATTR_VEHICLE);
87  if (myEmissionClassByVehicle.count(id) == 0) {
88  WRITE_WARNING("Motion state for unknown vehicle '" + id + "'!");
90  }
92  double v = attrs.getFloat(SUMO_ATTR_SPEED) / 100.;
93  double a = attrs.hasAttribute(SUMO_ATTR_ACCELERATION) ? attrs.get<double>(SUMO_ATTR_ACCELERATION, id.c_str(), ok) / 1000. : INVALID_VALUE;
94  double s = attrs.hasAttribute(SUMO_ATTR_SLOPE) ? RAD2DEG(asin(attrs.get<double>(SUMO_ATTR_SLOPE, id.c_str(), ok) / 10000.)) : INVALID_VALUE;
95  const SUMOTime time = attrs.getOpt<int>(SUMO_ATTR_TIME, id.c_str(), ok, INVALID_VALUE);
96  if (myXMLOut != nullptr) {
97  writeXMLEmissions(id, c, time, v, a, s);
98  }
99  if (myStdOut != nullptr) {
100  writeEmissions(*myStdOut, id, c, STEPS2TIME(time), v, a, s);
101  }
102  break;
103  }
104  default:
105  break;
106  }
107 }
108 
109 
112  double& v, double& a, double& s) {
113 
114  if (myComputeA) {
115  if (myLastV.count(id) == 0) {
116  a = 0.;
117  } else {
118  a = v - myLastV[id];
119  }
120  myLastV[id] = v;
121  if (myComputeAForward) {
122  v -= a;
123  }
124  }
125  if (myAccelZeroCorrection) {
127  }
128  if (a == INVALID_VALUE) {
129  throw ProcessError("Acceleration information is missing; try running with --compute-a.");
130  }
131  if (s == INVALID_VALUE) {
132  s = myDefaultSlope;
133  }
135  mySums[id].addScaled(result, myStepSize);
136  if (id != "") {
137  mySums[""].addScaled(result, myStepSize);
138  }
139  return result;
140 }
141 
142 
143 bool
144 TrajectoriesHandler::writeEmissions(std::ostream& o, const std::string id,
145  const SUMOEmissionClass c,
146  double t, double& v,
147  double& a, double& s) {
148  if (myComputeA && myLastV.count(id) == 0) {
149  myLastV[id] = v;
150  myLastSlope[id] = s;
151  return false;
152  }
153  if (myComputeAForward) {
154  t -= TS;
155  const double nextS = s;
156  s = myLastSlope[id];
157  myLastSlope[id] = nextS;
158  }
159  const PollutantsInterface::Emissions e = computeEmissions(id, c, v, a, s);
160  o << t << ";" << v << ";" << a << ";" << s << ";"
161  << e.CO << ";" << e.CO2 << ";" << e.HC << ";" << e.PMx << ";"
162  << e.NOx << ";" << e.fuel << ";" << e.electricity << std::endl;
163  return true;
164 }
165 
166 
167 bool
169  const SUMOEmissionClass c,
170  SUMOTime t, double& v,
171  double a, double s) {
172  if (myComputeA && myLastV.count(id) == 0) {
173  myLastV[id] = v;
174  return false;
175  }
176  if (myCurrentTime != t) {
177  if (myCurrentTime != -1) {
178  myXMLOut->closeTag();
179  }
180  myCurrentTime = t;
182  }
183  const PollutantsInterface::Emissions e = computeEmissions(id, c, v, a, s);
184  myXMLOut->openTag("vehicle").writeAttr("id", id).writeAttr("eclass", PollutantsInterface::getName(c));
185  myXMLOut->writeAttr("CO2", e.CO2).writeAttr("CO", e.CO).writeAttr("HC", e.HC).writeAttr("NOx", e.NOx);
186  myXMLOut->writeAttr("PMx", e.PMx).writeAttr("fuel", e.fuel).writeAttr("electricity", e.electricity);
187  myXMLOut->writeAttr("speed", v).closeTag();
188  return true;
189 }
190 
191 
192 void
193 TrajectoriesHandler::writeSums(std::ostream& o, const std::string id) {
194  o << "CO:" << mySums[id].CO << std::endl
195  << "CO2:" << mySums[id].CO2 << std::endl
196  << "HC:" << mySums[id].HC << std::endl
197  << "NOx:" << mySums[id].NOx << std::endl
198  << "PMx:" << mySums[id].PMx << std::endl
199  << "fuel:" << mySums[id].fuel << std::endl
200  << "electricity:" << mySums[id].electricity << std::endl;
201 }
202 
203 
204 void
205 TrajectoriesHandler::writeNormedSums(std::ostream& o, const std::string id, const double factor) {
206  o << mySums[id].fuel / factor << ","
207  << mySums[id].electricity / factor << ","
208  << mySums[id].CO2 / factor << ","
209  << mySums[id].NOx / factor << ","
210  << mySums[id].CO / factor << ","
211  << mySums[id].HC / factor << ","
212  << mySums[id].PMx / factor << std::endl;
213 }
214 
215 
216 /****************************************************************************/
#define RAD2DEG(x)
Definition: GeomHelper.h:36
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
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:31
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
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
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:239
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 Emissions computeAll(const SUMOEmissionClass c, const double v, const double a, const double slope, const std::map< int, double > *param=0)
Returns the amount of all emitted pollutants given the vehicle type and state (in mg/s or ml/s for fu...
static std::string getName(const SUMOEmissionClass c)
Checks whether the string describes a known vehicle class.
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)
const PollutantsInterface::Emissions computeEmissions(const std::string id, const SUMOEmissionClass c, double &v, double &a, double &s)
std::map< std::string, PollutantsInterface::Emissions > mySums
void writeSums(std::ostream &o, const std::string id)
static const int INVALID_VALUE
TrajectoriesHandler(const bool computeA, const bool computeAForward, const bool accelZeroCorrection, const SUMOEmissionClass defaultClass, const double defaultSlope, std::ostream *stdOut, OutputDevice *xmlOut)
Constructor.
std::map< std::string, SUMOEmissionClass > myEmissionClassByVehicle
const bool myAccelZeroCorrection
std::map< std::string, SUMOEmissionClass > myEmissionClassByType
bool writeXMLEmissions(const std::string id, const SUMOEmissionClass c, SUMOTime t, double &v, double a=INVALID_VALUE, double s=INVALID_VALUE)
std::map< std::string, double > myLastV
bool writeEmissions(std::ostream &o, const std::string id, const SUMOEmissionClass c, double t, 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.