Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
SUMOVehicleParserHelper.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2008-2026 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
23// Helper methods for parsing vehicle attributes
24/****************************************************************************/
25#include <config.h>
26
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<long long 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<long long 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<long long 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<long long int>::max();
318 } else {
319 const SUMOTime repLength = flowParameter->repetitionEnd - flowParameter->depart;
320 flowParameter->repetitionNumber = (long long 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, const SUMOVTypeParameter* const base) {
757 const std::string id = (attrs.hasAttribute(SUMO_ATTR_ID) || base == nullptr) ? parseID(attrs, SUMO_TAG_VTYPE) : "";
758 if (!id.empty()) {
759 // create vType
760 SUMOVehicleClass vClass = base == nullptr ? SVC_PASSENGER : base->vehicleClass;
761 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
762 vClass = parseVehicleClass(attrs, id);
763 }
764 SUMOVTypeParameter* vType;
765 if (base == nullptr) {
766 vType = new SUMOVTypeParameter(id, vClass);
767 } else {
768 vType = new SUMOVTypeParameter(*base);
769 vType->id = id;
770 vType->vehicleClass = vClass;
771 }
772 // parse attributes
773 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
775 }
776 if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
777 bool ok = true;
778 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, vType->id.c_str(), ok);
779 if (!ok) {
780 return handleVehicleTypeError(hardFail, vType);
781 } else if (length <= 0) {
782 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LENGTH) + " must be greater than 0");
783 } else {
784 vType->length = length;
786 }
787 }
788 if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
789 bool ok = true;
790 const double minGap = attrs.get<double>(SUMO_ATTR_MINGAP, vType->id.c_str(), ok);
791 if (!ok) {
792 return handleVehicleTypeError(hardFail, vType);
793 } else if (minGap < 0) {
794 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP) + " must be equal or greater than 0");
795 } else {
796 vType->minGap = minGap;
798 }
799 }
800 if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
801 bool ok = true;
802 const double maxSpeed = attrs.get<double>(SUMO_ATTR_MAXSPEED, vType->id.c_str(), ok);
803 if (!ok) {
804 return handleVehicleTypeError(hardFail, vType);
805 } else if (maxSpeed <= 0) {
806 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED) + " must be greater than 0");
807 } else {
808 vType->maxSpeed = maxSpeed;
810 }
811 }
813 bool ok = true;
814 const double desiredMaxSpeed = attrs.get<double>(SUMO_ATTR_DESIRED_MAXSPEED, vType->id.c_str(), ok);
815 if (!ok) {
816 return handleVehicleTypeError(hardFail, vType);
817 } else if (desiredMaxSpeed <= 0) {
818 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_DESIRED_MAXSPEED) + " must be greater than 0");
819 } else {
820 vType->desiredMaxSpeed = desiredMaxSpeed;
822 }
823 } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
824 if (vClass == SVC_PEDESTRIAN) {
825 // backward compatibility because pedestrian maxSpeed was subject to speedFactor up to 1.14.1
826 vType->desiredMaxSpeed = vType->maxSpeed;;
828 } else if (vClass == SVC_BICYCLE) {
829 // backward compatibility because default desired speed did not exist up to 1.14.1
830 vType->desiredMaxSpeed = MAX2(vType->maxSpeed, vType->desiredMaxSpeed);
831 }
832 }
833
835 bool ok = true;
836 vType->speedFactor.parse(attrs.get<std::string>(SUMO_ATTR_SPEEDFACTOR, vType->id.c_str(), ok), hardFail);
837 if (!ok) {
838 return handleVehicleTypeError(hardFail, vType);
839 } else {
841 }
842 }
843 if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
844 bool ok = true;
845 const double speedDev = attrs.get<double>(SUMO_ATTR_SPEEDDEV, vType->id.c_str(), ok);
846 if (!ok) {
847 return handleVehicleTypeError(hardFail, vType);
848 } else if (speedDev < 0) {
849 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SPEEDDEV) + " must be equal or greater than 0");
850 } else {
851 vType->speedFactor.setParameter(1, speedDev);
853 }
854 }
855 // validate speed distribution
856 const std::string& error = vType->speedFactor.isValid();
857 if (error != "") {
858 return handleVehicleTypeError(hardFail, vType, "Invalid speed distribution when parsing vType '" + vType->id + "' (" + error + ")");
859 }
861 bool ok = true;
862 const double actionStepLengthSecs = attrs.get<double>(SUMO_ATTR_ACTIONSTEPLENGTH, vType->id.c_str(), ok);
863 if (!ok) {
864 return handleVehicleTypeError(hardFail, vType);
865 } else {
866 // processActionStepLength(...) function includes warnings
867 vType->actionStepLength = processActionStepLength(actionStepLengthSecs);
869 }
870 }
872 bool ok = true;
873 const std::string parsedEmissionClass = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
874 // check if emission class is correct
875 try {
876 vType->emissionClass = PollutantsInterface::getClassByName(parsedEmissionClass);
878 } catch (...) {
879 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_EMISSIONCLASS) + " with name '" + parsedEmissionClass + "' doesn't exist.");
880 }
881 }
882 if (attrs.hasAttribute(SUMO_ATTR_MASS)) {
883 bool ok = true;
884 const double mass = attrs.get<double>(SUMO_ATTR_MASS, vType->id.c_str(), ok);
885 if (!ok) {
886 return handleVehicleTypeError(hardFail, vType);
887 } else if (mass < 0) {
888 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MASS) + " must be equal or greater than 0");
889 } else {
890 vType->mass = mass;
892 }
893 }
895 bool ok = true;
896 const std::string impatienceStr = attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
897 if (!ok) {
898 return handleVehicleTypeError(hardFail, vType);
899 } else if (impatienceStr == "off") {
900 vType->impatience = -std::numeric_limits<double>::max();
901 } else {
902 const double impatienceDouble = attrs.get<double>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
903 if (!ok) {
904 return handleVehicleTypeError(hardFail, vType);
905 } else {
906 vType->impatience = impatienceDouble;
908 }
909 }
910 }
911 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
912 bool ok = true;
913 const double width = attrs.get<double>(SUMO_ATTR_WIDTH, vType->id.c_str(), ok);
914 if (!ok) {
915 return handleVehicleTypeError(hardFail, vType);
916 } else if (width <= 0) {
917 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_WIDTH) + " must be greater than 0");
918 } else {
919 vType->width = width;
921 if (vClass == SVC_PEDESTRIAN
922 && OptionsCont::getOptions().exists("pedestrian.striping.stripe-width")
923 && OptionsCont::getOptions().getString("pedestrian.model") == "striping"
924 && OptionsCont::getOptions().getFloat("pedestrian.striping.stripe-width") < vType->width) {
925 WRITE_WARNINGF(TL("Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."), id, vType->width);
926 }
927 }
928 }
929 if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
930 bool ok = true;
931 const double height = attrs.get<double>(SUMO_ATTR_HEIGHT, vType->id.c_str(), ok);
932 if (!ok) {
933 return handleVehicleTypeError(hardFail, vType);
934 } else if (height < 0) {
935 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_HEIGHT) + " must be equal or greater than 0");
936 } else {
937 vType->height = height;
939 }
940 }
941 if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
942 vType->shape = parseGuiShape(attrs, vType->id);
943 if (vType->shape != SUMOVehicleShape::UNKNOWN) {
945 }
946 }
947 if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
948 bool ok = true;
949 const std::string osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vType->id.c_str(), ok);
950 if (!ok) {
951 return handleVehicleTypeError(hardFail, vType);
952 } else {
953 vType->osgFile = osgFile;
955 }
956 }
957 if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
958 bool ok = true;
959 std::string imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vType->id.c_str(), ok);
960 if (!ok) {
961 return handleVehicleTypeError(hardFail, vType);
962 } else {
963 // check relative path
964 if ((imgFile != "") && !FileHelpers::isAbsolute(imgFile)) {
965 imgFile = FileHelpers::getConfigurationRelative(file, imgFile);
966 }
967 vType->imgFile = imgFile;
969 }
970 }
971 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
972 bool ok = true;
973 const RGBColor color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vType->id.c_str(), ok);
974 if (!ok) {
975 return handleVehicleTypeError(hardFail, vType);
976 } else {
977 vType->color = color;
979 }
980 } else {
981 vType->color = RGBColor::YELLOW;
982 }
983 if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
984 bool ok = true;
985 const double defaultProbability = attrs.get<double>(SUMO_ATTR_PROB, vType->id.c_str(), ok);
986 if (!ok) {
987 return handleVehicleTypeError(hardFail, vType);
988 } else if (defaultProbability < 0) {
989 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PROB) + " must be equal or greater than 0");
990 } else {
991 vType->defaultProbability = defaultProbability;
993 }
994 }
996 bool ok = true;
997 std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vType->id.c_str(), ok);
998 if (!ok) {
999 return handleVehicleTypeError(hardFail, vType);
1000 } else if (lcmS == "JE2013") {
1001 WRITE_WARNING(TL("Lane change model 'JE2013' is deprecated. Using default model instead."));
1002 lcmS = "default";
1003 }
1004 if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
1007 } else {
1008 return handleVehicleTypeError(hardFail, vType, "Unknown lane change model '" + lcmS + "' when parsing vType '" + vType->id + "'");
1009 }
1010 }
1012 bool ok = true;
1013 const std::string cfmValue = attrs.get<std::string>(SUMO_ATTR_CAR_FOLLOW_MODEL, vType->id.c_str(), ok);
1014 if (!ok) {
1015 return handleVehicleTypeError(hardFail, vType);
1016 } else if (SUMOXMLDefinitions::CarFollowModels.hasString(cfmValue)) {
1019 } else {
1020 return handleVehicleTypeError(hardFail, vType, "Unknown car following model '" + cfmValue + "' when parsing vType '" + vType->id + "'");
1021 }
1022 }
1024 bool ok = true;
1025 const int personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, vType->id.c_str(), ok);
1026 if (!ok) {
1027 return handleVehicleTypeError(hardFail, vType);
1028 } else if (personCapacity < 0) {
1029 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PERSON_CAPACITY) + " must be equal or greater than 0");
1030 } else {
1031 vType->personCapacity = personCapacity;
1033 }
1034 }
1036 bool ok = true;
1037 const int containerCapacity = attrs.get<int>(SUMO_ATTR_CONTAINER_CAPACITY, vType->id.c_str(), ok);
1038 if (!ok) {
1039 return handleVehicleTypeError(hardFail, vType);
1040 } else if (containerCapacity < 0) {
1041 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_CONTAINER_CAPACITY) + " must be equal or greater than 0");
1042 } else {
1043 vType->containerCapacity = containerCapacity;
1045 }
1046 }
1048 bool ok = true;
1049 const SUMOTime boardingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_BOARDING_DURATION, vType->id.c_str(), ok);
1050 if (!ok) {
1051 return handleVehicleTypeError(hardFail, vType);
1052 } else if (boardingDuration < 0) {
1053 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_DURATION) + " must be equal or greater than 0");
1054 } else {
1055 vType->boardingDuration = boardingDuration;
1057 }
1058 }
1060 bool ok = true;
1061 const SUMOTime loadingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_LOADING_DURATION, vType->id.c_str(), ok);
1062 if (!ok) {
1063 return handleVehicleTypeError(hardFail, vType);
1064 } else if (loadingDuration < 0) {
1065 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LOADING_DURATION) + " must be equal or greater than 0");
1066 } else {
1067 vType->loadingDuration = loadingDuration;
1069 }
1070 }
1071 if (attrs.hasAttribute(SUMO_ATTR_SCALE)) {
1072 bool ok = true;
1073 const double scale = attrs.get<double>(SUMO_ATTR_SCALE, id.c_str(), ok);
1074 if (!ok) {
1075 return handleVehicleTypeError(hardFail, vType);
1076 } else if (scale < 0) {
1077 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SCALE) + " may be not be negative");
1078 } else {
1079 vType->scale = scale;
1081 }
1082 }
1084 bool ok = true;
1085 const SUMOTime ttt = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT, vType->id.c_str(), ok);
1086 if (!ok) {
1087 return handleVehicleTypeError(hardFail, vType);
1088 } else {
1089 vType->timeToTeleport = ttt;
1091 }
1092 }
1094 bool ok = true;
1095 const SUMOTime tttb = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT_BIDI, vType->id.c_str(), ok);
1096 if (!ok) {
1097 return handleVehicleTypeError(hardFail, vType);
1098 } else {
1099 vType->timeToTeleportBidi = tttb;
1101 }
1102 }
1104 bool ok = true;
1105 const double sfp = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR_PREMATURE, id.c_str(), ok);
1106 if (!ok) {
1107 return handleVehicleTypeError(hardFail, vType);
1108 } else {
1109 vType->speedFactorPremature = sfp;
1111 }
1112 }
1114 bool ok = true;
1115 const double bf = attrs.get<double>(SUMO_ATTR_BOARDING_FACTOR, id.c_str(), ok);
1116 if (!ok) {
1117 return handleVehicleTypeError(hardFail, vType);
1118 } else if (bf < 0) {
1119 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_FACTOR) + " must be equal or greater than 0");
1120 } else {
1121 vType->boardingFactor = bf;
1123 }
1124 }
1126 bool ok = true;
1127 const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1128 if (!ok) {
1129 return handleVehicleTypeError(hardFail, vType);
1130 } else if (maxSpeedLat <= 0) {
1131 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1132 } else {
1133 vType->maxSpeedLat = maxSpeedLat;
1135 }
1136 }
1138 bool ok = true;
1139 const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1140 if (!ok) {
1141 return handleVehicleTypeError(hardFail, vType);
1142 } else if (minGapLat < 0) {
1143 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1144 } else {
1145 vType->minGapLat = minGapLat;
1147 }
1148 }
1150 bool ok = true;
1151 const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1152 if (!ok) {
1153 return handleVehicleTypeError(hardFail, vType);
1154 } else {
1155 double lao;
1157 if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1158 vType->latAlignmentOffset = lao;
1159 vType->latAlignmentProcedure = lad;
1161 } else {
1162 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)");
1163 }
1164 }
1165 }
1167 bool ok = true;
1168 const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1169 if (!ok) {
1170 return handleVehicleTypeError(hardFail, vType);
1171 } else if (parseAngleTimesMap(vType, angleTimesS)) {
1173 } else {
1174 return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1175 }
1176 }
1178 bool ok = true;
1179 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1180 if (!ok) {
1181 return handleVehicleTypeError(hardFail, vType);
1182 } else {
1184 vType->parkingBadges = badges;
1185 }
1186 }
1187 // try to parse Car Following Model params
1188 if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1189 return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1190 }
1191 // try to parse Lane Change Model params
1192 if (!parseLCParams(vType, vType->lcModel, attrs)) {
1193 return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1194 }
1195 // try to Junction Model params
1196 if (!parseJMParams(vType, attrs)) {
1197 return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1198 }
1199 // all ok, then return vType
1200 return vType;
1201 } else if (base != nullptr) {
1202 return const_cast<SUMOVTypeParameter*>(base);
1203 } else {
1204 return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1205 }
1206}
1207
1208
1209bool
1211 StringTokenizer st(atm, ",");
1212 std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1213 int tripletCount = 0;
1214 while (st.hasNext()) {
1215 StringTokenizer pos(st.next());
1216 if (pos.size() != 3) {
1217 WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1218 return false;
1219 } else {
1220 try {
1221 const int angle = StringUtils::toInt(pos.next());
1222 const SUMOTime t1 = string2time(pos.next());
1223 const SUMOTime t2 = string2time(pos.next());
1224 angleTimesMap[angle] = std::make_pair(t1, t2);
1225 } catch (...) {
1226 WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1227 return false;
1228 }
1229 tripletCount++;
1230 }
1231 }
1232 if (angleTimesMap.size() > 0) {
1233 vtype->myManoeuverAngleTimes.clear();
1234 for (const auto& angleTime : angleTimesMap) {
1235 vtype->myManoeuverAngleTimes.insert(angleTime);
1236 }
1237 angleTimesMap.clear();
1238 return true;
1239 } else {
1240 return false;
1241 }
1242}
1243
1244
1245bool
1246SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1247 const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1248 CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1249 // check if given CFM is allowed
1250 if (cf_it == allowedCFM.end()) {
1251 if (SUMOXMLDefinitions::Tags.has((int)element)) {
1252 WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1253 } else {
1254 WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1255 }
1256 return false;
1257 }
1258 // check if we're parsing a nested CFM
1259 if (nestedCFM) {
1260 into->cfModel = cf_it->first;
1262 }
1263 // set CFM values
1264 for (const auto& it : cf_it->second) {
1265 if (attrs.hasAttribute(it)) {
1266 // first obtain CFM attribute in string format
1267 bool ok = true;
1268 std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1269 // check CFM Attribute
1270 if (!ok) {
1271 return false;
1272 } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1273 // check if train value is valid
1274 if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1275 WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1276 return false;
1277 }
1278 // add parsedCFMAttribute to cfParameter
1279 into->cfParameter[it] = parsedCFMAttribute;
1281 into->cfParameter[it] = parsedCFMAttribute;
1282 } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1283 // declare a int in wich save CFM int attribute
1284 double CFMDoubleAttribute = -1;
1285 try {
1286 // obtain CFM attribute in int format
1287 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1288 } catch (...) {
1289 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1290 return false;
1291 }
1292 if (CFMDoubleAttribute <= 0) {
1293 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1294 return false;
1295 }
1296 // add parsedCFMAttribute to cfParameter
1297 into->cfParameter[it] = parsedCFMAttribute;
1298 } else if (it == SUMO_ATTR_MAXACCEL_PROFILE || it == SUMO_ATTR_DESACCEL_PROFILE) {
1299 if (validProfile(into, parsedCFMAttribute, it)) {
1300 into->cfParameter[it] = parsedCFMAttribute;
1301 } else {
1302 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed as a vector of <speed accel> pairs"), toString(it));
1303 return false;
1304 }
1305 } else {
1306 // declare a double in wich save CFM float attribute
1307 double CFMDoubleAttribute = -1;
1308 try {
1309 // obtain CFM attribute in double format
1310 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1311 } catch (...) {
1312 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1313 return false;
1314 }
1315 // check attributes of type "positiveFloatType" (> 0)
1316 switch (it) {
1317 case SUMO_ATTR_ACCEL:
1318 case SUMO_ATTR_DECEL:
1321 case SUMO_ATTR_TAU:
1322 if (CFMDoubleAttribute <= 0) {
1323 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1324 return false;
1325 }
1326 break;
1327 default:
1328 break;
1329 }
1330 // check attributes restricted to [0-1]
1331 switch (it) {
1332 case SUMO_ATTR_SIGMA:
1333 if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1334 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1335 return false;
1336 }
1337 break;
1338 default:
1339 break;
1340 }
1341 // add parsedCFMAttribute to cfParameter
1342 into->cfParameter[it] = parsedCFMAttribute;
1343 }
1344 }
1345 }
1346 // all CFM successfully parsed, then return true
1347 return true;
1348}
1349
1350
1353 // init on first use
1354 if (allowedCFModelAttrs.size() == 0) {
1355 std::set<SumoXMLAttr> genericParams;
1356 genericParams.insert(SUMO_ATTR_TAU);
1357 genericParams.insert(SUMO_ATTR_ACCEL);
1358 genericParams.insert(SUMO_ATTR_DECEL);
1359 genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1360 genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1361 genericParams.insert(SUMO_ATTR_SPEED_TABLE);
1362 genericParams.insert(SUMO_ATTR_MAXACCEL_PROFILE);
1363 genericParams.insert(SUMO_ATTR_DESACCEL_PROFILE);
1364 genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1365 genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1366 // Krauss
1367 std::set<SumoXMLAttr> kraussParams(genericParams);
1368 kraussParams.insert(SUMO_ATTR_SIGMA);
1369 kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1373 std::set<SumoXMLAttr> allParams(kraussParams);
1374 // KraussX
1375 std::set<SumoXMLAttr> kraussXParams(kraussParams);
1376 kraussXParams.insert(SUMO_ATTR_TMP1);
1377 kraussXParams.insert(SUMO_ATTR_TMP2);
1378 kraussXParams.insert(SUMO_ATTR_TMP3);
1379 kraussXParams.insert(SUMO_ATTR_TMP4);
1380 kraussXParams.insert(SUMO_ATTR_TMP5);
1382 allParams.insert(kraussXParams.begin(), kraussXParams.end());
1383 // SmartSK
1384 std::set<SumoXMLAttr> smartSKParams(genericParams);
1385 smartSKParams.insert(SUMO_ATTR_SIGMA);
1386 smartSKParams.insert(SUMO_ATTR_TMP1);
1387 smartSKParams.insert(SUMO_ATTR_TMP2);
1388 smartSKParams.insert(SUMO_ATTR_TMP3);
1389 smartSKParams.insert(SUMO_ATTR_TMP4);
1390 smartSKParams.insert(SUMO_ATTR_TMP5);
1392 allParams.insert(smartSKParams.begin(), smartSKParams.end());
1393 // Daniel
1394 std::set<SumoXMLAttr> daniel1Params(genericParams);
1395 daniel1Params.insert(SUMO_ATTR_SIGMA);
1396 daniel1Params.insert(SUMO_ATTR_TMP1);
1397 daniel1Params.insert(SUMO_ATTR_TMP2);
1398 daniel1Params.insert(SUMO_ATTR_TMP3);
1399 daniel1Params.insert(SUMO_ATTR_TMP4);
1400 daniel1Params.insert(SUMO_ATTR_TMP5);
1402 allParams.insert(daniel1Params.begin(), daniel1Params.end());
1403 // Peter Wagner
1404 std::set<SumoXMLAttr> pwagParams(genericParams);
1405 pwagParams.insert(SUMO_ATTR_SIGMA);
1406 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1407 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1409 allParams.insert(pwagParams.begin(), pwagParams.end());
1410 // IDM params
1411 std::set<SumoXMLAttr> idmParams(genericParams);
1412 idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1413 idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1415 allParams.insert(idmParams.begin(), idmParams.end());
1416 // EIDM
1417 std::set<SumoXMLAttr> eidmParams(genericParams);
1418 eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1419 eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1420 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1421 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1422 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1424 eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1425 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1426 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1427 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1428 eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1429 eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1430 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1431 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1432 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1433 eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1434 eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1436 allParams.insert(eidmParams.begin(), eidmParams.end());
1437 // IDMM
1438 std::set<SumoXMLAttr> idmmParams(genericParams);
1439 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1440 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1441 idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1443 allParams.insert(idmmParams.begin(), idmmParams.end());
1444 // Bieker
1445 std::set<SumoXMLAttr> bkernerParams(genericParams);
1446 bkernerParams.insert(SUMO_ATTR_K);
1447 bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1449 allParams.insert(bkernerParams.begin(), bkernerParams.end());
1450 // Wiedemann
1451 std::set<SumoXMLAttr> wiedemannParams(genericParams);
1452 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1453 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1454 allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1455 allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1456 // W99
1457 std::set<SumoXMLAttr> w99Params(genericParams);
1458 w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1459 w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1460 w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1461 w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1462 w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1463 w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1464 w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1465 w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1466 w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1468 allParams.insert(w99Params.begin(), w99Params.end());
1469 // Rail
1470 std::set<SumoXMLAttr> railParams(genericParams);
1471 railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1472 railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1473 railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1474 railParams.insert(SUMO_ATTR_MASSFACTOR);
1475 railParams.insert(SUMO_ATTR_MAXPOWER);
1476 railParams.insert(SUMO_ATTR_MAXTRACTION);
1478 railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1480 railParams.insert(SUMO_ATTR_CURVE_RESISTANCE);
1481 railParams.insert(SUMO_ATTR_CURVE_INTEGRATION);
1482 railParams.insert(SUMO_ATTR_ROECKL_SHARP_RADIUS);
1483 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR);
1484 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR_SHARP);
1485 railParams.insert(SUMO_ATTR_ROECKL_OFFSET);
1486 railParams.insert(SUMO_ATTR_ROECKL_OFFSET_SHARP);
1488 allParams.insert(railParams.begin(), railParams.end());
1489 // ACC
1490 std::set<SumoXMLAttr> ACCParams(genericParams);
1491 ACCParams.insert(SUMO_ATTR_SC_GAIN);
1492 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1493 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1494 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1495 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1496 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1497 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1498 ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1499 ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1501 allParams.insert(ACCParams.begin(), ACCParams.end());
1502 // CACC
1503 std::set<SumoXMLAttr> CACCParams(genericParams);
1504 CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1505 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1506 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1507 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1508 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1509 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1510 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1511 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1512 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1513 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1514 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1515 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1516 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1517 CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1518 CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1519 CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1520 CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1522 allParams.insert(CACCParams.begin(), CACCParams.end());
1523 // CC
1524 std::set<SumoXMLAttr> ccParams(genericParams);
1525 ccParams.insert(SUMO_ATTR_CF_CC_C1);
1526 ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1527 ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1528 ccParams.insert(SUMO_ATTR_CF_CC_KP);
1529 ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1530 ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1531 ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1532 ccParams.insert(SUMO_ATTR_CF_CC_XI);
1533 ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1534 ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1535 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1536 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1537 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1538 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1539 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1540 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1541 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1542 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1544 allParams.insert(ccParams.begin(), ccParams.end());
1545 // last element
1547 }
1548 return allowedCFModelAttrs;
1549}
1550
1551
1552bool
1554 if (allowedLCModelAttrs.size() == 0) {
1555 // lc2013
1556 std::set<SumoXMLAttr> lc2013Params;
1557 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1558 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1559 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1560 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1561 lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1562 lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1563 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1564 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1565 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1566 lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1567 lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1568 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD);
1569 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1570 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME);
1571 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_URGENCY);
1572 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1573 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1574 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1575 lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1576 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1577 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1578 lc2013Params.insert(SUMO_ATTR_LCA_CONTRIGHT);
1579 lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1581 // sl2015 (extension of lc2013)
1582 std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1583 sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1584 sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1585 sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1586 sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1587 sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1588 sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1589 sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1590 sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1592 // DK2008
1593 std::set<SumoXMLAttr> noParams;
1595 // default model may be either LC2013 or SL2015
1596 // we allow both sets (sl2015 is a superset of lc2013Params)
1598 }
1599 std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1600 // iterate over LCM attributes
1601 for (const auto& it : allowed) {
1602 if (attrs.hasAttribute(it)) {
1603 // first obtain CFM attribute in string format
1604 bool ok = true;
1605 std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1606 if (!ok) {
1607 return false;
1608 }
1609 // declare a double in wich save CFM attribute
1610 double LCMAttribute = -1;
1611 try {
1612 // obtain CFM attribute in double format
1613 LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1614 } catch (...) {
1615 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1616 return false;
1617 }
1618 // check attributes of type "nonNegativeFloatType" (>= 0)
1619 switch (it) {
1631 if (LCMAttribute < 0) {
1632 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1633 return false;
1634 }
1635 break;
1636 default:
1637 break;
1638 }
1639 // check attributes of type "positiveFloatType" (> 0)
1640 switch (it) {
1642 if (LCMAttribute <= 0) {
1643 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1644 return false;
1645 }
1646 break;
1647 default:
1648 break;
1649 }
1650 // check limits of attributes
1651 switch (it) {
1653 if (LCMAttribute < -1 || LCMAttribute > 1) {
1654 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1655 return false;
1656 }
1657 break;
1658 default:
1659 break;
1660 }
1661 // add parsedLCMAttribute to cfParameter
1662 into->lcParameter[it] = parsedLCMAttribute;
1663 }
1664 }
1665 // all LCM parsed ok, then return true
1666 return true;
1667}
1668
1669
1670bool
1672 for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1673 if (attrs.hasAttribute(it)) {
1674 // first obtain CFM attribute in string format
1675 bool ok = true;
1676 std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1677 if (!ok) {
1678 return false;
1679 }
1680 // declare a double in wich save CFM attribute
1681 double JMAttribute = INVALID_DOUBLE;
1682 try {
1683 // obtain CFM attribute in double format
1684 JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1685 } catch (...) {
1686 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1687 return false;
1688 }
1689 // now continue checking other properties (-1 is the default value)
1690 if (JMAttribute != INVALID_DOUBLE) {
1691 // special case for sigma minor
1692 if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1693 // check attributes sigma minor
1694 if ((JMAttribute < 0) || (JMAttribute > 1)) {
1695 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1696 return false;
1697 }
1698 } else if (JMAttribute < 0
1700 && it != SUMO_ATTR_JM_EXTRA_GAP) {
1701 // attributes with error value
1702 if (JMAttribute != -1 || (it != SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
1705 // check attributes of type "nonNegativeFloatType" (>= 0)
1706 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1707 return false;
1708 }
1709 }
1710 // add parsedJMAttribute to cfParameter
1711 into->jmParameter[it] = parsedJMAttribute;
1712 }
1713 }
1714 }
1715 // all JM parameters successfully parsed, then return true
1716 return true;
1717}
1718
1719
1723 bool ok = true;
1724 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1725 if (vclassS == "") {
1726 return vclass;
1727 }
1728 try {
1729 const SUMOVehicleClass result = getVehicleClassID(vclassS);
1730 const std::string& realName = SumoVehicleClassStrings.getString(result);
1731 if (realName != vclassS) {
1732 WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1733 }
1734 return result;
1735 } catch (...) {
1736 WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1737 }
1738 return vclass;
1739}
1740
1741
1743SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1744 bool ok = true;
1745 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1746 if (SumoVehicleShapeStrings.hasString(vclassS)) {
1747 const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1748 const std::string& realName = SumoVehicleShapeStrings.getString(result);
1749 if (realName != vclassS) {
1750 WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1751 }
1752 return result;
1753 } else {
1754 WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1756 }
1757}
1758
1759
1760double
1761SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1762 double result;
1763 std::string error;
1765 // only supports 'random' and 'max'
1766 if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1767 handleVehicleError(hardFail, nullptr, error);
1768 }
1769 if (proc == ArrivalPosDefinition::RANDOM) {
1770 result = RandHelper::rand(maxPos, rng);
1771 } else if (proc == ArrivalPosDefinition::CENTER) {
1772 result = maxPos / 2.;
1773 } else if (proc == ArrivalPosDefinition::MAX) {
1774 result = maxPos;
1775 }
1776 return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1777}
1778
1779
1782 const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1783 SUMOTime result = TIME2STEPS(given);
1784 if (result <= 0) {
1785 if (result < 0) {
1786 WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1787 }
1788 result = DELTA_T;
1789 } else if (result % DELTA_T != 0 && OptionsCont::getOptions().exists("step-length")) {
1790 result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1791 result = MAX2(DELTA_T, result);
1792 if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1793 WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1794 }
1795 }
1796 return result;
1797}
1798
1799
1800bool
1802 return id.substr(0, 1) == "!";
1803}
1804
1805
1806bool
1807SUMOVehicleParserHelper::validProfile(SUMOVTypeParameter* vtype, const std::string data, const SumoXMLAttr attr) {
1808 for (std::string value : StringTokenizer(data).getVector()) {
1809 try {
1810 double v = StringUtils::toDouble(value);
1811 if (v < 0.) {
1812 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. An acceleration profile value cannot be negative"), toString(attr));
1813 return false;
1814 }
1815 } catch (...) {
1816 WRITE_ERRORF(TL("Entry '%' of % table for vType '%' cannot be parsed as 'double'"), value, toString(attr), vtype->id);
1817 return false;
1818 }
1819 }
1820 return true;
1821}
1822
1823
1824int
1826 int carWalk = 0;
1827 for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) {
1828 if (opt == "parkingAreas") {
1830 } else if (opt == "ptStops") {
1831 carWalk |= ModeChangeOptions::PT_STOPS;
1832 } else if (opt == "allJunctions") {
1834 } else {
1835 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1836 }
1837 }
1838 const StringVector taxiDropoff = oc.getStringVector("persontrip.transfer.taxi-walk");
1839 const StringVector taxiPickup = oc.getStringVector("persontrip.transfer.walk-taxi");
1840 if (taxiDropoff.empty() && hasTaxi) {
1842 } else {
1843 for (const std::string& opt : taxiDropoff) {
1844 if (opt == "parkingAreas") {
1846 } else if (opt == "ptStops") {
1848 } else if (opt == "allJunctions") {
1850 } else {
1851 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1852 }
1853 }
1854 }
1855 if (taxiPickup.empty() && hasTaxi) {
1857 } else {
1858 for (const std::string& opt : taxiPickup) {
1859 if (opt == "parkingAreas") {
1861 } else if (opt == "ptStops") {
1863 } else if (opt == "allJunctions") {
1865 } else {
1866 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1867 }
1868 }
1869 }
1870 return carWalk;
1871}
1872
1873
1875SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1876 if (vehicleParameter) {
1877 delete vehicleParameter;
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
1889SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1890 if (vehicleTypeParameter) {
1891 delete vehicleTypeParameter;
1892 }
1893 if (hardFail) {
1894 throw ProcessError(message);
1895 } else if (message.size() > 0) {
1896 WRITE_ERROR(message);
1897 }
1898 return nullptr;
1899}
1900
1901/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ TAXI_DROPOFF_ANYWHERE
taxi customer may exit anywhere
@ PT_STOPS
public transport stops and access
@ TAXI_PICKUP_ANYWHERE
taxi customer may be picked up anywhere
@ TAXI_PICKUP_PARKING_AREAS
taxi customer may be picked up at parking areas
@ TAXI_DROPOFF_PT
taxi customer may exit at public transport stops
@ TAXI_DROPOFF_PARKING_AREAS
taxi customer may exit at parking areas
@ ALL_JUNCTIONS
junctions with edges allowing the additional mode
@ TAXI_PICKUP_PT
taxi customer may be picked up at public transport stops
@ PARKING_AREAS
parking areas
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
std::vector< std::string > StringVector
Definition of a vector of strings.
Definition Option.h:42
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TIME2STEPS(x)
Definition SUMOTime.h:60
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_ROECKL_OFFSET_SHARP
@ SUMO_ATTR_CURVE_INTEGRATION
@ SUMO_ATTR_EMISSIONCLASS
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_CF_CC_LAMBDA
@ SUMO_ATTR_DEPARTEDGE
@ SUMO_ATTR_CF_CC_FLATBED_D
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_ARRIVALEDGE
@ SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_LCA_COOPERATIVE_SPEED
@ SUMO_ATTR_RESISTANCE_TABLE
@ SUMO_ATTR_MAXACCEL_PROFILE
@ SUMO_ATTR_ROECKL_NUMERATOR_SHARP
@ SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD
@ SUMO_ATTR_CF_CC_FLATBED_KA
@ SUMO_ATTR_CF_CC_PLOEG_KP
@ SUMO_ATTR_CF_WIEDEMANN_SECURITY
@ SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_LANE_DISCIPLINE
@ SUMO_ATTR_TRAIN_TYPE
@ SUMO_ATTR_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_CURVE_RESISTANCE
@ SUMO_ATTR_ROECKL_SHARP_RADIUS
@ SUMO_ATTR_MAXSPEED_LAT
@ SUMO_ATTR_GC_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_TMP3
@ SUMO_ATTR_MASSFACTOR
@ SUMO_ATTR_ACTIONSTEPLENGTH
@ SUMO_ATTR_CF_CC_PLOEG_H
@ SUMO_ATTR_LCA_MAXDISTLATSTANDING
@ SUMO_ATTR_LCA_IMPATIENCE
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_MINGAP
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_MAXTRACTION
@ SUMO_ATTR_CA_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_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_ROECKL_NUMERATOR
@ SUMO_ATTR_CF_EIDM_T_REACTION
@ SUMO_ATTR_JM_EXTRA_GAP
@ SUMO_ATTR_MODES
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_ESTIMATE
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_MAXPOWER
@ SUMO_ATTR_CF_PWAGNER2009_TAULAST
@ SUMO_ATTR_TIME_TO_TELEPORT_BIDI
@ SUMO_ATTR_CF_CC_PLOEG_KD
@ SUMO_ATTR_CF_CC_TAU
@ SUMO_ATTR_GC_GAIN_GAP_CACC
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_CF_EIDM_SIG_GAP
@ SUMO_ATTR_CAR_FOLLOW_MODEL
@ SUMO_ATTR_CF_EIDM_JERK_MAX
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_QUADRATIC
@ SUMO_ATTR_DECEL
@ SUMO_ATTR_LCA_MAXSPEEDLATSTANDING
@ SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_GUISHAPE
@ SUMO_ATTR_DESIRED_MAXSPEED
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_PERHOUR
@ SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD
@ SUMO_ATTR_LCA_CONTRIGHT
@ SUMO_ATTR_CONTAINER_CAPACITY
@ SUMO_ATTR_CF_CC_XI
@ SUMO_ATTR_CA_OVERRIDE
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_OPPOSITE_PARAM
@ SUMO_ATTR_BOARDING_FACTOR
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_CF_CC_CCDECEL
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME
@ SUMO_ATTR_GCC_GAIN_SPACE
@ SUMO_ATTR_MINGAP_LAT
@ SUMO_ATTR_EMERGENCYDECEL
@ SUMO_ATTR_CF_CC_FLATBED_H
@ SUMO_ATTR_CF_W99_CC3
@ SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR
@ SUMO_ATTR_CF_CC_LANES_COUNT
@ SUMO_ATTR_HEIGHT
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_LCA_SUBLANE_PARAM
@ SUMO_ATTR_LCA_SIGMA
@ SUMO_ATTR_LATALIGNMENT
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_CF_IDM_STEPPING
@ SUMO_ATTR_SIGMA_STEP
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
@ SUMO_ATTR_SPEED_TABLE
@ SUMO_ATTR_IMPATIENCE
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_VCLASS
@ SUMO_ATTR_ROECKL_OFFSET
@ SUMO_ATTR_ACCEL
@ SUMO_ATTR_BOARDING_DURATION
@ SUMO_ATTR_CF_CC_CONSTSPACING
@ SUMO_ATTR_CF_EIDM_M_FLATNESS
@ SUMO_ATTR_CF_W99_CC2
@ SUMO_ATTR_CF_W99_CC4
@ SUMO_ATTR_JM_SIGMA_MINOR
@ SUMO_ATTR_CF_W99_CC6
@ SUMO_ATTR_PROB
@ SUMO_ATTR_CF_EIDM_M_BEGIN
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE
@ SUMO_ATTR_TIME_TO_TELEPORT
@ SUMO_ATTR_SPEEDFACTOR
@ SUMO_ATTR_CA_GAIN_SPEED
@ SUMO_ATTR_CF_EIDM_SIG_LEADER
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_CF_CC_KP
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR
@ SUMO_ATTR_APPLYDRIVERSTATE
@ SUMO_ATTR_PERSON_NUMBER
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_CF_PWAGNER2009_APPROB
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_SIGMA
@ SUMO_ATTR_DESACCEL_PROFILE
@ SUMO_ATTR_K
@ SUMO_ATTR_TMP1
@ SUMO_ATTR_SPEEDFACTOR_PREMATURE
@ SUMO_ATTR_OSGFILE
@ SUMO_ATTR_LCA_OVERTAKE_RIGHT
@ SUMO_ATTR_ARRIVALPOS_LAT
@ SUMO_ATTR_LCA_ACCEL_LAT
@ SUMO_ATTR_CF_W99_CC7
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_TRACTION_TABLE
@ SUMO_ATTR_CF_W99_CC1
@ SUMO_ATTR_TAU
@ SUMO_ATTR_INSERTIONCHECKS
@ SUMO_ATTR_IMGFILE
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_PERSON_CAPACITY
@ SUMO_ATTR_GC_GAIN_SPEED
@ SUMO_ATTR_GCC_GAIN_GAP_CACC
@ SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME
@ SUMO_ATTR_LCA_EXPERIMENTAL1
@ SUMO_ATTR_SC_GAIN
@ SUMO_ATTR_TMP5
@ SUMO_ATTR_SC_GAIN_CACC
@ SUMO_ATTR_LCA_TIME_TO_IMPATIENCE
@ SUMO_ATTR_JM_TIMEGAP_MINOR
@ SUMO_ATTR_CF_CC_FLATBED_KV
@ SUMO_ATTR_LCA_SPEEDGAIN_URGENCY
@ SUMO_ATTR_SC_MIN_GAP
@ SUMO_ATTR_SPEEDDEV
@ SUMO_ATTR_CF_WIEDEMANN_ESTIMATION
@ SUMO_ATTR_PERSONSPERHOUR
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
void setParameter(const int index, const double value)
Set a parameter of this distribution.
const std::string isValid() const
check whether the distribution is valid
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
A storage for options typed value containers)
Definition OptionsCont.h:89
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
static const RGBColor YELLOW
Definition RGBColor.h:201
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:212
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getName(int attr) const =0
Converts the given attribute id into a man readable string.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
const std::string & getObjectType() const
return the objecttype to which these attributes belong
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
Structure representing possible vehicle parameter.
double width
This class' width.
SubParams cfParameter
Car-following parameter.
double defaultProbability
The probability when being added to a distribution without an explicit probability.
SUMOTime actionStepLength
The vehicle type's default actionStepLength [ms], i.e. the interval between two control actions....
double height
This class' height.
double desiredMaxSpeed
The vehicle type's desired maximum speed [m/s].
SUMOEmissionClass emissionClass
The emission class of this vehicle.
double latAlignmentOffset
(optional) The vehicle's desired lateral alignment as offset in m from center line
std::vector< std::string > parkingBadges
the parking access rights
static std::set< SumoXMLAttr > AllowedJMAttrs
allowed attrs for the junction model
double length
The physical vehicle length.
double maxSpeedLat
The vehicle type's maximum lateral speed [m/s].
double speedFactorPremature
the possible speed reduction when a train is ahead of schedule
RGBColor color
The color.
long long int parametersSet
Information for the router which parameter were set.
double minGap
This class' free space in front of the vehicle itself.
std::string imgFile
Image file for this class.
SUMOVehicleShape shape
This class' shape.
int personCapacity
The person capacity of the vehicle.
Distribution_Parameterized speedFactor
The factor by which the maximum speed may deviate from the allowed max speed on the street.
double scale
individual scaling factor (-1 for undefined)
SUMOTime timeToTeleport
the custom time-to-teleport for this type
std::string osgFile
3D model file for this class
double maxSpeed
The vehicle type's (technical) maximum speed [m/s].
SUMOTime timeToTeleportBidi
the custom time-to-teleport.bidi for this type
int containerCapacity
The container capacity of the vehicle.
SUMOTime boardingDuration
The time a person needs to board the vehicle.
double minGapLat
The vehicle type's minimum lateral gap [m].
double boardingFactor
factor for boardingDuration / loadingDuration
SUMOVehicleClass vehicleClass
The vehicle's class.
SUMOTime loadingDuration
The time a container needs to get loaded on the vehicle.
std::string id
The vehicle type's id.
SumoXMLTag cfModel
The enum-representation of the car-following model to use.
SubParams lcParameter
Lane-changing parameter.
LatAlignmentDefinition latAlignmentProcedure
Information on how the vehicle shall choose the lateral alignment.
SubParams jmParameter
Junction-model parameter.
double impatience
The vehicle's impatience (willingness to obstruct others)
std::map< int, std::pair< SUMOTime, SUMOTime > > myManoeuverAngleTimes
Map of manoeuver angles versus the times (entry, exit) to execute the manoeuver.
LaneChangeModel lcModel
The lane-change model to use.
static bool parseLatAlignment(const std::string &val, double &lao, LatAlignmentDefinition &lad)
Parses and validates a given latAlignment value.
Structure representing possible vehicle parameter.
double departPosLat
(optional) The lateral position the vehicle shall depart from
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
double repetitionProbability
The probability for emitting a vehicle per second.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
double departSpeed
(optional) The initial speed of the vehicle
SumoXMLTag tag
The vehicle tag.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
double speedFactor
individual speedFactor (overriding distribution from vType)
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
static bool parseArrivalPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosLatDefinition &apd, std::string &error)
Validates a given arrivalPosLat value.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons)
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
double poissonRate
The rate for emitting vehicles with a poisson distribution.
RouteIndexDefinition arrivalEdgeProcedure
Information how the vehicle's final edge shall be chosen.
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.
SVCPermissions modes
The modes a person or container can use.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string vTypes
The types of usable (auto-generated) vehicles for a person / container.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
RGBColor color
The vehicle's color, TraCI may change this.
double arrivalPos
(optional) The position the vehicle shall arrive on
static int parseInsertionChecks(const std::string &value)
parses insertion checks
double calibratorSpeed
speed (used by calibrator flows
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< std::string > parkingBadges
The parking access rights.
int departEdge
(optional) The initial edge within the route of the vehicle
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error, const std::string &attr="departure")
Validates a given depart value.
static bool parsePersonModes(const std::string &modes, const std::string &element, const std::string &id, SVCPermissions &modeSet, std::string &error)
Validates a given person modes value.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
static bool parseRouteIndex(const std::string &val, const std::string &element, const std::string &id, const SumoXMLAttr attr, int &edgeIndex, RouteIndexDefinition &rid, std::string &error)
Validates a given departEdge or arrivalEdge value.
static bool parseDepartPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosLatDefinition &dpd, std::string &error)
Validates a given departPosLat value.
std::string toTaz
The vehicle's destination zone (district)
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
static double interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string &id, bool silent=false)
Interprets negative edge positions and fits them onto a given edge.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
int insertionChecks
bitset of InsertionCheck
int arrivalEdge
(optional) The final edge within the route of the vehicle
std::string fromTaz
The vehicle's origin zone (district)
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::string line
The vehicle's line (mainly for public transport)
int containerNumber
The static number of containers in the vehicle when it departs.
RouteIndexDefinition departEdgeProcedure
Information how the vehicle's initial edge shall be chosen.
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
static const CFAttrMap & getAllowedCFModelAttrs()
returns allowed attrs for each known CF-model (init on first use)
static SUMOVTypeParameter * beginVTypeParsing(const SUMOSAXAttributes &attrs, const bool hardFail, const std::string &file, const SUMOVTypeParameter *const base)
Starts to parse a vehicle type.
static bool parseLCParams(SUMOVTypeParameter *into, LaneChangeModel model, const SUMOSAXAttributes &attrs)
Parses lane change model attributes.
static bool isInternalRouteID(const std::string &id)
Checks whether the route ID uses the syntax of internal routes.
std::map< SumoXMLTag, std::set< SumoXMLAttr > > CFAttrMap
Car-Following attributes map.
static int parseCarWalkTransfer(const OptionsCont &oc, const bool hasTaxi)
static std::string parseID(const SUMOSAXAttributes &attrs, const SumoXMLTag element)
parse ID
static bool parseCFMParams(SUMOVTypeParameter *into, const SumoXMLTag element, const SUMOSAXAttributes &attrs, const bool nestedCFM)
Parses Car Following Mode params.
static SUMOTime processActionStepLength(double given)
Checks and converts given value for the action step length from seconds to miliseconds assuring it be...
std::map< LaneChangeModel, std::set< SumoXMLAttr > > LCAttrMap
Lane-Change-Model attributes map.
static SUMOVTypeParameter * handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter *vehicleTypeParameter, const std::string message="")
handle error loading SUMOVTypeParameter
static void parseCommonAttributes(const SUMOSAXAttributes &attrs, SUMOVehicleParameter *ret, SumoXMLTag tag, const bool allowInternalRoutes=false)
Parses attributes common to vehicles and flows.
static bool parseAngleTimesMap(SUMOVTypeParameter *vtype, const std::string)
Parse string containing AngleTimes triplets (angle, entry time, exit time)
static SUMOVehicleParameter * parseVehicleAttributes(int element, const SUMOSAXAttributes &attrs, const bool hardFail, const bool optionalID=false, const bool skipDepart=false, const bool allowInternalRoutes=false)
Parses a vehicle's attributes.
static SUMOVehicleShape parseGuiShape(const SUMOSAXAttributes &attrs, const std::string &id)
Parses the vehicle class.
static SUMOVehicleClass parseVehicleClass(const SUMOSAXAttributes &attrs, const std::string &id)
Parses the vehicle class.
static 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)