1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    SUMOVTypeParameter.cpp
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Michael Behrisch
14 /// @date    10.09.2009
15 /// @version $Id$
16 ///
17 // Structure representing possible vehicle parameter
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <algorithm>
27 #include <utils/vehicle/SUMOVTypeParameter.h>
28 #include <utils/common/ToString.h>
29 #include <utils/common/StringUtils.h>
30 #include <utils/common/MsgHandler.h>
31 #include <utils/iodevices/OutputDevice.h>
32 #include <utils/options/OptionsCont.h>
33 #include <utils/xml/SUMOXMLDefinitions.h>
34 #include <utils/emissions/PollutantsInterface.h>
35 
36 #define EMPREFIX std::string("HBEFA3/")
37 
38 
39 // ===========================================================================
40 // member method definitions
41 // ===========================================================================
SUMOVTypeParameter(const std::string & vtid,const SUMOVehicleClass vclass)42 SUMOVTypeParameter::SUMOVTypeParameter(const std::string& vtid, const SUMOVehicleClass vclass) :
43     id(vtid), length(5./*4.3*/), minGap(2.5), maxSpeed(200. / 3.6),
44     actionStepLength(0), defaultProbability(DEFAULT_VEH_PROB),
45     speedFactor("normc", 1.0, 0.0, 0.2, 2.0),
46     emissionClass(PollutantsInterface::getClassByName(EMPREFIX + "PC_G_EU4", vclass)), color(RGBColor::DEFAULT_COLOR),
47     vehicleClass(vclass), impatience(0.0), personCapacity(4), containerCapacity(0), boardingDuration(500),
48     loadingDuration(90000), width(1.8), height(1.5), shape(SVS_UNKNOWN), osgFile("car-normal-citrus.obj"),
49     cfModel(SUMO_TAG_CF_KRAUSS),
50     hasDriverState(false), lcModel(LCM_DEFAULT),
51     maxSpeedLat(1.0), latAlignment(LATALIGN_CENTER), minGapLat(0.6),
52     carriageLength(-1), locomotiveLength(-1), carriageGap(1),
53     parametersSet(0), saved(false), onlyReferenced(false) {
54     const OptionsCont& oc = OptionsCont::getOptions();
55     if (oc.exists("carfollow.model")) {
56         // check for valid value has been performed in MSFrame
57         cfModel = SUMOXMLDefinitions::CarFollowModels.get(oc.getString("carfollow.model"));
58     }
59     switch (vclass) {
60         case SVC_PEDESTRIAN:
61             length = 0.215;
62             minGap = 0.25;
63             maxSpeed = DEFAULT_PEDESTRIAN_SPEED;
64             width = 0.478;
65             height = 1.719;
66             shape = SVS_PEDESTRIAN;
67             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
68             speedFactor.getParameter()[1] = 0.1;
69             break;
70         case SVC_BICYCLE:
71             length = 1.6;
72             minGap = 0.5;
73             maxSpeed = 20. / 3.6;
74             width = 0.65;
75             height = 1.7;
76             shape = SVS_BICYCLE;
77             personCapacity = 1;
78             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
79             speedFactor.getParameter()[1] = 0.1;
80             break;
81         case SVC_MOPED:
82             length = 2.1;
83             maxSpeed = 60. / 3.6;
84             width = 0.8;
85             height = 1.7;
86             shape = SVS_MOPED;
87             personCapacity = 1;
88             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "LDV_G_EU6", vclass);
89             speedFactor.getParameter()[1] = 0.1;
90             break;
91         case SVC_MOTORCYCLE:
92             length = 2.2;
93             width = 0.9;
94             height = 1.5;
95             shape = SVS_MOTORCYCLE;
96             personCapacity = 1;
97             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "LDV_G_EU6", vclass);
98             speedFactor.getParameter()[1] = 0.1;
99             break;
100         case SVC_TRUCK:
101             length = 7.1;
102             maxSpeed = 130. / 3.6;
103             width = 2.4;
104             height = 2.4;
105             shape = SVS_TRUCK;
106             osgFile = "car-microcargo-citrus.obj";
107             personCapacity = 2;
108             containerCapacity = 1;
109             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "HDV", vclass);
110             speedFactor.getParameter()[1] = 0.05;
111             break;
112         case SVC_TRAILER:
113             length = 16.5;
114             maxSpeed = 130. / 3.6;
115             width = 2.55;
116             height = 4.;
117             shape = SVS_TRUCK_1TRAILER;
118             osgFile = "car-microcargo-citrus.obj";
119             personCapacity = 2;
120             containerCapacity = 2;
121             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "HDV", vclass);
122             speedFactor.getParameter()[1] = 0.05;
123             break;
124         case SVC_BUS:
125             length = 12.;
126             maxSpeed = 100. / 3.6;
127             width = 2.5;
128             height = 3.4;
129             shape = SVS_BUS;
130             osgFile = "car-minibus-citrus.obj";
131             personCapacity = 85;
132             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "Bus", vclass);
133             break;
134         case SVC_COACH:
135             length = 14.;
136             maxSpeed = 100. / 3.6;
137             width = 2.6;
138             height = 4.;
139             shape = SVS_BUS_COACH;
140             osgFile = "car-minibus-citrus.obj";
141             personCapacity = 70;
142             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "Coach", vclass);
143             speedFactor.getParameter()[1] = 0.05;
144             break;
145         case SVC_TRAM:
146             length = 22.;
147             maxSpeed = 80. / 3.6;
148             width = 2.4;
149             height = 3.2;
150             shape = SVS_RAIL_CAR;
151             carriageLength = 5.71; // http://de.wikipedia.org/wiki/Bombardier_Flexity_Berlin
152             locomotiveLength = 5.71;
153             personCapacity = 120;
154             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
155             break;
156         case SVC_RAIL_URBAN:
157             length = 36.5 * 3;
158             maxSpeed = 100. / 3.6;
159             width = 3.0;
160             height = 3.6;
161             shape = SVS_RAIL_CAR;
162             carriageLength = 18.4;  // https://en.wikipedia.org/wiki/DBAG_Class_481
163             locomotiveLength = 18.4;
164             personCapacity = 300;
165             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
166             break;
167         case SVC_RAIL:
168             length = 67.5 * 2;
169             maxSpeed = 160. / 3.6;
170             width = 2.84;
171             height = 3.75;
172             shape = SVS_RAIL;
173             carriageLength = 24.5; // http://de.wikipedia.org/wiki/UIC-Y-Wagen_%28DR%29
174             locomotiveLength = 16.4; // https://en.wikipedia.org/wiki/DB_Class_218
175             personCapacity = 434;
176             // slight understatement (-:
177             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "HDV_D_EU0", vclass);
178             break;
179         case SVC_RAIL_ELECTRIC:
180             length = 25. * 8;
181             maxSpeed = 330. / 3.6;
182             width = 2.95;
183             height = 3.89;
184             shape = SVS_RAIL;
185             carriageLength = 24.775; // http://de.wikipedia.org/wiki/ICE_3
186             locomotiveLength = 25.835;
187             personCapacity = 425;
188             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
189             break;
190         case SVC_DELIVERY:
191             length = 6.5;
192             width = 2.16;
193             height = 2.86;
194             shape = SVS_DELIVERY;
195             personCapacity = 2;
196             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "LDV", vclass);
197             speedFactor.getParameter()[1] = 0.05;
198             break;
199         case SVC_EMERGENCY:
200             length = 6.5;
201             width = 2.16;
202             height = 2.86;
203             shape = SVS_DELIVERY;
204             personCapacity = 2;
205             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "LDV", vclass);
206             break;
207         case SVC_PRIVATE:
208         case SVC_VIP:
209         case SVC_PASSENGER:
210         case SVC_HOV:
211         case SVC_CUSTOM1:
212         case SVC_CUSTOM2:
213             shape = SVS_PASSENGER;
214             speedFactor.getParameter()[1] = 0.1;
215             break;
216         case SVC_TAXI:
217             shape = SVS_PASSENGER;
218             speedFactor.getParameter()[1] = 0.05;
219             break;
220         case SVC_E_VEHICLE:
221             shape = SVS_E_VEHICLE;
222             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "zero", vclass);
223             speedFactor.getParameter()[1] = 0.1;
224             break;
225         case SVC_SHIP:
226             length = 17;
227             width = 4;
228             maxSpeed = 8 / 1.94; // 8 knots
229             height = 4;
230             shape = SVS_SHIP;
231             // slight understatement (-:
232             emissionClass = PollutantsInterface::getClassByName(EMPREFIX + "HDV_D_EU0", vclass);
233             speedFactor.getParameter()[1] = 0.1;
234             break;
235         default:
236             break;
237     }
238     if (oc.exists("default.speeddev")) {
239         const double defaultSpeedDev = oc.getFloat("default.speeddev");
240         if (defaultSpeedDev >= 0) {
241             speedFactor.getParameter()[1] = defaultSpeedDev;
242         }
243     } else {
244         speedFactor.getParameter()[1] = 0;
245     }
246 }
247 
248 
249 void
write(OutputDevice & dev) const250 SUMOVTypeParameter::write(OutputDevice& dev) const {
251     if (onlyReferenced) {
252         return;
253     }
254     dev.openTag(SUMO_TAG_VTYPE);
255     dev.writeAttr(SUMO_ATTR_ID, id);
256     if (wasSet(VTYPEPARS_LENGTH_SET)) {
257         dev.writeAttr(SUMO_ATTR_LENGTH, length);
258     }
259     if (wasSet(VTYPEPARS_MINGAP_SET)) {
260         dev.writeAttr(SUMO_ATTR_MINGAP, minGap);
261     }
262     if (wasSet(VTYPEPARS_MAXSPEED_SET)) {
263         dev.writeAttr(SUMO_ATTR_MAXSPEED, maxSpeed);
264     }
265     if (wasSet(VTYPEPARS_PROBABILITY_SET)) {
266         dev.writeAttr(SUMO_ATTR_PROB, defaultProbability);
267     }
268     if (wasSet(VTYPEPARS_SPEEDFACTOR_SET)) {
269         dev.writeAttr(SUMO_ATTR_SPEEDFACTOR, speedFactor);
270     }
271     if (wasSet(VTYPEPARS_ACTIONSTEPLENGTH_SET)) {
272         // Note: action step length is only exposed in seconds to the user
273         dev.writeAttr(SUMO_ATTR_ACTIONSTEPLENGTH, STEPS2TIME(actionStepLength));
274     }
275     if (wasSet(VTYPEPARS_ACTIONSTEPLENGTH_SET)) {
276         // Note: action step length is only exposed in seconds to the user
277         dev.writeAttr(SUMO_ATTR_HASDRIVERSTATE, hasDriverState);
278     }
279     if (wasSet(VTYPEPARS_VEHICLECLASS_SET)) {
280         dev.writeAttr(SUMO_ATTR_VCLASS, toString(vehicleClass));
281     }
282     if (wasSet(VTYPEPARS_EMISSIONCLASS_SET)) {
283         dev.writeAttr(SUMO_ATTR_EMISSIONCLASS, PollutantsInterface::getName(emissionClass));
284     }
285     if (wasSet(VTYPEPARS_IMPATIENCE_SET)) {
286         if (impatience == -std::numeric_limits<double>::max()) {
287             dev.writeAttr(SUMO_ATTR_IMPATIENCE, "off");
288         } else {
289             dev.writeAttr(SUMO_ATTR_IMPATIENCE, impatience);
290         }
291     }
292     if (wasSet(VTYPEPARS_SHAPE_SET)) {
293         dev.writeAttr(SUMO_ATTR_GUISHAPE, getVehicleShapeName(shape));
294     }
295     if (wasSet(VTYPEPARS_WIDTH_SET)) {
296         dev.writeAttr(SUMO_ATTR_WIDTH, width);
297     }
298     if (wasSet(VTYPEPARS_HEIGHT_SET)) {
299         dev.writeAttr(SUMO_ATTR_HEIGHT, height);
300     }
301     if (wasSet(VTYPEPARS_COLOR_SET)) {
302         dev.writeAttr(SUMO_ATTR_COLOR, color);
303     }
304     if (wasSet(VTYPEPARS_OSGFILE_SET)) {
305         dev.writeAttr(SUMO_ATTR_OSGFILE, osgFile);
306     }
307     if (wasSet(VTYPEPARS_IMGFILE_SET)) {
308         dev.writeAttr(SUMO_ATTR_IMGFILE, imgFile);
309     }
310     if (wasSet(VTYPEPARS_PERSON_CAPACITY)) {
311         dev.writeAttr(SUMO_ATTR_PERSON_CAPACITY, personCapacity);
312     }
313     if (wasSet(VTYPEPARS_CONTAINER_CAPACITY)) {
314         dev.writeAttr(SUMO_ATTR_CONTAINER_CAPACITY, containerCapacity);
315     }
316     if (wasSet(VTYPEPARS_BOARDING_DURATION)) {
317         dev.writeAttr(SUMO_ATTR_BOARDING_DURATION, boardingDuration);
318     }
319     if (wasSet(VTYPEPARS_LOADING_DURATION)) {
320         dev.writeAttr(SUMO_ATTR_LOADING_DURATION, loadingDuration);
321     }
322     if (wasSet(VTYPEPARS_MAXSPEED_LAT_SET)) {
323         dev.writeAttr(SUMO_ATTR_MAXSPEED_LAT, maxSpeedLat);
324     }
325     if (wasSet(VTYPEPARS_LATALIGNMENT_SET)) {
326         dev.writeAttr(SUMO_ATTR_LATALIGNMENT, latAlignment);
327     }
328     if (wasSet(VTYPEPARS_MINGAP_LAT_SET)) {
329         dev.writeAttr(SUMO_ATTR_MINGAP_LAT, minGapLat);
330     }
331     if (wasSet(VTYPEPARS_LANE_CHANGE_MODEL_SET)) {
332         dev.writeAttr(SUMO_ATTR_LANE_CHANGE_MODEL, lcModel);
333     }
334     for (SubParams::const_iterator i = lcParameter.begin(); i != lcParameter.end(); ++i) {
335         dev.writeAttr(i->first, i->second);
336     }
337     for (SubParams::const_iterator i = jmParameter.begin(); i != jmParameter.end(); ++i) {
338         dev.writeAttr(i->first, i->second);
339     }
340     if (wasSet(VTYPEPARS_CAR_FOLLOW_MODEL)) {
341         dev.writeAttr(SUMO_ATTR_CAR_FOLLOW_MODEL, SUMOXMLDefinitions::CarFollowModels.getString(cfModel));
342     }
343     for (SubParams::const_iterator i = cfParameter.begin(); i != cfParameter.end(); ++i) {
344         dev.writeAttr(i->first, i->second);
345     }
346     writeParams(dev);
347     dev.closeTag();
348 }
349 
350 
351 double
getCFParam(const SumoXMLAttr attr,const double defaultValue) const352 SUMOVTypeParameter::getCFParam(const SumoXMLAttr attr, const double defaultValue) const {
353     if (cfParameter.count(attr)) {
354         return StringUtils::toDouble(cfParameter.find(attr)->second);
355     } else {
356         return defaultValue;
357     }
358 }
359 
360 
361 std::string
getCFParamString(const SumoXMLAttr attr,const std::string defaultValue) const362 SUMOVTypeParameter::getCFParamString(const SumoXMLAttr attr, const std::string defaultValue) const {
363     if (cfParameter.count(attr)) {
364         return cfParameter.find(attr)->second;
365     } else {
366         return defaultValue;
367     }
368 }
369 
370 double
getLCParam(const SumoXMLAttr attr,const double defaultValue) const371 SUMOVTypeParameter::getLCParam(const SumoXMLAttr attr, const double defaultValue) const {
372     if (lcParameter.count(attr)) {
373         return StringUtils::toDouble(lcParameter.find(attr)->second);
374     } else {
375         return defaultValue;
376     }
377 }
378 
379 const SUMOVTypeParameter::SubParams&
getLCParams() const380 SUMOVTypeParameter::getLCParams() const {
381     return lcParameter;
382 }
383 
384 
385 double
getJMParam(const SumoXMLAttr attr,const double defaultValue) const386 SUMOVTypeParameter::getJMParam(const SumoXMLAttr attr, const double defaultValue) const {
387     if (jmParameter.count(attr)) {
388         return StringUtils::toDouble(jmParameter.find(attr)->second);
389     } else {
390         return defaultValue;
391     }
392 }
393 
394 
395 std::string
getJMParamString(const SumoXMLAttr attr,const std::string defaultValue) const396 SUMOVTypeParameter::getJMParamString(const SumoXMLAttr attr, const std::string defaultValue) const {
397     if (jmParameter.count(attr)) {
398         return jmParameter.find(attr)->second;
399     } else {
400         return defaultValue;
401     }
402 }
403 
404 
405 double
getDefaultAccel(const SUMOVehicleClass vc)406 SUMOVTypeParameter::getDefaultAccel(const SUMOVehicleClass vc) {
407     switch (vc) {
408         case SVC_PEDESTRIAN:
409             return 1.5;
410         case SVC_BICYCLE:
411             return 1.2;
412         case SVC_MOTORCYCLE:
413             return 6.;
414         case SVC_MOPED:
415             return 1.1;
416         case SVC_TRUCK:
417             return 1.3;
418         case SVC_TRAILER:
419             return 1.1;
420         case SVC_BUS:
421             return 1.2;
422         case SVC_COACH:
423             return 2.;
424         case SVC_TRAM:
425             return 1.;
426         case SVC_RAIL_URBAN:
427             return 1.;
428         case SVC_RAIL:
429             return 0.25;
430         case SVC_RAIL_ELECTRIC:
431             return 0.5;
432         case SVC_SHIP:
433             return 0.1;
434         default:
435             return 2.6;//2.9;
436     }
437 }
438 
439 
440 double
getDefaultDecel(const SUMOVehicleClass vc)441 SUMOVTypeParameter::getDefaultDecel(const SUMOVehicleClass vc) {
442     switch (vc) {
443         case SVC_PEDESTRIAN:
444             return 2.;
445         case SVC_BICYCLE:
446             return 3.;
447         case SVC_MOPED:
448             return 7.;
449         case SVC_MOTORCYCLE:
450             return 10.;
451         case SVC_TRUCK:
452         case SVC_TRAILER:
453         case SVC_BUS:
454         case SVC_COACH:
455             return 4.;
456         case SVC_TRAM:
457         case SVC_RAIL_URBAN:
458             return 3.;
459         case SVC_RAIL:
460         case SVC_RAIL_ELECTRIC:
461             return 1.3;
462         case SVC_SHIP:
463             return 0.15;
464         default:
465             return 4.5;//7.5;
466     }
467 }
468 
469 
470 double
getDefaultEmergencyDecel(const SUMOVehicleClass vc,double decel,double defaultOption)471 SUMOVTypeParameter::getDefaultEmergencyDecel(const SUMOVehicleClass vc, double decel, double defaultOption) {
472     if (defaultOption == VTYPEPARS_DEFAULT_EMERGENCYDECEL_DEFAULT) {
473         double vcDecel;
474         switch (vc) {
475             case SVC_PEDESTRIAN:
476                 vcDecel = 5.;
477                 break;
478             case SVC_BICYCLE:
479                 vcDecel = 7.;
480                 break;
481             case SVC_MOPED:
482             case SVC_MOTORCYCLE:
483                 vcDecel = 10.;
484                 break;
485             case SVC_TRUCK:
486             case SVC_TRAILER:
487             case SVC_BUS:
488             case SVC_COACH:
489             case SVC_TRAM:
490             case SVC_RAIL_URBAN:
491                 vcDecel = 7.;
492                 break;
493             case SVC_RAIL:
494             case SVC_RAIL_ELECTRIC:
495                 vcDecel = 5.;
496                 break;
497             case SVC_SHIP:
498                 vcDecel = 1.;
499                 break;
500             default:
501                 vcDecel = 9.;
502         }
503         return MAX2(decel, vcDecel);
504     } else if (defaultOption == VTYPEPARS_DEFAULT_EMERGENCYDECEL_DECEL) {
505         return decel;
506     } else {
507         // value already checked in MSFrame::checkOptions
508         return MAX2(decel, defaultOption);
509     }
510 }
511 
512 
513 
514 double
getDefaultImperfection(const SUMOVehicleClass vc)515 SUMOVTypeParameter::getDefaultImperfection(const SUMOVehicleClass vc) {
516     switch (vc) {
517         case SVC_TRAM:
518         case SVC_RAIL_URBAN:
519         case SVC_RAIL:
520         case SVC_RAIL_ELECTRIC:
521         case SVC_SHIP:
522             return 0.;
523         default:
524             return 0.5;
525     }
526 }
527 
528 
529 const SUMOVTypeParameter&
getDefault()530 SUMOVTypeParameter::getDefault() {
531     static SUMOVTypeParameter defaultParams("");
532     return defaultParams;
533 }
534 
535 
536 /****************************************************************************/
537