Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 MSVehicleType.cpp
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Jakob Erdmann
18 : /// @author Thimor Bohn
19 : /// @author Michael Behrisch
20 : /// @date Tue, 06 Mar 2001
21 : ///
22 : // The car-following model and parameter
23 : /****************************************************************************/
24 : #include <config.h>
25 :
26 : #include <cassert>
27 : #include <memory>
28 : #include <utils/common/MsgHandler.h>
29 : #include <utils/options/OptionsCont.h>
30 : #include <utils/common/FileHelpers.h>
31 : #include <utils/common/RandHelper.h>
32 : #include <utils/common/StringUtils.h>
33 : #include <utils/vehicle/SUMOVTypeParameter.h>
34 : #include <microsim/cfmodels/MSCFModel_Rail.h>
35 : #include "MSNet.h"
36 : #include "cfmodels/MSCFModel_IDM.h"
37 : #include "cfmodels/MSCFModel_Kerner.h"
38 : #include "cfmodels/MSCFModel_Krauss.h"
39 : #include "cfmodels/MSCFModel_KraussOrig1.h"
40 : #include "cfmodels/MSCFModel_KraussPS.h"
41 : #include "cfmodels/MSCFModel_KraussX.h"
42 : #include "cfmodels/MSCFModel_EIDM.h"
43 : #include "cfmodels/MSCFModel_SmartSK.h"
44 : #include "cfmodels/MSCFModel_Daniel1.h"
45 : #include "cfmodels/MSCFModel_PWag2009.h"
46 : #include "cfmodels/MSCFModel_Wiedemann.h"
47 : #include "cfmodels/MSCFModel_W99.h"
48 : #include "cfmodels/MSCFModel_ACC.h"
49 : #include "cfmodels/MSCFModel_CACC.h"
50 : #include "MSInsertionControl.h"
51 : #include "MSVehicleControl.h"
52 : #include "cfmodels/MSCFModel_CC.h"
53 : #include "cfmodels/MSCFModel_NaSch.h"
54 : #include "MSVehicleType.h"
55 :
56 :
57 : // ===========================================================================
58 : // static members
59 : // ===========================================================================
60 : int MSVehicleType::myNextIndex = 0;
61 :
62 :
63 : // ===========================================================================
64 : // method definitions
65 : // ===========================================================================
66 321862 : MSVehicleType::MSVehicleType(const SUMOVTypeParameter& parameter) :
67 321862 : myParameter(parameter),
68 321862 : myEnergyParams(¶meter),
69 321862 : myWarnedActionStepLengthTauOnce(false),
70 321862 : myWarnedActionStepLengthBallisticOnce(false),
71 321862 : myWarnedStepLengthTauOnce(false),
72 321862 : myIndex(myNextIndex++),
73 321862 : myCarFollowModel(nullptr),
74 643724 : myOriginalType(nullptr) {
75 : assert(getLength() > 0);
76 : assert(getMaxSpeed() > 0);
77 :
78 : // Check if actionStepLength was set by user, if not init to global default
79 321862 : if (!myParameter.wasSet(VTYPEPARS_ACTIONSTEPLENGTH_SET)) {
80 321631 : myParameter.actionStepLength = MSGlobals::gActionStepLength;
81 : }
82 321862 : myCachedActionStepLengthSecs = STEPS2TIME(myParameter.actionStepLength);
83 321862 : }
84 :
85 :
86 953943 : MSVehicleType::~MSVehicleType() {
87 317981 : delete myCarFollowModel;
88 635962 : }
89 :
90 :
91 : double
92 5801346 : MSVehicleType::computeChosenSpeedDeviation(double speedFactorOverride, SumoRNG* rng, const double minDev) const {
93 : return speedFactorOverride < 0
94 11591220 : ? roundDecimal(MAX2(minDev, myParameter.speedFactor.sample(rng)), gPrecisionRandom)
95 5801346 : : speedFactorOverride;
96 : }
97 :
98 :
99 : // ------------ Setter methods
100 : void
101 729 : MSVehicleType::setLength(const double& length) {
102 729 : if (myOriginalType != nullptr && length < 0) {
103 0 : myParameter.length = myOriginalType->getLength();
104 : } else {
105 729 : myParameter.length = length;
106 : }
107 729 : myParameter.parametersSet |= VTYPEPARS_LENGTH_SET;
108 729 : }
109 :
110 :
111 : void
112 21 : MSVehicleType::setHeight(const double& height) {
113 21 : if (myOriginalType != nullptr && height < 0) {
114 0 : myParameter.height = myOriginalType->getHeight();
115 : } else {
116 21 : myParameter.height = height;
117 : }
118 21 : myParameter.parametersSet |= VTYPEPARS_HEIGHT_SET;
119 21 : }
120 :
121 :
122 : void
123 1465 : MSVehicleType::setMinGap(const double& minGap) {
124 1465 : if (myOriginalType != nullptr && minGap < 0) {
125 0 : myParameter.minGap = myOriginalType->getMinGap();
126 : } else {
127 1465 : myParameter.minGap = minGap;
128 : }
129 1465 : myParameter.parametersSet |= VTYPEPARS_MINGAP_SET;
130 1465 : }
131 :
132 :
133 : void
134 11 : MSVehicleType::setMinGapLat(const double& minGapLat) {
135 11 : if (myOriginalType != nullptr && minGapLat < 0) {
136 0 : myParameter.minGapLat = myOriginalType->getMinGapLat();
137 : } else {
138 11 : myParameter.minGapLat = minGapLat;
139 : }
140 11 : myParameter.parametersSet |= VTYPEPARS_MINGAP_LAT_SET;
141 11 : }
142 :
143 :
144 : void
145 467 : MSVehicleType::setMaxSpeed(const double& maxSpeed) {
146 467 : if (myOriginalType != nullptr && maxSpeed < 0) {
147 3 : myParameter.maxSpeed = myOriginalType->getMaxSpeed();
148 : } else {
149 464 : myParameter.maxSpeed = maxSpeed;
150 : }
151 467 : myParameter.parametersSet |= VTYPEPARS_MAXSPEED_SET;
152 467 : }
153 :
154 :
155 : void
156 15 : MSVehicleType::setMaxSpeedLat(const double& maxSpeedLat) {
157 15 : if (myOriginalType != nullptr && maxSpeedLat < 0) {
158 0 : myParameter.maxSpeedLat = myOriginalType->getMaxSpeedLat();
159 : } else {
160 15 : myParameter.maxSpeedLat = maxSpeedLat;
161 : }
162 15 : myParameter.parametersSet |= VTYPEPARS_MAXSPEED_LAT_SET;
163 15 : }
164 :
165 :
166 : void
167 330 : MSVehicleType::setVClass(SUMOVehicleClass vclass) {
168 330 : myParameter.vehicleClass = vclass;
169 330 : myParameter.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
170 330 : }
171 :
172 :
173 : void
174 148 : MSVehicleType::setGUIShape(SUMOVehicleShape shape) {
175 148 : myParameter.shape = shape;
176 148 : myParameter.parametersSet |= VTYPEPARS_SHAPE_SET;
177 148 : }
178 :
179 : void
180 144386 : MSVehicleType::setPreferredLateralAlignment(const LatAlignmentDefinition& latAlignment, double latAlignmentOffset) {
181 144386 : myParameter.latAlignmentProcedure = latAlignment;
182 144386 : myParameter.latAlignmentOffset = latAlignmentOffset;
183 144386 : myParameter.parametersSet |= VTYPEPARS_LATALIGNMENT_SET;
184 144386 : }
185 :
186 : void
187 5 : MSVehicleType::setScale(double value) {
188 5 : myParameter.scale = value;
189 5 : MSInsertionControl& insertControl = MSNet::getInstance()->getInsertionControl();
190 5 : insertControl.updateScale(getID());
191 5 : }
192 :
193 : void
194 3 : MSVehicleType::setLcContRight(const std::string& value) {
195 3 : myParameter.lcParameter[SUMO_ATTR_LCA_CONTRIGHT] = value;
196 3 : }
197 :
198 : void
199 0 : MSVehicleType::setDefaultProbability(const double& prob) {
200 0 : if (myOriginalType != nullptr && prob < 0) {
201 0 : myParameter.defaultProbability = myOriginalType->getDefaultProbability();
202 : } else {
203 0 : myParameter.defaultProbability = prob;
204 : }
205 0 : myParameter.parametersSet |= VTYPEPARS_PROBABILITY_SET;
206 0 : }
207 :
208 :
209 : void
210 9 : MSVehicleType::setSpeedFactor(const double& factor) {
211 9 : if (myOriginalType != nullptr && factor < 0) {
212 0 : myParameter.speedFactor.setParameter(0, myOriginalType->myParameter.speedFactor.getParameter(0));
213 : } else {
214 9 : myParameter.speedFactor.setParameter(0, factor);
215 : }
216 9 : myParameter.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
217 9 : }
218 :
219 :
220 : void
221 5 : MSVehicleType::setSpeedDeviation(const double& dev) {
222 5 : if (myOriginalType != nullptr && dev < 0) {
223 0 : myParameter.speedFactor.setParameter(1, myOriginalType->myParameter.speedFactor.getParameter(1));
224 : } else {
225 5 : myParameter.speedFactor.setParameter(1, dev);
226 : }
227 5 : myParameter.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
228 5 : }
229 :
230 :
231 : void
232 20 : MSVehicleType::setActionStepLength(const SUMOTime actionStepLength, bool resetActionOffset) {
233 : assert(actionStepLength >= 0);
234 20 : myParameter.parametersSet |= VTYPEPARS_ACTIONSTEPLENGTH_SET;
235 :
236 20 : if (myParameter.actionStepLength == actionStepLength) {
237 : return;
238 : }
239 :
240 : SUMOTime previousActionStepLength = myParameter.actionStepLength;
241 20 : myParameter.actionStepLength = actionStepLength;
242 20 : myCachedActionStepLengthSecs = STEPS2TIME(myParameter.actionStepLength);
243 20 : check();
244 :
245 20 : if (isVehicleSpecific()) {
246 : // don't perform vehicle lookup for singular vtype
247 : return;
248 : }
249 :
250 : // For non-singular vType reset all vehicle's actionOffsets
251 : // Iterate through vehicles
252 13 : MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
253 34 : for (auto vehIt = vc.loadedVehBegin(); vehIt != vc.loadedVehEnd(); ++vehIt) {
254 21 : MSVehicle* veh = static_cast<MSVehicle*>(vehIt->second);
255 21 : if (&veh->getVehicleType() == this) {
256 : // Found vehicle of this type. Perform requested actionOffsetReset
257 13 : if (resetActionOffset) {
258 13 : veh->resetActionOffset();
259 : } else {
260 0 : veh->updateActionOffset(previousActionStepLength, actionStepLength);
261 : }
262 : }
263 : }
264 : }
265 :
266 :
267 : void
268 30 : MSVehicleType::setEmissionClass(SUMOEmissionClass eclass) {
269 30 : myParameter.emissionClass = eclass;
270 30 : myParameter.parametersSet |= VTYPEPARS_EMISSIONCLASS_SET;
271 30 : }
272 :
273 :
274 : void
275 532 : MSVehicleType::setMass(double mass) {
276 532 : myParameter.mass = mass;
277 532 : myParameter.parametersSet |= VTYPEPARS_MASS_SET;
278 532 : const_cast<EnergyParams&>(myEnergyParams).setMass(mass);
279 532 : }
280 :
281 :
282 : void
283 5 : MSVehicleType::setColor(const RGBColor& color) {
284 5 : myParameter.color = color;
285 5 : myParameter.parametersSet |= VTYPEPARS_COLOR_SET;
286 5 : }
287 :
288 :
289 : void
290 0 : MSVehicleType::setParkingBadges(const std::vector<std::string>& badges) {
291 0 : myParameter.parkingBadges.assign(badges.begin(), badges.end());
292 0 : myParameter.parametersSet |= VTYPEPARS_PARKING_BADGES_SET;
293 0 : }
294 :
295 :
296 : void
297 30 : MSVehicleType::setWidth(const double& width) {
298 30 : if (myOriginalType != nullptr && width < 0) {
299 0 : myParameter.width = myOriginalType->getWidth();
300 : } else {
301 30 : myParameter.width = width;
302 : }
303 30 : myParameter.parametersSet |= VTYPEPARS_WIDTH_SET;
304 30 : }
305 :
306 : void
307 5 : MSVehicleType::setImpatience(const double impatience) {
308 5 : myParameter.impatience = impatience;
309 5 : myParameter.parametersSet |= VTYPEPARS_IMPATIENCE_SET;
310 5 : }
311 :
312 :
313 : void
314 14 : MSVehicleType::setBoardingDuration(SUMOTime duration, bool isPerson) {
315 14 : if (myOriginalType != nullptr && duration < 0) {
316 0 : myParameter.boardingDuration = myOriginalType->getBoardingDuration(isPerson);
317 : } else {
318 14 : if (isPerson) {
319 14 : myParameter.boardingDuration = duration;
320 : } else {
321 0 : myParameter.loadingDuration = duration;
322 : }
323 : }
324 14 : myParameter.parametersSet |= VTYPEPARS_BOARDING_DURATION;
325 14 : }
326 :
327 : void
328 16 : MSVehicleType::setShape(SUMOVehicleShape shape) {
329 16 : myParameter.shape = shape;
330 16 : myParameter.parametersSet |= VTYPEPARS_SHAPE_SET;
331 16 : }
332 :
333 :
334 :
335 : // ------------ Static methods for building vehicle types
336 : MSVehicleType*
337 320408 : MSVehicleType::build(SUMOVTypeParameter& from, const std::string& fileName) {
338 640816 : if (from.hasParameter("vehicleMass")) {
339 5 : if (from.wasSet(VTYPEPARS_MASS_SET)) {
340 0 : WRITE_WARNINGF(TL("The vType '%' has a 'mass' attribute and a 'vehicleMass' parameter. The 'mass' attribute will take precedence."), from.id);
341 : } else {
342 15 : WRITE_WARNINGF(TL("The vType '%' has a 'vehicleMass' parameter, which is deprecated. Please use the 'mass' attribute (for the empty mass) and the 'loading' parameter, if needed."), from.id);
343 5 : from.mass = from.getDouble("vehicleMass", from.mass);
344 5 : from.parametersSet |= VTYPEPARS_MASS_SET;
345 : }
346 : }
347 : // the unique_ptr ensures the type is deleted if an exception occurs
348 320408 : std::unique_ptr<MSVehicleType> vtypeOwner(new MSVehicleType(from));
349 : MSVehicleType* vtype = vtypeOwner.get();
350 320408 : const double decel = from.getCFParam(SUMO_ATTR_DECEL, SUMOVTypeParameter::getDefaultDecel(from.vehicleClass));
351 320408 : const double emergencyDecel = from.getCFParam(SUMO_ATTR_EMERGENCYDECEL, SUMOVTypeParameter::getDefaultEmergencyDecel(from.vehicleClass, decel, MSGlobals::gDefaultEmergencyDecel));
352 : // by default decel and apparentDecel are identical
353 320408 : const double apparentDecel = from.getCFParam(SUMO_ATTR_APPARENTDECEL, decel);
354 :
355 320408 : if (emergencyDecel < decel) {
356 30 : WRITE_WARNINGF(TL("Value of 'emergencyDecel' (%) should be higher than 'decel' (%) for vType '%'."), toString(emergencyDecel), toString(decel), from.id);
357 : }
358 320408 : if (emergencyDecel < apparentDecel) {
359 33 : WRITE_WARNINGF(TL("Value of 'emergencyDecel' (%) is lower than 'apparentDecel' (%) for vType '%' may cause collisions."), toString(emergencyDecel), toString(apparentDecel), from.id);
360 : }
361 :
362 320408 : switch (from.cfModel) {
363 8354 : case SUMO_TAG_CF_IDM:
364 8354 : vtype->myCarFollowModel = new MSCFModel_IDM(vtype, false);
365 8354 : break;
366 275 : case SUMO_TAG_CF_IDMM:
367 275 : vtype->myCarFollowModel = new MSCFModel_IDM(vtype, true);
368 275 : break;
369 242 : case SUMO_TAG_CF_BKERNER:
370 242 : vtype->myCarFollowModel = new MSCFModel_Kerner(vtype);
371 242 : break;
372 338 : case SUMO_TAG_CF_KRAUSS_ORIG1:
373 338 : vtype->myCarFollowModel = new MSCFModel_KraussOrig1(vtype);
374 338 : break;
375 159 : case SUMO_TAG_CF_KRAUSS_PLUS_SLOPE:
376 159 : vtype->myCarFollowModel = new MSCFModel_KraussPS(vtype);
377 159 : break;
378 12 : case SUMO_TAG_CF_KRAUSSX:
379 12 : vtype->myCarFollowModel = new MSCFModel_KraussX(vtype);
380 12 : break;
381 302 : case SUMO_TAG_CF_EIDM:
382 302 : vtype->myCarFollowModel = new MSCFModel_EIDM(vtype);
383 302 : break;
384 18 : case SUMO_TAG_CF_SMART_SK:
385 18 : vtype->myCarFollowModel = new MSCFModel_SmartSK(vtype);
386 18 : break;
387 22 : case SUMO_TAG_CF_DANIEL1:
388 22 : vtype->myCarFollowModel = new MSCFModel_Daniel1(vtype);
389 22 : break;
390 25 : case SUMO_TAG_CF_PWAGNER2009:
391 25 : vtype->myCarFollowModel = new MSCFModel_PWag2009(vtype);
392 25 : break;
393 291 : case SUMO_TAG_CF_WIEDEMANN:
394 291 : vtype->myCarFollowModel = new MSCFModel_Wiedemann(vtype);
395 291 : break;
396 287 : case SUMO_TAG_CF_W99:
397 287 : vtype->myCarFollowModel = new MSCFModel_W99(vtype);
398 287 : break;
399 386 : case SUMO_TAG_CF_RAIL:
400 386 : vtype->myCarFollowModel = new MSCFModel_Rail(vtype);
401 382 : break;
402 368 : case SUMO_TAG_CF_ACC:
403 368 : vtype->myCarFollowModel = new MSCFModel_ACC(vtype);
404 368 : break;
405 450 : case SUMO_TAG_CF_CACC:
406 450 : vtype->myCarFollowModel = new MSCFModel_CACC(vtype);
407 450 : break;
408 78 : case SUMO_TAG_CF_CC:
409 78 : vtype->myCarFollowModel = new MSCFModel_CC(vtype);
410 78 : break;
411 36 : case SUMO_TAG_CF_NASCH:
412 36 : vtype->myCarFollowModel = new MSCFModel_NaSch(vtype,
413 36 : from.getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(from.vehicleClass)));
414 36 : break;
415 308765 : case SUMO_TAG_CF_KRAUSS:
416 : default:
417 308765 : vtype->myCarFollowModel = new MSCFModel_Krauss(vtype);
418 308765 : break;
419 : }
420 : // init Rail visualization parameters
421 640812 : vtype->myParameter.initRailVisualizationParameters(fileName);
422 320404 : return vtypeOwner.release();
423 : }
424 :
425 : SUMOTime
426 30 : MSVehicleType::getEntryManoeuvreTime(const int angle) const {
427 30 : return (getParameter().getEntryManoeuvreTime(angle));
428 : }
429 :
430 : SUMOTime
431 30 : MSVehicleType::getExitManoeuvreTime(const int angle) const {
432 30 : return (getParameter().getExitManoeuvreTime(angle));
433 : }
434 :
435 : MSVehicleType*
436 1444 : MSVehicleType::buildSingularType(const std::string& id) const {
437 1444 : return duplicateType(id, false);
438 : }
439 :
440 :
441 : MSVehicleType*
442 1450 : MSVehicleType::duplicateType(const std::string& id, bool persistent) const {
443 1450 : MSVehicleType* vtype = new MSVehicleType(myParameter);
444 1450 : vtype->myParameter.id = id;
445 1450 : vtype->myCarFollowModel = myCarFollowModel->duplicate(vtype);
446 1450 : if (!persistent) {
447 1444 : vtype->myOriginalType = this;
448 : }
449 1450 : if (!MSNet::getInstance()->getVehicleControl().addVType(vtype)) {
450 0 : std::string singular = persistent ? "" : TL("singular ");
451 0 : throw ProcessError(TLF("could not add %type %", singular, vtype->getID()));
452 : }
453 1450 : return vtype;
454 : }
455 :
456 : void
457 82543 : MSVehicleType::check() {
458 82543 : if (!myWarnedActionStepLengthTauOnce
459 82536 : && myParameter.actionStepLength != DELTA_T
460 83470 : && STEPS2TIME(myParameter.actionStepLength) > getCarFollowModel().getHeadwayTime()) {
461 77 : myWarnedActionStepLengthTauOnce = true;
462 77 : std::stringstream s;
463 77 : s << "Given action step length " << STEPS2TIME(myParameter.actionStepLength) << " for vehicle type '" << getID()
464 77 : << "' is larger than its parameter tau (=" << getCarFollowModel().getHeadwayTime() << ")!"
465 77 : << " This may lead to collisions. (This warning is only issued once per vehicle type).";
466 77 : WRITE_WARNING(s.str());
467 77 : }
468 82543 : if (!myWarnedActionStepLengthBallisticOnce
469 82543 : && myParameter.actionStepLength != DELTA_T
470 934 : && MSGlobals::gSemiImplicitEulerUpdate) {
471 53 : myWarnedActionStepLengthBallisticOnce = true;
472 : std::string warning2;
473 106 : if (OptionsCont::getOptions().isDefault("step-method.ballistic")) {
474 : warning2 = " Setting it now to avoid collisions.";
475 41 : MSGlobals::gSemiImplicitEulerUpdate = false;
476 : } else {
477 : warning2 = " This may cause collisions.";
478 : }
479 159 : WRITE_WARNINGF("Action step length '%' is used for vehicle type '%' but step-method.ballistic was not set." + warning2
480 : , STEPS2TIME(myParameter.actionStepLength), getID())
481 : }
482 82543 : if (!myWarnedStepLengthTauOnce && TS > getCarFollowModel().getHeadwayTime()
483 82737 : && !MSGlobals::gUseMesoSim) {
484 159 : myWarnedStepLengthTauOnce = true;
485 477 : WRITE_WARNINGF(TL("Value of tau=% in vehicle type '%' lower than simulation step size may cause collisions."),
486 : getCarFollowModel().getHeadwayTime(), getID());
487 : }
488 91234 : if (MSGlobals::gUseMesoSim && getVehicleClass() != SVC_PEDESTRIAN && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
489 17206 : SVCPermissions ignoreVClasses = parseVehicleClasses(OptionsCont::getOptions().getStringVector("meso-ignore-lanes-by-vclass"));
490 8603 : if ((ignoreVClasses & getVehicleClass()) != 0) {
491 339 : WRITE_WARNINGF(TL("Vehicle class '%' of vType '%' is set as ignored by option --meso-ignore-lanes-by-vclass to ensure default vehicle capacity. Set option --meso-lane-queue for multi-modal meso simulation"),
492 : toString(getVehicleClass()), getID());
493 : }
494 : }
495 163239 : if (!myParameter.wasSet(VTYPEPARS_EMISSIONCLASS_SET) && !OptionsCont::getOptions().getBool("device.battery.track-fuel")
496 245770 : && (OptionsCont::getOptions().getFloat("device.battery.probability") == 1.
497 163068 : || myParameter.getDouble("device.battery.probability", -1.) == 1.
498 324118 : || StringUtils::toBool(myParameter.getParameter("has.battery.device", "false")))) {
499 173 : myParameter.emissionClass = PollutantsInterface::getClassByName("Energy");
500 173 : myParameter.parametersSet |= VTYPEPARS_EMISSIONCLASS_SET;
501 519 : WRITE_MESSAGEF(TL("The battery device is active for vType '%' but no emission class is set. The emission class Energy/unknown will be used, please consider setting an explicit emission class!"),
502 : getID());
503 : }
504 82543 : }
505 :
506 :
507 : void
508 37 : MSVehicleType::setAccel(double accel) {
509 37 : if (myOriginalType != nullptr && accel < 0) {
510 0 : accel = myOriginalType->getCarFollowModel().getMaxAccel();
511 : }
512 37 : myCarFollowModel->setMaxAccel(accel);
513 37 : myParameter.cfParameter[SUMO_ATTR_ACCEL] = toString(accel);
514 37 : }
515 :
516 : void
517 23 : MSVehicleType::setDecel(double decel) {
518 23 : if (myOriginalType != nullptr && decel < 0) {
519 0 : decel = myOriginalType->getCarFollowModel().getMaxDecel();
520 : }
521 23 : myCarFollowModel->setMaxDecel(decel);
522 23 : myParameter.cfParameter[SUMO_ATTR_DECEL] = toString(decel);
523 23 : }
524 :
525 : void
526 42 : MSVehicleType::setEmergencyDecel(double emergencyDecel) {
527 42 : if (myOriginalType != nullptr && emergencyDecel < 0) {
528 0 : emergencyDecel = myOriginalType->getCarFollowModel().getEmergencyDecel();
529 : }
530 42 : myCarFollowModel->setEmergencyDecel(emergencyDecel);
531 42 : myParameter.cfParameter[SUMO_ATTR_EMERGENCYDECEL] = toString(emergencyDecel);
532 42 : }
533 :
534 : void
535 23 : MSVehicleType::setApparentDecel(double apparentDecel) {
536 23 : if (myOriginalType != nullptr && apparentDecel < 0) {
537 0 : apparentDecel = myOriginalType->getCarFollowModel().getApparentDecel();
538 : }
539 23 : myCarFollowModel->setApparentDecel(apparentDecel);
540 23 : myParameter.cfParameter[SUMO_ATTR_APPARENTDECEL] = toString(apparentDecel);
541 23 : }
542 :
543 : void
544 0 : MSVehicleType::setMaxAccelProfile(std::vector<std::pair<double, double> > /* accelProfile */) {
545 : /*
546 : if (myOriginalType != nullptr) {
547 : accelProfile = myOriginalType->getCarFollowModel().getMaxAccelProfile();
548 : } else {
549 : if (accelProfile[0].first > 0.) {
550 : accelProfile.insert(accelProfile.begin(), std::make_pair(0.0, accelProfile[0].second));
551 : }
552 : if (accelProfile.back().first < (10000 / 3.6)) {
553 : accelProfile.push_back(std::make_pair((10000 / 3.6), accelProfile.back().second));
554 : }
555 : double prevSpeed = 0.0;
556 : for (const auto& accelPair : accelProfile) {
557 : if (accelPair.first < 0.) {
558 : accelProfile = myOriginalType->getCarFollowModel().getMaxAccelProfile();
559 : break;
560 : } else if (accelPair.second < 0.) {
561 : accelProfile = myOriginalType->getCarFollowModel().getMaxAccelProfile();
562 : break;
563 : } else if (accelPair.first < prevSpeed) {
564 : accelProfile = myOriginalType->getCarFollowModel().getMaxAccelProfile();
565 : break;
566 : }
567 : prevSpeed = accelPair.first;
568 : }
569 : }
570 : myCarFollowModel->setMaxAccelProfile(accelProfile);
571 :
572 : std::stringstream accelProfileString;
573 : accelProfileString << std::fixed << std::setprecision(2);
574 : int count = 0;
575 : for (const auto& accelPair : accelProfile) {
576 : if (count > 0) {
577 : accelProfileString << " ";
578 : }
579 : accelProfileString << toString(accelPair.first) + "," << accelPair.second;
580 : count++;
581 : }
582 : myParameter.cfParameter[SUMO_ATTR_MAXACCEL_PROFILE] = accelProfileString.str();
583 : */
584 0 : }
585 :
586 : void
587 0 : MSVehicleType::setDesAccelProfile(std::vector<std::pair<double, double> > /* accelProfile */) {
588 : /*
589 : if (myOriginalType != nullptr) {
590 : accelProfile = myOriginalType->getCarFollowModel().getDesAccelProfile();
591 : } else {
592 : if (accelProfile[0].first > 0.) {
593 : accelProfile.insert(accelProfile.begin(), std::make_pair(0.0, accelProfile[0].second));
594 : }
595 : if (accelProfile.back().first < (10000 / 3.6)) {
596 : accelProfile.push_back(std::make_pair((10000 / 3.6), accelProfile.back().second));
597 : }
598 : double prevSpeed = 0.0;
599 : for (const auto& accelPair : accelProfile) {
600 : if (accelPair.first < 0.) {
601 : accelProfile = myOriginalType->getCarFollowModel().getDesAccelProfile();
602 : break;
603 : } else if (accelPair.second < 0.) {
604 : accelProfile = myOriginalType->getCarFollowModel().getDesAccelProfile();
605 : break;
606 : } else if (accelPair.first < prevSpeed) {
607 : accelProfile = myOriginalType->getCarFollowModel().getDesAccelProfile();
608 : break;
609 : }
610 : prevSpeed = accelPair.first;
611 : }
612 : }
613 : myCarFollowModel->setDesAccelProfile(accelProfile);
614 :
615 : std::stringstream accelProfileString;
616 : accelProfileString << std::fixed << std::setprecision(2);
617 : int count = 0;
618 : for (const auto& accelPair : accelProfile) {
619 : if (count > 0) {
620 : accelProfileString << " ";
621 : }
622 : accelProfileString << toString(accelPair.first) + "," << accelPair.second;
623 : count++;
624 : }
625 : myParameter.cfParameter[SUMO_ATTR_DESACCEL_PROFILE] = accelProfileString.str();
626 : */
627 0 : }
628 :
629 : void
630 37 : MSVehicleType::setImperfection(double imperfection) {
631 37 : if (myOriginalType != nullptr && imperfection < 0) {
632 0 : imperfection = myOriginalType->getCarFollowModel().getImperfection();
633 : }
634 37 : myCarFollowModel->setImperfection(imperfection);
635 37 : myParameter.cfParameter[SUMO_ATTR_SIGMA] = toString(imperfection);
636 37 : }
637 :
638 : void
639 23 : MSVehicleType::setTau(double tau) {
640 23 : if (myOriginalType != nullptr && tau < 0) {
641 0 : tau = myOriginalType->getCarFollowModel().getHeadwayTime();
642 : }
643 23 : myCarFollowModel->setHeadwayTime(tau);
644 23 : myParameter.cfParameter[SUMO_ATTR_TAU] = toString(tau);
645 23 : }
646 :
647 :
648 : /****************************************************************************/
|