Eclipse SUMO - Simulation of Urban MObility
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-2024 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 
32 #include <utils/common/ToString.h>
39 
41 
42 
43 // ===========================================================================
44 // static members
45 // ===========================================================================
46 
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 
56 SUMOVehicleParserHelper::parseFlowAttributes(SumoXMLTag tag, const SUMOSAXAttributes& attrs, const bool hardFail, const bool needID,
57  const SUMOTime beginDefault, const SUMOTime endDefault, const bool allowInternalRoutes) {
58  // first parse ID
59  const std::string id = attrs.hasAttribute(SUMO_ATTR_ID) ? parseID(attrs, tag) : "";
60  // check if ID is valid
61  if (!needID || !id.empty()) {
62  if (needID && !SUMOXMLDefinitions::isValidVehicleID(id)) {
63  return handleVehicleError(hardFail, nullptr, "Invalid flow id '" + id + "'.");
64  }
65  // declare flags
66  const bool hasPeriod = attrs.hasAttribute(SUMO_ATTR_PERIOD);
67  const bool hasVPH = attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR);
68  const bool hasPPH = attrs.hasAttribute(SUMO_ATTR_PERSONSPERHOUR);
69  const bool hasCPH = attrs.hasAttribute(SUMO_ATTR_CONTAINERSPERHOUR);
70  const bool hasPH = attrs.hasAttribute(SUMO_ATTR_PERHOUR);
71  const bool hasXPH = hasVPH || hasPPH || hasCPH || hasPH;
72  const bool hasProb = attrs.hasAttribute(SUMO_ATTR_PROB);
73  const bool hasNumber = attrs.hasAttribute(SUMO_ATTR_NUMBER);
74  const bool hasBegin = attrs.hasAttribute(SUMO_ATTR_BEGIN);
75  const bool hasEnd = attrs.hasAttribute(SUMO_ATTR_END);
77  if (hasVPH) {
78  PERHOUR = SUMO_ATTR_VEHSPERHOUR;
79  }
80  if (hasPPH) {
81  PERHOUR = SUMO_ATTR_PERSONSPERHOUR;
82  }
83  if (hasCPH) {
85  }
86  if (hasXPH && !(hasVPH ^ hasPPH ^ hasCPH ^ hasPH)) {
87  return handleVehicleError(hardFail, nullptr,
88  "At most one of '" + attrs.getName(SUMO_ATTR_PERHOUR) +
89  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
90  "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
91  "' and '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
92  "' has to be given in the definition of " + toString(tag) + " '" + id + "'.");
93  }
94  if (hasPeriod && hasXPH) {
95  return handleVehicleError(hardFail, nullptr,
96  "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
97  "' and '" + attrs.getName(PERHOUR) +
98  "' has to be given in the definition of "
99  + toString(tag) + " '" + id + "'.");
100  }
101  if (hasPeriod && hasProb) {
102  return handleVehicleError(hardFail, nullptr,
103  "At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
104  "' and '" + attrs.getName(SUMO_ATTR_PROB) +
105  "' has to be given in the definition of "
106  + toString(tag) + " '" + id + "'.");
107  }
108  if (hasProb && hasXPH) {
109  return handleVehicleError(hardFail, nullptr,
110  "At most one of '" + attrs.getName(SUMO_ATTR_PROB) +
111  "' and '" + attrs.getName(PERHOUR) +
112  "' has to be given in the definition of "
113  + toString(tag) + " '" + id + "'.");
114  }
115  if (hasPeriod || hasXPH || hasProb) {
116  if (hasEnd && hasNumber) {
117  return handleVehicleError(hardFail, nullptr,
118  "If '" + attrs.getName(SUMO_ATTR_PERIOD) +
119  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
120  "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
121  "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
122  "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
123  "' or '" + attrs.getName(SUMO_ATTR_PROB) +
124  "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
125  "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
126  "' are allowed in "
127  + toString(tag) + " '" + id + "'.");
128  }
129  } else {
130  if (!hasNumber) {
131  return handleVehicleError(hardFail, nullptr,
132  "At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
133  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
134  "', '" + attrs.getName(SUMO_ATTR_PERSONSPERHOUR) +
135  "', '" + attrs.getName(SUMO_ATTR_CONTAINERSPERHOUR) +
136  "', '" + attrs.getName(SUMO_ATTR_PERHOUR) +
137  "', '" + attrs.getName(SUMO_ATTR_PROB) +
138  "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
139  "' is needed in "
140  + toString(tag) + " '" + id + "'.");
141  }
142  }
143  // declare flow
144  SUMOVehicleParameter* flowParameter = new SUMOVehicleParameter();
145  // set tag
146  flowParameter->tag = tag;
147  // set id
148  flowParameter->id = id;
149  if (tag == SUMO_TAG_PERSONFLOW) {
150  flowParameter->vtypeid = DEFAULT_PEDTYPE_ID;
151  }
152  if (tag == SUMO_TAG_CONTAINERFLOW) {
153  flowParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
154  }
155  // parse common vehicle attributes
156  try {
157  parseCommonAttributes(attrs, flowParameter, tag, allowInternalRoutes);
158  } catch (ProcessError& attributeError) {
159  // check if continue handling another vehicles or stop handling
160  if (hardFail) {
161  throw ProcessError(attributeError.what());
162  } else {
163  return nullptr;
164  }
165  }
166  // parse period
167  bool poissonFlow = false;
168  if (hasPeriod) {
169  bool ok = true;
170  const std::string description = attrs.get<std::string>(SUMO_ATTR_PERIOD, id.c_str(), ok);
171  const std::string distName = description.substr(0, description.find('('));
172  if (distName == "exp") {
173  // declare rate
174  double rate = -1;
175  // parse rate
176  try {
177  rate = StringUtils::toDouble(description.substr(distName.size() + 1, description.size() - distName.size() - 2));
178  } catch (ProcessError& attributeError) {
179  // check if continue handling another vehicles or stop handling
180  if (hardFail) {
181  throw ProcessError(attributeError.what());
182  } else {
183  return nullptr;
184  }
185  }
186  if (rate <= 0) {
187  return handleVehicleError(hardFail, flowParameter, "Invalid rate parameter for exponentially distributed period in the definition of " + toString(tag) + " '" + id + "'.");
188  }
189  flowParameter->poissonRate = rate;
190  poissonFlow = true;
191  } else {
192  flowParameter->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
193  }
194  if (!ok) {
195  return handleVehicleError(hardFail, flowParameter);
196  } else {
197  flowParameter->parametersSet |= VEHPARS_PERIOD_SET;
198  }
199  }
200  // parse vehicle/person/container/etc per hour
201  if (hasXPH) {
202  bool ok = true;
203  const double vph = attrs.get<double>(PERHOUR, id.c_str(), ok);
204  if (!ok) {
205  return handleVehicleError(hardFail, flowParameter);
206  } else if (vph <= 0) {
207  return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
208  } else {
209  if (vph != 0) {
210  flowParameter->repetitionOffset = TIME2STEPS(3600. / vph);
211  }
212  flowParameter->parametersSet |= VEHPARS_VPH_SET;
213  }
214  }
215  // parse probability
216  if (hasProb) {
217  bool ok = true;
218  flowParameter->repetitionProbability = attrs.get<double>(SUMO_ATTR_PROB, id.c_str(), ok);
219  if (!ok) {
220  return handleVehicleError(hardFail, flowParameter);
221  } else if (flowParameter->repetitionProbability <= 0 || flowParameter->repetitionProbability > 1) {
222  return handleVehicleError(hardFail, flowParameter, "Invalid repetition probability in the definition of " + toString(tag) + " '" + id + "'.");
223  } else {
224  flowParameter->parametersSet |= VEHPARS_PROB_SET;
225  }
226  }
227  // set default begin
228  flowParameter->depart = beginDefault;
229  // parse begin
230  if (hasBegin) {
231  // first get begin
232  bool ok = true;
233  const std::string begin = attrs.get<std::string>(SUMO_ATTR_BEGIN, id.c_str(), ok);
234  if (!ok) {
235  return handleVehicleError(hardFail, flowParameter);
236  } else {
237  // parse begin
238  std::string errorMsg;
239  if (!SUMOVehicleParameter::parseDepart(begin, toString(tag), id, flowParameter->depart, flowParameter->departProcedure, errorMsg, "begin")) {
240  return handleVehicleError(hardFail, flowParameter, errorMsg);
241  }
242  }
243  }
244  if (flowParameter->depart < 0) {
245  return handleVehicleError(hardFail, flowParameter, "Negative begin time in the definition of " + toString(tag) + " '" + id + "'.");
246  }
247  // set default end
248  flowParameter->repetitionEnd = endDefault;
249  if (flowParameter->repetitionEnd < 0) {
250  flowParameter->repetitionEnd = SUMOTime_MAX;
251  }
252  // parse end
253  if (hasEnd) {
254  bool ok = true;
255  flowParameter->repetitionEnd = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
256  if (!ok) {
257  return handleVehicleError(hardFail, flowParameter);
258  } else {
259  flowParameter->parametersSet |= VEHPARS_END_SET;
260  }
261  } else if (flowParameter->departProcedure == DepartDefinition::TRIGGERED) {
262  if (!hasNumber) {
263  return handleVehicleError(hardFail, flowParameter, toString(tag) + " '" + id + "' with triggered begin must define 'number'.");
264  } else {
265  flowParameter->repetitionEnd = flowParameter->depart;
266  }
267  } else if ((endDefault == SUMOTime_MAX || endDefault < 0) && (!hasNumber || (!hasProb && !hasPeriod && !hasXPH))) {
268  WRITE_WARNINGF(TL("Undefined end for % '%', defaulting to 24hour duration."), toString(tag), id);
269  flowParameter->repetitionEnd = flowParameter->depart + TIME2STEPS(24 * 3600);
270  }
271  if (flowParameter->repetitionEnd < flowParameter->depart) {
272  std::string flow = toString(tag);
273  flow[0] = (char)::toupper((char)flow[0]);
274  return handleVehicleError(hardFail, flowParameter, flow + " '" + id + "' ends before its begin time.");
275  }
276  // parse number
277  if (hasNumber) {
278  bool ok = true;
279  flowParameter->repetitionNumber = attrs.get<int>(SUMO_ATTR_NUMBER, id.c_str(), ok);
280  if (!ok) {
281  return handleVehicleError(hardFail, flowParameter);
282  } else {
283  flowParameter->parametersSet |= VEHPARS_NUMBER_SET;
284  if (flowParameter->repetitionNumber == 0) {
285  std::string flow = toString(tag);
286  flow[0] = (char)::toupper((char)flow[0]);
287  WRITE_WARNING(flow + " '" + id + "' has no instances; will skip it.");
288  flowParameter->repetitionEnd = flowParameter->depart;
289  } else {
290  if (flowParameter->repetitionNumber < 0) {
291  return handleVehicleError(hardFail, flowParameter, "Negative repetition number in the definition of " + toString(tag) + " '" + id + "'.");
292  }
293  if (flowParameter->repetitionOffset < 0 && !hasProb) {
294  if (poissonFlow) {
295  flowParameter->repetitionEnd = SUMOTime_MAX;
296  } else {
297  flowParameter->repetitionOffset = (flowParameter->repetitionEnd - flowParameter->depart) / flowParameter->repetitionNumber;
298  }
299  }
300  }
301  }
302  } else {
303  // interpret repetitionNumber
304  if (flowParameter->repetitionProbability > 0) {
305  flowParameter->repetitionNumber = std::numeric_limits<int>::max();
306  } else {
307  if (flowParameter->repetitionOffset <= 0) {
308  if (poissonFlow) {
309  // number is random but flow has a fixed end time
310  flowParameter->repetitionNumber = std::numeric_limits<int>::max();
311  } else {
312  return handleVehicleError(hardFail, flowParameter, "Invalid repetition rate in the definition of " + toString(tag) + " '" + id + "'.");
313  }
314  } else {
315  if (flowParameter->repetitionEnd == SUMOTime_MAX) {
316  flowParameter->repetitionNumber = std::numeric_limits<int>::max();
317  } else {
318  const SUMOTime repLength = flowParameter->repetitionEnd - flowParameter->depart;
319  flowParameter->repetitionNumber = (int)ceil((double)repLength / (double)flowParameter->repetitionOffset);
320  }
321  }
322  }
323  }
324  // all ok, then return flow parameter
325  return flowParameter;
326  } else {
327  return handleVehicleError(hardFail, nullptr, toString(tag) + " cannot be created");
328  }
329 }
330 
331 
333 SUMOVehicleParserHelper::parseVehicleAttributes(int element, const SUMOSAXAttributes& attrs, const bool hardFail, const bool optionalID, const bool skipDepart, const bool allowInternalRoutes) {
334  // declare vehicle ID
335  std::string id;
336  // for certain vehicles, ID can be optional
337  if (optionalID) {
338  bool ok = true;
339  id = attrs.getOpt<std::string>(SUMO_ATTR_ID, nullptr, ok, "");
340  if (!ok) {
341  return handleVehicleError(hardFail, nullptr);
342  }
343  } else {
344  // parse ID
345  id = parseID(attrs, (SumoXMLTag)element);
346  }
347  // only continue if id is valid, or if is optional
348  if (optionalID || !id.empty()) {
349  // declare vehicle parameter
350  SUMOVehicleParameter* vehicleParameter = new SUMOVehicleParameter();
351  vehicleParameter->id = id;
352  if (element == SUMO_TAG_PERSON) {
353  vehicleParameter->vtypeid = DEFAULT_PEDTYPE_ID;
354  } else if (element == SUMO_TAG_CONTAINER) {
355  vehicleParameter->vtypeid = DEFAULT_CONTAINERTYPE_ID;
356  }
357  // parse common attributes
358  try {
359  parseCommonAttributes(attrs, vehicleParameter, (SumoXMLTag)element, allowInternalRoutes);
360  } catch (ProcessError& attributeError) {
361  // check if continue handling another vehicles or stop handling
362  if (hardFail) {
363  throw ProcessError(attributeError.what());
364  } else {
365  return nullptr;
366  }
367  }
368  // check depart
369  if (!skipDepart) {
370  bool ok = true;
371  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPART, vehicleParameter->id.c_str(), ok);
372  if (!ok) {
373  return handleVehicleError(hardFail, vehicleParameter);
374  }
375  // now parse depart
376  std::string departErrorMsg;
377  if (!SUMOVehicleParameter::parseDepart(helper, "vehicle", vehicleParameter->id, vehicleParameter->depart, vehicleParameter->departProcedure, departErrorMsg)) {
378  return handleVehicleError(hardFail, vehicleParameter, departErrorMsg);
379  }
380  }
381  // set tag
382  vehicleParameter->tag = (SumoXMLTag)element;
383  // all ok, then return vehicleParameter
384  return vehicleParameter;
385  } else {
386  return handleVehicleError(hardFail, nullptr, toString((SumoXMLTag)element) + " cannot be created");
387  }
388 }
389 
390 
391 std::string
393  bool ok = true;
394  std::string id;
395  // first check if attrs contain an ID
396  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
397  id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
399  return id;
400  } else if (id.empty()) {
401  // add extra information for empty IDs
402  WRITE_ERRORF(TL("Invalid % id '%'."), toString(element), id);
403  } else {
404  WRITE_ERRORF(TL("Invalid % id '%'. Contains invalid characters."), toString(element), id);
405  }
406  } else {
407  WRITE_ERROR("Attribute '" + toString(SUMO_ATTR_ID) + "' is missing in definition of " + toString(element));
408  }
409  // return empty (invalid) ID
410  return "";
411 }
412 
413 
414 void
416  const std::string element = toString(tag);
417  //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
418  // parse route information
419  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
420  bool ok = true;
421  std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, ret->id.c_str(), ok);
422  if (!allowInternalRoutes && isInternalRouteID(routeID)) {
423  WRITE_WARNINGF(TL("Internal routes receive an ID starting with '!' and must not be referenced in other vehicle or flow definitions. Please remove all references to route '%' in case it is internal."), routeID);
424  }
425  ret->routeid = routeID;
426  if (ok) {
427  ret->parametersSet |= VEHPARS_ROUTE_SET; // !!! needed?
428  } else {
429  handleVehicleError(true, ret);
430  }
431  }
432  // parse type information
433  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
434  bool ok = true;
435  ret->vtypeid = attrs.get<std::string>(SUMO_ATTR_TYPE, ret->id.c_str(), ok);
436  if (ok) {
437  ret->parametersSet |= VEHPARS_VTYPE_SET; // !!! needed?
438  } else {
439  handleVehicleError(true, ret);
440  }
441  }
442  // parse line information
443  if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
444  bool ok = true;
445  ret->line = attrs.get<std::string>(SUMO_ATTR_LINE, ret->id.c_str(), ok);
446  if (ok) {
447  ret->parametersSet |= VEHPARS_LINE_SET; // !!! needed?
448  } else {
449  handleVehicleError(true, ret);
450  }
451  }
452  // parse zone information
453  if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) {
454  bool ok = true;
455  ret->fromTaz = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, ret->id.c_str(), ok);
456  if (ok) {
458  } else {
459  handleVehicleError(true, ret);
460  }
461  }
462  if (attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
463  bool ok = true;
464  ret->toTaz = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, ret->id.c_str(), ok);
465  if (ok) {
467  } else {
468  handleVehicleError(true, ret);
469  }
470  }
471  // parse reroute information
472  if (attrs.hasAttribute(SUMO_ATTR_REROUTE)) {
473  bool ok = true;
474  if (attrs.get<bool>(SUMO_ATTR_REROUTE, ret->id.c_str(), ok)) {
475  if (ok) {
477  } else {
478  handleVehicleError(true, ret);
479  }
480  }
481  }
482  // parse depart lane information
483  if (attrs.hasAttribute(SUMO_ATTR_DEPARTLANE)) {
484  bool ok = true;
485  const std::string departLaneStr = attrs.get<std::string>(SUMO_ATTR_DEPARTLANE, ret->id.c_str(), ok);
486  int lane;
488  std::string error;
489  if (SUMOVehicleParameter::parseDepartLane(departLaneStr, element, ret->id, lane, dld, error)) {
491  ret->departLane = lane;
492  ret->departLaneProcedure = dld;
493  } else {
494  handleVehicleError(true, ret, error);
495  }
496  }
497  // parse depart position information
498  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
499  bool ok = true;
500  const std::string departPosStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS, ret->id.c_str(), ok);
501  double pos;
503  std::string error;
504  if (SUMOVehicleParameter::parseDepartPos(departPosStr, element, ret->id, pos, dpd, error)) {
506  ret->departPos = pos;
507  ret->departPosProcedure = dpd;
508  } else {
509  handleVehicleError(true, ret, error);
510  }
511  }
512  // parse lateral depart position information
514  bool ok = true;
515  const std::string departPosLatStr = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS_LAT, ret->id.c_str(), ok);
516  double pos;
518  std::string error;
519  if (SUMOVehicleParameter::parseDepartPosLat(departPosLatStr, element, ret->id, pos, dpd, error)) {
521  ret->departPosLat = pos;
522  ret->departPosLatProcedure = dpd;
523  } else {
524  handleVehicleError(true, ret, error);
525  }
526  }
527  // parse depart speed information
528  if (attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED)) {
529  bool ok = true;
530  const std::string departSpeed = attrs.get<std::string>(SUMO_ATTR_DEPARTSPEED, ret->id.c_str(), ok);
531  double speed;
533  std::string error;
534  if (SUMOVehicleParameter::parseDepartSpeed(departSpeed, element, ret->id, speed, dsd, error)) {
536  ret->departSpeed = speed;
537  ret->departSpeedProcedure = dsd;
538  } else {
539  handleVehicleError(true, ret, error);
540  }
541  }
542  // parse depart edge information
543  if (attrs.hasAttribute(SUMO_ATTR_DEPARTEDGE)) {
544  bool ok = true;
545  const std::string departEdgeStr = attrs.get<std::string>(SUMO_ATTR_DEPARTEDGE, ret->id.c_str(), ok);
546  int edgeIndex;
548  std::string error;
549  if (SUMOVehicleParameter::parseRouteIndex(departEdgeStr, element, ret->id, SUMO_ATTR_DEPARTEDGE, edgeIndex, rid, error)) {
551  ret->departEdge = edgeIndex;
552  ret->departEdgeProcedure = rid;
553  } else {
554  handleVehicleError(true, ret, error);
555  }
556  }
557  // parse arrival lane information
558  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE)) {
559  bool ok = true;
560  const std::string arrivalLaneStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALLANE, ret->id.c_str(), ok);
561  int lane;
563  std::string error;
564  if (SUMOVehicleParameter::parseArrivalLane(arrivalLaneStr, element, ret->id, lane, ald, error)) {
566  ret->arrivalLane = lane;
567  ret->arrivalLaneProcedure = ald;
568  } else {
569  handleVehicleError(true, ret, error);
570  }
571  }
572  // parse arrival position information
573  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
574  bool ok = true;
575  const std::string arrivalPosStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, ret->id.c_str(), ok);
576  double pos;
578  std::string error;
579  if (SUMOVehicleParameter::parseArrivalPos(arrivalPosStr, element, ret->id, pos, apd, error)) {
581  ret->arrivalPos = pos;
582  ret->arrivalPosProcedure = apd;
583  } else {
584  handleVehicleError(true, ret, error);
585  }
586  }
587  // parse lateral arrival position information
589  bool ok = true;
590  const std::string arrivalPosLatStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS_LAT, ret->id.c_str(), ok);
591  double pos;
593  std::string error;
594  if (SUMOVehicleParameter::parseArrivalPosLat(arrivalPosLatStr, element, ret->id, pos, apd, error)) {
596  ret->arrivalPosLat = pos;
597  ret->arrivalPosLatProcedure = apd;
598  } else {
599  handleVehicleError(true, ret, error);
600  }
601  }
602  // parse arrival speed information
604  bool ok = true;
605  std::string arrivalSpeedStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALSPEED, ret->id.c_str(), ok);
606  double speed;
608  std::string error;
609  if (SUMOVehicleParameter::parseArrivalSpeed(arrivalSpeedStr, element, ret->id, speed, asd, error)) {
611  ret->arrivalSpeed = speed;
612  ret->arrivalSpeedProcedure = asd;
613  } else {
614  handleVehicleError(true, ret, error);
615  }
616  }
617  // parse arrival edge information
618  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALEDGE)) {
619  bool ok = true;
620  std::string arrivalEdgeStr = attrs.get<std::string>(SUMO_ATTR_ARRIVALEDGE, ret->id.c_str(), ok);
621  int edgeIndex;
623  std::string error;
624  if (SUMOVehicleParameter::parseRouteIndex(arrivalEdgeStr, element, ret->id, SUMO_ATTR_ARRIVALEDGE, edgeIndex, rid, error)) {
626  ret->arrivalEdge = edgeIndex;
627  ret->arrivalEdgeProcedure = rid;
628  } else {
629  handleVehicleError(true, ret, error);
630  }
631  }
632  // parse color
633  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
634  bool ok = true;
635  ret->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, ret->id.c_str(), ok);
636  if (ok) {
638  } else {
639  handleVehicleError(true, ret, "Invalid RGBColor format");
640  }
641  } else {
643  }
644  // parse person number
646  bool ok = true;
647  int personNumber = attrs.get<int>(SUMO_ATTR_PERSON_NUMBER, ret->id.c_str(), ok);
648  if (!ok) {
649  handleVehicleError(true, ret);
650  } else if (personNumber >= 0) {
652  ret->personNumber = personNumber;
653  } else {
654  handleVehicleError(true, ret, toString(SUMO_ATTR_PERSON_NUMBER) + " cannot be negative");
655  }
656  }
657  // parse container number
659  bool ok = true;
660  int containerNumber = attrs.get<int>(SUMO_ATTR_CONTAINER_NUMBER, ret->id.c_str(), ok);
661  if (!ok) {
662  handleVehicleError(true, ret);
663  } else if (containerNumber >= 0) {
665  ret->containerNumber = containerNumber;
666  } else {
667  handleVehicleError(true, ret, toString(SUMO_ATTR_CONTAINER_NUMBER) + " cannot be negative");
668  }
669  }
670  // parse individual speedFactor
671  if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) {
672  bool ok = true;
673  double speedFactor = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR, ret->id.c_str(), ok);
674  if (!ok) {
675  handleVehicleError(true, ret);
676  } else if (speedFactor > 0) {
678  ret->speedFactor = speedFactor;
679  } else {
680  handleVehicleError(true, ret, toString(SUMO_ATTR_SPEEDFACTOR) + " must be positive");
681  }
682  }
683  // parse insertion checks
685  ret->insertionChecks = 0;
686  bool ok = true;
687  std::vector<std::string> checks = attrs.get<std::vector<std::string> >(SUMO_ATTR_INSERTIONCHECKS, ret->id.c_str(), ok);
688  if (!ok) {
689  handleVehicleError(true, ret);
690  } else {
691  for (std::string check : checks) {
692  if (!SUMOXMLDefinitions::InsertionChecks.hasString(check)) {
693  handleVehicleError(true, ret, "Unknown value '" + check + "' in " + toString(SUMO_ATTR_INSERTIONCHECKS));
694  }
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 speed (only used by calibrators flow)
711  // also used by vehicle in saved state but this is parsed elsewhere
712  if (tag == SUMO_TAG_FLOW && attrs.hasAttribute(SUMO_ATTR_SPEED)) {
713  bool ok = true;
714  double calibratorSpeed = attrs.get<double>(SUMO_ATTR_SPEED, ret->id.c_str(), ok);
715  if (!ok) {
716  handleVehicleError(true, ret);
717  } else if (calibratorSpeed >= 0 || calibratorSpeed == -1) {
719  ret->calibratorSpeed = calibratorSpeed;
720  } else {
721  handleVehicleError(true, ret, toString(SUMO_ATTR_SPEED) + " may not be negative");
722  }
723  }
724  /*/ parse via
725  if (attrs.hasAttribute(SUMO_ATTR_VIA)) {
726  ret->setParameter |= VEHPARS_VIA_SET;
727  SUMOSAXAttributes::parseStringVector(attrs.get<std::string>(SUMO_ATTR_VIA, ret->id.c_str(), ok), ret->via);
728  }
729  */
730 }
731 
732 
734 SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const bool hardFail, const std::string& file) {
735  // first obtain ID
736  std::string id = parseID(attrs, SUMO_TAG_VTYPE);
737  // check if ID is valid
738  if (!id.empty()) {
740  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
741  vClass = parseVehicleClass(attrs, id);
742  }
743  // create vType
744  SUMOVTypeParameter* vType = new SUMOVTypeParameter(id, vClass);
745  // parse attributes
746  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
748  }
749  if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
750  bool ok = true;
751  const double length = attrs.get<double>(SUMO_ATTR_LENGTH, vType->id.c_str(), ok);
752  if (!ok) {
753  return handleVehicleTypeError(hardFail, vType);
754  } else if (length <= 0) {
755  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LENGTH) + " must be greater than 0");
756  } else {
757  vType->length = length;
759  }
760  }
761  if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
762  bool ok = true;
763  const double minGap = attrs.get<double>(SUMO_ATTR_MINGAP, vType->id.c_str(), ok);
764  if (!ok) {
765  return handleVehicleTypeError(hardFail, vType);
766  } else if (minGap < 0) {
767  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP) + " must be equal or greater than 0");
768  } else {
769  vType->minGap = minGap;
771  }
772  }
773  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
774  bool ok = true;
775  const double maxSpeed = attrs.get<double>(SUMO_ATTR_MAXSPEED, vType->id.c_str(), ok);
776  if (!ok) {
777  return handleVehicleTypeError(hardFail, vType);
778  } else if (maxSpeed <= 0) {
779  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED) + " must be greater than 0");
780  } else {
781  vType->maxSpeed = maxSpeed;
783  }
784  }
786  bool ok = true;
787  const double desiredMaxSpeed = attrs.get<double>(SUMO_ATTR_DESIRED_MAXSPEED, vType->id.c_str(), ok);
788  if (!ok) {
789  return handleVehicleTypeError(hardFail, vType);
790  } else if (desiredMaxSpeed <= 0) {
791  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_DESIRED_MAXSPEED) + " must be greater than 0");
792  } else {
793  vType->desiredMaxSpeed = desiredMaxSpeed;
795  }
796  } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
797  if (vClass == SVC_PEDESTRIAN) {
798  // backward compatibility because pedestrian maxSpeed was subject to speedFactor up to 1.14.1
799  vType->desiredMaxSpeed = vType->maxSpeed;;
801  } else if (vClass == SVC_BICYCLE) {
802  // backward compatibility because default desired speed did not exist up to 1.14.1
803  vType->desiredMaxSpeed = MAX2(vType->maxSpeed, vType->desiredMaxSpeed);
804  }
805  }
806 
807  if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) {
808  bool ok = true;
809  vType->speedFactor.parse(attrs.get<std::string>(SUMO_ATTR_SPEEDFACTOR, vType->id.c_str(), ok), hardFail);
810  if (!ok) {
811  return handleVehicleTypeError(hardFail, vType);
812  } else {
814  }
815  }
816  if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
817  bool ok = true;
818  const double speedDev = attrs.get<double>(SUMO_ATTR_SPEEDDEV, vType->id.c_str(), ok);
819  if (!ok) {
820  return handleVehicleTypeError(hardFail, vType);
821  } else if (speedDev < 0) {
822  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SPEEDDEV) + " must be equal or greater than 0");
823  } else {
824  vType->speedFactor.getParameter()[1] = speedDev;
826  }
827  }
828  // validate speed distribution
829  std::string error;
830  if (!vType->speedFactor.isValid(error)) {
831  return handleVehicleTypeError(hardFail, vType, "Invalid speed distribution when parsing vType '" + vType->id + "' (" + error + ")");
832  }
834  bool ok = true;
835  const double actionStepLengthSecs = attrs.get<double>(SUMO_ATTR_ACTIONSTEPLENGTH, vType->id.c_str(), ok);
836  if (!ok) {
837  return handleVehicleTypeError(hardFail, vType);
838  } else {
839  // processActionStepLength(...) function includes warnings
840  vType->actionStepLength = processActionStepLength(actionStepLengthSecs);
842  }
843  }
845  bool ok = true;
846  const std::string parsedEmissionClass = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
847  // check if emission class is correct
848  try {
849  vType->emissionClass = PollutantsInterface::getClassByName(parsedEmissionClass);
851  } catch (...) {
852  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_EMISSIONCLASS) + " with name '" + parsedEmissionClass + "' doesn't exist.");
853  }
854  }
855  if (attrs.hasAttribute(SUMO_ATTR_MASS)) {
856  bool ok = true;
857  const double mass = attrs.get<double>(SUMO_ATTR_MASS, vType->id.c_str(), ok);
858  if (!ok) {
859  return handleVehicleTypeError(hardFail, vType);
860  } else if (mass < 0) {
861  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MASS) + " must be equal or greater than 0");
862  } else {
863  vType->mass = mass;
865  }
866  }
867  if (attrs.hasAttribute(SUMO_ATTR_IMPATIENCE)) {
868  bool ok = true;
869  const std::string impatienceStr = attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
870  if (!ok) {
871  return handleVehicleTypeError(hardFail, vType);
872  } else if (impatienceStr == "off") {
873  vType->impatience = -std::numeric_limits<double>::max();
874  } else {
875  const double impatienceDouble = attrs.get<double>(SUMO_ATTR_IMPATIENCE, vType->id.c_str(), ok);
876  if (!ok) {
877  return handleVehicleTypeError(hardFail, vType);
878  } else {
879  vType->impatience = impatienceDouble;
881  }
882  }
883  }
884  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
885  bool ok = true;
886  const double width = attrs.get<double>(SUMO_ATTR_WIDTH, vType->id.c_str(), ok);
887  if (!ok) {
888  return handleVehicleTypeError(hardFail, vType);
889  } else if (width <= 0) {
890  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_WIDTH) + " must be greater than 0");
891  } else {
892  vType->width = width;
894  if (vClass == SVC_PEDESTRIAN
895  && OptionsCont::getOptions().exists("pedestrian.striping.stripe-width")
896  && OptionsCont::getOptions().getString("pedestrian.model") == "striping"
897  && OptionsCont::getOptions().getFloat("pedestrian.striping.stripe-width") < vType->width) {
898  WRITE_WARNINGF(TL("Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."), id, vType->width);
899  }
900  }
901  }
902  if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
903  bool ok = true;
904  const double height = attrs.get<double>(SUMO_ATTR_HEIGHT, vType->id.c_str(), ok);
905  if (!ok) {
906  return handleVehicleTypeError(hardFail, vType);
907  } else if (height < 0) {
908  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_HEIGHT) + " must be equal or greater than 0");
909  } else {
910  vType->height = height;
912  }
913  }
914  if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
915  vType->shape = parseGuiShape(attrs, vType->id);
916  if (vType->shape != SUMOVehicleShape::UNKNOWN) {
918  }
919  }
920  if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
921  bool ok = true;
922  const std::string osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vType->id.c_str(), ok);
923  if (!ok) {
924  return handleVehicleTypeError(hardFail, vType);
925  } else {
926  vType->osgFile = osgFile;
928  }
929  }
930  if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
931  bool ok = true;
932  std::string imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vType->id.c_str(), ok);
933  if (!ok) {
934  return handleVehicleTypeError(hardFail, vType);
935  } else {
936  // check relative path
937  if ((imgFile != "") && !FileHelpers::isAbsolute(imgFile)) {
938  imgFile = FileHelpers::getConfigurationRelative(file, imgFile);
939  }
940  vType->imgFile = imgFile;
942  }
943  }
944  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
945  bool ok = true;
946  const RGBColor color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vType->id.c_str(), ok);
947  if (!ok) {
948  return handleVehicleTypeError(hardFail, vType);
949  } else {
950  vType->color = color;
952  }
953  } else {
954  vType->color = RGBColor::YELLOW;
955  }
956  if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
957  bool ok = true;
958  const double defaultProbability = attrs.get<double>(SUMO_ATTR_PROB, vType->id.c_str(), ok);
959  if (!ok) {
960  return handleVehicleTypeError(hardFail, vType);
961  } else if (defaultProbability < 0) {
962  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PROB) + " must be equal or greater than 0");
963  } else {
964  vType->defaultProbability = defaultProbability;
966  }
967  }
969  bool ok = true;
970  std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vType->id.c_str(), ok);
971  if (!ok) {
972  return handleVehicleTypeError(hardFail, vType);
973  } else if (lcmS == "JE2013") {
974  WRITE_WARNING(TL("Lane change model 'JE2013' is deprecated. Using default model instead."));
975  lcmS = "default";
976  }
977  if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
980  } else {
981  return handleVehicleTypeError(hardFail, vType, "Unknown lane change model '" + lcmS + "' when parsing vType '" + vType->id + "'");
982  }
983  }
985  bool ok = true;
986  const std::string cfmValue = attrs.get<std::string>(SUMO_ATTR_CAR_FOLLOW_MODEL, vType->id.c_str(), ok);
987  if (!ok) {
988  return handleVehicleTypeError(hardFail, vType);
989  } else if (SUMOXMLDefinitions::CarFollowModels.hasString(cfmValue)) {
992  } else {
993  return handleVehicleTypeError(hardFail, vType, "Unknown car following model '" + cfmValue + "' when parsing vType '" + vType->id + "'");
994  }
995  }
997  bool ok = true;
998  const int personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, vType->id.c_str(), ok);
999  if (!ok) {
1000  return handleVehicleTypeError(hardFail, vType);
1001  } else if (personCapacity < 0) {
1002  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_PERSON_CAPACITY) + " must be equal or greater than 0");
1003  } else {
1004  vType->personCapacity = personCapacity;
1006  }
1007  }
1009  bool ok = true;
1010  const int containerCapacity = attrs.get<int>(SUMO_ATTR_CONTAINER_CAPACITY, vType->id.c_str(), ok);
1011  if (!ok) {
1012  return handleVehicleTypeError(hardFail, vType);
1013  } else if (containerCapacity < 0) {
1014  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_CONTAINER_CAPACITY) + " must be equal or greater than 0");
1015  } else {
1016  vType->containerCapacity = containerCapacity;
1018  }
1019  }
1021  bool ok = true;
1022  const SUMOTime boardingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_BOARDING_DURATION, vType->id.c_str(), ok);
1023  if (!ok) {
1024  return handleVehicleTypeError(hardFail, vType);
1025  } else if (boardingDuration < 0) {
1026  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_DURATION) + " must be equal or greater than 0");
1027  } else {
1028  vType->boardingDuration = boardingDuration;
1030  }
1031  }
1033  bool ok = true;
1034  const SUMOTime loadingDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_LOADING_DURATION, vType->id.c_str(), ok);
1035  if (!ok) {
1036  return handleVehicleTypeError(hardFail, vType);
1037  } else if (loadingDuration < 0) {
1038  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_LOADING_DURATION) + " must be equal or greater than 0");
1039  } else {
1040  vType->loadingDuration = loadingDuration;
1042  }
1043  }
1044  if (attrs.hasAttribute(SUMO_ATTR_SCALE)) {
1045  bool ok = true;
1046  const double scale = attrs.get<double>(SUMO_ATTR_SCALE, id.c_str(), ok);
1047  if (!ok) {
1048  return handleVehicleTypeError(hardFail, vType);
1049  } else if (scale < 0) {
1050  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_SCALE) + " may be not be negative");
1051  } else {
1052  vType->scale = scale;
1054  }
1055  }
1057  bool ok = true;
1058  const SUMOTime ttt = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT, vType->id.c_str(), ok);
1059  if (!ok) {
1060  return handleVehicleTypeError(hardFail, vType);
1061  } else {
1062  vType->timeToTeleport = ttt;
1063  vType->parametersSet |= VTYPEPARS_TTT_SET;
1064  }
1065  }
1067  bool ok = true;
1068  const SUMOTime tttb = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME_TO_TELEPORT_BIDI, vType->id.c_str(), ok);
1069  if (!ok) {
1070  return handleVehicleTypeError(hardFail, vType);
1071  } else {
1072  vType->timeToTeleportBidi = tttb;
1074  }
1075  }
1077  bool ok = true;
1078  const double sfp = attrs.get<double>(SUMO_ATTR_SPEEDFACTOR_PREMATURE, id.c_str(), ok);
1079  if (!ok) {
1080  return handleVehicleTypeError(hardFail, vType);
1081  } else {
1082  vType->speedFactorPremature = sfp;
1084  }
1085  }
1086  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED_LAT)) {
1087  bool ok = true;
1088  const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1089  if (!ok) {
1090  return handleVehicleTypeError(hardFail, vType);
1091  } else if (maxSpeedLat <= 0) {
1092  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1093  } else {
1094  vType->maxSpeedLat = maxSpeedLat;
1096  }
1097  }
1098  if (attrs.hasAttribute(SUMO_ATTR_MINGAP_LAT)) {
1099  bool ok = true;
1100  const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1101  if (!ok) {
1102  return handleVehicleTypeError(hardFail, vType);
1103  } else if (minGapLat < 0) {
1104  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1105  } else {
1106  vType->minGapLat = minGapLat;
1108  }
1109  }
1110  if (attrs.hasAttribute(SUMO_ATTR_LATALIGNMENT)) {
1111  bool ok = true;
1112  const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1113  if (!ok) {
1114  return handleVehicleTypeError(hardFail, vType);
1115  } else {
1116  double lao;
1118  if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1119  vType->latAlignmentOffset = lao;
1120  vType->latAlignmentProcedure = lad;
1122  } else {
1123  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)");
1124  }
1125  }
1126  }
1128  bool ok = true;
1129  const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1130  if (!ok) {
1131  return handleVehicleTypeError(hardFail, vType);
1132  } else if (parseAngleTimesMap(vType, angleTimesS)) {
1134  } else {
1135  return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1136  }
1137  }
1139  bool ok = true;
1140  std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1141  if (!ok) {
1142  return handleVehicleTypeError(hardFail, vType);
1143  } else {
1145  vType->parkingBadges = badges;
1146  }
1147  }
1148  // try to parse Car Following Model params
1149  if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1150  return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1151  }
1152  // try to parse Lane Change Model params
1153  if (!parseLCParams(vType, vType->lcModel, attrs)) {
1154  return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1155  }
1156  // try to Junction Model params
1157  if (!parseJMParams(vType, attrs)) {
1158  return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1159  }
1160  // all ok, then return vType
1161  return vType;
1162  } else {
1163  return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1164  }
1165 }
1166 
1167 
1168 bool
1170  StringTokenizer st(atm, ",");
1171  std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1172  int tripletCount = 0;
1173  while (st.hasNext()) {
1174  StringTokenizer pos(st.next());
1175  if (pos.size() != 3) {
1176  WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1177  return false;
1178  } else {
1179  try {
1180  const int angle = StringUtils::toInt(pos.next());
1181  const SUMOTime t1 = string2time(pos.next());
1182  const SUMOTime t2 = string2time(pos.next());
1183  angleTimesMap[angle] = std::make_pair(t1, t2);
1184  } catch (...) {
1185  WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1186  return false;
1187  }
1188  tripletCount++;
1189  }
1190  }
1191  if (angleTimesMap.size() > 0) {
1192  vtype->myManoeuverAngleTimes.clear();
1193  for (const auto& angleTime : angleTimesMap) {
1194  vtype->myManoeuverAngleTimes.insert(angleTime);
1195  }
1196  angleTimesMap.clear();
1197  return true;
1198  } else {
1199  return false;
1200  }
1201 }
1202 
1203 
1204 bool
1205 SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1206  const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1207  CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1208  // check if given CFM is allowed
1209  if (cf_it == allowedCFM.end()) {
1210  if (SUMOXMLDefinitions::Tags.has((int)element)) {
1211  WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1212  } else {
1213  WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1214  }
1215  return false;
1216  }
1217  // check if we're parsing a nested CFM
1218  if (nestedCFM) {
1219  into->cfModel = cf_it->first;
1221  }
1222  // set CFM values
1223  for (const auto& it : cf_it->second) {
1224  if (attrs.hasAttribute(it)) {
1225  // first obtain CFM attribute in string format
1226  bool ok = true;
1227  std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1228  // check CFM Attribute
1229  if (!ok) {
1230  return false;
1231  } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1232  // check if train value is valid
1233  if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1234  WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1235  return false;
1236  }
1237  // add parsedCFMAttribute to cfParameter
1238  into->cfParameter[it] = parsedCFMAttribute;
1239  } else if (it == SUMO_ATTR_SPEED_TABLE || it == SUMO_ATTR_TRACTION_TABLE || it == SUMO_ATTR_RESISTANCE_TABLE) {
1240  into->cfParameter[it] = parsedCFMAttribute;
1241  } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1242  // declare a int in wich save CFM int attribute
1243  double CFMDoubleAttribute = -1;
1244  try {
1245  // obtain CFM attribute in int format
1246  CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1247  } catch (...) {
1248  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1249  return false;
1250  }
1251  if (CFMDoubleAttribute <= 0) {
1252  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1253  return false;
1254  }
1255  // add parsedCFMAttribute to cfParameter
1256  into->cfParameter[it] = parsedCFMAttribute;
1257  } else {
1258  // declare a double in wich save CFM float attribute
1259  double CFMDoubleAttribute = -1;
1260  try {
1261  // obtain CFM attribute in double format
1262  CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1263  } catch (...) {
1264  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1265  return false;
1266  }
1267  // check attributes of type "positiveFloatType" (> 0)
1268  switch (it) {
1269  case SUMO_ATTR_ACCEL:
1270  case SUMO_ATTR_DECEL:
1273  case SUMO_ATTR_TAU:
1274  if (CFMDoubleAttribute <= 0) {
1275  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1276  return false;
1277  }
1278  break;
1279  default:
1280  break;
1281  }
1282  // check attributes restricted to [0-1]
1283  switch (it) {
1284  case SUMO_ATTR_SIGMA:
1285  if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1286  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1287  return false;
1288  }
1289  break;
1290  default:
1291  break;
1292  }
1293  // add parsedCFMAttribute to cfParameter
1294  into->cfParameter[it] = parsedCFMAttribute;
1295  }
1296  }
1297  }
1298  // all CFM successfully parsed, then return true
1299  return true;
1300 }
1301 
1302 
1305  // init on first use
1306  if (allowedCFModelAttrs.size() == 0) {
1307  std::set<SumoXMLAttr> genericParams;
1308  genericParams.insert(SUMO_ATTR_TAU);
1309  genericParams.insert(SUMO_ATTR_ACCEL);
1310  genericParams.insert(SUMO_ATTR_DECEL);
1311  genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1312  genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1313  genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1314  genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1315  // Krauss
1316  std::set<SumoXMLAttr> kraussParams(genericParams);
1317  kraussParams.insert(SUMO_ATTR_SIGMA);
1318  kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1319  allowedCFModelAttrs[SUMO_TAG_CF_KRAUSS] = kraussParams;
1322  std::set<SumoXMLAttr> allParams(kraussParams);
1323  // KraussX
1324  std::set<SumoXMLAttr> kraussXParams(kraussParams);
1325  kraussXParams.insert(SUMO_ATTR_TMP1);
1326  kraussXParams.insert(SUMO_ATTR_TMP2);
1327  kraussXParams.insert(SUMO_ATTR_TMP3);
1328  kraussXParams.insert(SUMO_ATTR_TMP4);
1329  kraussXParams.insert(SUMO_ATTR_TMP5);
1330  allowedCFModelAttrs[SUMO_TAG_CF_KRAUSSX] = kraussXParams;
1331  allParams.insert(kraussXParams.begin(), kraussXParams.end());
1332  // SmartSK
1333  std::set<SumoXMLAttr> smartSKParams(genericParams);
1334  smartSKParams.insert(SUMO_ATTR_SIGMA);
1335  smartSKParams.insert(SUMO_ATTR_TMP1);
1336  smartSKParams.insert(SUMO_ATTR_TMP2);
1337  smartSKParams.insert(SUMO_ATTR_TMP3);
1338  smartSKParams.insert(SUMO_ATTR_TMP4);
1339  smartSKParams.insert(SUMO_ATTR_TMP5);
1340  allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
1341  allParams.insert(smartSKParams.begin(), smartSKParams.end());
1342  // Daniel
1343  std::set<SumoXMLAttr> daniel1Params(genericParams);
1344  daniel1Params.insert(SUMO_ATTR_SIGMA);
1345  daniel1Params.insert(SUMO_ATTR_TMP1);
1346  daniel1Params.insert(SUMO_ATTR_TMP2);
1347  daniel1Params.insert(SUMO_ATTR_TMP3);
1348  daniel1Params.insert(SUMO_ATTR_TMP4);
1349  daniel1Params.insert(SUMO_ATTR_TMP5);
1350  allowedCFModelAttrs[SUMO_TAG_CF_DANIEL1] = daniel1Params;
1351  allParams.insert(daniel1Params.begin(), daniel1Params.end());
1352  // Peter Wagner
1353  std::set<SumoXMLAttr> pwagParams(genericParams);
1354  pwagParams.insert(SUMO_ATTR_SIGMA);
1355  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1356  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1358  allParams.insert(pwagParams.begin(), pwagParams.end());
1359  // IDM params
1360  std::set<SumoXMLAttr> idmParams(genericParams);
1361  idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1362  idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1363  allowedCFModelAttrs[SUMO_TAG_CF_IDM] = idmParams;
1364  allParams.insert(idmParams.begin(), idmParams.end());
1365  // EIDM
1366  std::set<SumoXMLAttr> eidmParams(genericParams);
1367  eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1368  eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1369  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1370  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1371  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1372  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_ESTIMATE);
1373  eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1374  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1375  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1376  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1377  eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1378  eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1379  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1380  eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1381  eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1382  eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1383  eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1384  allowedCFModelAttrs[SUMO_TAG_CF_EIDM] = eidmParams;
1385  allParams.insert(eidmParams.begin(), eidmParams.end());
1386  // IDMM
1387  std::set<SumoXMLAttr> idmmParams(genericParams);
1388  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1389  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1390  idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1391  allowedCFModelAttrs[SUMO_TAG_CF_IDMM] = idmmParams;
1392  allParams.insert(idmmParams.begin(), idmmParams.end());
1393  // Bieker
1394  std::set<SumoXMLAttr> bkernerParams(genericParams);
1395  bkernerParams.insert(SUMO_ATTR_K);
1396  bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1397  allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams;
1398  allParams.insert(bkernerParams.begin(), bkernerParams.end());
1399  // Wiedemann
1400  std::set<SumoXMLAttr> wiedemannParams(genericParams);
1401  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1402  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1403  allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1404  allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1405  // W99
1406  std::set<SumoXMLAttr> w99Params(genericParams);
1407  w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1408  w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1409  w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1410  w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1411  w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1412  w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1413  w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1414  w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1415  w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1416  allowedCFModelAttrs[SUMO_TAG_CF_W99] = w99Params;
1417  allParams.insert(w99Params.begin(), w99Params.end());
1418  // Rail
1419  std::set<SumoXMLAttr> railParams(genericParams);
1420  railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1421  railParams.insert(SUMO_ATTR_SPEED_TABLE);
1422  railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1423  railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1424  railParams.insert(SUMO_ATTR_MASSFACTOR);
1425  railParams.insert(SUMO_ATTR_MAXPOWER);
1426  railParams.insert(SUMO_ATTR_MAXTRACTION);
1427  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_CONSTANT);
1428  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1429  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_QUADRATIC);
1430  allowedCFModelAttrs[SUMO_TAG_CF_RAIL] = railParams;
1431  allParams.insert(railParams.begin(), railParams.end());
1432  // ACC
1433  std::set<SumoXMLAttr> ACCParams(genericParams);
1434  ACCParams.insert(SUMO_ATTR_SC_GAIN);
1435  ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1436  ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1437  ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1438  ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1439  ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1440  ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1441  ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1442  ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1443  allowedCFModelAttrs[SUMO_TAG_CF_ACC] = ACCParams;
1444  allParams.insert(ACCParams.begin(), ACCParams.end());
1445  // CACC
1446  std::set<SumoXMLAttr> CACCParams(genericParams);
1447  CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1448  CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1449  CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1450  CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1451  CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1452  CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1453  CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1454  CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1455  CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1456  CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1457  CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1458  CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1459  CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1460  CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1461  CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1462  CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1463  CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1464  allowedCFModelAttrs[SUMO_TAG_CF_CACC] = CACCParams;
1465  allParams.insert(CACCParams.begin(), CACCParams.end());
1466  // CC
1467  std::set<SumoXMLAttr> ccParams(genericParams);
1468  ccParams.insert(SUMO_ATTR_CF_CC_C1);
1469  ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1470  ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1471  ccParams.insert(SUMO_ATTR_CF_CC_KP);
1472  ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1473  ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1474  ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1475  ccParams.insert(SUMO_ATTR_CF_CC_XI);
1476  ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1477  ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1478  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1479  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1480  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1481  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1482  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1483  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1484  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1485  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1486  allowedCFModelAttrs[SUMO_TAG_CF_CC] = ccParams;
1487  allParams.insert(ccParams.begin(), ccParams.end());
1488  // last element
1490  }
1491  return allowedCFModelAttrs;
1492 }
1493 
1494 
1495 bool
1497  if (allowedLCModelAttrs.size() == 0) {
1498  // lc2013
1499  std::set<SumoXMLAttr> lc2013Params;
1500  lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1501  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1502  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1503  lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1504  lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1505  lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1506  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1507  lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1508  lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1509  lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1510  lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1511  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1512  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1513  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1514  lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1515  lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1516  lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1517  lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1518  lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1520  // sl2015 (extension of lc2013)
1521  std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1522  sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1523  sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1524  sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1525  sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1526  sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1527  sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1528  sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1529  sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1531  // DK2008
1532  std::set<SumoXMLAttr> noParams;
1534  // default model may be either LC2013 or SL2015
1535  // we allow both sets (sl2015 is a superset of lc2013Params)
1537  }
1538  std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1539  // iterate over LCM attributes
1540  for (const auto& it : allowed) {
1541  if (attrs.hasAttribute(it)) {
1542  // first obtain CFM attribute in string format
1543  bool ok = true;
1544  std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1545  if (!ok) {
1546  return false;
1547  }
1548  // declare a double in wich save CFM attribute
1549  double LCMAttribute = -1;
1550  try {
1551  // obtain CFM attribute in double format
1552  LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1553  } catch (...) {
1554  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1555  return false;
1556  }
1557  // check attributes of type "nonNegativeFloatType" (>= 0)
1558  switch (it) {
1569  case SUMO_ATTR_LCA_SIGMA:
1570  if (LCMAttribute < 0) {
1571  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1572  return false;
1573  }
1574  break;
1575  default:
1576  break;
1577  }
1578  // check attributes of type "positiveFloatType" (> 0)
1579  switch (it) {
1581  if (LCMAttribute <= 0) {
1582  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1583  return false;
1584  }
1585  break;
1586  default:
1587  break;
1588  }
1589  // check limits of attributes
1590  switch (it) {
1592  if (LCMAttribute < -1 || LCMAttribute > 1) {
1593  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1594  return false;
1595  }
1596  break;
1597  default:
1598  break;
1599  }
1600  // add parsedLCMAttribute to cfParameter
1601  into->lcParameter[it] = parsedLCMAttribute;
1602  }
1603  }
1604  // all LCM parsed ok, then return true
1605  return true;
1606 }
1607 
1608 
1609 bool
1611  for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1612  if (attrs.hasAttribute(it)) {
1613  // first obtain CFM attribute in string format
1614  bool ok = true;
1615  std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1616  if (!ok) {
1617  return false;
1618  }
1619  // declare a double in wich save CFM attribute
1620  double JMAttribute = -1;
1621  try {
1622  // obtain CFM attribute in double format
1623  JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1624  } catch (...) {
1625  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1626  return false;
1627  }
1628  // now continue checking other properties (-1 is the default value)
1629  if (JMAttribute != -1) {
1630  // special case for sigma minor
1631  if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1632  // check attributes sigma minor
1633  if ((JMAttribute < 0) || (JMAttribute > 1)) {
1634  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1635  return false;
1636  }
1637  } else {
1638  // check attributes of type "nonNegativeFloatType" (>= 0)
1639  if (JMAttribute < 0) {
1640  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1641  return false;
1642  }
1643  }
1644  // add parsedJMAttribute to cfParameter
1645  into->jmParameter[it] = parsedJMAttribute;
1646  }
1647  }
1648  }
1649  // all JM parameters successfully parsed, then return true
1650  return true;
1651 }
1652 
1653 
1656  SUMOVehicleClass vclass = SVC_IGNORING;
1657  bool ok = true;
1658  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1659  if (vclassS == "") {
1660  return vclass;
1661  }
1662  try {
1663  const SUMOVehicleClass result = getVehicleClassID(vclassS);
1664  const std::string& realName = SumoVehicleClassStrings.getString(result);
1665  if (realName != vclassS) {
1666  WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1667  }
1668  return result;
1669  } catch (...) {
1670  WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1671  }
1672  return vclass;
1673 }
1674 
1675 
1677 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1678  bool ok = true;
1679  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1680  if (SumoVehicleShapeStrings.hasString(vclassS)) {
1681  const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1682  const std::string& realName = SumoVehicleShapeStrings.getString(result);
1683  if (realName != vclassS) {
1684  WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1685  }
1686  return result;
1687  } else {
1688  WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1690  }
1691 }
1692 
1693 
1694 double
1695 SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1696  double result;
1697  std::string error;
1699  // only supports 'random' and 'max'
1700  if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1701  handleVehicleError(hardFail, nullptr, error);
1702  }
1703  if (proc == ArrivalPosDefinition::RANDOM) {
1704  result = RandHelper::rand(maxPos, rng);
1705  } else if (proc == ArrivalPosDefinition::CENTER) {
1706  result = maxPos / 2.;
1707  } else if (proc == ArrivalPosDefinition::MAX) {
1708  result = maxPos;
1709  }
1710  return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1711 }
1712 
1713 
1714 SUMOTime
1716  const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1717  SUMOTime result = TIME2STEPS(given);
1718  if (result <= 0) {
1719  if (result < 0) {
1720  WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1721  }
1722  result = DELTA_T;
1723  } else if (result % DELTA_T != 0) {
1724  result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1725  result = MAX2(DELTA_T, result);
1726  if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1727  WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1728  }
1729  }
1730  return result;
1731 }
1732 
1733 
1734 bool
1736  return id.substr(0, 1) == "!";
1737 }
1738 
1739 
1741 SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1742  if (vehicleParameter) {
1743  delete vehicleParameter;
1744  }
1745  if (hardFail) {
1746  throw ProcessError(message);
1747  } else if (message.size() > 0) {
1748  WRITE_ERROR(message);
1749  }
1750  return nullptr;
1751 }
1752 
1753 
1755 SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1756  if (vehicleTypeParameter) {
1757  delete vehicleTypeParameter;
1758  }
1759  if (hardFail) {
1760  throw ProcessError(message);
1761  } else if (message.size() > 0) {
1762  WRITE_ERROR(message);
1763  }
1764  return nullptr;
1765 }
1766 
1767 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
const long long int VTYPEPARS_TTT_SET
const long long int VTYPEPARS_SHAPE_SET
const long long int VTYPEPARS_LOADING_DURATION
const long long int VTYPEPARS_TTT_BIDI_SET
const long long int VTYPEPARS_SCALE_SET
const long long int VTYPEPARS_PERSON_CAPACITY
const long long int VTYPEPARS_CAR_FOLLOW_MODEL
const long long int VTYPEPARS_WIDTH_SET
const long long int VTYPEPARS_ACTIONSTEPLENGTH_SET
const long long int VTYPEPARS_MAXSPEED_LAT_SET
const long long int VTYPEPARS_MAXSPEED_SET
const long long int VTYPEPARS_EMISSIONCLASS_SET
const long long int VTYPEPARS_LATALIGNMENT_SET
const long long int VTYPEPARS_COLOR_SET
const long long int VTYPEPARS_LANE_CHANGE_MODEL_SET
const long long int VTYPEPARS_DESIRED_MAXSPEED_SET
const long long int VTYPEPARS_OSGFILE_SET
const long long int VTYPEPARS_MANEUVER_ANGLE_TIMES_SET
const long long int VTYPEPARS_SPEEDFACTOR_PREMATURE_SET
const long long int VTYPEPARS_SPEEDFACTOR_SET
const long long int VTYPEPARS_MINGAP_SET
const long long int VTYPEPARS_PROBABILITY_SET
const long long int VTYPEPARS_HEIGHT_SET
const long long int VTYPEPARS_PARKING_BADGES_SET
const long long int VTYPEPARS_MASS_SET
const long long int VTYPEPARS_BOARDING_DURATION
LatAlignmentDefinition
Possible ways to choose the lateral alignment, i.e., how vehicles align themselves within their lane.
const long long int VTYPEPARS_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
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)
StringBijection< SUMOVehicleShape > SumoVehicleShapeStrings(sumoVehicleShapeStringInitializer, SUMOVehicleShape::UNKNOWN, 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 int VEHPARS_DEPARTEDGE_SET
const int VEHPARS_ARRIVALEDGE_SET
const int VEHPARS_PARKING_BADGES_SET
const int VEHPARS_PROB_SET
RouteIndexDefinition
Possible ways to choose the departure and arrival edge.
const int VEHPARS_VPH_SET
const int VEHPARS_END_SET
const int VEHPARS_ROUTE_SET
const int VEHPARS_COLOR_SET
DepartLaneDefinition
Possible ways to choose a lane on depart.
const int VEHPARS_TO_TAZ_SET
ArrivalSpeedDefinition
Possible ways to choose the arrival speed.
DepartPosLatDefinition
Possible ways to choose the lateral departure position.
DepartPosDefinition
Possible ways to choose the departure position.
const int VEHPARS_SPEEDFACTOR_SET
ArrivalLaneDefinition
Possible ways to choose the arrival lane.
const int VEHPARS_DEPARTPOS_SET
const int VEHPARS_CONTAINER_NUMBER_SET
const int VEHPARS_ARRIVALLANE_SET
DepartSpeedDefinition
Possible ways to choose the departure speed.
const int VEHPARS_DEPARTLANE_SET
const int VEHPARS_ARRIVALPOSLAT_SET
const int VEHPARS_FROM_TAZ_SET
const int VEHPARS_NUMBER_SET
const int VEHPARS_ARRIVALSPEED_SET
const int VEHPARS_CALIBRATORSPEED_SET
const int VEHPARS_FORCE_REROUTE
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 int VEHPARS_LINE_SET
const int VEHPARS_PERSON_NUMBER_SET
const int VEHPARS_DEPARTSPEED_SET
const int VEHPARS_PERIOD_SET
ArrivalPosLatDefinition
Possible ways to choose the lateral arrival position.
const int VEHPARS_VTYPE_SET
const int VEHPARS_ARRIVALPOS_SET
@ TRIGGERED
The departure is person triggered.
const int VEHPARS_DEPARTPOSLAT_SET
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
@ 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
LaneChangeModel
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_TMP4
@ SUMO_ATTR_CF_W99_CC9
@ SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_CF_EIDM_T_ACC_MAX
@ SUMO_ATTR_STARTUP_DELAY
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_CONSTANT
@ SUMO_ATTR_CF_EIDM_EPSILON_ACC
@ SUMO_ATTR_CF_W99_CC5
@ SUMO_ATTR_LCA_PUSHY
@ SUMO_ATTR_CF_CC_FLATBED_KP
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_ARRIVALSPEED
@ SUMO_ATTR_GCC_GAIN_SPEED
@ SUMO_ATTR_EMISSIONCLASS
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_CF_CC_LAMBDA
@ SUMO_ATTR_DEPARTEDGE
@ SUMO_ATTR_CF_CC_FLATBED_D
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_ARRIVALEDGE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_LCA_COOPERATIVE_SPEED
@ SUMO_ATTR_RESISTANCE_TABLE
@ SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD
@ SUMO_ATTR_CF_CC_FLATBED_KA
@ SUMO_ATTR_CF_CC_PLOEG_KP
@ SUMO_ATTR_CF_WIEDEMANN_SECURITY
@ SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_LANE_DISCIPLINE
@ SUMO_ATTR_TRAIN_TYPE
@ SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS
@ SUMO_ATTR_CF_IDMM_ADAPT_TIME
@ SUMO_ATTR_LANE_CHANGE_MODEL
@ SUMO_ATTR_CF_KERNER_PHI
@ SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE
@ SUMO_ATTR_GC_GAIN_SPACE
@ SUMO_ATTR_SCALE
@ SUMO_ATTR_DEPARTPOS_LAT
@ SUMO_ATTR_PARKING_BADGES
@ SUMO_ATTR_CF_EIDM_C_COOLNESS
@ SUMO_ATTR_CF_EIDM_SIG_ERROR
@ SUMO_ATTR_LCA_PUSHYGAP
@ SUMO_ATTR_CA_GAIN_GAP_CACC
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_APPARENTDECEL
@ SUMO_ATTR_MAXSPEED_LAT
@ SUMO_ATTR_GC_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_TMP3
@ SUMO_ATTR_MASSFACTOR
@ SUMO_ATTR_ACTIONSTEPLENGTH
@ SUMO_ATTR_CF_CC_PLOEG_H
@ SUMO_ATTR_LCA_MAXDISTLATSTANDING
@ SUMO_ATTR_LCA_IMPATIENCE
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_MINGAP
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_MAXTRACTION
@ SUMO_ATTR_CA_GAIN_GAP_DOT_CACC
@ SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC
@ SUMO_ATTR_MASS
@ SUMO_ATTR_CF_CC_OMEGAN
@ SUMO_ATTR_CONTAINER_NUMBER
@ SUMO_ATTR_CF_CC_C1
@ SUMO_ATTR_TMP2
@ SUMO_ATTR_CF_W99_CC8
@ SUMO_ATTR_CA_GAIN_SPACE
@ SUMO_ATTR_LINE
@ SUMO_ATTR_LOADING_DURATION
@ SUMO_ATTR_CF_IDM_DELTA
@ SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ SUMO_ATTR_LCA_MAXSPEEDLATFACTOR
@ SUMO_ATTR_MANEUVER_ANGLE_TIMES
Class specific timing values for vehicle maneuvering through angle ranges.
@ SUMO_ATTR_CF_CC_CCACCEL
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_CF_EIDM_T_REACTION
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_ESTIMATE
@ 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_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_GUISHAPE
@ SUMO_ATTR_DESIRED_MAXSPEED
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_PERHOUR
@ 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_TO_TAZ
@ SUMO_ATTR_CF_CC_CCDECEL
@ SUMO_ATTR_DEPARTSPEED
@ SUMO_ATTR_GCC_GAIN_SPACE
@ SUMO_ATTR_MINGAP_LAT
@ SUMO_ATTR_EMERGENCYDECEL
@ SUMO_ATTR_CF_CC_FLATBED_H
@ SUMO_ATTR_CF_W99_CC3
@ SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR
@ SUMO_ATTR_CF_CC_LANES_COUNT
@ SUMO_ATTR_HEIGHT
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_LCA_SUBLANE_PARAM
@ SUMO_ATTR_LCA_SIGMA
@ SUMO_ATTR_LATALIGNMENT
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_CF_IDM_STEPPING
@ SUMO_ATTR_SIGMA_STEP
@ SUMO_ATTR_DEPARTLANE
@ SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
@ SUMO_ATTR_SPEED_TABLE
@ SUMO_ATTR_IMPATIENCE
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_VCLASS
@ SUMO_ATTR_ACCEL
@ SUMO_ATTR_BOARDING_DURATION
@ SUMO_ATTR_CF_CC_CONSTSPACING
@ SUMO_ATTR_CF_EIDM_M_FLATNESS
@ SUMO_ATTR_CF_W99_CC2
@ SUMO_ATTR_CF_W99_CC4
@ SUMO_ATTR_JM_SIGMA_MINOR
@ SUMO_ATTR_CF_W99_CC6
@ SUMO_ATTR_PROB
@ SUMO_ATTR_CF_EIDM_M_BEGIN
@ SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE
@ SUMO_ATTR_TIME_TO_TELEPORT
@ SUMO_ATTR_SPEEDFACTOR
@ SUMO_ATTR_CA_GAIN_SPEED
@ SUMO_ATTR_CF_EIDM_SIG_LEADER
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_CF_CC_KP
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR
@ SUMO_ATTR_APPLYDRIVERSTATE
@ SUMO_ATTR_PERSON_NUMBER
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_CF_PWAGNER2009_APPROB
@ SUMO_ATTR_MAXSPEED
@ SUMO_ATTR_ID
@ SUMO_ATTR_SIGMA
@ SUMO_ATTR_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_CF_CC_FLATBED_KV
@ SUMO_ATTR_SC_MIN_GAP
@ SUMO_ATTR_SPEEDDEV
@ SUMO_ATTR_CF_WIEDEMANN_ESTIMATION
@ SUMO_ATTR_PERSONSPERHOUR
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
std::vector< double > & getParameter()
Returns the parameters of this distribution.
bool isValid(std::string &error)
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.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
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:188
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:199
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
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.
const std::string & getObjectType() const
return the objecttype to which these attributes belong
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.
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 mass
The mass.
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 parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
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.
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.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
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
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.
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 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 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 StringBijection< InsertionCheck > InsertionChecks
traffic light layouts
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 StringBijection< int > 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
int size() const
returns the number of existing substrings
std::string get(int pos) const
returns the item at the given position
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,...
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4451
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)