Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-2025 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
23// Helper methods for parsing vehicle attributes
24/****************************************************************************/
25#include <config.h>
26
40
42
43
44// ===========================================================================
45// static members
46// ===========================================================================
47
50
51
52// ===========================================================================
53// method definitions
54// ===========================================================================
55
57SUMOVehicleParserHelper::parseFlowAttributes(SumoXMLTag tag, const SUMOSAXAttributes& attrs, const bool hardFail, const bool needID,
58 const SUMOTime beginDefault, const SUMOTime endDefault, const bool allowInternalRoutes) {
59 // first parse ID
60 const std::string id = attrs.hasAttribute(SUMO_ATTR_ID) ? parseID(attrs, tag) : "";
61 // check if ID is valid
62 if (!needID || !id.empty()) {
63 if (needID && !SUMOXMLDefinitions::isValidVehicleID(id)) {
64 return handleVehicleError(hardFail, nullptr, "Invalid flow id '" + id + "'.");
65 }
66 // declare flags
67 const bool hasPeriod = attrs.hasAttribute(SUMO_ATTR_PERIOD);
68 const bool hasVPH = attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR);
69 const bool hasPPH = attrs.hasAttribute(SUMO_ATTR_PERSONSPERHOUR);
70 const bool hasCPH = attrs.hasAttribute(SUMO_ATTR_CONTAINERSPERHOUR);
71 const bool hasPH = attrs.hasAttribute(SUMO_ATTR_PERHOUR);
72 const bool hasXPH = hasVPH || hasPPH || hasCPH || hasPH;
73 const bool hasProb = attrs.hasAttribute(SUMO_ATTR_PROB);
74 const bool hasNumber = attrs.hasAttribute(SUMO_ATTR_NUMBER);
75 const bool hasBegin = attrs.hasAttribute(SUMO_ATTR_BEGIN);
76 const bool hasEnd = attrs.hasAttribute(SUMO_ATTR_END);
78 if (hasVPH) {
79 PERHOUR = SUMO_ATTR_VEHSPERHOUR;
80 }
81 if (hasPPH) {
83 }
84 if (hasCPH) {
86 }
87 if (hasXPH && !(hasVPH ^ hasPPH ^ hasCPH ^ hasPH)) {
88 return handleVehicleError(hardFail, nullptr,
89 "At most one of '" + attrs.getName(SUMO_ATTR_PERHOUR) +
90 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
91 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
92 "' and '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
93 "' has to be given in the definition of " + toString(tag) + " '" + id + "'.");
94 }
95 if (hasPeriod && hasXPH) {
96 return handleVehicleError(hardFail, nullptr,
97 "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
98 "' and '" + attrs.getName(PERHOUR) +
99 "' has to be given in the definition of "
100 + toString(tag) + " '" + id + "'.");
101 }
102 if (hasPeriod && hasProb) {
103 return handleVehicleError(hardFail, nullptr,
104 "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
105 "' and '" + attrs.getName(SUMO_ATTR_PROB) +
106 "' has to be given in the definition of "
107 + toString(tag) + " '" + id + "'.");
108 }
109 if (hasProb && hasXPH) {
110 return handleVehicleError(hardFail, nullptr,
111 "At most one of '" + attrs.getName(SUMO_ATTR_PROB) +
112 "' and '" + attrs.getName(PERHOUR) +
113 "' has to be given in the definition of "
114 + toString(tag) + " '" + id + "'.");
115 }
116 if (hasPeriod || hasXPH || hasProb) {
117 if (hasEnd && hasNumber) {
118 return handleVehicleError(hardFail, nullptr,
119 "If '" + attrs.getName(SUMO_ATTR_PERIOD) +
120 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
121 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
122 "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
123 "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
124 "' or '" + attrs.getName(SUMO_ATTR_PROB) +
125 "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
126 "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
127 "' are allowed in "
128 + toString(tag) + " '" + id + "'.");
129 }
130 } else {
131 if (!hasNumber) {
132 return handleVehicleError(hardFail, nullptr,
133 "At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
134 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
135 "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
136 "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
137 "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
138 "', '" + attrs.getName(SUMO_ATTR_PROB) +
139 "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
140 "' is needed in "
141 + toString(tag) + " '" + id + "'.");
142 }
143 }
144 // declare flow
145 SUMOVehicleParameter* flowParameter = new SUMOVehicleParameter();
146 // set tag
147 flowParameter->tag = tag;
148 // set id
149 flowParameter->id = id;
150 if (tag == SUMO_TAG_PERSONFLOW) {
151 flowParameter->vtypeid = DEFAULT_PEDTYPE_ID;
152 }
153 if (tag == SUMO_TAG_CONTAINERFLOW) {
154 flowParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
155 }
156 // parse common vehicle attributes
157 try {
158 parseCommonAttributes(attrs, flowParameter, tag, allowInternalRoutes);
159 } catch (ProcessError& attributeError) {
160 // check if continue handling another vehicles or stop handling
161 if (hardFail) {
162 throw ProcessError(attributeError.what());
163 } else {
164 return nullptr;
165 }
166 }
167 // parse period
168 bool poissonFlow = false;
169 if (hasPeriod) {
170 bool ok = true;
171 const std::string description = attrs.get<std::string>(SUMO_ATTR_PERIOD, id.c_str(), ok);
172 const std::string distName = description.substr(0, description.find('('));
173 if (distName == "exp") {
174 // declare rate
175 double rate = -1;
176 // parse rate
177 try {
178 rate = StringUtils::toDouble(description.substr(distName.size() + 1, description.size() - distName.size() - 2));
179 } catch (ProcessError& attributeError) {
180 // check if continue handling another vehicles or stop handling
181 if (hardFail) {
182 throw ProcessError(attributeError.what());
183 } else {
184 return nullptr;
185 }
186 }
187 if (rate <= 0) {
188 return handleVehicleError(hardFail, flowParameter, "Invalid rate parameter for exponentially distributed period in the definition of " + toString(tag) + " '" + id + "'.");
189 }
190 flowParameter->poissonRate = rate;
191 poissonFlow = true;
192 } else {
193 flowParameter->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
194 }
195 if (!ok) {
196 return handleVehicleError(hardFail, flowParameter);
197 } else {
198 flowParameter->parametersSet |= VEHPARS_PERIOD_SET;
199 }
200 }
201 // parse vehicle/person/container/etc per hour
202 if (hasXPH) {
203 bool ok = true;
204 const double vph = attrs.get<double>(PERHOUR, id.c_str(), ok);
205 if (!ok) {
206 return handleVehicleError(hardFail, flowParameter);
207 } else if (vph <= 0) {
208 return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
209 } else {
210 if (vph != 0) {
211 flowParameter->repetitionOffset = TIME2STEPS(3600. / vph);
212 }
213 flowParameter->parametersSet |= VEHPARS_VPH_SET;
214 }
215 }
216 // parse probability
217 if (hasProb) {
218 bool ok = true;
219 flowParameter->repetitionProbability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
220 if (!ok) {
221 return handleVehicleError(hardFail, flowParameter);
222 } else if (flowParameter->repetitionProbability <= 0 || flowParameter->repetitionProbability > 1) {
223 return handleVehicleError(hardFail, flowParameter, "Invalid repetition probability in the definition of " + toString(tag) + " '" + id + "'.");
224 } else {
225 flowParameter->parametersSet |= VEHPARS_PROB_SET;
226 }
227 }
228 // set default begin
229 flowParameter->depart = beginDefault;
230 // parse begin
231 if (hasBegin) {
232 // first get begin
233 bool ok = true;
234 const std::string begin = attrs.get<std::string>(SUMO_ATTR_BEGIN, id.c_str(), ok);
235 if (!ok) {
236 return handleVehicleError(hardFail, flowParameter);
237 } else {
238 // parse begin
239 std::string errorMsg;
240 if (!SUMOVehicleParameter::parseDepart(begin, toString(tag), id, flowParameter->depart, flowParameter->departProcedure, errorMsg, "begin")) {
241 return handleVehicleError(hardFail, flowParameter, errorMsg);
242 }
243 }
244 }
245 if (flowParameter->depart < 0) {
246 return handleVehicleError(hardFail, flowParameter, "Negative begin time in the definition of " + toString(tag) + " '" + id + "'.");
247 }
248 // set default end
249 flowParameter->repetitionEnd = endDefault;
250 if (flowParameter->repetitionEnd < 0) {
251 flowParameter->repetitionEnd = SUMOTime_MAX;
252 }
253 // parse end
254 if (hasEnd) {
255 bool ok = true;
256 flowParameter->repetitionEnd = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
257 if (!ok) {
258 return handleVehicleError(hardFail, flowParameter);
259 } else {
260 flowParameter->parametersSet |= VEHPARS_END_SET;
261 }
262 } else if (flowParameter->departProcedure == DepartDefinition::TRIGGERED) {
263 if (!hasNumber) {
264 return handleVehicleError(hardFail, flowParameter, toString(tag) + " '" + id + "' with triggered begin must define 'number'.");
265 } else {
266 flowParameter->repetitionEnd = flowParameter->depart;
267 }
268 } else if ((endDefault == SUMOTime_MAX || endDefault < 0) && (!hasNumber || (!hasProb && !hasPeriod && !hasXPH))) {
269 WRITE_WARNINGF(TL("Undefined end for % '%', defaulting to 24hour duration."), toString(tag), id);
270 flowParameter->repetitionEnd = flowParameter->depart + TIME2STEPS(24 * 3600);
271 }
272 if (flowParameter->repetitionEnd < flowParameter->depart) {
273 std::string flow = toString(tag);
274 flow[0] = (char)::toupper((char)flow[0]);
275 return handleVehicleError(hardFail, flowParameter, flow + " '" + id + "' ends before its begin time.");
276 }
277 // parse number
278 if (hasNumber) {
279 bool ok = true;
280 flowParameter->repetitionNumber = attrs.get<int>(SUMO_ATTR_NUMBER, id.c_str(), ok);
281 if (!ok) {
282 return handleVehicleError(hardFail, flowParameter);
283 } else {
284 flowParameter->parametersSet |= VEHPARS_NUMBER_SET;
285 if (flowParameter->repetitionNumber == 0) {
286 std::string flow = toString(tag);
287 flow[0] = (char)::toupper((char)flow[0]);
288 WRITE_WARNING(flow + " '" + id + "' has no instances; will skip it.");
289 flowParameter->repetitionEnd = flowParameter->depart;
290 } else {
291 if (flowParameter->repetitionNumber < 0) {
292 return handleVehicleError(hardFail, flowParameter, "Negative repetition number in the definition of " + toString(tag) + " '" + id + "'.");
293 }
294 if (flowParameter->repetitionOffset < 0 && !hasProb) {
295 if (poissonFlow) {
296 flowParameter->repetitionEnd = SUMOTime_MAX;
297 } else {
298 flowParameter->repetitionOffset = (flowParameter->repetitionEnd - flowParameter->depart) / flowParameter->repetitionNumber;
299 }
300 }
301 }
302 }
303 } else {
304 // interpret repetitionNumber
305 if (flowParameter->repetitionProbability > 0) {
306 flowParameter->repetitionNumber = std::numeric_limits<int>::max();
307 } else {
308 if (flowParameter->repetitionOffset <= 0) {
309 if (poissonFlow) {
310 // number is random but flow has a fixed end time
311 flowParameter->repetitionNumber = std::numeric_limits<int>::max();
312 } else {
313 return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
314 }
315 } else {
316 if (flowParameter->repetitionEnd == SUMOTime_MAX) {
317 flowParameter->repetitionNumber = std::numeric_limits<int>::max();
318 } else {
319 const SUMOTime repLength = flowParameter->repetitionEnd - flowParameter->depart;
320 flowParameter->repetitionNumber = (int)ceil((double)repLength / (double)flowParameter->repetitionOffset);
321 }
322 }
323 }
324 }
325 // all ok, then return flow parameter
326 return flowParameter;
327 } else {
328 return handleVehicleError(hardFail, nullptr, toString(tag) + " cannot be created");
329 }
330}
331
332
334SUMOVehicleParserHelper::parseVehicleAttributes(int element, const SUMOSAXAttributes& attrs, const bool hardFail, const bool optionalID, const bool skipDepart, const bool allowInternalRoutes) {
335 // declare vehicle ID
336 std::string id;
337 // for certain vehicles, ID can be optional
338 if (optionalID) {
339 bool ok = true;
340 id = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
341 if (!ok) {
342 return handleVehicleError(hardFail, nullptr);
343 }
344 } else {
345 // parse ID
346 id = parseID(attrs, (SumoXMLTag)element);
347 }
348 // only continue if id is valid, or if is optional
349 if (optionalID || !id.empty()) {
350 // declare vehicle parameter
351 SUMOVehicleParameter* vehicleParameter = new SUMOVehicleParameter();
352 vehicleParameter->id = id;
353 if (element == SUMO_TAG_PERSON) {
354 vehicleParameter->vtypeid = DEFAULT_PEDTYPE_ID;
355 } else if (element == SUMO_TAG_CONTAINER) {
356 vehicleParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
357 }
358 // parse common attributes
359 try {
360 parseCommonAttributes(attrs, vehicleParameter, (SumoXMLTag)element, allowInternalRoutes);
361 } catch (ProcessError& attributeError) {
362 // check if continue handling another vehicles or stop handling
363 if (hardFail) {
364 throw ProcessError(attributeError.what());
365 } else {
366 return nullptr;
367 }
368 }
369 // check depart
370 if (!skipDepart) {
371 bool ok = true;
372 const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPART, vehicleParameter->id.c_str(), ok);
373 if (!ok) {
374 return handleVehicleError(hardFail, vehicleParameter);
375 }
376 // now parse depart
377 std::string departErrorMsg;
378 if (!SUMOVehicleParameter::parseDepart(helper, "vehicle", vehicleParameter->id, vehicleParameter->depart, vehicleParameter->departProcedure, departErrorMsg)) {
379 return handleVehicleError(hardFail, vehicleParameter, departErrorMsg);
380 }
381 }
382 // set tag
383 vehicleParameter->tag = (SumoXMLTag)element;
384 // all ok, then return vehicleParameter
385 return vehicleParameter;
386 } else {
387 return handleVehicleError(hardFail, nullptr, toString((SumoXMLTag)element) + " cannot be created");
388 }
389}
390
391
392std::string
394 bool ok = true;
395 std::string id;
396 // first check if attrs contain an ID
397 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
398 id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
400 return id;
401 } else if (id.empty()) {
402 // add extra information for empty IDs
403 WRITE_ERRORF(TL("Invalid % id '%'."), toString(element), id);
404 } else {
405 WRITE_ERRORF(TL("Invalid % id '%'. Contains invalid characters."), toString(element), id);
406 }
407 } else {
408 WRITE_ERROR("Attribute '" + toString(SUMO_ATTR_ID) + "' is missing in definition of " + toString(element));
409 }
410 // return empty (invalid) ID
411 return "";
412}
413
414
415void
417 const std::string element = toString(tag);
418 //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
419 // parse route information
420 if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
421 bool ok = true;
422 std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, ret->id.c_str(), ok);
423 if (!allowInternalRoutes && isInternalRouteID(routeID)) {
424 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);
425 }
426 ret->routeid = routeID;
427 if (ok) {
428 ret->parametersSet |= VEHPARS_ROUTE_SET; // !!! needed?
429 } else {
430 handleVehicleError(true, ret);
431 }
432 }
433 // parse type information
434 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
435 bool ok = true;
436 ret->vtypeid = attrs.get<std::string>(SUMO_ATTR_TYPE, ret->id.c_str(), ok);
437 if (ok) {
438 ret->parametersSet |= VEHPARS_VTYPE_SET; // !!! needed?
439 } else {
440 handleVehicleError(true, ret);
441 }
442 }
443 // parse line information
444 if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
445 bool ok = true;
446 ret->line = attrs.get<std::string>(SUMO_ATTR_LINE, ret->id.c_str(), ok);
447 if (ok) {
448 ret->parametersSet |= VEHPARS_LINE_SET; // !!! needed?
449 } else {
450 handleVehicleError(true, ret);
451 }
452 }
453 // parse zone information
454 if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) {
455 bool ok = true;
456 ret->fromTaz = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, ret->id.c_str(), ok);
457 if (ok) {
459 } else {
460 handleVehicleError(true, ret);
461 }
462 }
463 if (attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
464 bool ok = true;
465 ret->toTaz = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, ret->id.c_str(), ok);
466 if (ok) {
468 } else {
469 handleVehicleError(true, ret);
470 }
471 }
472 // parse reroute information
473 if (attrs.hasAttribute(SUMO_ATTR_REROUTE)) {
474 bool ok = true;
475 if (attrs.get<bool>(SUMO_ATTR_REROUTE, ret->id.c_str(), ok)) {
476 if (ok) {
478 } else {
479 handleVehicleError(true, ret);
480 }
481 }
482 }
483 // parse depart lane information
485 bool ok = true;
486 const std::string departLaneStr = attrs.get<std::string>(SUMO_ATTR_DEPARTLANE, ret->id.c_str(), ok);
487 int lane;
489 std::string error;
490 if (SUMOVehicleParameter::parseDepartLane(departLaneStr, element, ret->id, lane, dld, error)) {
492 ret->departLane = lane;
493 ret->departLaneProcedure = dld;
494 } else {
495 handleVehicleError(true, ret, error);
496 }
497 }
498 // parse depart position information
500 bool ok = true;
501 const std::string departPosStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS, ret->id.c_str(), ok);
502 double pos;
504 std::string error;
505 if (SUMOVehicleParameter::parseDepartPos(departPosStr, element, ret->id, pos, dpd, error)) {
507 ret->departPos = pos;
508 ret->departPosProcedure = dpd;
509 } else {
510 handleVehicleError(true, ret, error);
511 }
512 }
513 // parse lateral depart position information
515 bool ok = true;
516 const std::string departPosLatStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS_LAT, ret->id.c_str(), ok);
517 double pos;
519 std::string error;
520 if (SUMOVehicleParameter::parseDepartPosLat(departPosLatStr, element, ret->id, pos, dpd, error)) {
522 ret->departPosLat = pos;
523 ret->departPosLatProcedure = dpd;
524 } else {
525 handleVehicleError(true, ret, error);
526 }
527 }
528 // parse depart speed information
530 bool ok = true;
531 const std::string departSpeed = attrs.get<std::string>(SUMO_ATTR_DEPARTSPEED, ret->id.c_str(), ok);
532 double speed;
534 std::string error;
535 if (SUMOVehicleParameter::parseDepartSpeed(departSpeed, element, ret->id, speed, dsd, error)) {
537 ret->departSpeed = speed;
538 ret->departSpeedProcedure = dsd;
539 } else {
540 handleVehicleError(true, ret, error);
541 }
542 }
543 // parse depart edge information
545 bool ok = true;
546 const std::string departEdgeStr = attrs.get<std::string>(SUMO_ATTR_DEPARTEDGE, ret->id.c_str(), ok);
547 int edgeIndex;
549 std::string error;
550 if (SUMOVehicleParameter::parseRouteIndex(departEdgeStr, element, ret->id, SUMO_ATTR_DEPARTEDGE, edgeIndex, rid, error)) {
552 ret->departEdge = edgeIndex;
553 ret->departEdgeProcedure = rid;
554 } else {
555 handleVehicleError(true, ret, error);
556 }
557 }
558 // parse arrival lane information
560 bool ok = true;
561 const std::string arrivalLaneStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALLANE, ret->id.c_str(), ok);
562 int lane;
564 std::string error;
565 if (SUMOVehicleParameter::parseArrivalLane(arrivalLaneStr, element, ret->id, lane, ald, error)) {
567 ret->arrivalLane = lane;
568 ret->arrivalLaneProcedure = ald;
569 } else {
570 handleVehicleError(true, ret, error);
571 }
572 }
573 // parse arrival position information
575 bool ok = true;
576 const std::string arrivalPosStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, ret->id.c_str(), ok);
577 double pos;
579 std::string error;
580 if (SUMOVehicleParameter::parseArrivalPos(arrivalPosStr, element, ret->id, pos, apd, error)) {
582 ret->arrivalPos = pos;
583 ret->arrivalPosProcedure = apd;
584 } else {
585 handleVehicleError(true, ret, error);
586 }
587 }
588 // parse lateral arrival position information
590 bool ok = true;
591 const std::string arrivalPosLatStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS_LAT, ret->id.c_str(), ok);
592 double pos;
594 std::string error;
595 if (SUMOVehicleParameter::parseArrivalPosLat(arrivalPosLatStr, element, ret->id, pos, apd, error)) {
597 ret->arrivalPosLat = pos;
598 ret->arrivalPosLatProcedure = apd;
599 } else {
600 handleVehicleError(true, ret, error);
601 }
602 }
603 // parse arrival speed information
605 bool ok = true;
606 std::string arrivalSpeedStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALSPEED, ret->id.c_str(), ok);
607 double speed;
609 std::string error;
610 if (SUMOVehicleParameter::parseArrivalSpeed(arrivalSpeedStr, element, ret->id, speed, asd, error)) {
612 ret->arrivalSpeed = speed;
613 ret->arrivalSpeedProcedure = asd;
614 } else {
615 handleVehicleError(true, ret, error);
616 }
617 }
618 // parse arrival edge information
620 bool ok = true;
621 std::string arrivalEdgeStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALEDGE, ret->id.c_str(), ok);
622 int edgeIndex;
624 std::string error;
625 if (SUMOVehicleParameter::parseRouteIndex(arrivalEdgeStr, element, ret->id, SUMO_ATTR_ARRIVALEDGE, edgeIndex, rid, error)) {
627 ret->arrivalEdge = edgeIndex;
628 ret->arrivalEdgeProcedure = rid;
629 } else {
630 handleVehicleError(true, ret, error);
631 }
632 }
633 // parse color
634 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
635 bool ok = true;
636 ret->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, ret->id.c_str(), ok);
637 if (ok) {
639 } else {
640 handleVehicleError(true, ret, "Invalid RGBColor format");
641 }
642 } else {
644 }
645 // parse person number
647 bool ok = true;
648 int personNumber = attrs.get<int>(SUMO_ATTR_PERSON_NUMBER, ret->id.c_str(), ok);
649 if (!ok) {
650 handleVehicleError(true, ret);
651 } else if (personNumber >= 0) {
653 ret->personNumber = personNumber;
654 } else {
655 handleVehicleError(true, ret, toString(SUMO_ATTR_PERSON_NUMBER) + " cannot be negative");
656 }
657 }
658 // parse container number
660 bool ok = true;
661 int containerNumber = attrs.get<int>(SUMO_ATTR_CONTAINER_NUMBER, ret->id.c_str(), ok);
662 if (!ok) {
663 handleVehicleError(true, ret);
664 } else if (containerNumber >= 0) {
666 ret->containerNumber = containerNumber;
667 } else {
668 handleVehicleError(true, ret, toString(SUMO_ATTR_CONTAINER_NUMBER) + " cannot be negative");
669 }
670 }
671 // parse individual speedFactor
673 bool ok = true;
674 double speedFactor = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR, ret->id.c_str(), ok);
675 if (!ok) {
676 handleVehicleError(true, ret);
677 } else if (speedFactor > 0) {
679 ret->speedFactor = speedFactor;
680 } else {
681 handleVehicleError(true, ret, toString(SUMO_ATTR_SPEEDFACTOR) + " must be positive");
682 }
683 }
684 // parse insertion checks
687 bool ok = true;
688 std::string checks = attrs.get<std::string>(SUMO_ATTR_INSERTIONCHECKS, ret->id.c_str(), ok);
689 if (!ok) {
690 handleVehicleError(true, ret);
691 } else {
692 try {
694 } catch (InvalidArgument& e) {
695 handleVehicleError(true, ret, e.what());
696 }
697 }
698 }
699 // parse parking access rights
701 bool ok = true;
702 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, ret->id.c_str(), ok);
703 if (!ok) {
704 handleVehicleError(true, ret);
705 } else {
707 ret->parkingBadges = badges;
708 }
709 }
710 // parse modes (transportables only)
711 ret->modes = 0;
712 if (attrs.hasAttribute(SUMO_ATTR_MODES)) {
713 bool ok = true;
714 const std::string modeString = attrs.get<std::string>(SUMO_ATTR_MODES, ret->id.c_str(), ok);
715 if (!ok) {
716 handleVehicleError(true, ret);
717 } else {
718 std::string errorMsg;
719 if (!SUMOVehicleParameter::parsePersonModes(modeString, toString(tag), ret->id, ret->modes, errorMsg)) {
720 handleVehicleError(true, ret, errorMsg);
721 }
722 }
723 }
724 // parse usable vehicle types (transportables only)
725 if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
726 bool ok = true;
727 ret->vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, ret->id.c_str(), ok);
728 if (!ok) {
729 handleVehicleError(true, ret);
730 }
731 }
732 // parse speed (only used by calibrators flow)
733 // also used by vehicle in saved state but this is parsed elsewhere
734 if (tag == SUMO_TAG_FLOW && attrs.hasAttribute(SUMO_ATTR_SPEED)) {
735 bool ok = true;
736 double calibratorSpeed = attrs.get<double>(SUMO_ATTR_SPEED, ret->id.c_str(), ok);
737 if (!ok) {
738 handleVehicleError(true, ret);
739 } else if (calibratorSpeed >= 0 || calibratorSpeed == -1) {
741 ret->calibratorSpeed = calibratorSpeed;
742 } else {
743 handleVehicleError(true, ret, toString(SUMO_ATTR_SPEED) + " may not be negative");
744 }
745 }
746 /*/ parse via
747 if (attrs.hasAttribute(SUMO_ATTR_VIA)) {
748 ret->setParameter |= VEHPARS_VIA_SET;
749 SUMOSAXAttributes::parseStringVector(attrs.get<std::string>(SUMO_ATTR_VIA, ret->id.c_str(), ok), ret->via);
750 }
751 */
752}
753
754
756SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const bool hardFail, const std::string& file) {
757 // first obtain ID
758 std::string id = parseID(attrs, SUMO_TAG_VTYPE);
759 // check if ID is valid
760 if (!id.empty()) {
762 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
763 vClass = parseVehicleClass(attrs, id);
764 }
765 // create vType
766 SUMOVTypeParameter* vType = new SUMOVTypeParameter(id, vClass);
767 // parse attributes
768 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
770 }
771 if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
772 bool ok = true;
773 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, vType->id.c_str(), ok);
774 if (!ok) {
775 return handleVehicleTypeError(hardFail, vType);
776 } else if (length <= 0) {
777 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LENGTH) + " must be greater than 0");
778 } else {
779 vType->length = length;
781 }
782 }
783 if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
784 bool ok = true;
785 const double minGap = attrs.get<double>(SUMO_ATTR_MINGAP, vType->id.c_str(), ok);
786 if (!ok) {
787 return handleVehicleTypeError(hardFail, vType);
788 } else if (minGap < 0) {
789 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP) + " must be equal or greater than 0");
790 } else {
791 vType->minGap = minGap;
793 }
794 }
795 if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
796 bool ok = true;
797 const double maxSpeed = attrs.get<double>(SUMO_ATTR_MAXSPEED, vType->id.c_str(), ok);
798 if (!ok) {
799 return handleVehicleTypeError(hardFail, vType);
800 } else if (maxSpeed <= 0) {
801 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED) + " must be greater than 0");
802 } else {
803 vType->maxSpeed = maxSpeed;
805 }
806 }
808 bool ok = true;
809 const double desiredMaxSpeed = attrs.get<double>(SUMO_ATTR_DESIRED_MAXSPEED, vType->id.c_str(), ok);
810 if (!ok) {
811 return handleVehicleTypeError(hardFail, vType);
812 } else if (desiredMaxSpeed <= 0) {
813 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_DESIRED_MAXSPEED) + " must be greater than 0");
814 } else {
815 vType->desiredMaxSpeed = desiredMaxSpeed;
817 }
818 } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
819 if (vClass == SVC_PEDESTRIAN) {
820 // backward compatibility because pedestrian maxSpeed was subject to speedFactor up to 1.14.1
821 vType->desiredMaxSpeed = vType->maxSpeed;;
823 } else if (vClass == SVC_BICYCLE) {
824 // backward compatibility because default desired speed did not exist up to 1.14.1
825 vType->desiredMaxSpeed = MAX2(vType->maxSpeed, vType->desiredMaxSpeed);
826 }
827 }
828
830 bool ok = true;
831 vType->speedFactor.parse(attrs.get<std::string>(SUMO_ATTR_SPEEDFACTOR, vType->id.c_str(), ok), hardFail);
832 if (!ok) {
833 return handleVehicleTypeError(hardFail, vType);
834 } else {
836 }
837 }
838 if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
839 bool ok = true;
840 const double speedDev = attrs.get<double>(SUMO_ATTR_SPEEDDEV, vType->id.c_str(), ok);
841 if (!ok) {
842 return handleVehicleTypeError(hardFail, vType);
843 } else if (speedDev < 0) {
844 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SPEEDDEV) + " must be equal or greater than 0");
845 } else {
846 vType->speedFactor.getParameter()[1] = speedDev;
848 }
849 }
850 // validate speed distribution
851 const std::string& error = vType->speedFactor.isValid();
852 if (error != "") {
853 return handleVehicleTypeError(hardFail, vType, "Invalid speed distribution when parsing vType '" + vType->id + "' (" + error + ")");
854 }
856 bool ok = true;
857 const double actionStepLengthSecs = attrs.get<double>(SUMO_ATTR_ACTIONSTEPLENGTH, vType->id.c_str(), ok);
858 if (!ok) {
859 return handleVehicleTypeError(hardFail, vType);
860 } else {
861 // processActionStepLength(...) function includes warnings
862 vType->actionStepLength = processActionStepLength(actionStepLengthSecs);
864 }
865 }
867 bool ok = true;
868 const std::string parsedEmissionClass = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
869 // check if emission class is correct
870 try {
871 vType->emissionClass = PollutantsInterface::getClassByName(parsedEmissionClass);
873 } catch (...) {
874 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_EMISSIONCLASS) + " with name '" + parsedEmissionClass + "' doesn't exist.");
875 }
876 }
877 if (attrs.hasAttribute(SUMO_ATTR_MASS)) {
878 bool ok = true;
879 const double mass = attrs.get<double>(SUMO_ATTR_MASS, vType->id.c_str(), ok);
880 if (!ok) {
881 return handleVehicleTypeError(hardFail, vType);
882 } else if (mass < 0) {
883 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MASS) + " must be equal or greater than 0");
884 } else {
885 vType->mass = mass;
887 }
888 }
890 bool ok = true;
891 const std::string impatienceStr = attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
892 if (!ok) {
893 return handleVehicleTypeError(hardFail, vType);
894 } else if (impatienceStr == "off") {
895 vType->impatience = -std::numeric_limits<double>::max();
896 } else {
897 const double impatienceDouble = attrs.get<double>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
898 if (!ok) {
899 return handleVehicleTypeError(hardFail, vType);
900 } else {
901 vType->impatience = impatienceDouble;
903 }
904 }
905 }
906 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
907 bool ok = true;
908 const double width = attrs.get<double>(SUMO_ATTR_WIDTH, vType->id.c_str(), ok);
909 if (!ok) {
910 return handleVehicleTypeError(hardFail, vType);
911 } else if (width <= 0) {
912 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_WIDTH) + " must be greater than 0");
913 } else {
914 vType->width = width;
916 if (vClass == SVC_PEDESTRIAN
917 && OptionsCont::getOptions().exists("pedestrian.striping.stripe-width")
918 && OptionsCont::getOptions().getString("pedestrian.model") == "striping"
919 && OptionsCont::getOptions().getFloat("pedestrian.striping.stripe-width") < vType->width) {
920 WRITE_WARNINGF(TL("Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."), id, vType->width);
921 }
922 }
923 }
924 if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
925 bool ok = true;
926 const double height = attrs.get<double>(SUMO_ATTR_HEIGHT, vType->id.c_str(), ok);
927 if (!ok) {
928 return handleVehicleTypeError(hardFail, vType);
929 } else if (height < 0) {
930 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_HEIGHT) + " must be equal or greater than 0");
931 } else {
932 vType->height = height;
934 }
935 }
936 if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
937 vType->shape = parseGuiShape(attrs, vType->id);
938 if (vType->shape != SUMOVehicleShape::UNKNOWN) {
940 }
941 }
942 if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
943 bool ok = true;
944 const std::string osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vType->id.c_str(), ok);
945 if (!ok) {
946 return handleVehicleTypeError(hardFail, vType);
947 } else {
948 vType->osgFile = osgFile;
950 }
951 }
952 if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
953 bool ok = true;
954 std::string imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vType->id.c_str(), ok);
955 if (!ok) {
956 return handleVehicleTypeError(hardFail, vType);
957 } else {
958 // check relative path
959 if ((imgFile != "") && !FileHelpers::isAbsolute(imgFile)) {
960 imgFile = FileHelpers::getConfigurationRelative(file, imgFile);
961 }
962 vType->imgFile = imgFile;
964 }
965 }
966 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
967 bool ok = true;
968 const RGBColor color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vType->id.c_str(), ok);
969 if (!ok) {
970 return handleVehicleTypeError(hardFail, vType);
971 } else {
972 vType->color = color;
974 }
975 } else {
976 vType->color = RGBColor::YELLOW;
977 }
978 if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
979 bool ok = true;
980 const double defaultProbability = attrs.get<double>(SUMO_ATTR_PROB, vType->id.c_str(), ok);
981 if (!ok) {
982 return handleVehicleTypeError(hardFail, vType);
983 } else if (defaultProbability < 0) {
984 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PROB) + " must be equal or greater than 0");
985 } else {
986 vType->defaultProbability = defaultProbability;
988 }
989 }
991 bool ok = true;
992 std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vType->id.c_str(), ok);
993 if (!ok) {
994 return handleVehicleTypeError(hardFail, vType);
995 } else if (lcmS == "JE2013") {
996 WRITE_WARNING(TL("Lane change model 'JE2013' is deprecated. Using default model instead."));
997 lcmS = "default";
998 }
999 if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
1002 } else {
1003 return handleVehicleTypeError(hardFail, vType, "Unknown lane change model '" + lcmS + "' when parsing vType '" + vType->id + "'");
1004 }
1005 }
1007 bool ok = true;
1008 const std::string cfmValue = attrs.get<std::string>(SUMO_ATTR_CAR_FOLLOW_MODEL, vType->id.c_str(), ok);
1009 if (!ok) {
1010 return handleVehicleTypeError(hardFail, vType);
1011 } else if (SUMOXMLDefinitions::CarFollowModels.hasString(cfmValue)) {
1014 } else {
1015 return handleVehicleTypeError(hardFail, vType, "Unknown car following model '" + cfmValue + "' when parsing vType '" + vType->id + "'");
1016 }
1017 }
1019 bool ok = true;
1020 const int personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, vType->id.c_str(), ok);
1021 if (!ok) {
1022 return handleVehicleTypeError(hardFail, vType);
1023 } else if (personCapacity < 0) {
1024 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PERSON_CAPACITY) + " must be equal or greater than 0");
1025 } else {
1026 vType->personCapacity = personCapacity;
1028 }
1029 }
1031 bool ok = true;
1032 const int containerCapacity = attrs.get<int>(SUMO_ATTR_CONTAINER_CAPACITY, vType->id.c_str(), ok);
1033 if (!ok) {
1034 return handleVehicleTypeError(hardFail, vType);
1035 } else if (containerCapacity < 0) {
1036 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_CONTAINER_CAPACITY) + " must be equal or greater than 0");
1037 } else {
1038 vType->containerCapacity = containerCapacity;
1040 }
1041 }
1043 bool ok = true;
1044 const SUMOTime boardingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_BOARDING_DURATION, vType->id.c_str(), ok);
1045 if (!ok) {
1046 return handleVehicleTypeError(hardFail, vType);
1047 } else if (boardingDuration < 0) {
1048 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_DURATION) + " must be equal or greater than 0");
1049 } else {
1050 vType->boardingDuration = boardingDuration;
1052 }
1053 }
1055 bool ok = true;
1056 const SUMOTime loadingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_LOADING_DURATION, vType->id.c_str(), ok);
1057 if (!ok) {
1058 return handleVehicleTypeError(hardFail, vType);
1059 } else if (loadingDuration < 0) {
1060 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LOADING_DURATION) + " must be equal or greater than 0");
1061 } else {
1062 vType->loadingDuration = loadingDuration;
1064 }
1065 }
1066 if (attrs.hasAttribute(SUMO_ATTR_SCALE)) {
1067 bool ok = true;
1068 const double scale = attrs.get<double>(SUMO_ATTR_SCALE, id.c_str(), ok);
1069 if (!ok) {
1070 return handleVehicleTypeError(hardFail, vType);
1071 } else if (scale < 0) {
1072 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SCALE) + " may be not be negative");
1073 } else {
1074 vType->scale = scale;
1076 }
1077 }
1079 bool ok = true;
1080 const SUMOTime ttt = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT, vType->id.c_str(), ok);
1081 if (!ok) {
1082 return handleVehicleTypeError(hardFail, vType);
1083 } else {
1084 vType->timeToTeleport = ttt;
1086 }
1087 }
1089 bool ok = true;
1090 const SUMOTime tttb = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT_BIDI, vType->id.c_str(), ok);
1091 if (!ok) {
1092 return handleVehicleTypeError(hardFail, vType);
1093 } else {
1094 vType->timeToTeleportBidi = tttb;
1096 }
1097 }
1099 bool ok = true;
1100 const double sfp = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR_PREMATURE, id.c_str(), ok);
1101 if (!ok) {
1102 return handleVehicleTypeError(hardFail, vType);
1103 } else {
1104 vType->speedFactorPremature = sfp;
1106 }
1107 }
1109 bool ok = true;
1110 const double bf = attrs.get<double>(SUMO_ATTR_BOARDING_FACTOR, id.c_str(), ok);
1111 if (!ok) {
1112 return handleVehicleTypeError(hardFail, vType);
1113 } else if (bf < 0) {
1114 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_FACTOR) + " must be equal or greater than 0");
1115 } else {
1116 vType->boardingFactor = bf;
1118 }
1119 }
1121 bool ok = true;
1122 const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1123 if (!ok) {
1124 return handleVehicleTypeError(hardFail, vType);
1125 } else if (maxSpeedLat <= 0) {
1126 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1127 } else {
1128 vType->maxSpeedLat = maxSpeedLat;
1130 }
1131 }
1133 bool ok = true;
1134 const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1135 if (!ok) {
1136 return handleVehicleTypeError(hardFail, vType);
1137 } else if (minGapLat < 0) {
1138 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1139 } else {
1140 vType->minGapLat = minGapLat;
1142 }
1143 }
1145 bool ok = true;
1146 const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1147 if (!ok) {
1148 return handleVehicleTypeError(hardFail, vType);
1149 } else {
1150 double lao;
1152 if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1153 vType->latAlignmentOffset = lao;
1154 vType->latAlignmentProcedure = lad;
1156 } else {
1157 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)");
1158 }
1159 }
1160 }
1162 bool ok = true;
1163 const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1164 if (!ok) {
1165 return handleVehicleTypeError(hardFail, vType);
1166 } else if (parseAngleTimesMap(vType, angleTimesS)) {
1168 } else {
1169 return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1170 }
1171 }
1173 bool ok = true;
1174 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1175 if (!ok) {
1176 return handleVehicleTypeError(hardFail, vType);
1177 } else {
1179 vType->parkingBadges = badges;
1180 }
1181 }
1182 // try to parse Car Following Model params
1183 if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1184 return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1185 }
1186 // try to parse Lane Change Model params
1187 if (!parseLCParams(vType, vType->lcModel, attrs)) {
1188 return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1189 }
1190 // try to Junction Model params
1191 if (!parseJMParams(vType, attrs)) {
1192 return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1193 }
1194 // all ok, then return vType
1195 return vType;
1196 } else {
1197 return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1198 }
1199}
1200
1201
1202bool
1204 StringTokenizer st(atm, ",");
1205 std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1206 int tripletCount = 0;
1207 while (st.hasNext()) {
1208 StringTokenizer pos(st.next());
1209 if (pos.size() != 3) {
1210 WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1211 return false;
1212 } else {
1213 try {
1214 const int angle = StringUtils::toInt(pos.next());
1215 const SUMOTime t1 = string2time(pos.next());
1216 const SUMOTime t2 = string2time(pos.next());
1217 angleTimesMap[angle] = std::make_pair(t1, t2);
1218 } catch (...) {
1219 WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1220 return false;
1221 }
1222 tripletCount++;
1223 }
1224 }
1225 if (angleTimesMap.size() > 0) {
1226 vtype->myManoeuverAngleTimes.clear();
1227 for (const auto& angleTime : angleTimesMap) {
1228 vtype->myManoeuverAngleTimes.insert(angleTime);
1229 }
1230 angleTimesMap.clear();
1231 return true;
1232 } else {
1233 return false;
1234 }
1235}
1236
1237
1238bool
1239SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1240 const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1241 CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1242 // check if given CFM is allowed
1243 if (cf_it == allowedCFM.end()) {
1244 if (SUMOXMLDefinitions::Tags.has((int)element)) {
1245 WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1246 } else {
1247 WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1248 }
1249 return false;
1250 }
1251 // check if we're parsing a nested CFM
1252 if (nestedCFM) {
1253 into->cfModel = cf_it->first;
1255 }
1256 // set CFM values
1257 for (const auto& it : cf_it->second) {
1258 if (attrs.hasAttribute(it)) {
1259 // first obtain CFM attribute in string format
1260 bool ok = true;
1261 std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1262 // check CFM Attribute
1263 if (!ok) {
1264 return false;
1265 } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1266 // check if train value is valid
1267 if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1268 WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1269 return false;
1270 }
1271 // add parsedCFMAttribute to cfParameter
1272 into->cfParameter[it] = parsedCFMAttribute;
1274 into->cfParameter[it] = parsedCFMAttribute;
1275 } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1276 // declare a int in wich save CFM int attribute
1277 double CFMDoubleAttribute = -1;
1278 try {
1279 // obtain CFM attribute in int format
1280 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1281 } catch (...) {
1282 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1283 return false;
1284 }
1285 if (CFMDoubleAttribute <= 0) {
1286 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1287 return false;
1288 }
1289 // add parsedCFMAttribute to cfParameter
1290 into->cfParameter[it] = parsedCFMAttribute;
1291 } else if (it == SUMO_ATTR_MAXACCEL_PROFILE || it == SUMO_ATTR_DESACCEL_PROFILE) {
1292 if (validProfile(into, parsedCFMAttribute, it)) {
1293 into->cfParameter[it] = parsedCFMAttribute;
1294 } else {
1295 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed as a vector of <speed accel> pairs"), toString(it));
1296 return false;
1297 }
1298 } else {
1299 // declare a double in wich save CFM float attribute
1300 double CFMDoubleAttribute = -1;
1301 try {
1302 // obtain CFM attribute in double format
1303 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1304 } catch (...) {
1305 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1306 return false;
1307 }
1308 // check attributes of type "positiveFloatType" (> 0)
1309 switch (it) {
1310 case SUMO_ATTR_ACCEL:
1311 case SUMO_ATTR_DECEL:
1314 case SUMO_ATTR_TAU:
1315 if (CFMDoubleAttribute <= 0) {
1316 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1317 return false;
1318 }
1319 break;
1320 default:
1321 break;
1322 }
1323 // check attributes restricted to [0-1]
1324 switch (it) {
1325 case SUMO_ATTR_SIGMA:
1326 if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1327 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1328 return false;
1329 }
1330 break;
1331 default:
1332 break;
1333 }
1334 // add parsedCFMAttribute to cfParameter
1335 into->cfParameter[it] = parsedCFMAttribute;
1336 }
1337 }
1338 }
1339 // all CFM successfully parsed, then return true
1340 return true;
1341}
1342
1343
1346 // init on first use
1347 if (allowedCFModelAttrs.size() == 0) {
1348 std::set<SumoXMLAttr> genericParams;
1349 genericParams.insert(SUMO_ATTR_TAU);
1350 genericParams.insert(SUMO_ATTR_ACCEL);
1351 genericParams.insert(SUMO_ATTR_DECEL);
1352 genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1353 genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1354 genericParams.insert(SUMO_ATTR_SPEED_TABLE);
1355 genericParams.insert(SUMO_ATTR_MAXACCEL_PROFILE);
1356 genericParams.insert(SUMO_ATTR_DESACCEL_PROFILE);
1357 genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1358 genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1359 // Krauss
1360 std::set<SumoXMLAttr> kraussParams(genericParams);
1361 kraussParams.insert(SUMO_ATTR_SIGMA);
1362 kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1366 std::set<SumoXMLAttr> allParams(kraussParams);
1367 // KraussX
1368 std::set<SumoXMLAttr> kraussXParams(kraussParams);
1369 kraussXParams.insert(SUMO_ATTR_TMP1);
1370 kraussXParams.insert(SUMO_ATTR_TMP2);
1371 kraussXParams.insert(SUMO_ATTR_TMP3);
1372 kraussXParams.insert(SUMO_ATTR_TMP4);
1373 kraussXParams.insert(SUMO_ATTR_TMP5);
1375 allParams.insert(kraussXParams.begin(), kraussXParams.end());
1376 // SmartSK
1377 std::set<SumoXMLAttr> smartSKParams(genericParams);
1378 smartSKParams.insert(SUMO_ATTR_SIGMA);
1379 smartSKParams.insert(SUMO_ATTR_TMP1);
1380 smartSKParams.insert(SUMO_ATTR_TMP2);
1381 smartSKParams.insert(SUMO_ATTR_TMP3);
1382 smartSKParams.insert(SUMO_ATTR_TMP4);
1383 smartSKParams.insert(SUMO_ATTR_TMP5);
1385 allParams.insert(smartSKParams.begin(), smartSKParams.end());
1386 // Daniel
1387 std::set<SumoXMLAttr> daniel1Params(genericParams);
1388 daniel1Params.insert(SUMO_ATTR_SIGMA);
1389 daniel1Params.insert(SUMO_ATTR_TMP1);
1390 daniel1Params.insert(SUMO_ATTR_TMP2);
1391 daniel1Params.insert(SUMO_ATTR_TMP3);
1392 daniel1Params.insert(SUMO_ATTR_TMP4);
1393 daniel1Params.insert(SUMO_ATTR_TMP5);
1395 allParams.insert(daniel1Params.begin(), daniel1Params.end());
1396 // Peter Wagner
1397 std::set<SumoXMLAttr> pwagParams(genericParams);
1398 pwagParams.insert(SUMO_ATTR_SIGMA);
1399 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1400 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1402 allParams.insert(pwagParams.begin(), pwagParams.end());
1403 // IDM params
1404 std::set<SumoXMLAttr> idmParams(genericParams);
1405 idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1406 idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1408 allParams.insert(idmParams.begin(), idmParams.end());
1409 // EIDM
1410 std::set<SumoXMLAttr> eidmParams(genericParams);
1411 eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1412 eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1413 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1414 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1415 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1417 eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1418 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1419 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1420 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1421 eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1422 eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1423 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1424 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1425 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1426 eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1427 eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1429 allParams.insert(eidmParams.begin(), eidmParams.end());
1430 // IDMM
1431 std::set<SumoXMLAttr> idmmParams(genericParams);
1432 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1433 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1434 idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1436 allParams.insert(idmmParams.begin(), idmmParams.end());
1437 // Bieker
1438 std::set<SumoXMLAttr> bkernerParams(genericParams);
1439 bkernerParams.insert(SUMO_ATTR_K);
1440 bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1442 allParams.insert(bkernerParams.begin(), bkernerParams.end());
1443 // Wiedemann
1444 std::set<SumoXMLAttr> wiedemannParams(genericParams);
1445 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1446 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1447 allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1448 allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1449 // W99
1450 std::set<SumoXMLAttr> w99Params(genericParams);
1451 w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1452 w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1453 w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1454 w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1455 w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1456 w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1457 w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1458 w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1459 w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1461 allParams.insert(w99Params.begin(), w99Params.end());
1462 // Rail
1463 std::set<SumoXMLAttr> railParams(genericParams);
1464 railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1465 railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1466 railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1467 railParams.insert(SUMO_ATTR_MASSFACTOR);
1468 railParams.insert(SUMO_ATTR_MAXPOWER);
1469 railParams.insert(SUMO_ATTR_MAXTRACTION);
1471 railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1474 allParams.insert(railParams.begin(), railParams.end());
1475 // ACC
1476 std::set<SumoXMLAttr> ACCParams(genericParams);
1477 ACCParams.insert(SUMO_ATTR_SC_GAIN);
1478 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1479 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1480 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1481 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1482 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1483 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1484 ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1485 ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1487 allParams.insert(ACCParams.begin(), ACCParams.end());
1488 // CACC
1489 std::set<SumoXMLAttr> CACCParams(genericParams);
1490 CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1491 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1492 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1493 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1494 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1495 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1496 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1497 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1498 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1499 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1500 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1501 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1502 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1503 CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1504 CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1505 CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1506 CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1508 allParams.insert(CACCParams.begin(), CACCParams.end());
1509 // CC
1510 std::set<SumoXMLAttr> ccParams(genericParams);
1511 ccParams.insert(SUMO_ATTR_CF_CC_C1);
1512 ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1513 ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1514 ccParams.insert(SUMO_ATTR_CF_CC_KP);
1515 ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1516 ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1517 ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1518 ccParams.insert(SUMO_ATTR_CF_CC_XI);
1519 ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1520 ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1521 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1522 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1523 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1524 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1525 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1526 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1527 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1528 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1530 allParams.insert(ccParams.begin(), ccParams.end());
1531 // last element
1533 }
1534 return allowedCFModelAttrs;
1535}
1536
1537
1538bool
1540 if (allowedLCModelAttrs.size() == 0) {
1541 // lc2013
1542 std::set<SumoXMLAttr> lc2013Params;
1543 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1544 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1545 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1546 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1547 lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1548 lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1549 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1550 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1551 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1552 lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1553 lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1554 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD);
1555 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1556 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME);
1557 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_URGENCY);
1558 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1559 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1560 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1561 lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1562 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1563 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1564 lc2013Params.insert(SUMO_ATTR_LCA_CONTRIGHT);
1565 lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1567 // sl2015 (extension of lc2013)
1568 std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1569 sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1570 sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1571 sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1572 sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1573 sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1574 sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1575 sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1576 sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1578 // DK2008
1579 std::set<SumoXMLAttr> noParams;
1581 // default model may be either LC2013 or SL2015
1582 // we allow both sets (sl2015 is a superset of lc2013Params)
1584 }
1585 std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1586 // iterate over LCM attributes
1587 for (const auto& it : allowed) {
1588 if (attrs.hasAttribute(it)) {
1589 // first obtain CFM attribute in string format
1590 bool ok = true;
1591 std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1592 if (!ok) {
1593 return false;
1594 }
1595 // declare a double in wich save CFM attribute
1596 double LCMAttribute = -1;
1597 try {
1598 // obtain CFM attribute in double format
1599 LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1600 } catch (...) {
1601 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1602 return false;
1603 }
1604 // check attributes of type "nonNegativeFloatType" (>= 0)
1605 switch (it) {
1617 if (LCMAttribute < 0) {
1618 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1619 return false;
1620 }
1621 break;
1622 default:
1623 break;
1624 }
1625 // check attributes of type "positiveFloatType" (> 0)
1626 switch (it) {
1628 if (LCMAttribute <= 0) {
1629 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1630 return false;
1631 }
1632 break;
1633 default:
1634 break;
1635 }
1636 // check limits of attributes
1637 switch (it) {
1639 if (LCMAttribute < -1 || LCMAttribute > 1) {
1640 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1641 return false;
1642 }
1643 break;
1644 default:
1645 break;
1646 }
1647 // add parsedLCMAttribute to cfParameter
1648 into->lcParameter[it] = parsedLCMAttribute;
1649 }
1650 }
1651 // all LCM parsed ok, then return true
1652 return true;
1653}
1654
1655
1656bool
1658 for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1659 if (attrs.hasAttribute(it)) {
1660 // first obtain CFM attribute in string format
1661 bool ok = true;
1662 std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1663 if (!ok) {
1664 return false;
1665 }
1666 // declare a double in wich save CFM attribute
1667 double JMAttribute = INVALID_DOUBLE;
1668 try {
1669 // obtain CFM attribute in double format
1670 JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1671 } catch (...) {
1672 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1673 return false;
1674 }
1675 // now continue checking other properties (-1 is the default value)
1676 if (JMAttribute != INVALID_DOUBLE) {
1677 // special case for sigma minor
1678 if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1679 // check attributes sigma minor
1680 if ((JMAttribute < 0) || (JMAttribute > 1)) {
1681 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1682 return false;
1683 }
1684 } else if (JMAttribute < 0
1686 && it != SUMO_ATTR_JM_EXTRA_GAP) {
1687 // attributes with error value
1688 if (JMAttribute != -1 || (it != SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
1691 // check attributes of type "nonNegativeFloatType" (>= 0)
1692 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1693 return false;
1694 }
1695 }
1696 // add parsedJMAttribute to cfParameter
1697 into->jmParameter[it] = parsedJMAttribute;
1698 }
1699 }
1700 }
1701 // all JM parameters successfully parsed, then return true
1702 return true;
1703}
1704
1705
1709 bool ok = true;
1710 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1711 if (vclassS == "") {
1712 return vclass;
1713 }
1714 try {
1715 const SUMOVehicleClass result = getVehicleClassID(vclassS);
1716 const std::string& realName = SumoVehicleClassStrings.getString(result);
1717 if (realName != vclassS) {
1718 WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1719 }
1720 return result;
1721 } catch (...) {
1722 WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1723 }
1724 return vclass;
1725}
1726
1727
1729SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1730 bool ok = true;
1731 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1732 if (SumoVehicleShapeStrings.hasString(vclassS)) {
1733 const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1734 const std::string& realName = SumoVehicleShapeStrings.getString(result);
1735 if (realName != vclassS) {
1736 WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1737 }
1738 return result;
1739 } else {
1740 WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1742 }
1743}
1744
1745
1746double
1747SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1748 double result;
1749 std::string error;
1751 // only supports 'random' and 'max'
1752 if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1753 handleVehicleError(hardFail, nullptr, error);
1754 }
1755 if (proc == ArrivalPosDefinition::RANDOM) {
1756 result = RandHelper::rand(maxPos, rng);
1757 } else if (proc == ArrivalPosDefinition::CENTER) {
1758 result = maxPos / 2.;
1759 } else if (proc == ArrivalPosDefinition::MAX) {
1760 result = maxPos;
1761 }
1762 return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1763}
1764
1765
1768 const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1769 SUMOTime result = TIME2STEPS(given);
1770 if (result <= 0) {
1771 if (result < 0) {
1772 WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1773 }
1774 result = DELTA_T;
1775 } else if (result % DELTA_T != 0) {
1776 result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1777 result = MAX2(DELTA_T, result);
1778 if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1779 WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1780 }
1781 }
1782 return result;
1783}
1784
1785
1786bool
1788 return id.substr(0, 1) == "!";
1789}
1790
1791
1792bool
1793SUMOVehicleParserHelper::validProfile(SUMOVTypeParameter* vtype, const std::string data, const SumoXMLAttr attr) {
1794 for (std::string value : StringTokenizer(data).getVector()) {
1795 try {
1796 double v = StringUtils::toDouble(value);
1797 if (v < 0.) {
1798 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. An acceleration profile value cannot be negative"), toString(attr));
1799 return false;
1800 }
1801 } catch (...) {
1802 WRITE_ERRORF(TL("Entry '%' of % table for vType '%' cannot be parsed as 'double'"), value, toString(attr), vtype->id);
1803 return false;
1804 }
1805 }
1806 return true;
1807}
1808
1809
1810int
1812 int carWalk = 0;
1813 for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) {
1814 if (opt == "parkingAreas") {
1816 } else if (opt == "ptStops") {
1817 carWalk |= ModeChangeOptions::PT_STOPS;
1818 } else if (opt == "allJunctions") {
1820 } else {
1821 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1822 }
1823 }
1824 const StringVector taxiDropoff = oc.getStringVector("persontrip.transfer.taxi-walk");
1825 const StringVector taxiPickup = oc.getStringVector("persontrip.transfer.walk-taxi");
1826 if (taxiDropoff.empty() && hasTaxi) {
1828 } else {
1829 for (const std::string& opt : taxiDropoff) {
1830 if (opt == "parkingAreas") {
1832 } else if (opt == "ptStops") {
1834 } else if (opt == "allJunctions") {
1836 } else {
1837 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1838 }
1839 }
1840 }
1841 if (taxiPickup.empty() && hasTaxi) {
1843 } else {
1844 for (const std::string& opt : taxiPickup) {
1845 if (opt == "parkingAreas") {
1847 } else if (opt == "ptStops") {
1849 } else if (opt == "allJunctions") {
1851 } else {
1852 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1853 }
1854 }
1855 }
1856 return carWalk;
1857}
1858
1859
1861SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1862 if (vehicleParameter) {
1863 delete vehicleParameter;
1864 }
1865 if (hardFail) {
1866 throw ProcessError(message);
1867 } else if (message.size() > 0) {
1868 WRITE_ERROR(message);
1869 }
1870 return nullptr;
1871}
1872
1873
1875SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1876 if (vehicleTypeParameter) {
1877 delete vehicleTypeParameter;
1878 }
1879 if (hardFail) {
1880 throw ProcessError(message);
1881 } else if (message.size() > 0) {
1882 WRITE_ERROR(message);
1883 }
1884 return nullptr;
1885}
1886
1887/****************************************************************************/
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:288
#define WRITE_ERRORF(...)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:305
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:55
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TIME2STEPS(x)
Definition SUMOTime.h:57
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_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_CONTAINERFLOW
@ SUMO_TAG_CF_KRAUSS_PLUS_SLOPE
@ SUMO_TAG_CF_IDM
@ 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_CONTAINER
@ SUMO_TAG_PERSON
@ 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_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_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_CF_EIDM_USEVEHDYNAMICS
@ 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_CF_EIDM_C_COOLNESS
@ SUMO_ATTR_CF_EIDM_SIG_ERROR
@ SUMO_ATTR_LCA_PUSHYGAP
@ SUMO_ATTR_CA_GAIN_GAP_CACC
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_APPARENTDECEL
@ 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_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_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_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_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_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_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:64
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
std::vector< double > & getParameter()
Returns the parameters 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:191
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:202
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
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.
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 int parseCarWalkTransfer(const OptionsCont &oc, const bool hasTaxi=false)
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)
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 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 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)