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