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