Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
SUMOVehicleParserHelper.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2008-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/****************************************************************************/
23// Helper methods for parsing vehicle attributes
24/****************************************************************************/
25#include <config.h>
26
39
41
42
43// ===========================================================================
44// static members
45// ===========================================================================
46
49
50
51// ===========================================================================
52// method definitions
53// ===========================================================================
54
56SUMOVehicleParserHelper::parseFlowAttributes(SumoXMLTag tag, const SUMOSAXAttributes& attrs, const bool hardFail, const bool needID,
57 const SUMOTime beginDefault, const SUMOTime endDefault, const bool allowInternalRoutes) {
58 // first parse ID
59 const std::string id = attrs.hasAttribute(SUMO_ATTR_ID) ? parseID(attrs, tag) : "";
60 // check if ID is valid
61 if (!needID || !id.empty()) {
62 if (needID && !SUMOXMLDefinitions::isValidVehicleID(id)) {
63 return handleVehicleError(hardFail, nullptr, "Invalid flow id '" + id + "'.");
64 }
65 // declare flags
66 const bool hasPeriod = attrs.hasAttribute(SUMO_ATTR_PERIOD);
67 const bool hasVPH = attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR);
68 const bool hasPPH = attrs.hasAttribute(SUMO_ATTR_PERSONSPERHOUR);
69 const bool hasCPH = attrs.hasAttribute(SUMO_ATTR_CONTAINERSPERHOUR);
70 const bool hasPH = attrs.hasAttribute(SUMO_ATTR_PERHOUR);
71 const bool hasXPH = hasVPH || hasPPH || hasCPH || hasPH;
72 const bool hasProb = attrs.hasAttribute(SUMO_ATTR_PROB);
73 const bool hasNumber = attrs.hasAttribute(SUMO_ATTR_NUMBER);
74 const bool hasBegin = attrs.hasAttribute(SUMO_ATTR_BEGIN);
75 const bool hasEnd = attrs.hasAttribute(SUMO_ATTR_END);
77 if (hasVPH) {
78 PERHOUR = SUMO_ATTR_VEHSPERHOUR;
79 }
80 if (hasPPH) {
82 }
83 if (hasCPH) {
85 }
86 if (hasXPH && !(hasVPH ^ hasPPH ^ hasCPH ^ hasPH)) {
87 return handleVehicleError(hardFail, nullptr,
88 "At most one of '" + attrs.getName(SUMO_ATTR_PERHOUR) +
89 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
90 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
91 "' and '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
92 "' has to be given in the definition of " + toString(tag) + " '" + id + "'.");
93 }
94 if (hasPeriod && hasXPH) {
95 return handleVehicleError(hardFail, nullptr,
96 "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
97 "' and '" + attrs.getName(PERHOUR) +
98 "' has to be given in the definition of "
99 + toString(tag) + " '" + id + "'.");
100 }
101 if (hasPeriod && hasProb) {
102 return handleVehicleError(hardFail, nullptr,
103 "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
104 "' and '" + attrs.getName(SUMO_ATTR_PROB) +
105 "' has to be given in the definition of "
106 + toString(tag) + " '" + id + "'.");
107 }
108 if (hasProb && hasXPH) {
109 return handleVehicleError(hardFail, nullptr,
110 "At most one of '" + attrs.getName(SUMO_ATTR_PROB) +
111 "' and '" + attrs.getName(PERHOUR) +
112 "' has to be given in the definition of "
113 + toString(tag) + " '" + id + "'.");
114 }
115 if (hasPeriod || hasXPH || hasProb) {
116 if (hasEnd && hasNumber) {
117 return handleVehicleError(hardFail, nullptr,
118 "If '" + attrs.getName(SUMO_ATTR_PERIOD) +
119 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
120 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
121 "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
122 "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
123 "' or '" + attrs.getName(SUMO_ATTR_PROB) +
124 "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
125 "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
126 "' are allowed in "
127 + toString(tag) + " '" + id + "'.");
128 }
129 } else {
130 if (!hasNumber) {
131 return handleVehicleError(hardFail, nullptr,
132 "At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
133 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
134 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
135 "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
136 "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
137 "', '" + attrs.getName(SUMO_ATTR_PROB) +
138 "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
139 "' is needed in "
140 + toString(tag) + " '" + id + "'.");
141 }
142 }
143 // declare flow
144 SUMOVehicleParameter* flowParameter = new SUMOVehicleParameter();
145 // set tag
146 flowParameter->tag = tag;
147 // set id
148 flowParameter->id = id;
149 if (tag == SUMO_TAG_PERSONFLOW) {
150 flowParameter->vtypeid = DEFAULT_PEDTYPE_ID;
151 }
152 if (tag == SUMO_TAG_CONTAINERFLOW) {
153 flowParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
154 }
155 // parse common vehicle attributes
156 try {
157 parseCommonAttributes(attrs, flowParameter, tag, allowInternalRoutes);
158 } catch (ProcessError& attributeError) {
159 // check if continue handling another vehicles or stop handling
160 if (hardFail) {
161 throw ProcessError(attributeError.what());
162 } else {
163 return nullptr;
164 }
165 }
166 // parse period
167 bool poissonFlow = false;
168 if (hasPeriod) {
169 bool ok = true;
170 const std::string description = attrs.get<std::string>(SUMO_ATTR_PERIOD, id.c_str(), ok);
171 const std::string distName = description.substr(0, description.find('('));
172 if (distName == "exp") {
173 // declare rate
174 double rate = -1;
175 // parse rate
176 try {
177 rate = StringUtils::toDouble(description.substr(distName.size() + 1, description.size() - distName.size() - 2));
178 } catch (ProcessError& attributeError) {
179 // check if continue handling another vehicles or stop handling
180 if (hardFail) {
181 throw ProcessError(attributeError.what());
182 } else {
183 return nullptr;
184 }
185 }
186 if (rate <= 0) {
187 return handleVehicleError(hardFail, flowParameter, "Invalid rate parameter for exponentially distributed period in the definition of " + toString(tag) + " '" + id + "'.");
188 }
189 flowParameter->poissonRate = rate;
190 poissonFlow = true;
191 } else {
192 flowParameter->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
193 }
194 if (!ok) {
195 return handleVehicleError(hardFail, flowParameter);
196 } else {
197 flowParameter->parametersSet |= VEHPARS_PERIOD_SET;
198 }
199 }
200 // parse vehicle/person/container/etc per hour
201 if (hasXPH) {
202 bool ok = true;
203 const double vph = attrs.get<double>(PERHOUR, id.c_str(), ok);
204 if (!ok) {
205 return handleVehicleError(hardFail, flowParameter);
206 } else if (vph <= 0) {
207 return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
208 } else {
209 if (vph != 0) {
210 flowParameter->repetitionOffset = TIME2STEPS(3600. / vph);
211 }
212 flowParameter->parametersSet |= VEHPARS_VPH_SET;
213 }
214 }
215 // parse probability
216 if (hasProb) {
217 bool ok = true;
218 flowParameter->repetitionProbability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
219 if (!ok) {
220 return handleVehicleError(hardFail, flowParameter);
221 } else if (flowParameter->repetitionProbability <= 0 || flowParameter->repetitionProbability > 1) {
222 return handleVehicleError(hardFail, flowParameter, "Invalid repetition probability in the definition of " + toString(tag) + " '" + id + "'.");
223 } else {
224 flowParameter->parametersSet |= VEHPARS_PROB_SET;
225 }
226 }
227 // set default begin
228 flowParameter->depart = beginDefault;
229 // parse begin
230 if (hasBegin) {
231 // first get begin
232 bool ok = true;
233 const std::string begin = attrs.get<std::string>(SUMO_ATTR_BEGIN, id.c_str(), ok);
234 if (!ok) {
235 return handleVehicleError(hardFail, flowParameter);
236 } else {
237 // parse begin
238 std::string errorMsg;
239 if (!SUMOVehicleParameter::parseDepart(begin, toString(tag), id, flowParameter->depart, flowParameter->departProcedure, errorMsg, "begin")) {
240 return handleVehicleError(hardFail, flowParameter, errorMsg);
241 }
242 }
243 }
244 if (flowParameter->depart < 0) {
245 return handleVehicleError(hardFail, flowParameter, "Negative begin time in the definition of " + toString(tag) + " '" + id + "'.");
246 }
247 // set default end
248 flowParameter->repetitionEnd = endDefault;
249 if (flowParameter->repetitionEnd < 0) {
250 flowParameter->repetitionEnd = SUMOTime_MAX;
251 }
252 // parse end
253 if (hasEnd) {
254 bool ok = true;
255 flowParameter->repetitionEnd = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
256 if (!ok) {
257 return handleVehicleError(hardFail, flowParameter);
258 } else {
259 flowParameter->parametersSet |= VEHPARS_END_SET;
260 }
261 } else if (flowParameter->departProcedure == DepartDefinition::TRIGGERED) {
262 if (!hasNumber) {
263 return handleVehicleError(hardFail, flowParameter, toString(tag) + " '" + id + "' with triggered begin must define 'number'.");
264 } else {
265 flowParameter->repetitionEnd = flowParameter->depart;
266 }
267 } else if ((endDefault == SUMOTime_MAX || endDefault < 0) && (!hasNumber || (!hasProb && !hasPeriod && !hasXPH))) {
268 WRITE_WARNINGF(TL("Undefined end for % '%', defaulting to 24hour duration."), toString(tag), id);
269 flowParameter->repetitionEnd = flowParameter->depart + TIME2STEPS(24 * 3600);
270 }
271 if (flowParameter->repetitionEnd < flowParameter->depart) {
272 std::string flow = toString(tag);
273 flow[0] = (char)::toupper((char)flow[0]);
274 return handleVehicleError(hardFail, flowParameter, flow + " '" + id + "' ends before its begin time.");
275 }
276 // parse number
277 if (hasNumber) {
278 bool ok = true;
279 flowParameter->repetitionNumber = attrs.get<long long int>(SUMO_ATTR_NUMBER, id.c_str(), ok);
280 if (!ok) {
281 return handleVehicleError(hardFail, flowParameter);
282 } else {
283 flowParameter->parametersSet |= VEHPARS_NUMBER_SET;
284 if (flowParameter->repetitionNumber == 0) {
285 std::string flow = toString(tag);
286 flow[0] = (char)::toupper((char)flow[0]);
287 WRITE_WARNING(flow + " '" + id + "' has no instances; will skip it.");
288 flowParameter->repetitionEnd = flowParameter->depart;
289 } else {
290 if (flowParameter->repetitionNumber < 0) {
291 return handleVehicleError(hardFail, flowParameter, "Negative repetition number in the definition of " + toString(tag) + " '" + id + "'.");
292 }
293 if (flowParameter->repetitionOffset < 0 && !hasProb) {
294 if (poissonFlow) {
295 flowParameter->repetitionEnd = SUMOTime_MAX;
296 } else {
297 flowParameter->repetitionOffset = (flowParameter->repetitionEnd - flowParameter->depart) / flowParameter->repetitionNumber;
298 }
299 }
300 }
301 }
302 } else {
303 // interpret repetitionNumber
304 if (flowParameter->repetitionProbability > 0) {
305 flowParameter->repetitionNumber = std::numeric_limits<long long int>::max();
306 } else {
307 if (flowParameter->repetitionOffset <= 0) {
308 if (poissonFlow) {
309 // number is random but flow has a fixed end time
310 flowParameter->repetitionNumber = std::numeric_limits<long long int>::max();
311 } else {
312 return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
313 }
314 } else {
315 if (flowParameter->repetitionEnd == SUMOTime_MAX) {
316 flowParameter->repetitionNumber = std::numeric_limits<long long int>::max();
317 } else {
318 const SUMOTime repLength = flowParameter->repetitionEnd - flowParameter->depart;
319 flowParameter->repetitionNumber = (long long int)ceil((double)repLength / (double)flowParameter->repetitionOffset);
320 }
321 }
322 }
323 }
324 // all ok, then return flow parameter
325 return flowParameter;
326 } else {
327 return handleVehicleError(hardFail, nullptr, toString(tag) + " cannot be created");
328 }
329}
330
331
333SUMOVehicleParserHelper::parseVehicleAttributes(int element, const SUMOSAXAttributes& attrs, const bool hardFail, const bool optionalID, const bool skipDepart, const bool allowInternalRoutes) {
334 // declare vehicle ID
335 std::string id;
336 // for certain vehicles, ID can be optional
337 if (optionalID) {
338 bool ok = true;
339 id = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
340 if (!ok) {
341 return handleVehicleError(hardFail, nullptr);
342 }
343 } else {
344 // parse ID
345 id = parseID(attrs, (SumoXMLTag)element);
346 }
347 // only continue if id is valid, or if is optional
348 if (optionalID || !id.empty()) {
349 // declare vehicle parameter
350 SUMOVehicleParameter* vehicleParameter = new SUMOVehicleParameter();
351 vehicleParameter->id = id;
352 if (element == SUMO_TAG_PERSON) {
353 vehicleParameter->vtypeid = DEFAULT_PEDTYPE_ID;
354 } else if (element == SUMO_TAG_CONTAINER) {
355 vehicleParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
356 }
357 // parse common attributes
358 try {
359 parseCommonAttributes(attrs, vehicleParameter, (SumoXMLTag)element, allowInternalRoutes);
360 } catch (ProcessError& attributeError) {
361 // check if continue handling another vehicles or stop handling
362 if (hardFail) {
363 throw ProcessError(attributeError.what());
364 } else {
365 return nullptr;
366 }
367 }
368 // check depart
369 if (!skipDepart) {
370 bool ok = true;
371 const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPART, vehicleParameter->id.c_str(), ok);
372 if (!ok) {
373 return handleVehicleError(hardFail, vehicleParameter);
374 }
375 // now parse depart
376 std::string departErrorMsg;
377 if (!SUMOVehicleParameter::parseDepart(helper, "vehicle", vehicleParameter->id, vehicleParameter->depart, vehicleParameter->departProcedure, departErrorMsg)) {
378 return handleVehicleError(hardFail, vehicleParameter, departErrorMsg);
379 }
380 }
381 // set tag
382 vehicleParameter->tag = (SumoXMLTag)element;
383 // all ok, then return vehicleParameter
384 return vehicleParameter;
385 } else {
386 return handleVehicleError(hardFail, nullptr, toString((SumoXMLTag)element) + " cannot be created");
387 }
388}
389
390
391std::string
393 bool ok = true;
394 std::string id;
395 // first check if attrs contain an ID
396 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
397 id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
399 return id;
400 } else if (id.empty()) {
401 // add extra information for empty IDs
402 WRITE_ERRORF(TL("Invalid % id '%'."), toString(element), id);
403 } else {
404 WRITE_ERRORF(TL("Invalid % id '%'. Contains invalid characters."), toString(element), id);
405 }
406 } else {
407 WRITE_ERROR("Attribute '" + toString(SUMO_ATTR_ID) + "' is missing in definition of " + toString(element));
408 }
409 // return empty (invalid) ID
410 return "";
411}
412
413
414void
416 const std::string element = toString(tag);
417 //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
418 // parse route information
419 if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
420 bool ok = true;
421 std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, ret->id.c_str(), ok);
422 if (!allowInternalRoutes && isInternalRouteID(routeID)) {
423 WRITE_WARNINGF(TL("Internal routes receive an ID starting with '!' and must not be referenced in other vehicle or flow definitions. Please remove all references to route '%' in case it is internal."), routeID);
424 }
425 ret->routeid = routeID;
426 if (ok) {
427 ret->parametersSet |= VEHPARS_ROUTE_SET; // !!! needed?
428 } else {
429 handleVehicleError(true, ret);
430 }
431 }
432 // parse type information
433 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
434 bool ok = true;
435 ret->vtypeid = attrs.get<std::string>(SUMO_ATTR_TYPE, ret->id.c_str(), ok);
436 if (ok) {
437 ret->parametersSet |= VEHPARS_VTYPE_SET; // !!! needed?
438 } else {
439 handleVehicleError(true, ret);
440 }
441 }
442 // parse line information
443 if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
444 bool ok = true;
445 ret->line = attrs.get<std::string>(SUMO_ATTR_LINE, ret->id.c_str(), ok);
446 if (ok) {
447 ret->parametersSet |= VEHPARS_LINE_SET; // !!! needed?
448 } else {
449 handleVehicleError(true, ret);
450 }
451 }
452 // parse zone information
453 if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) {
454 bool ok = true;
455 ret->fromTaz = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, ret->id.c_str(), ok);
456 if (ok) {
458 } else {
459 handleVehicleError(true, ret);
460 }
461 }
462 if (attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
463 bool ok = true;
464 ret->toTaz = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, ret->id.c_str(), ok);
465 if (ok) {
467 } else {
468 handleVehicleError(true, ret);
469 }
470 }
471 // parse reroute information
472 if (attrs.hasAttribute(SUMO_ATTR_REROUTE)) {
473 bool ok = true;
474 if (attrs.get<bool>(SUMO_ATTR_REROUTE, ret->id.c_str(), ok)) {
475 if (ok) {
477 } else {
478 handleVehicleError(true, ret);
479 }
480 }
481 }
482 // parse depart lane information
484 bool ok = true;
485 const std::string departLaneStr = attrs.get<std::string>(SUMO_ATTR_DEPARTLANE, ret->id.c_str(), ok);
486 int lane;
488 std::string error;
489 if (SUMOVehicleParameter::parseDepartLane(departLaneStr, element, ret->id, lane, dld, error)) {
491 ret->departLane = lane;
492 ret->departLaneProcedure = dld;
493 } else {
494 handleVehicleError(true, ret, error);
495 }
496 }
497 // parse depart position information
499 bool ok = true;
500 const std::string departPosStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS, ret->id.c_str(), ok);
501 double pos;
503 std::string error;
504 if (SUMOVehicleParameter::parseDepartPos(departPosStr, element, ret->id, pos, dpd, error)) {
506 ret->departPos = pos;
507 ret->departPosProcedure = dpd;
508 } else {
509 handleVehicleError(true, ret, error);
510 }
511 }
512 // parse lateral depart position information
514 bool ok = true;
515 const std::string departPosLatStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS_LAT, ret->id.c_str(), ok);
516 double pos;
518 std::string error;
519 if (SUMOVehicleParameter::parseDepartPosLat(departPosLatStr, element, ret->id, pos, dpd, error)) {
521 ret->departPosLat = pos;
522 ret->departPosLatProcedure = dpd;
523 } else {
524 handleVehicleError(true, ret, error);
525 }
526 }
527 // parse depart speed information
529 bool ok = true;
530 const std::string departSpeed = attrs.get<std::string>(SUMO_ATTR_DEPARTSPEED, ret->id.c_str(), ok);
531 double speed;
533 std::string error;
534 if (SUMOVehicleParameter::parseDepartSpeed(departSpeed, element, ret->id, speed, dsd, error)) {
536 ret->departSpeed = speed;
537 ret->departSpeedProcedure = dsd;
538 } else {
539 handleVehicleError(true, ret, error);
540 }
541 }
542 // parse depart edge information
544 bool ok = true;
545 const std::string departEdgeStr = attrs.get<std::string>(SUMO_ATTR_DEPARTEDGE, ret->id.c_str(), ok);
546 int edgeIndex;
548 std::string error;
549 if (SUMOVehicleParameter::parseRouteIndex(departEdgeStr, element, ret->id, SUMO_ATTR_DEPARTEDGE, edgeIndex, rid, error)) {
551 ret->departEdge = edgeIndex;
552 ret->departEdgeProcedure = rid;
553 } else {
554 handleVehicleError(true, ret, error);
555 }
556 }
557 // parse arrival lane information
559 bool ok = true;
560 const std::string arrivalLaneStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALLANE, ret->id.c_str(), ok);
561 int lane;
563 std::string error;
564 if (SUMOVehicleParameter::parseArrivalLane(arrivalLaneStr, element, ret->id, lane, ald, error)) {
566 ret->arrivalLane = lane;
567 ret->arrivalLaneProcedure = ald;
568 } else {
569 handleVehicleError(true, ret, error);
570 }
571 }
572 // parse arrival position information
574 bool ok = true;
575 const std::string arrivalPosStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, ret->id.c_str(), ok);
576 double pos;
578 std::string error;
579 if (SUMOVehicleParameter::parseArrivalPos(arrivalPosStr, element, ret->id, pos, apd, error)) {
581 ret->arrivalPos = pos;
582 ret->arrivalPosProcedure = apd;
583 } else {
584 handleVehicleError(true, ret, error);
585 }
586 }
587 // parse lateral arrival position information
589 bool ok = true;
590 const std::string arrivalPosLatStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS_LAT, ret->id.c_str(), ok);
591 double pos;
593 std::string error;
594 if (SUMOVehicleParameter::parseArrivalPosLat(arrivalPosLatStr, element, ret->id, pos, apd, error)) {
596 ret->arrivalPosLat = pos;
597 ret->arrivalPosLatProcedure = apd;
598 } else {
599 handleVehicleError(true, ret, error);
600 }
601 }
602 // parse arrival speed information
604 bool ok = true;
605 std::string arrivalSpeedStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALSPEED, ret->id.c_str(), ok);
606 double speed;
608 std::string error;
609 if (SUMOVehicleParameter::parseArrivalSpeed(arrivalSpeedStr, element, ret->id, speed, asd, error)) {
611 ret->arrivalSpeed = speed;
612 ret->arrivalSpeedProcedure = asd;
613 } else {
614 handleVehicleError(true, ret, error);
615 }
616 }
617 // parse arrival edge information
619 bool ok = true;
620 std::string arrivalEdgeStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALEDGE, ret->id.c_str(), ok);
621 int edgeIndex;
623 std::string error;
624 if (SUMOVehicleParameter::parseRouteIndex(arrivalEdgeStr, element, ret->id, SUMO_ATTR_ARRIVALEDGE, edgeIndex, rid, error)) {
626 ret->arrivalEdge = edgeIndex;
627 ret->arrivalEdgeProcedure = rid;
628 } else {
629 handleVehicleError(true, ret, error);
630 }
631 }
632 // parse color
633 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
634 bool ok = true;
635 ret->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, ret->id.c_str(), ok);
636 if (ok) {
638 } else {
639 handleVehicleError(true, ret, "Invalid RGBColor format");
640 }
641 } else {
643 }
644 // parse person number
646 bool ok = true;
647 int personNumber = attrs.get<int>(SUMO_ATTR_PERSON_NUMBER, ret->id.c_str(), ok);
648 if (!ok) {
649 handleVehicleError(true, ret);
650 } else if (personNumber >= 0) {
652 ret->personNumber = personNumber;
653 } else {
654 handleVehicleError(true, ret, toString(SUMO_ATTR_PERSON_NUMBER) + " cannot be negative");
655 }
656 }
657 // parse container number
659 bool ok = true;
660 int containerNumber = attrs.get<int>(SUMO_ATTR_CONTAINER_NUMBER, ret->id.c_str(), ok);
661 if (!ok) {
662 handleVehicleError(true, ret);
663 } else if (containerNumber >= 0) {
665 ret->containerNumber = containerNumber;
666 } else {
667 handleVehicleError(true, ret, toString(SUMO_ATTR_CONTAINER_NUMBER) + " cannot be negative");
668 }
669 }
670 // parse individual speedFactor
672 bool ok = true;
673 double speedFactor = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR, ret->id.c_str(), ok);
674 if (!ok) {
675 handleVehicleError(true, ret);
676 } else if (speedFactor > 0) {
678 ret->speedFactor = speedFactor;
679 } else {
680 handleVehicleError(true, ret, toString(SUMO_ATTR_SPEEDFACTOR) + " must be positive");
681 }
682 }
683 // parse insertion checks
686 bool ok = true;
687 std::string checks = attrs.get<std::string>(SUMO_ATTR_INSERTIONCHECKS, ret->id.c_str(), ok);
688 if (!ok) {
689 handleVehicleError(true, ret);
690 } else {
691 try {
693 } catch (InvalidArgument& e) {
694 handleVehicleError(true, ret, e.what());
695 }
696 }
697 }
698 // parse parking access rights
700 bool ok = true;
701 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, ret->id.c_str(), ok);
702 if (!ok) {
703 handleVehicleError(true, ret);
704 } else {
706 ret->parkingBadges = badges;
707 }
708 }
709 // parse modes (transportables only)
710 ret->modes = 0;
711 if (attrs.hasAttribute(SUMO_ATTR_MODES)) {
712 bool ok = true;
713 const std::string modeString = attrs.get<std::string>(SUMO_ATTR_MODES, ret->id.c_str(), ok);
714 if (!ok) {
715 handleVehicleError(true, ret);
716 } else {
717 std::string errorMsg;
718 if (!SUMOVehicleParameter::parsePersonModes(modeString, toString(tag), ret->id, ret->modes, errorMsg)) {
719 handleVehicleError(true, ret, errorMsg);
720 }
721 }
722 }
723 // parse usable vehicle types (transportables only)
724 if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
725 bool ok = true;
726 ret->vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, ret->id.c_str(), ok);
727 if (!ok) {
728 handleVehicleError(true, ret);
729 }
730 }
731 // parse speed (only used by calibrators flow)
732 // also used by vehicle in saved state but this is parsed elsewhere
733 if (tag == SUMO_TAG_FLOW && attrs.hasAttribute(SUMO_ATTR_SPEED)) {
734 bool ok = true;
735 double calibratorSpeed = attrs.get<double>(SUMO_ATTR_SPEED, ret->id.c_str(), ok);
736 if (!ok) {
737 handleVehicleError(true, ret);
738 } else if (calibratorSpeed >= 0 || calibratorSpeed == -1) {
740 ret->calibratorSpeed = calibratorSpeed;
741 } else {
742 handleVehicleError(true, ret, toString(SUMO_ATTR_SPEED) + " may not be negative");
743 }
744 }
745 /*/ parse via
746 if (attrs.hasAttribute(SUMO_ATTR_VIA)) {
747 ret->setParameter |= VEHPARS_VIA_SET;
748 SUMOSAXAttributes::parseStringVector(attrs.get<std::string>(SUMO_ATTR_VIA, ret->id.c_str(), ok), ret->via);
749 }
750 */
751}
752
753
755SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const bool hardFail, const std::string& file, const SUMOVTypeParameter* const base) {
756 const std::string id = (attrs.hasAttribute(SUMO_ATTR_ID) || base == nullptr) ? parseID(attrs, SUMO_TAG_VTYPE) : "";
757 if (!id.empty()) {
758 // create vType
759 SUMOVehicleClass vClass = base == nullptr ? SVC_PASSENGER : base->vehicleClass;
760 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
761 vClass = parseVehicleClass(attrs, id);
762 }
763 SUMOVTypeParameter* vType;
764 if (base == nullptr) {
765 vType = new SUMOVTypeParameter(id, vClass);
766 } else {
767 vType = new SUMOVTypeParameter(*base);
768 vType->id = id;
769 vType->vehicleClass = vClass;
770 }
771 // parse attributes
772 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
774 }
775 if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
776 bool ok = true;
777 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, vType->id.c_str(), ok);
778 if (!ok) {
779 return handleVehicleTypeError(hardFail, vType);
780 } else if (length <= 0) {
781 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LENGTH) + " must be greater than 0");
782 } else {
783 vType->length = length;
785 }
786 }
787 if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
788 bool ok = true;
789 const double minGap = attrs.get<double>(SUMO_ATTR_MINGAP, vType->id.c_str(), ok);
790 if (!ok) {
791 return handleVehicleTypeError(hardFail, vType);
792 } else if (minGap < 0) {
793 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP) + " must be equal or greater than 0");
794 } else {
795 vType->minGap = minGap;
797 }
798 }
799 if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
800 bool ok = true;
801 const double maxSpeed = attrs.get<double>(SUMO_ATTR_MAXSPEED, vType->id.c_str(), ok);
802 if (!ok) {
803 return handleVehicleTypeError(hardFail, vType);
804 } else if (maxSpeed <= 0) {
805 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED) + " must be greater than 0");
806 } else {
807 vType->maxSpeed = maxSpeed;
809 }
810 }
812 bool ok = true;
813 const double desiredMaxSpeed = attrs.get<double>(SUMO_ATTR_DESIRED_MAXSPEED, vType->id.c_str(), ok);
814 if (!ok) {
815 return handleVehicleTypeError(hardFail, vType);
816 } else if (desiredMaxSpeed <= 0) {
817 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_DESIRED_MAXSPEED) + " must be greater than 0");
818 } else {
819 vType->desiredMaxSpeed = desiredMaxSpeed;
821 }
822 } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
823 if (vClass == SVC_PEDESTRIAN) {
824 // backward compatibility because pedestrian maxSpeed was subject to speedFactor up to 1.14.1
825 vType->desiredMaxSpeed = vType->maxSpeed;;
827 } else if (vClass == SVC_BICYCLE) {
828 // backward compatibility because default desired speed did not exist up to 1.14.1
829 vType->desiredMaxSpeed = MAX2(vType->maxSpeed, vType->desiredMaxSpeed);
830 }
831 }
832
834 bool ok = true;
835 vType->speedFactor.parse(attrs.get<std::string>(SUMO_ATTR_SPEEDFACTOR, vType->id.c_str(), ok), hardFail);
836 if (!ok) {
837 return handleVehicleTypeError(hardFail, vType);
838 } else {
840 }
841 }
842 if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
843 bool ok = true;
844 const double speedDev = attrs.get<double>(SUMO_ATTR_SPEEDDEV, vType->id.c_str(), ok);
845 if (!ok) {
846 return handleVehicleTypeError(hardFail, vType);
847 } else if (speedDev < 0) {
848 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SPEEDDEV) + " must be equal or greater than 0");
849 } else {
850 vType->speedFactor.setParameter(1, speedDev);
852 }
853 }
854 // validate speed distribution
855 const std::string& error = vType->speedFactor.isValid();
856 if (error != "") {
857 return handleVehicleTypeError(hardFail, vType, "Invalid speed distribution when parsing vType '" + vType->id + "' (" + error + ")");
858 }
860 bool ok = true;
861 const double actionStepLengthSecs = attrs.get<double>(SUMO_ATTR_ACTIONSTEPLENGTH, vType->id.c_str(), ok);
862 if (!ok) {
863 return handleVehicleTypeError(hardFail, vType);
864 } else {
865 // processActionStepLength(...) function includes warnings
866 vType->actionStepLength = processActionStepLength(actionStepLengthSecs);
868 }
869 }
871 bool ok = true;
872 const std::string parsedEmissionClass = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
873 // check if emission class is correct
874 try {
875 vType->emissionClass = PollutantsInterface::getClassByName(parsedEmissionClass);
877 } catch (...) {
878 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_EMISSIONCLASS) + " with name '" + parsedEmissionClass + "' doesn't exist.");
879 }
880 }
881 if (attrs.hasAttribute(SUMO_ATTR_MASS)) {
882 bool ok = true;
883 const double mass = attrs.get<double>(SUMO_ATTR_MASS, vType->id.c_str(), ok);
884 if (!ok) {
885 return handleVehicleTypeError(hardFail, vType);
886 } else if (mass < 0) {
887 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MASS) + " must be equal or greater than 0");
888 } else {
889 vType->mass = mass;
891 }
892 }
894 bool ok = true;
895 const std::string impatienceStr = attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
896 if (!ok) {
897 return handleVehicleTypeError(hardFail, vType);
898 } else if (impatienceStr == "off") {
899 vType->impatience = -std::numeric_limits<double>::max();
900 } else {
901 const double impatienceDouble = attrs.get<double>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
902 if (!ok) {
903 return handleVehicleTypeError(hardFail, vType);
904 } else {
905 vType->impatience = impatienceDouble;
907 }
908 }
909 }
910 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
911 bool ok = true;
912 const double width = attrs.get<double>(SUMO_ATTR_WIDTH, vType->id.c_str(), ok);
913 if (!ok) {
914 return handleVehicleTypeError(hardFail, vType);
915 } else if (width <= 0) {
916 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_WIDTH) + " must be greater than 0");
917 } else {
918 vType->width = width;
920 if (vClass == SVC_PEDESTRIAN
921 && OptionsCont::getOptions().exists("pedestrian.striping.stripe-width")
922 && OptionsCont::getOptions().getString("pedestrian.model") == "striping"
923 && OptionsCont::getOptions().getFloat("pedestrian.striping.stripe-width") < vType->width) {
924 WRITE_WARNINGF(TL("Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."), id, vType->width);
925 }
926 }
927 }
928 if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
929 bool ok = true;
930 const double height = attrs.get<double>(SUMO_ATTR_HEIGHT, vType->id.c_str(), ok);
931 if (!ok) {
932 return handleVehicleTypeError(hardFail, vType);
933 } else if (height < 0) {
934 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_HEIGHT) + " must be equal or greater than 0");
935 } else {
936 vType->height = height;
938 }
939 }
940 if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
941 vType->shape = parseGuiShape(attrs, vType->id);
942 if (vType->shape != SUMOVehicleShape::UNKNOWN) {
944 }
945 }
946 if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
947 bool ok = true;
948 const std::string osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vType->id.c_str(), ok);
949 if (!ok) {
950 return handleVehicleTypeError(hardFail, vType);
951 } else {
952 vType->osgFile = osgFile;
954 }
955 }
956 if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
957 bool ok = true;
958 std::string imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vType->id.c_str(), ok);
959 if (!ok) {
960 return handleVehicleTypeError(hardFail, vType);
961 } else {
962 // check relative path
963 if ((imgFile != "") && !FileHelpers::isAbsolute(imgFile)) {
964 imgFile = FileHelpers::getConfigurationRelative(file, imgFile);
965 }
966 vType->imgFile = imgFile;
968 }
969 }
970 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
971 bool ok = true;
972 const RGBColor color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vType->id.c_str(), ok);
973 if (!ok) {
974 return handleVehicleTypeError(hardFail, vType);
975 } else {
976 vType->color = color;
978 }
979 } else {
980 vType->color = RGBColor::YELLOW;
981 }
982 if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
983 bool ok = true;
984 const double defaultProbability = attrs.get<double>(SUMO_ATTR_PROB, vType->id.c_str(), ok);
985 if (!ok) {
986 return handleVehicleTypeError(hardFail, vType);
987 } else if (defaultProbability < 0) {
988 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PROB) + " must be equal or greater than 0");
989 } else {
990 vType->defaultProbability = defaultProbability;
992 }
993 }
995 bool ok = true;
996 std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vType->id.c_str(), ok);
997 if (!ok) {
998 return handleVehicleTypeError(hardFail, vType);
999 } else if (lcmS == "JE2013") {
1000 WRITE_WARNING(TL("Lane change model 'JE2013' is deprecated. Using default model instead."));
1001 lcmS = "default";
1002 }
1003 if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
1006 } else {
1007 return handleVehicleTypeError(hardFail, vType, "Unknown lane change model '" + lcmS + "' when parsing vType '" + vType->id + "'");
1008 }
1009 }
1011 bool ok = true;
1012 const std::string cfmValue = attrs.get<std::string>(SUMO_ATTR_CAR_FOLLOW_MODEL, vType->id.c_str(), ok);
1013 if (!ok) {
1014 return handleVehicleTypeError(hardFail, vType);
1015 } else if (SUMOXMLDefinitions::CarFollowModels.hasString(cfmValue)) {
1018 } else {
1019 return handleVehicleTypeError(hardFail, vType, "Unknown car following model '" + cfmValue + "' when parsing vType '" + vType->id + "'");
1020 }
1021 }
1023 bool ok = true;
1024 const int personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, vType->id.c_str(), ok);
1025 if (!ok) {
1026 return handleVehicleTypeError(hardFail, vType);
1027 } else if (personCapacity < 0) {
1028 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PERSON_CAPACITY) + " must be equal or greater than 0");
1029 } else {
1030 vType->personCapacity = personCapacity;
1032 }
1033 }
1035 bool ok = true;
1036 const int containerCapacity = attrs.get<int>(SUMO_ATTR_CONTAINER_CAPACITY, vType->id.c_str(), ok);
1037 if (!ok) {
1038 return handleVehicleTypeError(hardFail, vType);
1039 } else if (containerCapacity < 0) {
1040 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_CONTAINER_CAPACITY) + " must be equal or greater than 0");
1041 } else {
1042 vType->containerCapacity = containerCapacity;
1044 }
1045 }
1047 bool ok = true;
1048 const SUMOTime boardingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_BOARDING_DURATION, vType->id.c_str(), ok);
1049 if (!ok) {
1050 return handleVehicleTypeError(hardFail, vType);
1051 } else if (boardingDuration < 0) {
1052 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_DURATION) + " must be equal or greater than 0");
1053 } else {
1054 vType->boardingDuration = boardingDuration;
1056 }
1057 }
1059 bool ok = true;
1060 const SUMOTime loadingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_LOADING_DURATION, vType->id.c_str(), ok);
1061 if (!ok) {
1062 return handleVehicleTypeError(hardFail, vType);
1063 } else if (loadingDuration < 0) {
1064 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LOADING_DURATION) + " must be equal or greater than 0");
1065 } else {
1066 vType->loadingDuration = loadingDuration;
1068 }
1069 }
1070 if (attrs.hasAttribute(SUMO_ATTR_SCALE)) {
1071 bool ok = true;
1072 const double scale = attrs.get<double>(SUMO_ATTR_SCALE, id.c_str(), ok);
1073 if (!ok) {
1074 return handleVehicleTypeError(hardFail, vType);
1075 } else if (scale < 0) {
1076 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SCALE) + " may be not be negative");
1077 } else {
1078 vType->scale = scale;
1080 }
1081 }
1083 bool ok = true;
1084 const SUMOTime ttt = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT, vType->id.c_str(), ok);
1085 if (!ok) {
1086 return handleVehicleTypeError(hardFail, vType);
1087 } else {
1088 vType->timeToTeleport = ttt;
1090 }
1091 }
1093 bool ok = true;
1094 const SUMOTime tttb = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT_BIDI, vType->id.c_str(), ok);
1095 if (!ok) {
1096 return handleVehicleTypeError(hardFail, vType);
1097 } else {
1098 vType->timeToTeleportBidi = tttb;
1100 }
1101 }
1103 bool ok = true;
1104 const double sfp = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR_PREMATURE, id.c_str(), ok);
1105 if (!ok) {
1106 return handleVehicleTypeError(hardFail, vType);
1107 } else {
1108 vType->speedFactorPremature = sfp;
1110 }
1111 }
1113 bool ok = true;
1114 const double bf = attrs.get<double>(SUMO_ATTR_BOARDING_FACTOR, id.c_str(), ok);
1115 if (!ok) {
1116 return handleVehicleTypeError(hardFail, vType);
1117 } else if (bf < 0) {
1118 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_FACTOR) + " must be equal or greater than 0");
1119 } else {
1120 vType->boardingFactor = bf;
1122 }
1123 }
1125 bool ok = true;
1126 const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1127 if (!ok) {
1128 return handleVehicleTypeError(hardFail, vType);
1129 } else if (maxSpeedLat <= 0) {
1130 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1131 } else {
1132 vType->maxSpeedLat = maxSpeedLat;
1134 }
1135 }
1137 bool ok = true;
1138 const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1139 if (!ok) {
1140 return handleVehicleTypeError(hardFail, vType);
1141 } else if (minGapLat < 0) {
1142 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1143 } else {
1144 vType->minGapLat = minGapLat;
1146 }
1147 }
1149 bool ok = true;
1150 const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1151 if (!ok) {
1152 return handleVehicleTypeError(hardFail, vType);
1153 } else {
1154 double lao;
1156 if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1157 vType->latAlignmentOffset = lao;
1158 vType->latAlignmentProcedure = lad;
1160 } else {
1161 return handleVehicleTypeError(hardFail, vType, "Unknown lateral alignment '" + alignS + "' when parsing vType '" + vType->id + "';\n must be one of (\"right\", \"center\", \"arbitrary\", \"nice\", \"compact\", \"left\" or a float)");
1162 }
1163 }
1164 }
1166 bool ok = true;
1167 const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1168 if (!ok) {
1169 return handleVehicleTypeError(hardFail, vType);
1170 } else if (parseAngleTimesMap(vType, angleTimesS)) {
1172 } else {
1173 return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1174 }
1175 }
1177 bool ok = true;
1178 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1179 if (!ok) {
1180 return handleVehicleTypeError(hardFail, vType);
1181 } else {
1183 vType->parkingBadges = badges;
1184 }
1185 }
1186 // try to parse Car Following Model params
1187 if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1188 return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1189 }
1190 // try to parse Lane Change Model params
1191 if (!parseLCParams(vType, vType->lcModel, attrs)) {
1192 return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1193 }
1194 // try to Junction Model params
1195 if (!parseJMParams(vType, attrs)) {
1196 return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1197 }
1198 // all ok, then return vType
1199 return vType;
1200 } else if (base != nullptr) {
1201 return const_cast<SUMOVTypeParameter*>(base);
1202 } else {
1203 return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1204 }
1205}
1206
1207
1208bool
1210 StringTokenizer st(atm, ",");
1211 std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1212 int tripletCount = 0;
1213 while (st.hasNext()) {
1214 StringTokenizer pos(st.next());
1215 if (pos.size() != 3) {
1216 WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1217 return false;
1218 } else {
1219 try {
1220 const int angle = StringUtils::toInt(pos.next());
1221 const SUMOTime t1 = string2time(pos.next());
1222 const SUMOTime t2 = string2time(pos.next());
1223 angleTimesMap[angle] = std::make_pair(t1, t2);
1224 } catch (...) {
1225 WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1226 return false;
1227 }
1228 tripletCount++;
1229 }
1230 }
1231 if (angleTimesMap.size() > 0) {
1232 vtype->myManoeuverAngleTimes.clear();
1233 for (const auto& angleTime : angleTimesMap) {
1234 vtype->myManoeuverAngleTimes.insert(angleTime);
1235 }
1236 angleTimesMap.clear();
1237 return true;
1238 } else {
1239 return false;
1240 }
1241}
1242
1243
1244bool
1245SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1246 const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1247 CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1248 // check if given CFM is allowed
1249 if (cf_it == allowedCFM.end()) {
1250 if (SUMOXMLDefinitions::Tags.has((int)element)) {
1251 WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1252 } else {
1253 WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1254 }
1255 return false;
1256 }
1257 // check if we're parsing a nested CFM
1258 if (nestedCFM) {
1259 into->cfModel = cf_it->first;
1261 }
1262 // set CFM values
1263 for (const auto& it : cf_it->second) {
1264 if (attrs.hasAttribute(it)) {
1265 // first obtain CFM attribute in string format
1266 bool ok = true;
1267 std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1268 // check CFM Attribute
1269 if (!ok) {
1270 return false;
1271 } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1272 // check if train value is valid
1273 if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1274 WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1275 return false;
1276 }
1277 // add parsedCFMAttribute to cfParameter
1278 into->cfParameter[it] = parsedCFMAttribute;
1280 into->cfParameter[it] = parsedCFMAttribute;
1281 } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1282 // declare a int in which save CFM int attribute
1283 double CFMDoubleAttribute = -1;
1284 try {
1285 // obtain CFM attribute in int format
1286 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1287 } catch (...) {
1288 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1289 return false;
1290 }
1291 if (CFMDoubleAttribute <= 0) {
1292 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1293 return false;
1294 }
1295 // add parsedCFMAttribute to cfParameter
1296 into->cfParameter[it] = parsedCFMAttribute;
1297 } else if (it == SUMO_ATTR_MAXACCEL_PROFILE || it == SUMO_ATTR_DESACCEL_PROFILE) {
1298 if (validProfile(into, parsedCFMAttribute, it)) {
1299 into->cfParameter[it] = parsedCFMAttribute;
1300 } else {
1301 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed as a vector of <speed accel> pairs"), toString(it));
1302 return false;
1303 }
1304 } else {
1305 // declare a double in which save CFM float attribute
1306 double CFMDoubleAttribute = -1;
1307 try {
1308 // obtain CFM attribute in double format
1309 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1310 } catch (...) {
1311 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1312 return false;
1313 }
1314 // check attributes of type "positiveFloatType" (> 0)
1315 switch (it) {
1316 case SUMO_ATTR_ACCEL:
1317 case SUMO_ATTR_DECEL:
1320 case SUMO_ATTR_TAU:
1321 if (CFMDoubleAttribute <= 0) {
1322 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1323 return false;
1324 }
1325 break;
1326 default:
1327 break;
1328 }
1329 // check attributes restricted to [0-1]
1330 switch (it) {
1331 case SUMO_ATTR_SIGMA:
1332 if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1333 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1334 return false;
1335 }
1336 break;
1337 default:
1338 break;
1339 }
1340 // add parsedCFMAttribute to cfParameter
1341 into->cfParameter[it] = parsedCFMAttribute;
1342 }
1343 }
1344 }
1345 // all CFM successfully parsed, then return true
1346 return true;
1347}
1348
1349
1352 // init on first use
1353 if (allowedCFModelAttrs.size() == 0) {
1354 std::set<SumoXMLAttr> genericParams;
1355 genericParams.insert(SUMO_ATTR_TAU);
1356 genericParams.insert(SUMO_ATTR_ACCEL);
1357 genericParams.insert(SUMO_ATTR_DECEL);
1358 genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1359 genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1360 genericParams.insert(SUMO_ATTR_SPEED_TABLE);
1361 genericParams.insert(SUMO_ATTR_MAXACCEL_PROFILE);
1362 genericParams.insert(SUMO_ATTR_DESACCEL_PROFILE);
1363 genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1364 genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1365 // Krauss
1366 std::set<SumoXMLAttr> kraussParams(genericParams);
1367 kraussParams.insert(SUMO_ATTR_SIGMA);
1368 kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1372 std::set<SumoXMLAttr> allParams(kraussParams);
1373 // KraussX
1374 std::set<SumoXMLAttr> kraussXParams(kraussParams);
1375 kraussXParams.insert(SUMO_ATTR_TMP1);
1376 kraussXParams.insert(SUMO_ATTR_TMP2);
1377 kraussXParams.insert(SUMO_ATTR_TMP3);
1378 kraussXParams.insert(SUMO_ATTR_TMP4);
1379 kraussXParams.insert(SUMO_ATTR_TMP5);
1381 allParams.insert(kraussXParams.begin(), kraussXParams.end());
1382 // SmartSK
1383 std::set<SumoXMLAttr> smartSKParams(genericParams);
1384 smartSKParams.insert(SUMO_ATTR_SIGMA);
1385 smartSKParams.insert(SUMO_ATTR_TMP1);
1386 smartSKParams.insert(SUMO_ATTR_TMP2);
1387 smartSKParams.insert(SUMO_ATTR_TMP3);
1388 smartSKParams.insert(SUMO_ATTR_TMP4);
1389 smartSKParams.insert(SUMO_ATTR_TMP5);
1391 allParams.insert(smartSKParams.begin(), smartSKParams.end());
1392 // Daniel
1393 std::set<SumoXMLAttr> daniel1Params(genericParams);
1394 daniel1Params.insert(SUMO_ATTR_SIGMA);
1395 daniel1Params.insert(SUMO_ATTR_TMP1);
1396 daniel1Params.insert(SUMO_ATTR_TMP2);
1397 daniel1Params.insert(SUMO_ATTR_TMP3);
1398 daniel1Params.insert(SUMO_ATTR_TMP4);
1399 daniel1Params.insert(SUMO_ATTR_TMP5);
1401 allParams.insert(daniel1Params.begin(), daniel1Params.end());
1402 // Peter Wagner
1403 std::set<SumoXMLAttr> pwagParams(genericParams);
1404 pwagParams.insert(SUMO_ATTR_SIGMA);
1405 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1406 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1408 allParams.insert(pwagParams.begin(), pwagParams.end());
1409 // IDM params
1410 std::set<SumoXMLAttr> idmParams(genericParams);
1411 idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1412 idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1414 allParams.insert(idmParams.begin(), idmParams.end());
1415 // EIDM
1416 std::set<SumoXMLAttr> eidmParams(genericParams);
1417 eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1418 eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1419 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1420 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1421 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1423 eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1424 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1425 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1426 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1427 eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1428 eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1429 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1430 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1431 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1432 eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1433 eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1435 allParams.insert(eidmParams.begin(), eidmParams.end());
1436 // IDMM
1437 std::set<SumoXMLAttr> idmmParams(genericParams);
1438 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1439 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1440 idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1442 allParams.insert(idmmParams.begin(), idmmParams.end());
1443 // Bieker
1444 std::set<SumoXMLAttr> bkernerParams(genericParams);
1445 bkernerParams.insert(SUMO_ATTR_K);
1446 bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1448 allParams.insert(bkernerParams.begin(), bkernerParams.end());
1449 // Wiedemann
1450 std::set<SumoXMLAttr> wiedemannParams(genericParams);
1451 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1452 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1453 allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1454 allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1455 // W99
1456 std::set<SumoXMLAttr> w99Params(genericParams);
1457 w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1458 w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1459 w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1460 w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1461 w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1462 w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1463 w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1464 w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1465 w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1467 allParams.insert(w99Params.begin(), w99Params.end());
1468 // Rail
1469 std::set<SumoXMLAttr> railParams(genericParams);
1470 railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1471 railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1472 railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1473 railParams.insert(SUMO_ATTR_MASSFACTOR);
1474 railParams.insert(SUMO_ATTR_MAXPOWER);
1475 railParams.insert(SUMO_ATTR_MAXTRACTION);
1477 railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1479 railParams.insert(SUMO_ATTR_CURVE_RESISTANCE);
1480 railParams.insert(SUMO_ATTR_CURVE_INTEGRATION);
1481 railParams.insert(SUMO_ATTR_ROECKL_SHARP_RADIUS);
1482 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR);
1483 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR_SHARP);
1484 railParams.insert(SUMO_ATTR_ROECKL_OFFSET);
1485 railParams.insert(SUMO_ATTR_ROECKL_OFFSET_SHARP);
1487 allParams.insert(railParams.begin(), railParams.end());
1488 // ACC
1489 std::set<SumoXMLAttr> ACCParams(genericParams);
1490 ACCParams.insert(SUMO_ATTR_SC_GAIN);
1491 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1492 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1493 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1494 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1495 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1496 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1497 ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1498 ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1500 allParams.insert(ACCParams.begin(), ACCParams.end());
1501 // CACC
1502 std::set<SumoXMLAttr> CACCParams(genericParams);
1503 CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1504 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1505 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1506 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1507 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1508 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1509 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1510 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1511 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1512 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1513 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1514 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1515 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1516 CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1517 CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1518 CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1519 CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1521 allParams.insert(CACCParams.begin(), CACCParams.end());
1522 // CC
1523 std::set<SumoXMLAttr> ccParams(genericParams);
1524 ccParams.insert(SUMO_ATTR_CF_CC_C1);
1525 ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1526 ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1527 ccParams.insert(SUMO_ATTR_CF_CC_KP);
1528 ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1529 ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1530 ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1531 ccParams.insert(SUMO_ATTR_CF_CC_XI);
1532 ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1533 ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1534 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1535 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1536 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1537 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1538 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1539 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1540 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1541 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1543 allParams.insert(ccParams.begin(), ccParams.end());
1544 // NaSch
1545 std::set<SumoXMLAttr> naschParams(genericParams);
1546 naschParams.insert(SUMO_ATTR_SIGMA);
1548 allParams.insert(naschParams.begin(), naschParams.end());
1549 // last element
1551 }
1552 return allowedCFModelAttrs;
1553}
1554
1555
1556bool
1558 if (allowedLCModelAttrs.size() == 0) {
1559 // lc2013
1560 std::set<SumoXMLAttr> lc2013Params;
1561 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1562 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1563 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1564 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1565 lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1566 lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1567 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1568 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1569 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1570 lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1571 lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1572 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD);
1573 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1574 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME);
1575 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_URGENCY);
1576 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1577 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1578 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_HELPTIME);
1579 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_HELPTHRESHOLD);
1580 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_MINSPEED);
1581 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1582 lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1583 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1584 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1585 lc2013Params.insert(SUMO_ATTR_LCA_CONTRIGHT);
1586 lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1588 // sl2015 (extension of lc2013)
1589 std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1590 sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1591 sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1592 sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1593 sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1594 sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1595 sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1596 sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1597 sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1599 // DK2008
1600 std::set<SumoXMLAttr> noParams;
1602 // default model may be either LC2013 or SL2015
1603 // we allow both sets (sl2015 is a superset of lc2013Params)
1605 }
1606 std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1607 // iterate over LCM attributes
1608 for (const auto& it : allowed) {
1609 if (attrs.hasAttribute(it)) {
1610 // first obtain CFM attribute in string format
1611 bool ok = true;
1612 std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1613 if (!ok) {
1614 return false;
1615 }
1616 // declare a double in which save CFM attribute
1617 double LCMAttribute = -1;
1618 try {
1619 // obtain CFM attribute in double format
1620 LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1621 } catch (...) {
1622 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1623 return false;
1624 }
1625 // check attributes of type "nonNegativeFloatType" (>= 0)
1626 switch (it) {
1638 if (LCMAttribute < 0) {
1639 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1640 return false;
1641 }
1642 break;
1643 default:
1644 break;
1645 }
1646 // check attributes of type "positiveFloatType" (> 0)
1647 switch (it) {
1649 if (LCMAttribute <= 0) {
1650 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1651 return false;
1652 }
1653 break;
1654 default:
1655 break;
1656 }
1657 // check limits of attributes
1658 switch (it) {
1660 if (LCMAttribute < -1 || LCMAttribute > 1) {
1661 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1662 return false;
1663 }
1664 break;
1665 default:
1666 break;
1667 }
1668 // add parsedLCMAttribute to cfParameter
1669 into->lcParameter[it] = parsedLCMAttribute;
1670 }
1671 }
1672 // all LCM parsed ok, then return true
1673 return true;
1674}
1675
1676
1677bool
1679 for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1680 if (attrs.hasAttribute(it)) {
1681 // first obtain CFM attribute in string format
1682 bool ok = true;
1683 std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1684 if (!ok) {
1685 return false;
1686 }
1687 // declare a double in which save CFM attribute
1688 double JMAttribute = INVALID_DOUBLE;
1689 try {
1690 // obtain CFM attribute in double format
1691 JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1692 } catch (...) {
1693 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1694 return false;
1695 }
1696 // now continue checking other properties (-1 is the default value)
1697 if (JMAttribute != INVALID_DOUBLE) {
1698 // special case for sigma minor
1699 if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1700 // check attributes sigma minor
1701 if ((JMAttribute < 0) || (JMAttribute > 1)) {
1702 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1703 return false;
1704 }
1705 } else if (JMAttribute < 0
1707 && it != SUMO_ATTR_JM_EXTRA_GAP) {
1708 // attributes with error value
1709 if (JMAttribute != -1 || (it != SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
1712 // check attributes of type "nonNegativeFloatType" (>= 0)
1713 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1714 return false;
1715 }
1716 }
1717 // add parsedJMAttribute to cfParameter
1718 into->jmParameter[it] = parsedJMAttribute;
1719 }
1720 }
1721 }
1722 // all JM parameters successfully parsed, then return true
1723 return true;
1724}
1725
1726
1730 bool ok = true;
1731 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1732 if (vclassS == "") {
1733 return vclass;
1734 }
1735 try {
1736 const SUMOVehicleClass result = getVehicleClassID(vclassS);
1737 const std::string& realName = SumoVehicleClassStrings.getString(result);
1738 if (realName != vclassS) {
1739 WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1740 }
1741 return result;
1742 } catch (...) {
1743 WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1744 }
1745 return vclass;
1746}
1747
1748
1750SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1751 bool ok = true;
1752 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1753 if (SumoVehicleShapeStrings.hasString(vclassS)) {
1754 const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1755 const std::string& realName = SumoVehicleShapeStrings.getString(result);
1756 if (realName != vclassS) {
1757 WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1758 }
1759 return result;
1760 } else {
1761 WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1763 }
1764}
1765
1766
1767double
1768SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1769 double result;
1770 std::string error;
1772 // only supports 'random' and 'max'
1773 if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1774 handleVehicleError(hardFail, nullptr, error);
1775 }
1776 if (proc == ArrivalPosDefinition::RANDOM) {
1777 result = RandHelper::rand(maxPos, rng);
1778 } else if (proc == ArrivalPosDefinition::CENTER) {
1779 result = maxPos / 2.;
1780 } else if (proc == ArrivalPosDefinition::MAX) {
1781 result = maxPos;
1782 }
1783 return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1784}
1785
1786
1789 const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1790 SUMOTime result = TIME2STEPS(given);
1791 if (result <= 0) {
1792 if (result < 0) {
1793 WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1794 }
1795 result = DELTA_T;
1796 } else if (result % DELTA_T != 0 && OptionsCont::getOptions().exists("step-length")) {
1797 result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1798 result = MAX2(DELTA_T, result);
1799 if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1800 WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1801 }
1802 }
1803 return result;
1804}
1805
1806
1807bool
1809 return id.substr(0, 1) == "!";
1810}
1811
1812
1813bool
1814SUMOVehicleParserHelper::validProfile(SUMOVTypeParameter* vtype, const std::string data, const SumoXMLAttr attr) {
1815 for (std::string value : StringTokenizer(data).getVector()) {
1816 try {
1817 double v = StringUtils::toDouble(value);
1818 if (v < 0.) {
1819 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. An acceleration profile value cannot be negative"), toString(attr));
1820 return false;
1821 }
1822 } catch (...) {
1823 WRITE_ERRORF(TL("Entry '%' of % table for vType '%' cannot be parsed as 'double'"), value, toString(attr), vtype->id);
1824 return false;
1825 }
1826 }
1827 return true;
1828}
1829
1830
1831int
1833 int carWalk = 0;
1834 for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) {
1835 if (opt == "parkingAreas") {
1837 } else if (opt == "ptStops") {
1838 carWalk |= ModeChangeOptions::PT_STOPS;
1839 } else if (opt == "allJunctions") {
1841 } else {
1842 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1843 }
1844 }
1845 const StringVector taxiDropoff = oc.getStringVector("persontrip.transfer.taxi-walk");
1846 const StringVector taxiPickup = oc.getStringVector("persontrip.transfer.walk-taxi");
1847 if (taxiDropoff.empty() && hasTaxi) {
1849 } else {
1850 for (const std::string& opt : taxiDropoff) {
1851 if (opt == "parkingAreas") {
1853 } else if (opt == "ptStops") {
1855 } else if (opt == "allJunctions") {
1857 } else {
1858 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1859 }
1860 }
1861 }
1862 if (taxiPickup.empty() && hasTaxi) {
1864 } else {
1865 for (const std::string& opt : taxiPickup) {
1866 if (opt == "parkingAreas") {
1868 } else if (opt == "ptStops") {
1870 } else if (opt == "allJunctions") {
1872 } else {
1873 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1874 }
1875 }
1876 }
1877 return carWalk;
1878}
1879
1880
1881bool
1883 bool ok = true;
1884 // dummy stop parameter to hold the attributes
1886 if (stopParam != nullptr) {
1887 stop = *stopParam;
1888 } else {
1889 stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
1890 stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, nullptr, ok, stop.busstop); // alias
1891 stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
1892 stop.overheadWireSegment = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, nullptr, ok, "");
1893 stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
1894 stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
1895 }
1896 if (stop.busstop != "") {
1897 tag = SUMO_TAG_BUS_STOP;
1898 id = stop.busstop;
1899 } else if (stop.containerstop != "") {
1901 id = stop.containerstop;
1902 } else if (stop.parkingarea != "") {
1904 id = stop.parkingarea;
1905 } else if (stop.chargingStation != "") {
1907 id = stop.chargingStation;
1908 } else if (stop.overheadWireSegment != "") {
1910 id = stop.overheadWireSegment;
1911 }
1912 return ok;
1913}
1914
1915
1917SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1918 if (vehicleParameter) {
1919 delete vehicleParameter;
1920 }
1921 if (hardFail) {
1922 throw ProcessError(message);
1923 } else if (message.size() > 0) {
1924 WRITE_ERROR(message);
1925 }
1926 return nullptr;
1927}
1928
1929
1931SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1932 if (vehicleTypeParameter) {
1933 delete vehicleTypeParameter;
1934 }
1935 if (hardFail) {
1936 throw ProcessError(message);
1937 } else if (message.size() > 0) {
1938 WRITE_ERROR(message);
1939 }
1940 return nullptr;
1941}
1942
1943/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ TAXI_DROPOFF_ANYWHERE
taxi customer may exit anywhere
@ PT_STOPS
public transport stops and access
@ TAXI_PICKUP_ANYWHERE
taxi customer may be picked up anywhere
@ TAXI_PICKUP_PARKING_AREAS
taxi customer may be picked up at parking areas
@ TAXI_DROPOFF_PT
taxi customer may exit at public transport stops
@ TAXI_DROPOFF_PARKING_AREAS
taxi customer may exit at parking areas
@ ALL_JUNCTIONS
junctions with edges allowing the additional mode
@ TAXI_PICKUP_PT
taxi customer may be picked up at public transport stops
@ PARKING_AREAS
parking areas
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
std::vector< std::string > StringVector
Definition of a vector of strings.
Definition Option.h:42
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:58
constexpr SUMOTime TIME2STEPS(double x)
Definition SUMOTime.h:60
#define SUMOTime_MAX
Definition SUMOTime.h:34
const long long int VTYPEPARS_TTT_SET
const long long int VTYPEPARS_SHAPE_SET
const long long int VTYPEPARS_LOADING_DURATION
const long long int VTYPEPARS_TTT_BIDI_SET
const long long int VTYPEPARS_SCALE_SET
const long long int VTYPEPARS_PERSON_CAPACITY
const long long int VTYPEPARS_CAR_FOLLOW_MODEL
const long long int VTYPEPARS_WIDTH_SET
const long long int VTYPEPARS_ACTIONSTEPLENGTH_SET
const long long int VTYPEPARS_MAXSPEED_LAT_SET
const long long int VTYPEPARS_MAXSPEED_SET
const long long int VTYPEPARS_EMISSIONCLASS_SET
const long long int VTYPEPARS_LATALIGNMENT_SET
const long long int VTYPEPARS_COLOR_SET
const long long int VTYPEPARS_LANE_CHANGE_MODEL_SET
const long long int VTYPEPARS_DESIRED_MAXSPEED_SET
const long long int VTYPEPARS_OSGFILE_SET
const long long int VTYPEPARS_MANEUVER_ANGLE_TIMES_SET
const long long int VTYPEPARS_SPEEDFACTOR_PREMATURE_SET
const long long int VTYPEPARS_SPEEDFACTOR_SET
const long long int VTYPEPARS_MINGAP_SET
const long long int VTYPEPARS_PROBABILITY_SET
const long long int VTYPEPARS_HEIGHT_SET
const long long int VTYPEPARS_PARKING_BADGES_SET
const long long int VTYPEPARS_MASS_SET
const long long int VTYPEPARS_BOARDING_DURATION
LatAlignmentDefinition
Possible ways to choose the lateral alignment, i.e., how vehicles align themselves within their lane.
const long long int VTYPEPARS_BOARDING_FACTOR_SET
const long long int VTYPEPARS_VEHICLECLASS_SET
const long long int VTYPEPARS_IMPATIENCE_SET
const long long int VTYPEPARS_LENGTH_SET
const long long int VTYPEPARS_IMGFILE_SET
const long long int VTYPEPARS_CONTAINER_CAPACITY
const long long int VTYPEPARS_MINGAP_LAT_SET
StringBijection< SUMOVehicleShape > SumoVehicleShapeStrings(sumoVehicleShapeStringInitializer, SUMOVehicleShape::UNKNOWN, false)
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
const std::string DEFAULT_PEDTYPE_ID
SUMOVehicleShape
Definition of vehicle classes to differ between different appearances.
@ UNKNOWN
not defined
const std::string DEFAULT_CONTAINERTYPE_ID
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_PEDESTRIAN
pedestrian
const long long int VEHPARS_ARRIVALSPEED_SET
const long long int VEHPARS_DEPARTPOSLAT_SET
const long long int VEHPARS_ARRIVALPOSLAT_SET
const long long int VEHPARS_PERSON_NUMBER_SET
const long long int VEHPARS_DEPARTSPEED_SET
RouteIndexDefinition
Possible ways to choose the departure and arrival edge.
const long long int VEHPARS_FORCE_REROUTE
DepartLaneDefinition
Possible ways to choose a lane on depart.
const long long int VEHPARS_END_SET
ArrivalSpeedDefinition
Possible ways to choose the arrival speed.
const long long int VEHPARS_PERIOD_SET
DepartPosLatDefinition
Possible ways to choose the lateral departure position.
DepartPosDefinition
Possible ways to choose the departure position.
const long long int VEHPARS_ROUTE_SET
ArrivalLaneDefinition
Possible ways to choose the arrival lane.
const long long int VEHPARS_COLOR_SET
DepartSpeedDefinition
Possible ways to choose the departure speed.
const long long int VEHPARS_TO_TAZ_SET
const long long int VEHPARS_ARRIVALLANE_SET
const long long int VEHPARS_DEPARTLANE_SET
const long long int VEHPARS_DEPARTPOS_SET
const long long int VEHPARS_ARRIVALPOS_SET
const long long int VEHPARS_ARRIVALEDGE_SET
const long long int VEHPARS_CONTAINER_NUMBER_SET
const long long int VEHPARS_FROM_TAZ_SET
const long long int VEHPARS_PARKING_BADGES_SET
const long long int VEHPARS_PROB_SET
const long long int VEHPARS_SPEEDFACTOR_SET
const long long int VEHPARS_VTYPE_SET
const long long int VEHPARS_VPH_SET
ArrivalPosDefinition
Possible ways to choose the arrival position.
@ RANDOM
The arrival position is chosen randomly.
@ MAX
The maximum arrival position is used.
@ DEFAULT
No information given; use default.
@ CENTER
Half the road length.
const long long int VEHPARS_CALIBRATORSPEED_SET
ArrivalPosLatDefinition
Possible ways to choose the lateral arrival position.
const long long int VEHPARS_LINE_SET
const long long int VEHPARS_DEPARTEDGE_SET
const long long int VEHPARS_INSERTION_CHECKS_SET
const long long int VEHPARS_NUMBER_SET
@ TRIGGERED
The departure is person triggered.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CF_KRAUSS
@ SUMO_TAG_CF_BKERNER
@ SUMO_TAG_CF_KRAUSSX
@ SUMO_TAG_CF_CACC
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_WALK
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_CF_CC
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_CF_KRAUSS_PLUS_SLOPE
@ SUMO_TAG_CF_IDM
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_CF_W99
@ SUMO_TAG_CF_RAIL
@ SUMO_TAG_CF_SMART_SK
@ SUMO_TAG_CF_EIDM
@ SUMO_TAG_CF_PWAGNER2009
@ SUMO_TAG_CF_KRAUSS_ORIG1
@ SUMO_TAG_CF_WIEDEMANN
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_TAG_PERSON
@ SUMO_TAG_CF_NASCH
@ SUMO_TAG_CF_IDMM
@ SUMO_TAG_CF_DANIEL1
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_CF_ACC
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_TMP4
@ SUMO_ATTR_CF_W99_CC9
@ SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_CF_EIDM_T_ACC_MAX
@ SUMO_ATTR_STARTUP_DELAY
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_CONSTANT
@ SUMO_ATTR_CF_EIDM_EPSILON_ACC
@ SUMO_ATTR_CF_W99_CC5
@ SUMO_ATTR_LCA_PUSHY
@ SUMO_ATTR_CF_CC_FLATBED_KP
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_GCC_GAIN_SPEED
@ SUMO_ATTR_ROECKL_OFFSET_SHARP
@ SUMO_ATTR_CURVE_INTEGRATION
@ SUMO_ATTR_EMISSIONCLASS
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_CF_CC_LAMBDA
@ SUMO_ATTR_DEPARTEDGE
@ SUMO_ATTR_CF_CC_FLATBED_D
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_ARRIVALEDGE
@ SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_LCA_COOPERATIVE_SPEED
@ SUMO_ATTR_RESISTANCE_TABLE
@ SUMO_ATTR_MAXACCEL_PROFILE
@ SUMO_ATTR_ROECKL_NUMERATOR_SHARP
@ SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD
@ SUMO_ATTR_CF_CC_FLATBED_KA
@ SUMO_ATTR_CF_CC_PLOEG_KP
@ SUMO_ATTR_CF_WIEDEMANN_SECURITY
@ SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_LANE_DISCIPLINE
@ SUMO_ATTR_TRAIN_TYPE
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_CF_IDMM_ADAPT_TIME
@ SUMO_ATTR_LANE_CHANGE_MODEL
@ SUMO_ATTR_CF_KERNER_PHI
@ SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE
@ SUMO_ATTR_GC_GAIN_SPACE
@ SUMO_ATTR_SCALE
@ SUMO_ATTR_DEPARTPOS_LAT
@ SUMO_ATTR_PARKING_BADGES
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_CF_EIDM_C_COOLNESS
@ SUMO_ATTR_CF_EIDM_SIG_ERROR
@ SUMO_ATTR_TRAIN_STOP
@ SUMO_ATTR_LCA_PUSHYGAP
@ SUMO_ATTR_LCA_COOPERATIVE_MINSPEED
@ SUMO_ATTR_CA_GAIN_GAP_CACC
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_APPARENTDECEL
@ SUMO_ATTR_CURVE_RESISTANCE
@ SUMO_ATTR_ROECKL_SHARP_RADIUS
@ SUMO_ATTR_MAXSPEED_LAT
@ SUMO_ATTR_GC_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_TMP3
@ SUMO_ATTR_MASSFACTOR
@ SUMO_ATTR_ACTIONSTEPLENGTH
@ SUMO_ATTR_CF_CC_PLOEG_H
@ SUMO_ATTR_LCA_MAXDISTLATSTANDING
@ SUMO_ATTR_LCA_IMPATIENCE
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_MINGAP
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_MAXTRACTION
@ SUMO_ATTR_CA_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_LCA_COOPERATIVE_HELPTIME
@ SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
@ SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC
@ SUMO_ATTR_MASS
@ SUMO_ATTR_CF_CC_OMEGAN
@ SUMO_ATTR_CONTAINER_NUMBER
@ SUMO_ATTR_CF_CC_C1
@ SUMO_ATTR_TMP2
@ SUMO_ATTR_CF_W99_CC8
@ SUMO_ATTR_CA_GAIN_SPACE
@ SUMO_ATTR_LINE
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_LOADING_DURATION
@ SUMO_ATTR_CF_IDM_DELTA
@ SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ SUMO_ATTR_LCA_MAXSPEEDLATFACTOR
@ SUMO_ATTR_MANEUVER_ANGLE_TIMES
Class specific timing values for vehicle maneuvering through angle ranges.
@ SUMO_ATTR_CF_CC_CCACCEL
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_ROECKL_NUMERATOR
@ SUMO_ATTR_CF_EIDM_T_REACTION
@ SUMO_ATTR_JM_EXTRA_GAP
@ SUMO_ATTR_MODES
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_ESTIMATE
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_MAXPOWER
@ SUMO_ATTR_CF_PWAGNER2009_TAULAST
@ SUMO_ATTR_TIME_TO_TELEPORT_BIDI
@ SUMO_ATTR_CF_CC_PLOEG_KD
@ SUMO_ATTR_CF_CC_TAU
@ SUMO_ATTR_GC_GAIN_GAP_CACC
@ SUMO_ATTR_OVERHEAD_WIRE_SEGMENT
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_CF_EIDM_SIG_GAP
@ SUMO_ATTR_CAR_FOLLOW_MODEL
@ SUMO_ATTR_CF_EIDM_JERK_MAX
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_QUADRATIC
@ SUMO_ATTR_DECEL
@ SUMO_ATTR_LCA_MAXSPEEDLATSTANDING
@ SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_GUISHAPE
@ SUMO_ATTR_DESIRED_MAXSPEED
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_PERHOUR
@ SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD
@ SUMO_ATTR_LCA_CONTRIGHT
@ SUMO_ATTR_CONTAINER_CAPACITY
@ SUMO_ATTR_CF_CC_XI
@ SUMO_ATTR_CA_OVERRIDE
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_OPPOSITE_PARAM
@ SUMO_ATTR_BOARDING_FACTOR
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_CF_CC_CCDECEL
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME
@ SUMO_ATTR_GCC_GAIN_SPACE
@ SUMO_ATTR_MINGAP_LAT
@ SUMO_ATTR_EMERGENCYDECEL
@ SUMO_ATTR_CF_CC_FLATBED_H
@ SUMO_ATTR_CF_W99_CC3
@ SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR
@ SUMO_ATTR_CF_CC_LANES_COUNT
@ SUMO_ATTR_HEIGHT
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_LCA_SUBLANE_PARAM
@ SUMO_ATTR_LCA_SIGMA
@ SUMO_ATTR_LATALIGNMENT
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_CF_IDM_STEPPING
@ SUMO_ATTR_SIGMA_STEP
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
@ SUMO_ATTR_SPEED_TABLE
@ SUMO_ATTR_IMPATIENCE
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_VCLASS
@ SUMO_ATTR_ROECKL_OFFSET
@ SUMO_ATTR_ACCEL
@ SUMO_ATTR_BOARDING_DURATION
@ SUMO_ATTR_CF_CC_CONSTSPACING
@ SUMO_ATTR_CF_EIDM_M_FLATNESS
@ SUMO_ATTR_CF_W99_CC2
@ SUMO_ATTR_CF_W99_CC4
@ SUMO_ATTR_JM_SIGMA_MINOR
@ SUMO_ATTR_CF_W99_CC6
@ SUMO_ATTR_PROB
@ SUMO_ATTR_CF_EIDM_M_BEGIN
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE
@ SUMO_ATTR_TIME_TO_TELEPORT
@ SUMO_ATTR_SPEEDFACTOR
@ SUMO_ATTR_CA_GAIN_SPEED
@ SUMO_ATTR_CF_EIDM_SIG_LEADER
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_CF_CC_KP
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_LCA_COOPERATIVE_HELPTHRESHOLD
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR
@ SUMO_ATTR_APPLYDRIVERSTATE
@ SUMO_ATTR_PERSON_NUMBER
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_CF_PWAGNER2009_APPROB
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_SIGMA
@ SUMO_ATTR_DESACCEL_PROFILE
@ SUMO_ATTR_K
@ SUMO_ATTR_TMP1
@ SUMO_ATTR_SPEEDFACTOR_PREMATURE
@ SUMO_ATTR_OSGFILE
@ SUMO_ATTR_LCA_OVERTAKE_RIGHT
@ SUMO_ATTR_ARRIVALPOS_LAT
@ SUMO_ATTR_LCA_ACCEL_LAT
@ SUMO_ATTR_CF_W99_CC7
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_TRACTION_TABLE
@ SUMO_ATTR_CF_W99_CC1
@ SUMO_ATTR_TAU
@ SUMO_ATTR_INSERTIONCHECKS
@ SUMO_ATTR_IMGFILE
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_GC_GAIN_SPEED
@ SUMO_ATTR_GCC_GAIN_GAP_CACC
@ SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME
@ SUMO_ATTR_LCA_EXPERIMENTAL1
@ SUMO_ATTR_SC_GAIN
@ SUMO_ATTR_TMP5
@ SUMO_ATTR_SC_GAIN_CACC
@ SUMO_ATTR_LCA_TIME_TO_IMPATIENCE
@ SUMO_ATTR_JM_TIMEGAP_MINOR
@ SUMO_ATTR_CF_CC_FLATBED_KV
@ SUMO_ATTR_LCA_SPEEDGAIN_URGENCY
@ SUMO_ATTR_SC_MIN_GAP
@ SUMO_ATTR_SPEEDDEV
@ SUMO_ATTR_CF_WIEDEMANN_ESTIMATION
@ SUMO_ATTR_PERSONSPERHOUR
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
void setParameter(const int index, const double value)
Set a parameter of this distribution.
const std::string isValid() const
check whether the distribution is valid
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
A storage for options typed value containers)
Definition OptionsCont.h:89
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
static const RGBColor YELLOW
Definition RGBColor.h:207
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:218
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getName(int attr) const =0
Converts the given attribute id into a man readable string.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
const std::string & getObjectType() const
return the objecttype to which these attributes belong
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
Structure representing possible vehicle parameter.
double width
This class' width.
SubParams cfParameter
Car-following parameter.
double defaultProbability
The probability when being added to a distribution without an explicit probability.
SUMOTime actionStepLength
The vehicle type's default actionStepLength [ms], i.e. the interval between two control actions....
double height
This class' height.
double desiredMaxSpeed
The vehicle type's desired maximum speed [m/s].
SUMOEmissionClass emissionClass
The emission class of this vehicle.
double latAlignmentOffset
(optional) The vehicle's desired lateral alignment as offset in m from center line
std::vector< std::string > parkingBadges
the parking access rights
static std::set< SumoXMLAttr > AllowedJMAttrs
allowed attrs for the junction model
double length
The physical vehicle length.
double maxSpeedLat
The vehicle type's maximum lateral speed [m/s].
double speedFactorPremature
the possible speed reduction when a train is ahead of schedule
RGBColor color
The color.
long long int parametersSet
Information for the router which parameter were set.
double minGap
This class' free space in front of the vehicle itself.
std::string imgFile
Image file for this class.
SUMOVehicleShape shape
This class' shape.
int personCapacity
The person capacity of the vehicle.
Distribution_Parameterized speedFactor
The factor by which the maximum speed may deviate from the allowed max speed on the street.
double scale
individual scaling factor (-1 for undefined)
SUMOTime timeToTeleport
the custom time-to-teleport for this type
std::string osgFile
3D model file for this class
double maxSpeed
The vehicle type's (technical) maximum speed [m/s].
SUMOTime timeToTeleportBidi
the custom time-to-teleport.bidi for this type
int containerCapacity
The container capacity of the vehicle.
SUMOTime boardingDuration
The time a person needs to board the vehicle.
double minGapLat
The vehicle type's minimum lateral gap [m].
double boardingFactor
factor for boardingDuration / loadingDuration
SUMOVehicleClass vehicleClass
The vehicle's class.
SUMOTime loadingDuration
The time a container needs to get loaded on the vehicle.
std::string id
The vehicle type's id.
SumoXMLTag cfModel
The enum-representation of the car-following model to use.
SubParams lcParameter
Lane-changing parameter.
LatAlignmentDefinition latAlignmentProcedure
Information on how the vehicle shall choose the lateral alignment.
SubParams jmParameter
Junction-model parameter.
double impatience
The vehicle's impatience (willingness to obstruct others)
std::map< int, std::pair< SUMOTime, SUMOTime > > myManoeuverAngleTimes
Map of manoeuver angles versus the times (entry, exit) to execute the manoeuver.
LaneChangeModel lcModel
The lane-change model to use.
static bool parseLatAlignment(const std::string &val, double &lao, LatAlignmentDefinition &lad)
Parses and validates a given latAlignment value.
Definition of vehicle stop (position and duration)
std::string parkingarea
(Optional) parking area if one is assigned to the stop
std::string chargingStation
(Optional) charging station if one is assigned to the stop
std::string overheadWireSegment
(Optional) overhead line segment if one is assigned to the stop
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string containerstop
(Optional) container stop if one is assigned to the stop
Structure representing possible vehicle parameter.
double departPosLat
(optional) The lateral position the vehicle shall depart from
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
double repetitionProbability
The probability for emitting a vehicle per second.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
double departSpeed
(optional) The initial speed of the vehicle
SumoXMLTag tag
The vehicle tag.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
double speedFactor
individual speedFactor (overriding distribution from vType)
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
static bool parseArrivalPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosLatDefinition &apd, std::string &error)
Validates a given arrivalPosLat value.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons)
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
double poissonRate
The rate for emitting vehicles with a poisson distribution.
RouteIndexDefinition arrivalEdgeProcedure
Information how the vehicle's final edge shall be chosen.
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.
SVCPermissions modes
The modes a person or container can use.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string vTypes
The types of usable (auto-generated) vehicles for a person / container.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
RGBColor color
The vehicle's color, TraCI may change this.
double arrivalPos
(optional) The position the vehicle shall arrive on
static int parseInsertionChecks(const std::string &value)
parses insertion checks
double calibratorSpeed
speed (used by calibrator flows
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< std::string > parkingBadges
The parking access rights.
int departEdge
(optional) The initial edge within the route of the vehicle
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error, const std::string &attr="departure")
Validates a given depart value.
static bool parsePersonModes(const std::string &modes, const std::string &element, const std::string &id, SVCPermissions &modeSet, std::string &error)
Validates a given person modes value.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
static bool parseRouteIndex(const std::string &val, const std::string &element, const std::string &id, const SumoXMLAttr attr, int &edgeIndex, RouteIndexDefinition &rid, std::string &error)
Validates a given departEdge or arrivalEdge value.
static bool parseDepartPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosLatDefinition &dpd, std::string &error)
Validates a given departPosLat value.
std::string toTaz
The vehicle's destination zone (district)
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
static double interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string &id, bool silent=false)
Interprets negative edge positions and fits them onto a given edge.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
int insertionChecks
bitset of InsertionCheck
int arrivalEdge
(optional) The final edge within the route of the vehicle
std::string fromTaz
The vehicle's origin zone (district)
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::string line
The vehicle's line (mainly for public transport)
int containerNumber
The static number of containers in the vehicle when it departs.
RouteIndexDefinition departEdgeProcedure
Information how the vehicle's initial edge shall be chosen.
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
static const CFAttrMap & getAllowedCFModelAttrs()
returns allowed attrs for each known CF-model (init on first use)
static SUMOVTypeParameter * beginVTypeParsing(const SUMOSAXAttributes &attrs, const bool hardFail, const std::string &file, const SUMOVTypeParameter *const base)
Starts to parse a vehicle type.
static bool parseLCParams(SUMOVTypeParameter *into, LaneChangeModel model, const SUMOSAXAttributes &attrs)
Parses lane change model attributes.
static bool isInternalRouteID(const std::string &id)
Checks whether the route ID uses the syntax of internal routes.
std::map< SumoXMLTag, std::set< SumoXMLAttr > > CFAttrMap
Car-Following attributes map.
static int parseCarWalkTransfer(const OptionsCont &oc, const bool hasTaxi)
static std::string parseID(const SUMOSAXAttributes &attrs, const SumoXMLTag element)
parse ID
static bool parseCFMParams(SUMOVTypeParameter *into, const SumoXMLTag element, const SUMOSAXAttributes &attrs, const bool nestedCFM)
Parses Car Following Mode params.
static SUMOTime processActionStepLength(double given)
Checks and converts given value for the action step length from seconds to miliseconds assuring it be...
std::map< LaneChangeModel, std::set< SumoXMLAttr > > LCAttrMap
Lane-Change-Model attributes map.
static SUMOVTypeParameter * handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter *vehicleTypeParameter, const std::string message="")
handle error loading SUMOVTypeParameter
static void parseCommonAttributes(const SUMOSAXAttributes &attrs, SUMOVehicleParameter *ret, SumoXMLTag tag, const bool allowInternalRoutes=false)
Parses attributes common to vehicles and flows.
static bool parseAngleTimesMap(SUMOVTypeParameter *vtype, const std::string)
Parse string containing AngleTimes triplets (angle, entry time, exit time)
static SUMOVehicleParameter * parseVehicleAttributes(int element, const SUMOSAXAttributes &attrs, const bool hardFail, const bool optionalID=false, const bool skipDepart=false, const bool allowInternalRoutes=false)
Parses a vehicle's attributes.
static SUMOVehicleShape parseGuiShape(const SUMOSAXAttributes &attrs, const std::string &id)
Parses the vehicle class.
static SUMOVehicleClass parseVehicleClass(const SUMOSAXAttributes &attrs, const std::string &id)
Parses the vehicle class.
static bool parseStopTag(const SUMOSAXAttributes &attrs, const SUMOVehicleParameter::Stop *stopParam, SumoXMLTag &tag, std::string &id)
parse named stopping place attrs (or use stopParam attrs) and return it's tag and id
static double parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string &id, double maxPos, const std::string &val, SumoRNG *rng=0)
parse departPos or arrivalPos for a walk
static LCAttrMap allowedLCModelAttrs
allowed attrs for each known LC-model
static bool validProfile(SUMOVTypeParameter *vtype, const std::string data, const SumoXMLAttr attr)
Parse string containing a vector of pairs.
static SUMOVehicleParameter * parseFlowAttributes(SumoXMLTag tag, const SUMOSAXAttributes &attrs, const bool hardFail, const bool needID, const SUMOTime beginDefault, const SUMOTime endDefault, const bool allowInternalRoutes=false)
Parses a flow's attributes.
static SUMOVehicleParameter * handleVehicleError(const bool hardFail, SUMOVehicleParameter *vehicleParameter, const std::string message="")
handle error loading SUMOVehicleParameter
static CFAttrMap allowedCFModelAttrs
allowed attrs for each known CF-model
static bool parseJMParams(SUMOVTypeParameter *into, const SUMOSAXAttributes &attrs)
Parses junction model attributes.
static StringBijection< SumoXMLTag > CarFollowModels
car following models
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static StringBijection< TrainType > TrainTypes
train types
static SequentialStringBijection Tags
The names of SUMO-XML elements for use in netbuild.
static StringBijection< LaneChangeModel > LaneChangeModels
lane change models
T get(const std::string &str) const
get key
int size() const
returns the number of existing substrings
std::string get(int pos) const
returns the item at the given position
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
struct for default values that depend of VClass
double maxSpeed
The vehicle type's maximum speed [m/s] (technical limit, not subject to speed deviation)