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