Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2001-2024 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 : /// @date Sept 2021 17 : /// 18 : // A class for parameters used by the emission models 19 : /****************************************************************************/ 20 : #include <config.h> 21 : 22 : #include <utils/common/MsgHandler.h> 23 : #include <utils/common/StringUtils.h> 24 : #include <utils/common/ToString.h> 25 : #include <utils/vehicle/SUMOVTypeParameter.h> 26 : 27 : #include "PollutantsInterface.h" 28 : #include "HelpersEnergy.h" 29 : #include "EnergyParams.h" 30 : 31 : 32 : // =========================================================================== 33 : // static definitions 34 : // =========================================================================== 35 : const EnergyParams* EnergyParams::myDefault = nullptr; 36 : 37 : 38 : // =========================================================================== 39 : // method definitions 40 : // =========================================================================== 41 272290 : EnergyParams::EnergyParams(const SUMOVTypeParameter* typeParams) : 42 272290 : EnergyParams(typeParams != nullptr ? typeParams->emissionClass : EMISSION_CLASS_UNSPECIFIED) { 43 272290 : if (typeParams != nullptr) { 44 8167896 : for (auto item : myMap) { 45 11979544 : myMap[item.first] = typeParams->getDouble(toString(item.first), item.second); 46 : } 47 272276 : for (auto item : myVecMap) { 48 0 : myVecMap[item.first] = typeParams->getDoubles(toString(item.first), item.second); 49 : } 50 544528 : for (auto item : myCharacteristicMapMap) { 51 544504 : std::string characteristicMapString = typeParams->getParameter(toString(item.first), ""); 52 272252 : if (characteristicMapString != "") { 53 60 : myCharacteristicMapMap.at(item.first) = CharacteristicMap(typeParams->getParameter(toString(item.first))); 54 : } 55 : } 56 272276 : if (typeParams->wasSet(VTYPEPARS_MASS_SET)) { 57 165 : myMap[SUMO_ATTR_MASS] = typeParams->mass; 58 : } 59 272276 : myMap[SUMO_ATTR_LOADING] = typeParams->getDouble("loading", INVALID_DOUBLE); 60 272276 : myMap[SUMO_ATTR_WIDTH] = typeParams->width; 61 272276 : myMap[SUMO_ATTR_HEIGHT] = typeParams->height; 62 544552 : if (!StringUtils::startsWith(PollutantsInterface::getName(typeParams->emissionClass), "MMPEVEM")) { 63 544492 : if (typeParams->hasParameter(toString(SUMO_ATTR_INTERNALMOMENTOFINERTIA))) { 64 12 : WRITE_WARNINGF(TL("Vehicle type '%' uses the Energy model with parameter 'internalMomentOfInertia' which is deprecated. Use 'rotatingMass' instead."), typeParams->id); 65 8 : if (!typeParams->hasParameter(toString(SUMO_ATTR_ROTATINGMASS))) { 66 4 : myMap[SUMO_ATTR_ROTATINGMASS] = myMap[SUMO_ATTR_INTERNALMOMENTOFINERTIA]; 67 : } 68 : } 69 : } 70 : } 71 272290 : } 72 : 73 : 74 276176 : EnergyParams::EnergyParams(const SUMOEmissionClass c) { 75 276176 : myMap[SUMO_ATTR_SHUT_OFF_STOP] = 300.; 76 276176 : myMap[SUMO_ATTR_SHUT_OFF_AUTO] = std::numeric_limits<double>::max(); 77 276176 : myMap[SUMO_ATTR_DURATION] = -1.; 78 276176 : myMap[SUMO_ATTR_PARKING] = 0.; 79 276176 : myMap[SUMO_ATTR_WAITINGTIME] = -1.; 80 : 81 1104618 : if (c != EMISSION_CLASS_UNSPECIFIED && StringUtils::startsWith(PollutantsInterface::getName(c), "PHEMlight5/")) { 82 44 : myMap[SUMO_ATTR_MASS] = INVALID_DOUBLE; 83 44 : myMap[SUMO_ATTR_LOADING] = INVALID_DOUBLE; 84 44 : myMap[SUMO_ATTR_FRONTSURFACEAREA] = INVALID_DOUBLE; 85 44 : myMap[SUMO_ATTR_AIRDRAGCOEFFICIENT] = INVALID_DOUBLE; 86 44 : myMap[SUMO_ATTR_CONSTANTPOWERINTAKE] = INVALID_DOUBLE; 87 44 : myMap[SUMO_ATTR_WHEELRADIUS] = INVALID_DOUBLE; 88 44 : myMap[SUMO_ATTR_ROLLDRAGCOEFFICIENT] = INVALID_DOUBLE; 89 44 : myMap[SUMO_ATTR_ROTATINGMASS] = INVALID_DOUBLE; 90 44 : return; 91 : } 92 276132 : const SUMOVTypeParameter::VClassDefaultValues defaultValues(SVC_PASSENGER); 93 276132 : myMap[SUMO_ATTR_MASS] = defaultValues.mass; 94 276132 : myMap[SUMO_ATTR_LOADING] = INVALID_DOUBLE; 95 276132 : myMap[SUMO_ATTR_WIDTH] = defaultValues.width; 96 276132 : myMap[SUMO_ATTR_HEIGHT] = defaultValues.height; 97 : 98 : // default values from 99 : // https://sumo.dlr.de/docs/Models/Electric.html#kia_soul_ev_2020 100 1104397 : if (c != EMISSION_CLASS_UNSPECIFIED && StringUtils::startsWith(PollutantsInterface::getName(c), "Energy/")) { 101 89 : myMap[SUMO_ATTR_MASS] = 1830.; 102 : } 103 276132 : myMap[SUMO_ATTR_FRONTSURFACEAREA] = 2.6; 104 276132 : myMap[SUMO_ATTR_AIRDRAGCOEFFICIENT] = 0.35; 105 276132 : myMap[SUMO_ATTR_ROTATINGMASS] = 40.; 106 276132 : myMap[SUMO_ATTR_RADIALDRAGCOEFFICIENT] = 0.1; 107 276132 : myMap[SUMO_ATTR_ROLLDRAGCOEFFICIENT] = 0.01; 108 276132 : myMap[SUMO_ATTR_CONSTANTPOWERINTAKE] = 100.; 109 276132 : myMap[SUMO_ATTR_PROPULSIONEFFICIENCY] = 0.98; 110 276132 : myMap[SUMO_ATTR_RECUPERATIONEFFICIENCY] = 0.96; 111 276132 : myMap[SUMO_ATTR_RECUPERATIONEFFICIENCY_BY_DECELERATION] = 0.0; 112 276132 : myMap[SUMO_ATTR_ANGLE] = 0.; // actually angleDiff in the last step 113 : // @todo set myVecMap defaults as needed 114 : 115 : // Default values for the MMPEVEM, taken from the VW_ID3 116 276132 : myMap[SUMO_ATTR_WHEELRADIUS] = 0.3588; // [m] 117 276132 : myMap[SUMO_ATTR_MAXIMUMTORQUE] = 310.0; // [Nm] 118 : // @todo SUMO_ATTR_MAXIMUMPOWER predates the MMPEVEM emission model. Do you want to set this somewhere else or to another value? 119 276132 : myMap[SUMO_ATTR_MAXIMUMPOWER] = 107000.0; // [W] 120 276132 : myMap[SUMO_ATTR_GEAREFFICIENCY] = 0.96; // [1] 121 276132 : myMap[SUMO_ATTR_GEARRATIO] = 10.0; // [1] 122 276132 : myMap[SUMO_ATTR_MAXIMUMRECUPERATIONTORQUE] = 95.5; // [Nm] 123 276132 : myMap[SUMO_ATTR_MAXIMUMRECUPERATIONPOWER] = 42800.0; // [W] 124 276132 : myMap[SUMO_ATTR_INTERNALBATTERYRESISTANCE] = 0.1142; // [Ohm] 125 276132 : myMap[SUMO_ATTR_NOMINALBATTERYVOLTAGE] = 396.0; // [V] 126 276132 : myMap[SUMO_ATTR_INTERNALMOMENTOFINERTIA] = 12.5; // [kgm^2] 127 552264 : 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 128 276132 : } 129 : 130 : 131 1147143 : EnergyParams::~EnergyParams() {} 132 : 133 : 134 : void 135 153075992 : EnergyParams::setDouble(SumoXMLAttr attr, double value) { 136 153075992 : myMap[attr] = value; 137 153075992 : } 138 : 139 : 140 : double 141 12058533546 : EnergyParams::getDouble(SumoXMLAttr attr) const { 142 : auto it = myMap.find(attr); 143 12058533546 : if (it != myMap.end()) { 144 6680861269 : return it->second; 145 : } 146 5377672277 : if (mySecondaryParams != nullptr) { 147 5377672277 : return mySecondaryParams->getDouble(attr); 148 : } 149 0 : throw UnknownElement("Unknown Energy Model parameter: " + toString(attr)); 150 : } 151 : 152 : 153 : double 154 5391242 : EnergyParams::getDoubleOptional(SumoXMLAttr attr, const double def) const { 155 : auto it = myMap.find(attr); 156 5391242 : if (it != myMap.end() && it->second != INVALID_DOUBLE) { 157 : return it->second; 158 : } 159 5345322 : if (mySecondaryParams != nullptr) { 160 659231 : return mySecondaryParams->getDoubleOptional(attr, def); 161 : } 162 : return def; 163 : } 164 : 165 : 166 : const std::vector<double>& 167 0 : EnergyParams::getDoubles(SumoXMLAttr attr) const { 168 : auto it = myVecMap.find(attr); 169 0 : if (it != myVecMap.end()) { 170 0 : return it->second; 171 : } 172 0 : if (mySecondaryParams != nullptr) { 173 0 : return mySecondaryParams->getDoubles(attr); 174 : } 175 0 : throw UnknownElement("Unknown Energy Model parameter: " + toString(attr)); 176 : } 177 : 178 : 179 : const CharacteristicMap& 180 10560 : EnergyParams::getCharacteristicMap(SumoXMLAttr attr) const { 181 : auto it = myCharacteristicMapMap.find(attr); 182 10560 : if (it != myCharacteristicMapMap.end()) { 183 5280 : return it->second; 184 : } 185 5280 : if (mySecondaryParams != nullptr) { 186 5280 : return mySecondaryParams->getCharacteristicMap(attr); 187 : } 188 0 : throw UnknownElement("Unknown Energy Model parameter: " + toString(attr)); 189 : } 190 : 191 : 192 : void 193 0 : EnergyParams::checkParam(const SumoXMLAttr paramKey, const std::string& id, const double lower, const double upper) { 194 : const auto& p = myMap.find(paramKey); 195 0 : if (p != myMap.end() && (p->second < lower || p->second > upper)) { 196 0 : WRITE_WARNINGF(TL("Vehicle device '%' doesn't have a valid value for parameter % (%)."), id, toString(paramKey), p->second); 197 0 : setDouble(paramKey, EnergyParams::getDefault()->getDouble(paramKey)); 198 : } 199 0 : } 200 : 201 : 202 : bool 203 1201807028 : EnergyParams::isEngineOff() const { 204 : // they all got a default in the constructor so getDouble is safe here 205 2371953826 : return getDouble(SUMO_ATTR_DURATION) > getDouble(SUMO_ATTR_SHUT_OFF_STOP) || 206 1170146798 : getDouble(SUMO_ATTR_WAITINGTIME) > getDouble(SUMO_ATTR_SHUT_OFF_AUTO); 207 : } 208 : 209 : 210 : bool 211 0 : EnergyParams::isOff() const { 212 : // they all got a default in the constructor so getDouble is safe here 213 0 : return getDouble(SUMO_ATTR_DURATION) > getDouble(SUMO_ATTR_SHUT_OFF_STOP) && getDouble(SUMO_ATTR_PARKING) > 0.; 214 : } 215 : 216 : 217 : /****************************************************************************/