Eclipse SUMO - Simulation of Urban MObility
HelpersMMPEVEM.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2002-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// The MMP's emission model for electric vehicles.
19// If you use this model for academic research, you are highly encouraged to
20// cite our paper "Accurate physics-based modeling of electric vehicle energy
21// consumption in the SUMO traffic microsimulator"
22// (DOI: 10.1109/ITSC48978.2021.9564463).
23// Teaching and Research Area Mechatronics in Mobile Propulsion (MMP), RWTH Aachen
24/****************************************************************************/
25#include <config.h>
26
32
33
34// ===========================================================================
35// method definitions
36// ===========================================================================
72bool calcPowerConsumption(double m, double r_wheel, double Theta, double c_rr,
73 double c_d, double A_front, double i_gear, double eta_gear, double M_max,
74 double P_max, double M_recup_max, double P_recup_max, double R_battery,
75 double U_battery_0, double P_const,
76 const CharacteristicMap& ref_powerLossMap, double dt, double v, double a,
77 double alpha, double& ref_powerConsumption) {
78 const double EPS = 1e-6;
79 const double RHO_AIR = 1.204; // Air density [kg/m^3]
80 bool b_stateValid = true;
81
82 // Mass factor [1]
83 const double e_i = 1.0 + Theta / (m * r_wheel * r_wheel);
84 // Average speed during the previous timestep
85 const double v_mean = v - 0.5 * a * dt;
86
87 // Force required for the desired acceleration [N]
88 double F_a = m * a * e_i;
89 // Grade resistance [N]
90 double F_gr = m * GRAVITY * std::sin(DEG2RAD(alpha));
91 // Rolling resistance [N]
92 double F_rr = m * GRAVITY * std::cos(DEG2RAD(alpha)) * c_rr;
93 if (std::abs(v_mean) <= EPS) {
94 F_rr = 0;
95 }
96 // Drag [N]
97 double F_d = 0.5 * c_d * A_front * RHO_AIR * v_mean * v_mean;
98 // Tractive force [N]
99 const double F_tractive = F_a + F_gr + F_rr + F_d;
100
101 // Speed of the motor [rpm]
102 const double n_motor = v_mean / (2 * M_PI * r_wheel) * 60 * i_gear;
103 // Angular velocity of the motor [1/s]
104 double omega_motor = 2 * M_PI * n_motor / 60;
105 if (omega_motor == 0) {
106 omega_motor = EPS;
107 }
108
109 // Torque at the motor [Nm]. Please note that this model, like most real EVs,
110 // utilizes the EM to hold the vehicle on an incline rather than the brakes.
111 double M_motor = F_tractive * r_wheel / i_gear;
112 if (F_tractive < 0) {
113 M_motor *= eta_gear;
114 } else {
115 M_motor /= eta_gear;
116 }
117 // Engine power [W]
118 double P_motor = M_motor * omega_motor;
119
120 // Cap torque or power if necessary
121 // Accelerating
122 if (M_motor >= 0) {
123 if (M_motor > M_max) {
124 M_motor = M_max;
125 P_motor = M_motor * omega_motor;
126 b_stateValid = false;
127 }
128 if (P_motor > P_max) {
129 P_motor = P_max;
130 M_motor = P_motor / omega_motor;
131 b_stateValid = false;
132 }
133 }
134 // Recuperating
135 else {
136 // Even when capping, the state is still valid here because the extra energy
137 // is assumed to go to the brakes
138 if (M_motor < -M_recup_max) {
139 M_motor = -M_recup_max;
140 P_motor = M_motor * omega_motor;
141 }
142 if (P_motor < -P_recup_max) {
143 P_motor = -P_recup_max;
144 M_motor = P_motor / omega_motor;
145 }
146 }
147
148 // Power loss in the electric motor + inverter [W]
149 double P_loss_motor =
150 ref_powerLossMap.eval(std::vector<double> {n_motor, M_motor})[0];
151 if (std::isnan(P_loss_motor)) {
152 P_loss_motor = 0.0;
153 b_stateValid = false;
154 }
155
156 // Power demand at the battery [W]
157 double P_battery = P_motor + P_loss_motor + P_const;
158 // Total power demand (including the power loss in the battery) [W]
159 double P_total = (U_battery_0 * U_battery_0) / (2.0 * R_battery)
160 - U_battery_0 * std::sqrt((U_battery_0 * U_battery_0
161 - 4.0 * R_battery * P_battery) / (4.0 * R_battery * R_battery));
162
163 ref_powerConsumption = P_total;
164 return b_stateValid;
165}
166
167
168
169
174 : PollutantsInterface::Helper("MMPEVEM", MMPEVEM_BASE, MMPEVEM_BASE + 1)
175{ }
176
177
178
179
180
198 const PollutantsInterface::EmissionType e, const double v, const double a,
199 const double slope, const EnergyParams* ptr_energyParams) const {
200 if (e != PollutantsInterface::ELEC) {
201 return 0.0;
202 }
203
204 // Extract all required parameters
205 // Vehicle mass
206 const double m = ptr_energyParams->getDouble(SUMO_ATTR_VEHICLEMASS);
207 // Wheel radius
208 const double r_wheel = ptr_energyParams->getDouble(SUMO_ATTR_WHEELRADIUS);
209 // Internal moment of inertia
210 const double Theta
211 = ptr_energyParams->getDouble(SUMO_ATTR_INTERNALMOMENTOFINERTIA);
212 // Rolling resistance coefficient
213 const double c_rr
214 = ptr_energyParams->getDouble(SUMO_ATTR_ROLLDRAGCOEFFICIENT);
215 // Air drag coefficient
216 const double c_d = ptr_energyParams->getDouble(SUMO_ATTR_AIRDRAGCOEFFICIENT);
217 // Cross-sectional area of the front of the car
218 const double A_front
219 = ptr_energyParams->getDouble(SUMO_ATTR_FRONTSURFACEAREA);
220 // Gear ratio
221 const double i_gear = ptr_energyParams->getDouble(SUMO_ATTR_GEARRATIO);
222 // Gearbox efficiency
223 const double eta_gear = ptr_energyParams->getDouble(SUMO_ATTR_GEAREFFICIENCY);
224 // Maximum torque
225 const double M_max = ptr_energyParams->getDouble(SUMO_ATTR_MAXIMUMTORQUE);
226 // Maximum power
227 const double P_max = ptr_energyParams->getDouble(SUMO_ATTR_MAXIMUMPOWER);
228 // Maximum recuperation torque
229 const double M_recup_max
231 // Maximum recuperation power
232 const double P_recup_max
234 // Internal battery resistance
235 const double R_battery
237 // Nominal battery voltage
238 const double U_battery_0
239 = ptr_energyParams->getDouble(SUMO_ATTR_NOMINALBATTERYVOLTAGE);
240 // Constant power consumption
241 const double P_const
242 = ptr_energyParams->getDouble(SUMO_ATTR_CONSTANTPOWERINTAKE);
243 // Power loss map
244 const CharacteristicMap& ref_powerLossMap
245 = ptr_energyParams->getCharacteristicMap(SUMO_ATTR_POWERLOSSMAP);
246
247 double P = 0.0; // [W]
248 bool b_stateValid = calcPowerConsumption(m, r_wheel, Theta, c_rr, c_d,
249 A_front, i_gear, eta_gear, M_max, P_max, M_recup_max, P_recup_max,
250 R_battery, U_battery_0, P_const, ref_powerLossMap, TS, v, a, slope, P);
251 P /= 3600.0; // [Wh/s]
252
253 if (b_stateValid) {
254 return P;
255 } else {
256 return std::nan("");
257 }
258}
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define GRAVITY
Definition: GeomHelper.h:37
bool calcPowerConsumption(double m, double r_wheel, double Theta, double c_rr, double c_d, double A_front, double i_gear, double eta_gear, double M_max, double P_max, double M_recup_max, double P_recup_max, double R_battery, double U_battery_0, double P_const, const CharacteristicMap &ref_powerLossMap, double dt, double v, double a, double alpha, double &ref_powerConsumption)
Compute the power consumption of an EV powertrain in a certain state.
#define TS
Definition: SUMOTime.h:41
int SUMOEmissionClass
@ SUMO_ATTR_GEAREFFICIENCY
Gear efficiency.
@ SUMO_ATTR_MAXIMUMPOWER
Maximum Power.
@ SUMO_ATTR_INTERNALBATTERYRESISTANCE
Internal battery resistance.
@ SUMO_ATTR_MAXIMUMTORQUE
Maximum torque.
@ SUMO_ATTR_ROLLDRAGCOEFFICIENT
Roll Drag coefficient.
@ SUMO_ATTR_CONSTANTPOWERINTAKE
Constant Power Intake.
@ SUMO_ATTR_WHEELRADIUS
@ SUMO_ATTR_AIRDRAGCOEFFICIENT
Air drag coefficient.
@ SUMO_ATTR_POWERLOSSMAP
A string encoding the power loss map.
@ SUMO_ATTR_MAXIMUMRECUPERATIONPOWER
Maximum recuperation power.
@ SUMO_ATTR_MAXIMUMRECUPERATIONTORQUE
Maximum recuperation torque.
@ SUMO_ATTR_VEHICLEMASS
Vehicle mass.
@ SUMO_ATTR_GEARRATIO
Gear ratio.
@ SUMO_ATTR_INTERNALMOMENTOFINERTIA
Internal moment of inertia.
@ SUMO_ATTR_NOMINALBATTERYVOLTAGE
Nominal battery voltage.
@ SUMO_ATTR_FRONTSURFACEAREA
Front surface area.
The purpose of this class is to store a characteristic map (German: Kennfeld) of arbitrary dimensions...
std::vector< double > eval(const std::vector< double > &ref_p, double eps=1e-6) const
Evaluate a point in the map using linear interpolation.
An upper class for objects with additional parameters.
Definition: EnergyParams.h:41
double getDouble(SumoXMLAttr attr) const
const CharacteristicMap & getCharacteristicMap(SumoXMLAttr attr) const
Return the CharacteristicMap that belongs to a given attribute.
HelpersMMPEVEM()
Constructor.
double compute(const SUMOEmissionClass, const PollutantsInterface::EmissionType e, const double v, const double a, const double slope, const EnergyParams *ptr_energyParams) const
Compute the amount of emitted pollutants for an emission class in a given state.
Helper methods for PHEMlight-based emission computation.
EmissionType
Enumerating all emission types, including fuel.
#define M_PI
Definition: odrSpiral.cpp:45