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) {
757 // first obtain ID
758 std::string id = parseID(attrs, SUMO_TAG_VTYPE);
759 // check if ID is valid
760 if (!id.empty()) {
762 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
763 vClass = parseVehicleClass(attrs, id);
764 }
765 // create vType
766 SUMOVTypeParameter* vType = new SUMOVTypeParameter(id, vClass);
767 // parse attributes
768 if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
770 }
771 if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
772 bool ok = true;
773 const double length = attrs.get<double>(SUMO_ATTR_LENGTH, vType->id.c_str(), ok);
774 if (!ok) {
775 return handleVehicleTypeError(hardFail, vType);
776 } else if (length <= 0) {
777 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LENGTH) + " must be greater than 0");
778 } else {
779 vType->length = length;
781 }
782 }
783 if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
784 bool ok = true;
785 const double minGap = attrs.get<double>(SUMO_ATTR_MINGAP, vType->id.c_str(), ok);
786 if (!ok) {
787 return handleVehicleTypeError(hardFail, vType);
788 } else if (minGap < 0) {
789 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP) + " must be equal or greater than 0");
790 } else {
791 vType->minGap = minGap;
793 }
794 }
795 if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
796 bool ok = true;
797 const double maxSpeed = attrs.get<double>(SUMO_ATTR_MAXSPEED, vType->id.c_str(), ok);
798 if (!ok) {
799 return handleVehicleTypeError(hardFail, vType);
800 } else if (maxSpeed <= 0) {
801 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED) + " must be greater than 0");
802 } else {
803 vType->maxSpeed = maxSpeed;
805 }
806 }
808 bool ok = true;
809 const double desiredMaxSpeed = attrs.get<double>(SUMO_ATTR_DESIRED_MAXSPEED, vType->id.c_str(), ok);
810 if (!ok) {
811 return handleVehicleTypeError(hardFail, vType);
812 } else if (desiredMaxSpeed <= 0) {
813 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_DESIRED_MAXSPEED) + " must be greater than 0");
814 } else {
815 vType->desiredMaxSpeed = desiredMaxSpeed;
817 }
818 } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
819 if (vClass == SVC_PEDESTRIAN) {
820 // backward compatibility because pedestrian maxSpeed was subject to speedFactor up to 1.14.1
821 vType->desiredMaxSpeed = vType->maxSpeed;;
823 } else if (vClass == SVC_BICYCLE) {
824 // backward compatibility because default desired speed did not exist up to 1.14.1
825 vType->desiredMaxSpeed = MAX2(vType->maxSpeed, vType->desiredMaxSpeed);
826 }
827 }
828
830 bool ok = true;
831 vType->speedFactor.parse(attrs.get<std::string>(SUMO_ATTR_SPEEDFACTOR, vType->id.c_str(), ok), hardFail);
832 if (!ok) {
833 return handleVehicleTypeError(hardFail, vType);
834 } else {
836 }
837 }
838 if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
839 bool ok = true;
840 const double speedDev = attrs.get<double>(SUMO_ATTR_SPEEDDEV, vType->id.c_str(), ok);
841 if (!ok) {
842 return handleVehicleTypeError(hardFail, vType);
843 } else if (speedDev < 0) {
844 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SPEEDDEV) + " must be equal or greater than 0");
845 } else {
846 vType->speedFactor.setParameter(1, speedDev);
848 }
849 }
850 // validate speed distribution
851 const std::string& error = vType->speedFactor.isValid();
852 if (error != "") {
853 return handleVehicleTypeError(hardFail, vType, "Invalid speed distribution when parsing vType '" + vType->id + "' (" + error + ")");
854 }
856 bool ok = true;
857 const double actionStepLengthSecs = attrs.get<double>(SUMO_ATTR_ACTIONSTEPLENGTH, vType->id.c_str(), ok);
858 if (!ok) {
859 return handleVehicleTypeError(hardFail, vType);
860 } else {
861 // processActionStepLength(...) function includes warnings
862 vType->actionStepLength = processActionStepLength(actionStepLengthSecs);
864 }
865 }
867 bool ok = true;
868 const std::string parsedEmissionClass = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
869 // check if emission class is correct
870 try {
871 vType->emissionClass = PollutantsInterface::getClassByName(parsedEmissionClass);
873 } catch (...) {
874 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_EMISSIONCLASS) + " with name '" + parsedEmissionClass + "' doesn't exist.");
875 }
876 }
877 if (attrs.hasAttribute(SUMO_ATTR_MASS)) {
878 bool ok = true;
879 const double mass = attrs.get<double>(SUMO_ATTR_MASS, vType->id.c_str(), ok);
880 if (!ok) {
881 return handleVehicleTypeError(hardFail, vType);
882 } else if (mass < 0) {
883 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MASS) + " must be equal or greater than 0");
884 } else {
885 vType->mass = mass;
887 }
888 }
890 bool ok = true;
891 const std::string impatienceStr = attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
892 if (!ok) {
893 return handleVehicleTypeError(hardFail, vType);
894 } else if (impatienceStr == "off") {
895 vType->impatience = -std::numeric_limits<double>::max();
896 } else {
897 const double impatienceDouble = attrs.get<double>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
898 if (!ok) {
899 return handleVehicleTypeError(hardFail, vType);
900 } else {
901 vType->impatience = impatienceDouble;
903 }
904 }
905 }
906 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
907 bool ok = true;
908 const double width = attrs.get<double>(SUMO_ATTR_WIDTH, vType->id.c_str(), ok);
909 if (!ok) {
910 return handleVehicleTypeError(hardFail, vType);
911 } else if (width <= 0) {
912 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_WIDTH) + " must be greater than 0");
913 } else {
914 vType->width = width;
916 if (vClass == SVC_PEDESTRIAN
917 && OptionsCont::getOptions().exists("pedestrian.striping.stripe-width")
918 && OptionsCont::getOptions().getString("pedestrian.model") == "striping"
919 && OptionsCont::getOptions().getFloat("pedestrian.striping.stripe-width") < vType->width) {
920 WRITE_WARNINGF(TL("Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."), id, vType->width);
921 }
922 }
923 }
924 if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
925 bool ok = true;
926 const double height = attrs.get<double>(SUMO_ATTR_HEIGHT, vType->id.c_str(), ok);
927 if (!ok) {
928 return handleVehicleTypeError(hardFail, vType);
929 } else if (height < 0) {
930 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_HEIGHT) + " must be equal or greater than 0");
931 } else {
932 vType->height = height;
934 }
935 }
936 if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
937 vType->shape = parseGuiShape(attrs, vType->id);
938 if (vType->shape != SUMOVehicleShape::UNKNOWN) {
940 }
941 }
942 if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
943 bool ok = true;
944 const std::string osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vType->id.c_str(), ok);
945 if (!ok) {
946 return handleVehicleTypeError(hardFail, vType);
947 } else {
948 vType->osgFile = osgFile;
950 }
951 }
952 if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
953 bool ok = true;
954 std::string imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vType->id.c_str(), ok);
955 if (!ok) {
956 return handleVehicleTypeError(hardFail, vType);
957 } else {
958 // check relative path
959 if ((imgFile != "") && !FileHelpers::isAbsolute(imgFile)) {
960 imgFile = FileHelpers::getConfigurationRelative(file, imgFile);
961 }
962 vType->imgFile = imgFile;
964 }
965 }
966 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
967 bool ok = true;
968 const RGBColor color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vType->id.c_str(), ok);
969 if (!ok) {
970 return handleVehicleTypeError(hardFail, vType);
971 } else {
972 vType->color = color;
974 }
975 } else {
976 vType->color = RGBColor::YELLOW;
977 }
978 if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
979 bool ok = true;
980 const double defaultProbability = attrs.get<double>(SUMO_ATTR_PROB, vType->id.c_str(), ok);
981 if (!ok) {
982 return handleVehicleTypeError(hardFail, vType);
983 } else if (defaultProbability < 0) {
984 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PROB) + " must be equal or greater than 0");
985 } else {
986 vType->defaultProbability = defaultProbability;
988 }
989 }
991 bool ok = true;
992 std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vType->id.c_str(), ok);
993 if (!ok) {
994 return handleVehicleTypeError(hardFail, vType);
995 } else if (lcmS == "JE2013") {
996 WRITE_WARNING(TL("Lane change model 'JE2013' is deprecated. Using default model instead."));
997 lcmS = "default";
998 }
999 if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
1002 } else {
1003 return handleVehicleTypeError(hardFail, vType, "Unknown lane change model '" + lcmS + "' when parsing vType '" + vType->id + "'");
1004 }
1005 }
1007 bool ok = true;
1008 const std::string cfmValue = attrs.get<std::string>(SUMO_ATTR_CAR_FOLLOW_MODEL, vType->id.c_str(), ok);
1009 if (!ok) {
1010 return handleVehicleTypeError(hardFail, vType);
1011 } else if (SUMOXMLDefinitions::CarFollowModels.hasString(cfmValue)) {
1014 } else {
1015 return handleVehicleTypeError(hardFail, vType, "Unknown car following model '" + cfmValue + "' when parsing vType '" + vType->id + "'");
1016 }
1017 }
1019 bool ok = true;
1020 const int personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, vType->id.c_str(), ok);
1021 if (!ok) {
1022 return handleVehicleTypeError(hardFail, vType);
1023 } else if (personCapacity < 0) {
1024 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PERSON_CAPACITY) + " must be equal or greater than 0");
1025 } else {
1026 vType->personCapacity = personCapacity;
1028 }
1029 }
1031 bool ok = true;
1032 const int containerCapacity = attrs.get<int>(SUMO_ATTR_CONTAINER_CAPACITY, vType->id.c_str(), ok);
1033 if (!ok) {
1034 return handleVehicleTypeError(hardFail, vType);
1035 } else if (containerCapacity < 0) {
1036 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_CONTAINER_CAPACITY) + " must be equal or greater than 0");
1037 } else {
1038 vType->containerCapacity = containerCapacity;
1040 }
1041 }
1043 bool ok = true;
1044 const SUMOTime boardingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_BOARDING_DURATION, vType->id.c_str(), ok);
1045 if (!ok) {
1046 return handleVehicleTypeError(hardFail, vType);
1047 } else if (boardingDuration < 0) {
1048 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_DURATION) + " must be equal or greater than 0");
1049 } else {
1050 vType->boardingDuration = boardingDuration;
1052 }
1053 }
1055 bool ok = true;
1056 const SUMOTime loadingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_LOADING_DURATION, vType->id.c_str(), ok);
1057 if (!ok) {
1058 return handleVehicleTypeError(hardFail, vType);
1059 } else if (loadingDuration < 0) {
1060 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LOADING_DURATION) + " must be equal or greater than 0");
1061 } else {
1062 vType->loadingDuration = loadingDuration;
1064 }
1065 }
1066 if (attrs.hasAttribute(SUMO_ATTR_SCALE)) {
1067 bool ok = true;
1068 const double scale = attrs.get<double>(SUMO_ATTR_SCALE, id.c_str(), ok);
1069 if (!ok) {
1070 return handleVehicleTypeError(hardFail, vType);
1071 } else if (scale < 0) {
1072 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SCALE) + " may be not be negative");
1073 } else {
1074 vType->scale = scale;
1076 }
1077 }
1079 bool ok = true;
1080 const SUMOTime ttt = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT, vType->id.c_str(), ok);
1081 if (!ok) {
1082 return handleVehicleTypeError(hardFail, vType);
1083 } else {
1084 vType->timeToTeleport = ttt;
1086 }
1087 }
1089 bool ok = true;
1090 const SUMOTime tttb = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT_BIDI, vType->id.c_str(), ok);
1091 if (!ok) {
1092 return handleVehicleTypeError(hardFail, vType);
1093 } else {
1094 vType->timeToTeleportBidi = tttb;
1096 }
1097 }
1099 bool ok = true;
1100 const double sfp = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR_PREMATURE, id.c_str(), ok);
1101 if (!ok) {
1102 return handleVehicleTypeError(hardFail, vType);
1103 } else {
1104 vType->speedFactorPremature = sfp;
1106 }
1107 }
1109 bool ok = true;
1110 const double bf = attrs.get<double>(SUMO_ATTR_BOARDING_FACTOR, id.c_str(), ok);
1111 if (!ok) {
1112 return handleVehicleTypeError(hardFail, vType);
1113 } else if (bf < 0) {
1114 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_FACTOR) + " must be equal or greater than 0");
1115 } else {
1116 vType->boardingFactor = bf;
1118 }
1119 }
1121 bool ok = true;
1122 const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1123 if (!ok) {
1124 return handleVehicleTypeError(hardFail, vType);
1125 } else if (maxSpeedLat <= 0) {
1126 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1127 } else {
1128 vType->maxSpeedLat = maxSpeedLat;
1130 }
1131 }
1133 bool ok = true;
1134 const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1135 if (!ok) {
1136 return handleVehicleTypeError(hardFail, vType);
1137 } else if (minGapLat < 0) {
1138 return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1139 } else {
1140 vType->minGapLat = minGapLat;
1142 }
1143 }
1145 bool ok = true;
1146 const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1147 if (!ok) {
1148 return handleVehicleTypeError(hardFail, vType);
1149 } else {
1150 double lao;
1152 if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1153 vType->latAlignmentOffset = lao;
1154 vType->latAlignmentProcedure = lad;
1156 } else {
1157 return handleVehicleTypeError(hardFail, vType, "Unknown lateral alignment '" + alignS + "' when parsing vType '" + vType->id + "';\n must be one of (\"right\", \"center\", \"arbitrary\", \"nice\", \"compact\", \"left\" or a float)");
1158 }
1159 }
1160 }
1162 bool ok = true;
1163 const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1164 if (!ok) {
1165 return handleVehicleTypeError(hardFail, vType);
1166 } else if (parseAngleTimesMap(vType, angleTimesS)) {
1168 } else {
1169 return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1170 }
1171 }
1173 bool ok = true;
1174 std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1175 if (!ok) {
1176 return handleVehicleTypeError(hardFail, vType);
1177 } else {
1179 vType->parkingBadges = badges;
1180 }
1181 }
1182 // try to parse Car Following Model params
1183 if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1184 return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1185 }
1186 // try to parse Lane Change Model params
1187 if (!parseLCParams(vType, vType->lcModel, attrs)) {
1188 return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1189 }
1190 // try to Junction Model params
1191 if (!parseJMParams(vType, attrs)) {
1192 return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1193 }
1194 // all ok, then return vType
1195 return vType;
1196 } else {
1197 return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1198 }
1199}
1200
1201
1202bool
1204 StringTokenizer st(atm, ",");
1205 std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1206 int tripletCount = 0;
1207 while (st.hasNext()) {
1208 StringTokenizer pos(st.next());
1209 if (pos.size() != 3) {
1210 WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1211 return false;
1212 } else {
1213 try {
1214 const int angle = StringUtils::toInt(pos.next());
1215 const SUMOTime t1 = string2time(pos.next());
1216 const SUMOTime t2 = string2time(pos.next());
1217 angleTimesMap[angle] = std::make_pair(t1, t2);
1218 } catch (...) {
1219 WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1220 return false;
1221 }
1222 tripletCount++;
1223 }
1224 }
1225 if (angleTimesMap.size() > 0) {
1226 vtype->myManoeuverAngleTimes.clear();
1227 for (const auto& angleTime : angleTimesMap) {
1228 vtype->myManoeuverAngleTimes.insert(angleTime);
1229 }
1230 angleTimesMap.clear();
1231 return true;
1232 } else {
1233 return false;
1234 }
1235}
1236
1237
1238bool
1239SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1240 const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1241 CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1242 // check if given CFM is allowed
1243 if (cf_it == allowedCFM.end()) {
1244 if (SUMOXMLDefinitions::Tags.has((int)element)) {
1245 WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1246 } else {
1247 WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1248 }
1249 return false;
1250 }
1251 // check if we're parsing a nested CFM
1252 if (nestedCFM) {
1253 into->cfModel = cf_it->first;
1255 }
1256 // set CFM values
1257 for (const auto& it : cf_it->second) {
1258 if (attrs.hasAttribute(it)) {
1259 // first obtain CFM attribute in string format
1260 bool ok = true;
1261 std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1262 // check CFM Attribute
1263 if (!ok) {
1264 return false;
1265 } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1266 // check if train value is valid
1267 if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1268 WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1269 return false;
1270 }
1271 // add parsedCFMAttribute to cfParameter
1272 into->cfParameter[it] = parsedCFMAttribute;
1274 into->cfParameter[it] = parsedCFMAttribute;
1275 } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1276 // declare a int in wich save CFM int attribute
1277 double CFMDoubleAttribute = -1;
1278 try {
1279 // obtain CFM attribute in int format
1280 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1281 } catch (...) {
1282 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1283 return false;
1284 }
1285 if (CFMDoubleAttribute <= 0) {
1286 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1287 return false;
1288 }
1289 // add parsedCFMAttribute to cfParameter
1290 into->cfParameter[it] = parsedCFMAttribute;
1291 } else if (it == SUMO_ATTR_MAXACCEL_PROFILE || it == SUMO_ATTR_DESACCEL_PROFILE) {
1292 if (validProfile(into, parsedCFMAttribute, it)) {
1293 into->cfParameter[it] = parsedCFMAttribute;
1294 } else {
1295 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed as a vector of <speed accel> pairs"), toString(it));
1296 return false;
1297 }
1298 } else {
1299 // declare a double in wich save CFM float attribute
1300 double CFMDoubleAttribute = -1;
1301 try {
1302 // obtain CFM attribute in double format
1303 CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1304 } catch (...) {
1305 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1306 return false;
1307 }
1308 // check attributes of type "positiveFloatType" (> 0)
1309 switch (it) {
1310 case SUMO_ATTR_ACCEL:
1311 case SUMO_ATTR_DECEL:
1314 case SUMO_ATTR_TAU:
1315 if (CFMDoubleAttribute <= 0) {
1316 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1317 return false;
1318 }
1319 break;
1320 default:
1321 break;
1322 }
1323 // check attributes restricted to [0-1]
1324 switch (it) {
1325 case SUMO_ATTR_SIGMA:
1326 if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1327 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1328 return false;
1329 }
1330 break;
1331 default:
1332 break;
1333 }
1334 // add parsedCFMAttribute to cfParameter
1335 into->cfParameter[it] = parsedCFMAttribute;
1336 }
1337 }
1338 }
1339 // all CFM successfully parsed, then return true
1340 return true;
1341}
1342
1343
1346 // init on first use
1347 if (allowedCFModelAttrs.size() == 0) {
1348 std::set<SumoXMLAttr> genericParams;
1349 genericParams.insert(SUMO_ATTR_TAU);
1350 genericParams.insert(SUMO_ATTR_ACCEL);
1351 genericParams.insert(SUMO_ATTR_DECEL);
1352 genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1353 genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1354 genericParams.insert(SUMO_ATTR_SPEED_TABLE);
1355 genericParams.insert(SUMO_ATTR_MAXACCEL_PROFILE);
1356 genericParams.insert(SUMO_ATTR_DESACCEL_PROFILE);
1357 genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1358 genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1359 // Krauss
1360 std::set<SumoXMLAttr> kraussParams(genericParams);
1361 kraussParams.insert(SUMO_ATTR_SIGMA);
1362 kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1366 std::set<SumoXMLAttr> allParams(kraussParams);
1367 // KraussX
1368 std::set<SumoXMLAttr> kraussXParams(kraussParams);
1369 kraussXParams.insert(SUMO_ATTR_TMP1);
1370 kraussXParams.insert(SUMO_ATTR_TMP2);
1371 kraussXParams.insert(SUMO_ATTR_TMP3);
1372 kraussXParams.insert(SUMO_ATTR_TMP4);
1373 kraussXParams.insert(SUMO_ATTR_TMP5);
1375 allParams.insert(kraussXParams.begin(), kraussXParams.end());
1376 // SmartSK
1377 std::set<SumoXMLAttr> smartSKParams(genericParams);
1378 smartSKParams.insert(SUMO_ATTR_SIGMA);
1379 smartSKParams.insert(SUMO_ATTR_TMP1);
1380 smartSKParams.insert(SUMO_ATTR_TMP2);
1381 smartSKParams.insert(SUMO_ATTR_TMP3);
1382 smartSKParams.insert(SUMO_ATTR_TMP4);
1383 smartSKParams.insert(SUMO_ATTR_TMP5);
1385 allParams.insert(smartSKParams.begin(), smartSKParams.end());
1386 // Daniel
1387 std::set<SumoXMLAttr> daniel1Params(genericParams);
1388 daniel1Params.insert(SUMO_ATTR_SIGMA);
1389 daniel1Params.insert(SUMO_ATTR_TMP1);
1390 daniel1Params.insert(SUMO_ATTR_TMP2);
1391 daniel1Params.insert(SUMO_ATTR_TMP3);
1392 daniel1Params.insert(SUMO_ATTR_TMP4);
1393 daniel1Params.insert(SUMO_ATTR_TMP5);
1395 allParams.insert(daniel1Params.begin(), daniel1Params.end());
1396 // Peter Wagner
1397 std::set<SumoXMLAttr> pwagParams(genericParams);
1398 pwagParams.insert(SUMO_ATTR_SIGMA);
1399 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1400 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1402 allParams.insert(pwagParams.begin(), pwagParams.end());
1403 // IDM params
1404 std::set<SumoXMLAttr> idmParams(genericParams);
1405 idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1406 idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1408 allParams.insert(idmParams.begin(), idmParams.end());
1409 // EIDM
1410 std::set<SumoXMLAttr> eidmParams(genericParams);
1411 eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1412 eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1413 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1414 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1415 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1417 eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1418 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1419 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1420 eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1421 eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1422 eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1423 eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1424 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1425 eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1426 eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1427 eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1429 allParams.insert(eidmParams.begin(), eidmParams.end());
1430 // IDMM
1431 std::set<SumoXMLAttr> idmmParams(genericParams);
1432 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1433 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1434 idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1436 allParams.insert(idmmParams.begin(), idmmParams.end());
1437 // Bieker
1438 std::set<SumoXMLAttr> bkernerParams(genericParams);
1439 bkernerParams.insert(SUMO_ATTR_K);
1440 bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1442 allParams.insert(bkernerParams.begin(), bkernerParams.end());
1443 // Wiedemann
1444 std::set<SumoXMLAttr> wiedemannParams(genericParams);
1445 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1446 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1447 allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1448 allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1449 // W99
1450 std::set<SumoXMLAttr> w99Params(genericParams);
1451 w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1452 w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1453 w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1454 w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1455 w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1456 w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1457 w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1458 w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1459 w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1461 allParams.insert(w99Params.begin(), w99Params.end());
1462 // Rail
1463 std::set<SumoXMLAttr> railParams(genericParams);
1464 railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1465 railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1466 railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1467 railParams.insert(SUMO_ATTR_MASSFACTOR);
1468 railParams.insert(SUMO_ATTR_MAXPOWER);
1469 railParams.insert(SUMO_ATTR_MAXTRACTION);
1471 railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1473 railParams.insert(SUMO_ATTR_CURVE_RESISTANCE);
1474 railParams.insert(SUMO_ATTR_ROECKL_SHARP_RADIUS);
1475 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR);
1476 railParams.insert(SUMO_ATTR_ROECKL_NUMERATOR_SHARP);
1477 railParams.insert(SUMO_ATTR_ROECKL_OFFSET);
1478 railParams.insert(SUMO_ATTR_ROECKL_OFFSET_SHARP);
1480 allParams.insert(railParams.begin(), railParams.end());
1481 // ACC
1482 std::set<SumoXMLAttr> ACCParams(genericParams);
1483 ACCParams.insert(SUMO_ATTR_SC_GAIN);
1484 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1485 ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1486 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1487 ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1488 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1489 ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1490 ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1491 ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1493 allParams.insert(ACCParams.begin(), ACCParams.end());
1494 // CACC
1495 std::set<SumoXMLAttr> CACCParams(genericParams);
1496 CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1497 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1498 CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1499 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1500 CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1501 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1502 CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1503 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1504 CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1505 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1506 CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1507 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1508 CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1509 CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1510 CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1511 CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1512 CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1514 allParams.insert(CACCParams.begin(), CACCParams.end());
1515 // CC
1516 std::set<SumoXMLAttr> ccParams(genericParams);
1517 ccParams.insert(SUMO_ATTR_CF_CC_C1);
1518 ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1519 ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1520 ccParams.insert(SUMO_ATTR_CF_CC_KP);
1521 ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1522 ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1523 ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1524 ccParams.insert(SUMO_ATTR_CF_CC_XI);
1525 ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1526 ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1527 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1528 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1529 ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1530 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1531 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1532 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1533 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1534 ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1536 allParams.insert(ccParams.begin(), ccParams.end());
1537 // last element
1539 }
1540 return allowedCFModelAttrs;
1541}
1542
1543
1544bool
1546 if (allowedLCModelAttrs.size() == 0) {
1547 // lc2013
1548 std::set<SumoXMLAttr> lc2013Params;
1549 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1550 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1551 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1552 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1553 lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1554 lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1555 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1556 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1557 lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1558 lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1559 lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1560 lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_LOOKAHEAD);
1561 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1562 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME);
1563 lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_URGENCY);
1564 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1565 lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1566 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1567 lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1568 lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1569 lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1570 lc2013Params.insert(SUMO_ATTR_LCA_CONTRIGHT);
1571 lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1573 // sl2015 (extension of lc2013)
1574 std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1575 sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1576 sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1577 sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1578 sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1579 sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1580 sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1581 sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1582 sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1584 // DK2008
1585 std::set<SumoXMLAttr> noParams;
1587 // default model may be either LC2013 or SL2015
1588 // we allow both sets (sl2015 is a superset of lc2013Params)
1590 }
1591 std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1592 // iterate over LCM attributes
1593 for (const auto& it : allowed) {
1594 if (attrs.hasAttribute(it)) {
1595 // first obtain CFM attribute in string format
1596 bool ok = true;
1597 std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1598 if (!ok) {
1599 return false;
1600 }
1601 // declare a double in wich save CFM attribute
1602 double LCMAttribute = -1;
1603 try {
1604 // obtain CFM attribute in double format
1605 LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1606 } catch (...) {
1607 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1608 return false;
1609 }
1610 // check attributes of type "nonNegativeFloatType" (>= 0)
1611 switch (it) {
1623 if (LCMAttribute < 0) {
1624 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1625 return false;
1626 }
1627 break;
1628 default:
1629 break;
1630 }
1631 // check attributes of type "positiveFloatType" (> 0)
1632 switch (it) {
1634 if (LCMAttribute <= 0) {
1635 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1636 return false;
1637 }
1638 break;
1639 default:
1640 break;
1641 }
1642 // check limits of attributes
1643 switch (it) {
1645 if (LCMAttribute < -1 || LCMAttribute > 1) {
1646 WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1647 return false;
1648 }
1649 break;
1650 default:
1651 break;
1652 }
1653 // add parsedLCMAttribute to cfParameter
1654 into->lcParameter[it] = parsedLCMAttribute;
1655 }
1656 }
1657 // all LCM parsed ok, then return true
1658 return true;
1659}
1660
1661
1662bool
1664 for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1665 if (attrs.hasAttribute(it)) {
1666 // first obtain CFM attribute in string format
1667 bool ok = true;
1668 std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1669 if (!ok) {
1670 return false;
1671 }
1672 // declare a double in wich save CFM attribute
1673 double JMAttribute = INVALID_DOUBLE;
1674 try {
1675 // obtain CFM attribute in double format
1676 JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1677 } catch (...) {
1678 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1679 return false;
1680 }
1681 // now continue checking other properties (-1 is the default value)
1682 if (JMAttribute != INVALID_DOUBLE) {
1683 // special case for sigma minor
1684 if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1685 // check attributes sigma minor
1686 if ((JMAttribute < 0) || (JMAttribute > 1)) {
1687 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1688 return false;
1689 }
1690 } else if (JMAttribute < 0
1692 && it != SUMO_ATTR_JM_EXTRA_GAP) {
1693 // attributes with error value
1694 if (JMAttribute != -1 || (it != SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
1697 // check attributes of type "nonNegativeFloatType" (>= 0)
1698 WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1699 return false;
1700 }
1701 }
1702 // add parsedJMAttribute to cfParameter
1703 into->jmParameter[it] = parsedJMAttribute;
1704 }
1705 }
1706 }
1707 // all JM parameters successfully parsed, then return true
1708 return true;
1709}
1710
1711
1715 bool ok = true;
1716 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1717 if (vclassS == "") {
1718 return vclass;
1719 }
1720 try {
1721 const SUMOVehicleClass result = getVehicleClassID(vclassS);
1722 const std::string& realName = SumoVehicleClassStrings.getString(result);
1723 if (realName != vclassS) {
1724 WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1725 }
1726 return result;
1727 } catch (...) {
1728 WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1729 }
1730 return vclass;
1731}
1732
1733
1735SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1736 bool ok = true;
1737 std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1738 if (SumoVehicleShapeStrings.hasString(vclassS)) {
1739 const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1740 const std::string& realName = SumoVehicleShapeStrings.getString(result);
1741 if (realName != vclassS) {
1742 WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1743 }
1744 return result;
1745 } else {
1746 WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1748 }
1749}
1750
1751
1752double
1753SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1754 double result;
1755 std::string error;
1757 // only supports 'random' and 'max'
1758 if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1759 handleVehicleError(hardFail, nullptr, error);
1760 }
1761 if (proc == ArrivalPosDefinition::RANDOM) {
1762 result = RandHelper::rand(maxPos, rng);
1763 } else if (proc == ArrivalPosDefinition::CENTER) {
1764 result = maxPos / 2.;
1765 } else if (proc == ArrivalPosDefinition::MAX) {
1766 result = maxPos;
1767 }
1768 return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1769}
1770
1771
1774 const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1775 SUMOTime result = TIME2STEPS(given);
1776 if (result <= 0) {
1777 if (result < 0) {
1778 WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1779 }
1780 result = DELTA_T;
1781 } else if (result % DELTA_T != 0 && OptionsCont::getOptions().exists("step-length")) {
1782 result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1783 result = MAX2(DELTA_T, result);
1784 if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1785 WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1786 }
1787 }
1788 return result;
1789}
1790
1791
1792bool
1794 return id.substr(0, 1) == "!";
1795}
1796
1797
1798bool
1799SUMOVehicleParserHelper::validProfile(SUMOVTypeParameter* vtype, const std::string data, const SumoXMLAttr attr) {
1800 for (std::string value : StringTokenizer(data).getVector()) {
1801 try {
1802 double v = StringUtils::toDouble(value);
1803 if (v < 0.) {
1804 WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. An acceleration profile value cannot be negative"), toString(attr));
1805 return false;
1806 }
1807 } catch (...) {
1808 WRITE_ERRORF(TL("Entry '%' of % table for vType '%' cannot be parsed as 'double'"), value, toString(attr), vtype->id);
1809 return false;
1810 }
1811 }
1812 return true;
1813}
1814
1815
1816int
1818 int carWalk = 0;
1819 for (const std::string& opt : oc.getStringVector("persontrip.transfer.car-walk")) {
1820 if (opt == "parkingAreas") {
1822 } else if (opt == "ptStops") {
1823 carWalk |= ModeChangeOptions::PT_STOPS;
1824 } else if (opt == "allJunctions") {
1826 } else {
1827 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1828 }
1829 }
1830 const StringVector taxiDropoff = oc.getStringVector("persontrip.transfer.taxi-walk");
1831 const StringVector taxiPickup = oc.getStringVector("persontrip.transfer.walk-taxi");
1832 if (taxiDropoff.empty() && hasTaxi) {
1834 } else {
1835 for (const std::string& opt : taxiDropoff) {
1836 if (opt == "parkingAreas") {
1838 } else if (opt == "ptStops") {
1840 } else if (opt == "allJunctions") {
1842 } else {
1843 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1844 }
1845 }
1846 }
1847 if (taxiPickup.empty() && hasTaxi) {
1849 } else {
1850 for (const std::string& opt : taxiPickup) {
1851 if (opt == "parkingAreas") {
1853 } else if (opt == "ptStops") {
1855 } else if (opt == "allJunctions") {
1857 } else {
1858 WRITE_ERRORF(TL("Invalid transfer option '%'. Must be one of 'parkingAreas', 'ptStops' and 'allJunctions'"), opt);
1859 }
1860 }
1861 }
1862 return carWalk;
1863}
1864
1865
1867SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1868 if (vehicleParameter) {
1869 delete vehicleParameter;
1870 }
1871 if (hardFail) {
1872 throw ProcessError(message);
1873 } else if (message.size() > 0) {
1874 WRITE_ERROR(message);
1875 }
1876 return nullptr;
1877}
1878
1879
1881SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1882 if (vehicleTypeParameter) {
1883 delete vehicleTypeParameter;
1884 }
1885 if (hardFail) {
1886 throw ProcessError(message);
1887 } else if (message.size() > 0) {
1888 WRITE_ERROR(message);
1889 }
1890 return nullptr;
1891}
1892
1893/****************************************************************************/
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_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:195
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:206
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
virtual std::string getName(int attr) const =0
Converts the given attribute id into a man readable string.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
const std::string & getObjectType() const
return the objecttype to which these attributes belong
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
Structure representing possible vehicle parameter.
double width
This class' width.
SubParams cfParameter
Car-following parameter.
double defaultProbability
The probability when being added to a distribution without an explicit probability.
SUMOTime actionStepLength
The vehicle type's default actionStepLength [ms], i.e. the interval between two control actions....
double height
This class' height.
double desiredMaxSpeed
The vehicle type's desired maximum speed [m/s].
SUMOEmissionClass emissionClass
The emission class of this vehicle.
double latAlignmentOffset
(optional) The vehicle's desired lateral alignment as offset in m from center line
std::vector< std::string > parkingBadges
the parking access rights
static std::set< SumoXMLAttr > AllowedJMAttrs
allowed attrs for the junction model
double length
The physical vehicle length.
double maxSpeedLat
The vehicle type's maximum lateral speed [m/s].
double speedFactorPremature
the possible speed reduction when a train is ahead of schedule
RGBColor color
The color.
long long int parametersSet
Information for the router which parameter were set.
double minGap
This class' free space in front of the vehicle itself.
std::string imgFile
Image file for this class.
SUMOVehicleShape shape
This class' shape.
int personCapacity
The person capacity of the vehicle.
Distribution_Parameterized speedFactor
The factor by which the maximum speed may deviate from the allowed max speed on the street.
double scale
individual scaling factor (-1 for undefined)
SUMOTime timeToTeleport
the custom time-to-teleport for this type
std::string osgFile
3D model file for this class
double maxSpeed
The vehicle type's (technical) maximum speed [m/s].
SUMOTime timeToTeleportBidi
the custom time-to-teleport.bidi for this type
int containerCapacity
The container capacity of the vehicle.
SUMOTime boardingDuration
The time a person needs to board the vehicle.
double minGapLat
The vehicle type's minimum lateral gap [m].
double boardingFactor
factor for boardingDuration / loadingDuration
SUMOTime loadingDuration
The time a container needs to get loaded on the vehicle.
std::string id
The vehicle type's id.
SumoXMLTag cfModel
The enum-representation of the car-following model to use.
SubParams lcParameter
Lane-changing parameter.
LatAlignmentDefinition latAlignmentProcedure
Information on how the vehicle shall choose the lateral alignment.
SubParams jmParameter
Junction-model parameter.
double impatience
The vehicle's impatience (willingness to obstruct others)
std::map< int, std::pair< SUMOTime, SUMOTime > > myManoeuverAngleTimes
Map of manoeuver angles versus the times (entry, exit) to execute the manoeuver.
LaneChangeModel lcModel
The lane-change model to use.
static bool parseLatAlignment(const std::string &val, double &lao, LatAlignmentDefinition &lad)
Parses and validates a given latAlignment value.
Structure representing possible vehicle parameter.
double departPosLat
(optional) The lateral position the vehicle shall depart from
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
double repetitionProbability
The probability for emitting a vehicle per second.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
double departSpeed
(optional) The initial speed of the vehicle
SumoXMLTag tag
The vehicle tag.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
double speedFactor
individual speedFactor (overriding distribution from vType)
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
static bool parseArrivalPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosLatDefinition &apd, std::string &error)
Validates a given arrivalPosLat value.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons)
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
double poissonRate
The rate for emitting vehicles with a poisson distribution.
RouteIndexDefinition arrivalEdgeProcedure
Information how the vehicle's final edge shall be chosen.
DepartPosLatDefinition departPosLatProcedure
Information how the vehicle shall choose the lateral departure position.
SVCPermissions modes
The modes a person or container can use.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string vTypes
The types of usable (auto-generated) vehicles for a person / container.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
RGBColor color
The vehicle's color, TraCI may change this.
double arrivalPos
(optional) The position the vehicle shall arrive on
static int parseInsertionChecks(const std::string &value)
parses insertion checks
double calibratorSpeed
speed (used by calibrator flows
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< std::string > parkingBadges
The parking access rights.
int departEdge
(optional) The initial edge within the route of the vehicle
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error, const std::string &attr="departure")
Validates a given depart value.
static bool parsePersonModes(const std::string &modes, const std::string &element, const std::string &id, SVCPermissions &modeSet, std::string &error)
Validates a given person modes value.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
static bool parseRouteIndex(const std::string &val, const std::string &element, const std::string &id, const SumoXMLAttr attr, int &edgeIndex, RouteIndexDefinition &rid, std::string &error)
Validates a given departEdge or arrivalEdge value.
static bool parseDepartPosLat(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosLatDefinition &dpd, std::string &error)
Validates a given departPosLat value.
std::string toTaz
The vehicle's destination zone (district)
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
static double interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string &id, bool silent=false)
Interprets negative edge positions and fits them onto a given edge.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
int insertionChecks
bitset of InsertionCheck
int arrivalEdge
(optional) The final edge within the route of the vehicle
std::string fromTaz
The vehicle's origin zone (district)
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::string line
The vehicle's line (mainly for public transport)
int containerNumber
The static number of containers in the vehicle when it departs.
RouteIndexDefinition departEdgeProcedure
Information how the vehicle's initial edge shall be chosen.
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
static const CFAttrMap & getAllowedCFModelAttrs()
returns allowed attrs for each known CF-model (init on first use)
static SUMOVTypeParameter * beginVTypeParsing(const SUMOSAXAttributes &attrs, const bool hardFail, const std::string &file)
Starts to parse a vehicle type.
static bool parseLCParams(SUMOVTypeParameter *into, LaneChangeModel model, const SUMOSAXAttributes &attrs)
Parses lane change model attributes.
static bool isInternalRouteID(const std::string &id)
Checks whether the route ID uses the syntax of internal routes.
std::map< SumoXMLTag, std::set< SumoXMLAttr > > CFAttrMap
Car-Following attributes map.
static 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)