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 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 <utils/options/OptionsCont.h>
28 : #include <utils/common/FileHelpers.h>
29 : #include <utils/common/RandHelper.h>
30 : #include <utils/common/StringUtils.h>
31 : #include <utils/vehicle/SUMOVTypeParameter.h>
32 : #include <microsim/cfmodels/MSCFModel_Rail.h>
33 : #include "MSNet.h"
34 : #include "cfmodels/MSCFModel_IDM.h"
35 : #include "cfmodels/MSCFModel_Kerner.h"
36 : #include "cfmodels/MSCFModel_Krauss.h"
37 : #include "cfmodels/MSCFModel_KraussOrig1.h"
38 : #include "cfmodels/MSCFModel_KraussPS.h"
39 : #include "cfmodels/MSCFModel_KraussX.h"
40 : #include "cfmodels/MSCFModel_EIDM.h"
41 : #include "cfmodels/MSCFModel_SmartSK.h"
42 : #include "cfmodels/MSCFModel_Daniel1.h"
43 : #include "cfmodels/MSCFModel_PWag2009.h"
44 : #include "cfmodels/MSCFModel_Wiedemann.h"
45 : #include "cfmodels/MSCFModel_W99.h"
46 : #include "cfmodels/MSCFModel_ACC.h"
47 : #include "cfmodels/MSCFModel_CACC.h"
48 : #include "MSInsertionControl.h"
49 : #include "MSVehicleControl.h"
50 : #include "cfmodels/MSCFModel_CC.h"
51 : #include "MSVehicleType.h"
52 :
53 :
54 : // ===========================================================================
55 : // static members
56 : // ===========================================================================
57 : int MSVehicleType::myNextIndex = 0;
58 :
59 :
60 : // ===========================================================================
61 : // method definitions
62 : // ===========================================================================
63 318742 : MSVehicleType::MSVehicleType(const SUMOVTypeParameter& parameter) :
64 318742 : myParameter(parameter),
65 318742 : myEnergyParams(¶meter),
66 318742 : myWarnedActionStepLengthTauOnce(false),
67 318742 : myWarnedActionStepLengthBallisticOnce(false),
68 318742 : myWarnedStepLengthTauOnce(false),
69 318742 : myIndex(myNextIndex++),
70 318742 : myCarFollowModel(nullptr),
71 637484 : myOriginalType(nullptr) {
72 : assert(getLength() > 0);
73 : assert(getMaxSpeed() > 0);
74 :
75 : // Check if actionStepLength was set by user, if not init to global default
76 318742 : if (!myParameter.wasSet(VTYPEPARS_ACTIONSTEPLENGTH_SET)) {
77 318513 : myParameter.actionStepLength = MSGlobals::gActionStepLength;
78 : }
79 318742 : myCachedActionStepLengthSecs = STEPS2TIME(myParameter.actionStepLength);
80 318742 : }
81 :
82 :
83 902355 : MSVehicleType::~MSVehicleType() {
84 300785 : delete myCarFollowModel;
85 601570 : }
86 :
87 :
88 : double
89 5455545 : MSVehicleType::computeChosenSpeedDeviation(SumoRNG* rng, const double minDev) const {
90 10911090 : return roundDecimal(MAX2(minDev, myParameter.speedFactor.sample(rng)), gPrecisionRandom);
91 : }
92 :
93 :
94 : // ------------ Setter methods
95 : void
96 525 : MSVehicleType::setLength(const double& length) {
97 525 : if (myOriginalType != nullptr && length < 0) {
98 0 : myParameter.length = myOriginalType->getLength();
99 : } else {
100 525 : myParameter.length = length;
101 : }
102 525 : myParameter.parametersSet |= VTYPEPARS_LENGTH_SET;
103 525 : }
104 :
105 :
106 : void
107 21 : MSVehicleType::setHeight(const double& height) {
108 21 : if (myOriginalType != nullptr && height < 0) {
109 0 : myParameter.height = myOriginalType->getHeight();
110 : } else {
111 21 : myParameter.height = height;
112 : }
113 21 : myParameter.parametersSet |= VTYPEPARS_HEIGHT_SET;
114 21 : }
115 :
116 :
117 : void
118 1270 : MSVehicleType::setMinGap(const double& minGap) {
119 1270 : if (myOriginalType != nullptr && minGap < 0) {
120 0 : myParameter.minGap = myOriginalType->getMinGap();
121 : } else {
122 1270 : myParameter.minGap = minGap;
123 : }
124 1270 : myParameter.parametersSet |= VTYPEPARS_MINGAP_SET;
125 1270 : }
126 :
127 :
128 : void
129 11 : MSVehicleType::setMinGapLat(const double& minGapLat) {
130 11 : if (myOriginalType != nullptr && minGapLat < 0) {
131 : myParameter.minGapLat = myOriginalType->getMinGapLat();
132 : } else {
133 11 : myParameter.minGapLat = minGapLat;
134 : }
135 11 : myParameter.parametersSet |= VTYPEPARS_MINGAP_LAT_SET;
136 11 : }
137 :
138 :
139 : void
140 409 : MSVehicleType::setMaxSpeed(const double& maxSpeed) {
141 409 : if (myOriginalType != nullptr && maxSpeed < 0) {
142 4 : myParameter.maxSpeed = myOriginalType->getMaxSpeed();
143 : } else {
144 405 : myParameter.maxSpeed = maxSpeed;
145 : }
146 409 : myParameter.parametersSet |= VTYPEPARS_MAXSPEED_SET;
147 409 : }
148 :
149 :
150 : void
151 15 : MSVehicleType::setMaxSpeedLat(const double& maxSpeedLat) {
152 15 : if (myOriginalType != nullptr && maxSpeedLat < 0) {
153 0 : myParameter.maxSpeedLat = myOriginalType->getMaxSpeedLat();
154 : } else {
155 15 : myParameter.maxSpeedLat = maxSpeedLat;
156 : }
157 15 : myParameter.parametersSet |= VTYPEPARS_MAXSPEED_LAT_SET;
158 15 : }
159 :
160 :
161 : void
162 58 : MSVehicleType::setVClass(SUMOVehicleClass vclass) {
163 58 : myParameter.vehicleClass = vclass;
164 58 : myParameter.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
165 58 : }
166 :
167 :
168 : void
169 150252 : MSVehicleType::setPreferredLateralAlignment(const LatAlignmentDefinition& latAlignment, double latAlignmentOffset) {
170 150252 : myParameter.latAlignmentProcedure = latAlignment;
171 150252 : myParameter.latAlignmentOffset = latAlignmentOffset;
172 150252 : myParameter.parametersSet |= VTYPEPARS_LATALIGNMENT_SET;
173 150252 : }
174 :
175 : void
176 5 : MSVehicleType::setScale(double value) {
177 5 : myParameter.scale = value;
178 5 : MSInsertionControl& insertControl = MSNet::getInstance()->getInsertionControl();
179 5 : insertControl.updateScale(getID());
180 5 : }
181 :
182 : void
183 0 : MSVehicleType::setDefaultProbability(const double& prob) {
184 0 : if (myOriginalType != nullptr && prob < 0) {
185 0 : myParameter.defaultProbability = myOriginalType->getDefaultProbability();
186 : } else {
187 0 : myParameter.defaultProbability = prob;
188 : }
189 0 : myParameter.parametersSet |= VTYPEPARS_PROBABILITY_SET;
190 0 : }
191 :
192 :
193 : void
194 9 : MSVehicleType::setSpeedFactor(const double& factor) {
195 9 : if (myOriginalType != nullptr && factor < 0) {
196 0 : myParameter.speedFactor.getParameter()[0] = myOriginalType->myParameter.speedFactor.getParameter()[0];
197 : } else {
198 9 : myParameter.speedFactor.getParameter()[0] = factor;
199 : }
200 9 : myParameter.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
201 9 : }
202 :
203 :
204 : void
205 5 : MSVehicleType::setSpeedDeviation(const double& dev) {
206 5 : if (myOriginalType != nullptr && dev < 0) {
207 0 : myParameter.speedFactor.getParameter()[1] = myOriginalType->myParameter.speedFactor.getParameter()[1];
208 : } else {
209 5 : myParameter.speedFactor.getParameter()[1] = dev;
210 : }
211 5 : myParameter.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
212 5 : }
213 :
214 :
215 : void
216 20 : MSVehicleType::setActionStepLength(const SUMOTime actionStepLength, bool resetActionOffset) {
217 : assert(actionStepLength >= 0);
218 20 : myParameter.parametersSet |= VTYPEPARS_ACTIONSTEPLENGTH_SET;
219 :
220 20 : if (myParameter.actionStepLength == actionStepLength) {
221 : return;
222 : }
223 :
224 : SUMOTime previousActionStepLength = myParameter.actionStepLength;
225 20 : myParameter.actionStepLength = actionStepLength;
226 20 : myCachedActionStepLengthSecs = STEPS2TIME(myParameter.actionStepLength);
227 20 : check();
228 :
229 20 : if (isVehicleSpecific()) {
230 : // don't perform vehicle lookup for singular vtype
231 : return;
232 : }
233 :
234 : // For non-singular vType reset all vehicle's actionOffsets
235 : // Iterate through vehicles
236 13 : MSVehicleControl& vc = MSNet::getInstance()->getVehicleControl();
237 34 : for (auto vehIt = vc.loadedVehBegin(); vehIt != vc.loadedVehEnd(); ++vehIt) {
238 21 : MSVehicle* veh = static_cast<MSVehicle*>(vehIt->second);
239 21 : if (&veh->getVehicleType() == this) {
240 : // Found vehicle of this type. Perform requested actionOffsetReset
241 13 : if (resetActionOffset) {
242 13 : veh->resetActionOffset();
243 : } else {
244 0 : veh->updateActionOffset(previousActionStepLength, actionStepLength);
245 : }
246 : }
247 : }
248 : }
249 :
250 :
251 : void
252 26 : MSVehicleType::setEmissionClass(SUMOEmissionClass eclass) {
253 26 : myParameter.emissionClass = eclass;
254 26 : myParameter.parametersSet |= VTYPEPARS_EMISSIONCLASS_SET;
255 26 : }
256 :
257 :
258 : void
259 14 : MSVehicleType::setMass(double mass) {
260 14 : myParameter.mass = mass;
261 14 : myParameter.parametersSet |= VTYPEPARS_MASS_SET;
262 14 : }
263 :
264 :
265 : void
266 5 : MSVehicleType::setColor(const RGBColor& color) {
267 5 : myParameter.color = color;
268 5 : myParameter.parametersSet |= VTYPEPARS_COLOR_SET;
269 5 : }
270 :
271 :
272 : void
273 0 : MSVehicleType::setParkingBadges(const std::vector<std::string>& badges) {
274 0 : myParameter.parkingBadges.assign(badges.begin(), badges.end());
275 0 : myParameter.parametersSet |= VTYPEPARS_PARKING_BADGES_SET;
276 0 : }
277 :
278 :
279 : void
280 30 : MSVehicleType::setWidth(const double& width) {
281 30 : if (myOriginalType != nullptr && width < 0) {
282 0 : myParameter.width = myOriginalType->getWidth();
283 : } else {
284 30 : myParameter.width = width;
285 : }
286 30 : myParameter.parametersSet |= VTYPEPARS_WIDTH_SET;
287 30 : }
288 :
289 : void
290 5 : MSVehicleType::setImpatience(const double impatience) {
291 5 : myParameter.impatience = impatience;
292 5 : myParameter.parametersSet |= VTYPEPARS_IMPATIENCE_SET;
293 5 : }
294 :
295 :
296 : void
297 14 : MSVehicleType::setBoardingDuration(SUMOTime duration, bool isPerson) {
298 14 : if (myOriginalType != nullptr && duration < 0) {
299 0 : myParameter.boardingDuration = myOriginalType->getBoardingDuration(isPerson);
300 : } else {
301 14 : if (isPerson) {
302 14 : myParameter.boardingDuration = duration;
303 : } else {
304 0 : myParameter.loadingDuration = duration;
305 : }
306 : }
307 14 : myParameter.parametersSet |= VTYPEPARS_BOARDING_DURATION;
308 14 : }
309 :
310 : void
311 16 : MSVehicleType::setShape(SUMOVehicleShape shape) {
312 16 : myParameter.shape = shape;
313 16 : myParameter.parametersSet |= VTYPEPARS_SHAPE_SET;
314 16 : }
315 :
316 :
317 :
318 : // ------------ Static methods for building vehicle types
319 : MSVehicleType*
320 317577 : MSVehicleType::build(SUMOVTypeParameter& from) {
321 635154 : if (from.hasParameter("vehicleMass")) {
322 5 : if (from.wasSet(VTYPEPARS_MASS_SET)) {
323 0 : WRITE_WARNINGF(TL("The vType '%' has a 'mass' attribute and a 'vehicleMass' parameter. The 'mass' attribute will take precedence."), from.id);
324 : } else {
325 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);
326 5 : from.mass = from.getDouble("vehicleMass", from.mass);
327 5 : from.parametersSet |= VTYPEPARS_MASS_SET;
328 : }
329 : }
330 317577 : MSVehicleType* vtype = new MSVehicleType(from);
331 317577 : const double decel = from.getCFParam(SUMO_ATTR_DECEL, SUMOVTypeParameter::getDefaultDecel(from.vehicleClass));
332 317577 : const double emergencyDecel = from.getCFParam(SUMO_ATTR_EMERGENCYDECEL, SUMOVTypeParameter::getDefaultEmergencyDecel(from.vehicleClass, decel, MSGlobals::gDefaultEmergencyDecel));
333 : // by default decel and apparentDecel are identical
334 317577 : const double apparentDecel = from.getCFParam(SUMO_ATTR_APPARENTDECEL, decel);
335 :
336 317577 : if (emergencyDecel < decel) {
337 30 : WRITE_WARNINGF(TL("Value of 'emergencyDecel' (%) should be higher than 'decel' (%) for vType '%'."), toString(emergencyDecel), toString(decel), from.id);
338 : }
339 317577 : if (emergencyDecel < apparentDecel) {
340 33 : WRITE_WARNINGF(TL("Value of 'emergencyDecel' (%) is lower than 'apparentDecel' (%) for vType '%' may cause collisions."), toString(emergencyDecel), toString(apparentDecel), from.id);
341 : }
342 :
343 317577 : switch (from.cfModel) {
344 7563 : case SUMO_TAG_CF_IDM:
345 7563 : vtype->myCarFollowModel = new MSCFModel_IDM(vtype, false);
346 7563 : break;
347 260 : case SUMO_TAG_CF_IDMM:
348 260 : vtype->myCarFollowModel = new MSCFModel_IDM(vtype, true);
349 260 : break;
350 227 : case SUMO_TAG_CF_BKERNER:
351 227 : vtype->myCarFollowModel = new MSCFModel_Kerner(vtype);
352 227 : break;
353 336 : case SUMO_TAG_CF_KRAUSS_ORIG1:
354 336 : vtype->myCarFollowModel = new MSCFModel_KraussOrig1(vtype);
355 336 : break;
356 45 : case SUMO_TAG_CF_KRAUSS_PLUS_SLOPE:
357 45 : vtype->myCarFollowModel = new MSCFModel_KraussPS(vtype);
358 45 : break;
359 12 : case SUMO_TAG_CF_KRAUSSX:
360 12 : vtype->myCarFollowModel = new MSCFModel_KraussX(vtype);
361 12 : break;
362 257 : case SUMO_TAG_CF_EIDM:
363 257 : vtype->myCarFollowModel = new MSCFModel_EIDM(vtype);
364 257 : break;
365 3 : case SUMO_TAG_CF_SMART_SK:
366 3 : vtype->myCarFollowModel = new MSCFModel_SmartSK(vtype);
367 3 : break;
368 20 : case SUMO_TAG_CF_DANIEL1:
369 20 : vtype->myCarFollowModel = new MSCFModel_Daniel1(vtype);
370 20 : break;
371 10 : case SUMO_TAG_CF_PWAGNER2009:
372 10 : vtype->myCarFollowModel = new MSCFModel_PWag2009(vtype);
373 10 : break;
374 272 : case SUMO_TAG_CF_WIEDEMANN:
375 272 : vtype->myCarFollowModel = new MSCFModel_Wiedemann(vtype);
376 272 : break;
377 287 : case SUMO_TAG_CF_W99:
378 287 : vtype->myCarFollowModel = new MSCFModel_W99(vtype);
379 287 : break;
380 335 : case SUMO_TAG_CF_RAIL:
381 335 : vtype->myCarFollowModel = new MSCFModel_Rail(vtype);
382 331 : break;
383 290 : case SUMO_TAG_CF_ACC:
384 290 : vtype->myCarFollowModel = new MSCFModel_ACC(vtype);
385 290 : break;
386 437 : case SUMO_TAG_CF_CACC:
387 437 : vtype->myCarFollowModel = new MSCFModel_CACC(vtype);
388 437 : break;
389 71 : case SUMO_TAG_CF_CC:
390 71 : vtype->myCarFollowModel = new MSCFModel_CC(vtype);
391 71 : break;
392 307152 : case SUMO_TAG_CF_KRAUSS:
393 : default:
394 307152 : vtype->myCarFollowModel = new MSCFModel_Krauss(vtype);
395 307152 : break;
396 : }
397 : // init Rail visualization parameters
398 317573 : vtype->myParameter.initRailVisualizationParameters();
399 317573 : return vtype;
400 : }
401 :
402 : SUMOTime
403 30 : MSVehicleType::getEntryManoeuvreTime(const int angle) const {
404 30 : return (getParameter().getEntryManoeuvreTime(angle));
405 : }
406 :
407 : SUMOTime
408 30 : MSVehicleType::getExitManoeuvreTime(const int angle) const {
409 30 : return (getParameter().getExitManoeuvreTime(angle));
410 : }
411 :
412 : MSVehicleType*
413 1155 : MSVehicleType::buildSingularType(const std::string& id) const {
414 1155 : return duplicateType(id, false);
415 : }
416 :
417 :
418 : MSVehicleType*
419 1161 : MSVehicleType::duplicateType(const std::string& id, bool persistent) const {
420 1161 : MSVehicleType* vtype = new MSVehicleType(myParameter);
421 1161 : vtype->myParameter.id = id;
422 1161 : vtype->myCarFollowModel = myCarFollowModel->duplicate(vtype);
423 1161 : if (!persistent) {
424 1155 : vtype->myOriginalType = this;
425 : }
426 1161 : if (!MSNet::getInstance()->getVehicleControl().addVType(vtype)) {
427 0 : std::string singular = persistent ? "" : "singular ";
428 0 : throw ProcessError("could not add " + singular + "type " + vtype->getID());
429 : }
430 1161 : return vtype;
431 : }
432 :
433 : void
434 79805 : MSVehicleType::check() {
435 79805 : if (!myWarnedActionStepLengthTauOnce
436 79798 : && myParameter.actionStepLength != DELTA_T
437 80734 : && STEPS2TIME(myParameter.actionStepLength) > getCarFollowModel().getHeadwayTime()) {
438 78 : myWarnedActionStepLengthTauOnce = true;
439 78 : std::stringstream s;
440 78 : s << "Given action step length " << STEPS2TIME(myParameter.actionStepLength) << " for vehicle type '" << getID()
441 78 : << "' is larger than its parameter tau (=" << getCarFollowModel().getHeadwayTime() << ")!"
442 78 : << " This may lead to collisions. (This warning is only issued once per vehicle type).";
443 78 : WRITE_WARNING(s.str());
444 78 : }
445 79805 : if (!myWarnedActionStepLengthBallisticOnce
446 79805 : && myParameter.actionStepLength != DELTA_T
447 936 : && MSGlobals::gSemiImplicitEulerUpdate) {
448 54 : myWarnedActionStepLengthBallisticOnce = true;
449 : std::string warning2;
450 108 : if (OptionsCont::getOptions().isDefault("step-method.ballistic")) {
451 : warning2 = " Setting it now to avoid collisions.";
452 42 : MSGlobals::gSemiImplicitEulerUpdate = false;
453 : } else {
454 : warning2 = " This may cause collisions.";
455 : }
456 162 : WRITE_WARNINGF("Action step length '%' is used for vehicle type '%' but step-method.ballistic was not set." + warning2
457 : , STEPS2TIME(myParameter.actionStepLength), getID())
458 : }
459 79805 : if (!myWarnedStepLengthTauOnce && TS > getCarFollowModel().getHeadwayTime()
460 79998 : && !MSGlobals::gUseMesoSim) {
461 161 : myWarnedStepLengthTauOnce = true;
462 483 : WRITE_WARNINGF(TL("Value of tau=% in vehicle type '%' lower than simulation step size may cause collisions."),
463 : getCarFollowModel().getHeadwayTime(), getID());
464 : }
465 86722 : if (MSGlobals::gUseMesoSim && getVehicleClass() != SVC_PEDESTRIAN && !OptionsCont::getOptions().getBool("meso-lane-queue")) {
466 13678 : SVCPermissions ignoreVClasses = parseVehicleClasses(OptionsCont::getOptions().getStringVector("meso-ignore-lanes-by-vclass"));
467 6839 : if ((ignoreVClasses & getVehicleClass()) != 0) {
468 285 : 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"),
469 : toString(getVehicleClass()), getID());
470 : }
471 : }
472 157898 : if (!myParameter.wasSet(VTYPEPARS_EMISSIONCLASS_SET) && !OptionsCont::getOptions().getBool("device.battery.track-fuel")
473 237691 : && (OptionsCont::getOptions().getFloat("device.battery.probability") == 1.
474 157766 : || myParameter.getDouble("device.battery.probability", -1.) == 1.
475 313688 : || StringUtils::toBool(myParameter.getParameter("has.battery.device", "false")))) {
476 129 : myParameter.emissionClass = PollutantsInterface::getClassByName("Energy");
477 129 : myParameter.parametersSet |= VTYPEPARS_EMISSIONCLASS_SET;
478 387 : 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!"),
479 : getID());
480 : }
481 79805 : }
482 :
483 :
484 : void
485 37 : MSVehicleType::setAccel(double accel) {
486 37 : if (myOriginalType != nullptr && accel < 0) {
487 0 : accel = myOriginalType->getCarFollowModel().getMaxAccel();
488 : }
489 37 : myCarFollowModel->setMaxAccel(accel);
490 37 : myParameter.cfParameter[SUMO_ATTR_ACCEL] = toString(accel);
491 37 : }
492 :
493 : void
494 23 : MSVehicleType::setDecel(double decel) {
495 23 : if (myOriginalType != nullptr && decel < 0) {
496 0 : decel = myOriginalType->getCarFollowModel().getMaxDecel();
497 : }
498 23 : myCarFollowModel->setMaxDecel(decel);
499 23 : myParameter.cfParameter[SUMO_ATTR_DECEL] = toString(decel);
500 23 : }
501 :
502 : void
503 42 : MSVehicleType::setEmergencyDecel(double emergencyDecel) {
504 42 : if (myOriginalType != nullptr && emergencyDecel < 0) {
505 0 : emergencyDecel = myOriginalType->getCarFollowModel().getEmergencyDecel();
506 : }
507 42 : myCarFollowModel->setEmergencyDecel(emergencyDecel);
508 42 : myParameter.cfParameter[SUMO_ATTR_EMERGENCYDECEL] = toString(emergencyDecel);
509 42 : }
510 :
511 : void
512 23 : MSVehicleType::setApparentDecel(double apparentDecel) {
513 23 : if (myOriginalType != nullptr && apparentDecel < 0) {
514 0 : apparentDecel = myOriginalType->getCarFollowModel().getApparentDecel();
515 : }
516 23 : myCarFollowModel->setApparentDecel(apparentDecel);
517 23 : myParameter.cfParameter[SUMO_ATTR_APPARENTDECEL] = toString(apparentDecel);
518 23 : }
519 :
520 : void
521 32 : MSVehicleType::setImperfection(double imperfection) {
522 32 : if (myOriginalType != nullptr && imperfection < 0) {
523 0 : imperfection = myOriginalType->getCarFollowModel().getImperfection();
524 : }
525 32 : myCarFollowModel->setImperfection(imperfection);
526 32 : myParameter.cfParameter[SUMO_ATTR_SIGMA] = toString(imperfection);
527 32 : }
528 :
529 : void
530 23 : MSVehicleType::setTau(double tau) {
531 23 : if (myOriginalType != nullptr && tau < 0) {
532 0 : tau = myOriginalType->getCarFollowModel().getHeadwayTime();
533 : }
534 23 : myCarFollowModel->setHeadwayTime(tau);
535 23 : myParameter.cfParameter[SUMO_ATTR_TAU] = toString(tau);
536 23 : }
537 :
538 : /****************************************************************************/
|