Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/emissions/EnergyParams.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-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
/****************************************************************************/
14
/// @file EnergyParams.cpp
15
/// @author Jakob Erdmann
16
/// @author Michael Behrisch
17
/// @date Sept 2021
18
///
19
// A class for parameters used by the emission models
20
/****************************************************************************/
21
#include <config.h>
22
23
#include <utils/common/MsgHandler.h>
24
#include <utils/common/StringUtils.h>
25
#include <utils/common/ToString.h>
26
#include <utils/geom/GeomHelper.h>
27
#include <utils/vehicle/SUMOVTypeParameter.h>
28
29
#include "PollutantsInterface.h"
30
#include "HelpersEnergy.h"
31
#include "EnergyParams.h"
32
33
34
// ===========================================================================
35
// static definitions
36
// ===========================================================================
37
const EnergyParams* EnergyParams::myDefault = nullptr;
38
const std::vector<SumoXMLAttr> EnergyParams::myParamAttrs = {
39
SUMO_ATTR_SHUT_OFF_STOP, SUMO_ATTR_SHUT_OFF_AUTO,
40
SUMO_ATTR_LOADING, SUMO_ATTR_FRONTSURFACEAREA, SUMO_ATTR_AIRDRAGCOEFFICIENT,
41
SUMO_ATTR_CONSTANTPOWERINTAKE, SUMO_ATTR_WHEELRADIUS, SUMO_ATTR_ROLLDRAGCOEFFICIENT, SUMO_ATTR_ROTATINGMASS,
42
SUMO_ATTR_RADIALDRAGCOEFFICIENT, SUMO_ATTR_PROPULSIONEFFICIENCY, SUMO_ATTR_RECUPERATIONEFFICIENCY,
43
SUMO_ATTR_RECUPERATIONEFFICIENCY_BY_DECELERATION,
44
SUMO_ATTR_MAXIMUMTORQUE, SUMO_ATTR_MAXIMUMPOWER, SUMO_ATTR_GEAREFFICIENCY, SUMO_ATTR_GEARRATIO,
45
SUMO_ATTR_MAXIMUMRECUPERATIONTORQUE, SUMO_ATTR_MAXIMUMRECUPERATIONPOWER,
46
SUMO_ATTR_INTERNALBATTERYRESISTANCE, SUMO_ATTR_NOMINALBATTERYVOLTAGE, SUMO_ATTR_INTERNALMOMENTOFINERTIA
47
};
48
49
50
// ===========================================================================
51
// method definitions
52
// ===========================================================================
53
EnergyParams::EnergyParams(const SUMOVTypeParameter* typeParams) {
54
myCharacteristicMapMap.insert(std::pair<SumoXMLAttr, CharacteristicMap>(SUMO_ATTR_POWERLOSSMAP, CharacteristicMap("2,1|-1e9,1e9;-1e9,1e9|0,0,0,0"))); // P_loss_EM = 0 W for all operating points in the default EV power loss map
55
56
if (typeParams == nullptr) {
57
myMap[SUMO_ATTR_MASS] = DEFAULT_VEH_MASS;
58
myHaveDefaultMass = true;
59
myMap[SUMO_ATTR_FRONTSURFACEAREA] = DEFAULT_VEH_WIDTH * DEFAULT_VEH_HEIGHT * M_PI / 4.;
60
myHaveDefaultFrontSurfaceArea = true;
61
} else {
62
for (SumoXMLAttr attr : myParamAttrs) {
63
if (typeParams->hasParameter(toString(attr))) {
64
myMap[attr] = typeParams->getDouble(toString(attr), INVALID_DOUBLE);
65
}
66
}
67
for (auto item : myCharacteristicMapMap) {
68
std::string characteristicMapString = typeParams->getParameter(toString(item.first), "");
69
if (characteristicMapString != "") {
70
myCharacteristicMapMap.at(item.first) = CharacteristicMap(typeParams->getParameter(toString(item.first)));
71
}
72
}
73
myMap[SUMO_ATTR_MASS] = typeParams->mass;
74
myHaveDefaultMass = !typeParams->wasSet(VTYPEPARS_MASS_SET);
75
if (myHaveDefaultMass) {
76
const double ecMass = PollutantsInterface::getWeight(typeParams->emissionClass);
77
if (ecMass != -1.) {
78
myMap[SUMO_ATTR_MASS] = ecMass;
79
}
80
}
81
if (myMap.count(SUMO_ATTR_FRONTSURFACEAREA) == 0) {
82
myHaveDefaultFrontSurfaceArea = true;
83
myMap[SUMO_ATTR_FRONTSURFACEAREA] = typeParams->width * typeParams->height * M_PI / 4.;
84
}
85
const std::string& ecName = PollutantsInterface::getName(typeParams->emissionClass);
86
if (typeParams->vehicleClass != SVC_IGNORING && (typeParams->vehicleClass & (SVC_PRIVATE | SVC_VIP | SVC_PASSENGER | SVC_HOV | SVC_TAXI | SVC_E_VEHICLE | SVC_CUSTOM1 | SVC_CUSTOM2)) == 0 && myHaveDefaultFrontSurfaceArea) {
87
if (StringUtils::startsWith(ecName, "MMPEVEM") || StringUtils::startsWith(ecName, "Energy")) {
88
WRITE_WARNINGF(TL("Vehicle type '%' uses the emission class '%' which does not have proper defaults for its vehicle class. "
89
"Please use a different emission model or complete the vType definition with further parameters."), typeParams->id, ecName);
90
if (!typeParams->wasSet(VTYPEPARS_MASS_SET)) {
91
WRITE_WARNING(TL(" And also set a vehicle mass!"));
92
}
93
}
94
}
95
if (!StringUtils::startsWith(ecName, "MMPEVEM")) {
96
if (myMap.count(SUMO_ATTR_INTERNALMOMENTOFINERTIA) > 0) {
97
WRITE_WARNINGF(TL("Vehicle type '%' uses the Energy model parameter 'internalMomentOfInertia' which is deprecated. Use 'rotatingMass' instead."), typeParams->id);
98
if (!typeParams->hasParameter(toString(SUMO_ATTR_ROTATINGMASS))) {
99
myMap[SUMO_ATTR_ROTATINGMASS] = myMap[SUMO_ATTR_INTERNALMOMENTOFINERTIA];
100
}
101
}
102
}
103
}
104
}
105
106
107
EnergyParams::~EnergyParams() {}
108
109
110
void
111
EnergyParams::setDynamicValues(const SUMOTime stopDuration, const bool parking, const SUMOTime waitingTime, const double angle) {
112
if ((stopDuration >= 0 && myStopDurationSeconds < 0.) || (stopDuration < 0 && myStopDurationSeconds >= 0.)) {
113
myStopDurationSeconds = STEPS2TIME(stopDuration);
114
myAmParking = parking;
115
}
116
myWaitingTimeSeconds = STEPS2TIME(waitingTime);
117
myLastAngle = myAngle;
118
myAngle = angle;
119
}
120
121
122
void
123
EnergyParams::setMass(const double mass) {
124
myMap[SUMO_ATTR_MASS] = mass;
125
myHaveDefaultMass = false;
126
}
127
128
129
void
130
EnergyParams::setTransportableMass(const double mass) {
131
myTransportableMass = mass;
132
}
133
134
135
double
136
EnergyParams::getTotalMass(const double defaultEmptyMass, const double defaultLoading) const {
137
return getDoubleOptional(SUMO_ATTR_MASS, defaultEmptyMass) + getDoubleOptional(SUMO_ATTR_LOADING, defaultLoading) + getTransportableMass();
138
}
139
140
141
double
142
EnergyParams::getAngleDiff() const {
143
return myLastAngle == INVALID_DOUBLE ? 0. : GeomHelper::angleDiff(myLastAngle, myAngle);
144
}
145
146
147
double
148
EnergyParams::getDouble(SumoXMLAttr attr) const {
149
auto it = myMap.find(attr);
150
if (it != myMap.end()) {
151
return it->second;
152
}
153
if (mySecondaryParams != nullptr) {
154
return mySecondaryParams->getDouble(attr);
155
}
156
throw UnknownElement("Unknown emission model parameter: " + toString(attr));
157
}
158
159
160
double
161
EnergyParams::getDoubleOptional(SumoXMLAttr attr, const double def) const {
162
auto it = myMap.find(attr);
163
if (it != myMap.end() && it->second != INVALID_DOUBLE) {
164
if (attr == SUMO_ATTR_MASS) {
165
if (!myHaveDefaultMass) {
166
return it->second;
167
}
168
} else if (attr == SUMO_ATTR_FRONTSURFACEAREA) {
169
if (!myHaveDefaultFrontSurfaceArea) {
170
return it->second;
171
}
172
} else {
173
return it->second;
174
}
175
}
176
if (mySecondaryParams != nullptr) {
177
return mySecondaryParams->getDoubleOptional(attr, def);
178
}
179
return def;
180
}
181
182
183
const CharacteristicMap&
184
EnergyParams::getCharacteristicMap(SumoXMLAttr attr) const {
185
auto it = myCharacteristicMapMap.find(attr);
186
if (it != myCharacteristicMapMap.end()) {
187
return it->second;
188
}
189
if (mySecondaryParams != nullptr) {
190
return mySecondaryParams->getCharacteristicMap(attr);
191
}
192
throw UnknownElement("Unknown emission model parameter: " + toString(attr));
193
}
194
195
196
bool
197
EnergyParams::isEngineOff() const {
198
return myStopDurationSeconds > getDoubleOptional(SUMO_ATTR_SHUT_OFF_STOP, DEFAULT_VEH_SHUT_OFF_STOP) ||
199
myWaitingTimeSeconds > getDoubleOptional(SUMO_ATTR_SHUT_OFF_AUTO, std::numeric_limits<double>::max());
200
}
201
202
203
bool
204
EnergyParams::isOff() const {
205
return myStopDurationSeconds > getDoubleOptional(SUMO_ATTR_SHUT_OFF_STOP, DEFAULT_VEH_SHUT_OFF_STOP);
206
}
207
208
209
/****************************************************************************/
210
211