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  }
1087  bool ok = true;
1088  const double bf = attrs.get<double>(SUMO_ATTR_BOARDING_FACTOR, id.c_str(), ok);
1089  if (!ok) {
1090  return handleVehicleTypeError(hardFail, vType);
1091  } else if (bf < 0) {
1092  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_BOARDING_FACTOR) + " must be equal or greater than 0");
1093  } else {
1094  vType->boardingFactor = bf;
1096  }
1097  }
1098  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED_LAT)) {
1099  bool ok = true;
1100  const double maxSpeedLat = attrs.get<double>(SUMO_ATTR_MAXSPEED_LAT, vType->id.c_str(), ok);
1101  if (!ok) {
1102  return handleVehicleTypeError(hardFail, vType);
1103  } else if (maxSpeedLat <= 0) {
1104  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MAXSPEED_LAT) + " must be greater than 0");
1105  } else {
1106  vType->maxSpeedLat = maxSpeedLat;
1108  }
1109  }
1110  if (attrs.hasAttribute(SUMO_ATTR_MINGAP_LAT)) {
1111  bool ok = true;
1112  const double minGapLat = attrs.get<double>(SUMO_ATTR_MINGAP_LAT, vType->id.c_str(), ok);
1113  if (!ok) {
1114  return handleVehicleTypeError(hardFail, vType);
1115  } else if (minGapLat < 0) {
1116  return handleVehicleTypeError(hardFail, vType, toString(SUMO_ATTR_MINGAP_LAT) + " must be equal or greater than 0");
1117  } else {
1118  vType->minGapLat = minGapLat;
1120  }
1121  }
1122  if (attrs.hasAttribute(SUMO_ATTR_LATALIGNMENT)) {
1123  bool ok = true;
1124  const std::string alignS = attrs.get<std::string>(SUMO_ATTR_LATALIGNMENT, vType->id.c_str(), ok);
1125  if (!ok) {
1126  return handleVehicleTypeError(hardFail, vType);
1127  } else {
1128  double lao;
1130  if (SUMOVTypeParameter::parseLatAlignment(alignS, lao, lad)) {
1131  vType->latAlignmentOffset = lao;
1132  vType->latAlignmentProcedure = lad;
1134  } else {
1135  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)");
1136  }
1137  }
1138  }
1140  bool ok = true;
1141  const std::string angleTimesS = attrs.get<std::string>(SUMO_ATTR_MANEUVER_ANGLE_TIMES, vType->id.c_str(), ok);
1142  if (!ok) {
1143  return handleVehicleTypeError(hardFail, vType);
1144  } else if (parseAngleTimesMap(vType, angleTimesS)) {
1146  } else {
1147  return handleVehicleTypeError(hardFail, vType, "Invalid manoeuver angle times map for vType '" + vType->id + "'");
1148  }
1149  }
1151  bool ok = true;
1152  std::vector<std::string> badges = attrs.get<std::vector<std::string>>(SUMO_ATTR_PARKING_BADGES, vType->id.c_str(), ok);
1153  if (!ok) {
1154  return handleVehicleTypeError(hardFail, vType);
1155  } else {
1157  vType->parkingBadges = badges;
1158  }
1159  }
1160  // try to parse Car Following Model params
1161  if (!parseCFMParams(vType, vType->cfModel, attrs, false)) {
1162  return handleVehicleTypeError(hardFail, vType, "Invalid parsing embedded VType");
1163  }
1164  // try to parse Lane Change Model params
1165  if (!parseLCParams(vType, vType->lcModel, attrs)) {
1166  return handleVehicleTypeError(hardFail, vType, "Invalid Lane Change Model Parameters");
1167  }
1168  // try to Junction Model params
1169  if (!parseJMParams(vType, attrs)) {
1170  return handleVehicleTypeError(hardFail, vType, "Invalid Junction Model Parameters");
1171  }
1172  // all ok, then return vType
1173  return vType;
1174  } else {
1175  return handleVehicleTypeError(hardFail, nullptr, "VType cannot be created");
1176  }
1177 }
1178 
1179 
1180 bool
1182  StringTokenizer st(atm, ",");
1183  std::map<int, std::pair<SUMOTime, SUMOTime>> angleTimesMap;
1184  int tripletCount = 0;
1185  while (st.hasNext()) {
1186  StringTokenizer pos(st.next());
1187  if (pos.size() != 3) {
1188  WRITE_ERRORF(TL("maneuverAngleTimes format for vType '%' % contains an invalid triplet."), vtype->id, atm);
1189  return false;
1190  } else {
1191  try {
1192  const int angle = StringUtils::toInt(pos.next());
1193  const SUMOTime t1 = string2time(pos.next());
1194  const SUMOTime t2 = string2time(pos.next());
1195  angleTimesMap[angle] = std::make_pair(t1, t2);
1196  } catch (...) {
1197  WRITE_ERRORF(TL("Triplet '%' for vType '%' maneuverAngleTimes cannot be parsed as 'int double double'"), st.get(tripletCount), vtype->id);
1198  return false;
1199  }
1200  tripletCount++;
1201  }
1202  }
1203  if (angleTimesMap.size() > 0) {
1204  vtype->myManoeuverAngleTimes.clear();
1205  for (const auto& angleTime : angleTimesMap) {
1206  vtype->myManoeuverAngleTimes.insert(angleTime);
1207  }
1208  angleTimesMap.clear();
1209  return true;
1210  } else {
1211  return false;
1212  }
1213 }
1214 
1215 
1216 bool
1217 SUMOVehicleParserHelper::parseCFMParams(SUMOVTypeParameter* into, const SumoXMLTag element, const SUMOSAXAttributes& attrs, const bool nestedCFM) {
1218  const CFAttrMap& allowedCFM = getAllowedCFModelAttrs();
1219  CFAttrMap::const_iterator cf_it = allowedCFM.find(element);
1220  // check if given CFM is allowed
1221  if (cf_it == allowedCFM.end()) {
1222  if (SUMOXMLDefinitions::Tags.has((int)element)) {
1223  WRITE_ERRORF(TL("Unknown car-following model % when parsing vType '%'"), toString(element), into->id);
1224  } else {
1225  WRITE_ERRORF(TL("Unknown car-following model when parsing vType '%'"), into->id);
1226  }
1227  return false;
1228  }
1229  // check if we're parsing a nested CFM
1230  if (nestedCFM) {
1231  into->cfModel = cf_it->first;
1233  }
1234  // set CFM values
1235  for (const auto& it : cf_it->second) {
1236  if (attrs.hasAttribute(it)) {
1237  // first obtain CFM attribute in string format
1238  bool ok = true;
1239  std::string parsedCFMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1240  // check CFM Attribute
1241  if (!ok) {
1242  return false;
1243  } else if (it == SUMO_ATTR_TRAIN_TYPE) {
1244  // check if train value is valid
1245  if (!SUMOXMLDefinitions::TrainTypes.hasString(parsedCFMAttribute)) {
1246  WRITE_ERROR("Invalid train type '" + parsedCFMAttribute + "' used in Car-Following-Attribute " + toString(it));
1247  return false;
1248  }
1249  // add parsedCFMAttribute to cfParameter
1250  into->cfParameter[it] = parsedCFMAttribute;
1251  } else if (it == SUMO_ATTR_SPEED_TABLE || it == SUMO_ATTR_TRACTION_TABLE || it == SUMO_ATTR_RESISTANCE_TABLE) {
1252  into->cfParameter[it] = parsedCFMAttribute;
1253  } else if (it == SUMO_ATTR_CF_IDM_STEPPING) {
1254  // declare a int in wich save CFM int attribute
1255  double CFMDoubleAttribute = -1;
1256  try {
1257  // obtain CFM attribute in int format
1258  CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1259  } catch (...) {
1260  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1261  return false;
1262  }
1263  if (CFMDoubleAttribute <= 0) {
1264  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1265  return false;
1266  }
1267  // add parsedCFMAttribute to cfParameter
1268  into->cfParameter[it] = parsedCFMAttribute;
1269  } else {
1270  // declare a double in wich save CFM float attribute
1271  double CFMDoubleAttribute = -1;
1272  try {
1273  // obtain CFM attribute in double format
1274  CFMDoubleAttribute = StringUtils::toDouble(parsedCFMAttribute);
1275  } catch (...) {
1276  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Cannot be parsed to float"), toString(it));
1277  return false;
1278  }
1279  // check attributes of type "positiveFloatType" (> 0)
1280  switch (it) {
1281  case SUMO_ATTR_ACCEL:
1282  case SUMO_ATTR_DECEL:
1285  case SUMO_ATTR_TAU:
1286  if (CFMDoubleAttribute <= 0) {
1287  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Must be greater than 0"), toString(it));
1288  return false;
1289  }
1290  break;
1291  default:
1292  break;
1293  }
1294  // check attributes restricted to [0-1]
1295  switch (it) {
1296  case SUMO_ATTR_SIGMA:
1297  if ((CFMDoubleAttribute < 0) || (CFMDoubleAttribute > 1)) {
1298  WRITE_ERRORF(TL("Invalid Car-Following-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1299  return false;
1300  }
1301  break;
1302  default:
1303  break;
1304  }
1305  // add parsedCFMAttribute to cfParameter
1306  into->cfParameter[it] = parsedCFMAttribute;
1307  }
1308  }
1309  }
1310  // all CFM successfully parsed, then return true
1311  return true;
1312 }
1313 
1314 
1317  // init on first use
1318  if (allowedCFModelAttrs.size() == 0) {
1319  std::set<SumoXMLAttr> genericParams;
1320  genericParams.insert(SUMO_ATTR_TAU);
1321  genericParams.insert(SUMO_ATTR_ACCEL);
1322  genericParams.insert(SUMO_ATTR_DECEL);
1323  genericParams.insert(SUMO_ATTR_APPARENTDECEL);
1324  genericParams.insert(SUMO_ATTR_EMERGENCYDECEL);
1325  genericParams.insert(SUMO_ATTR_COLLISION_MINGAP_FACTOR);
1326  genericParams.insert(SUMO_ATTR_STARTUP_DELAY);
1327  // Krauss
1328  std::set<SumoXMLAttr> kraussParams(genericParams);
1329  kraussParams.insert(SUMO_ATTR_SIGMA);
1330  kraussParams.insert(SUMO_ATTR_SIGMA_STEP);
1331  allowedCFModelAttrs[SUMO_TAG_CF_KRAUSS] = kraussParams;
1334  std::set<SumoXMLAttr> allParams(kraussParams);
1335  // KraussX
1336  std::set<SumoXMLAttr> kraussXParams(kraussParams);
1337  kraussXParams.insert(SUMO_ATTR_TMP1);
1338  kraussXParams.insert(SUMO_ATTR_TMP2);
1339  kraussXParams.insert(SUMO_ATTR_TMP3);
1340  kraussXParams.insert(SUMO_ATTR_TMP4);
1341  kraussXParams.insert(SUMO_ATTR_TMP5);
1342  allowedCFModelAttrs[SUMO_TAG_CF_KRAUSSX] = kraussXParams;
1343  allParams.insert(kraussXParams.begin(), kraussXParams.end());
1344  // SmartSK
1345  std::set<SumoXMLAttr> smartSKParams(genericParams);
1346  smartSKParams.insert(SUMO_ATTR_SIGMA);
1347  smartSKParams.insert(SUMO_ATTR_TMP1);
1348  smartSKParams.insert(SUMO_ATTR_TMP2);
1349  smartSKParams.insert(SUMO_ATTR_TMP3);
1350  smartSKParams.insert(SUMO_ATTR_TMP4);
1351  smartSKParams.insert(SUMO_ATTR_TMP5);
1352  allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
1353  allParams.insert(smartSKParams.begin(), smartSKParams.end());
1354  // Daniel
1355  std::set<SumoXMLAttr> daniel1Params(genericParams);
1356  daniel1Params.insert(SUMO_ATTR_SIGMA);
1357  daniel1Params.insert(SUMO_ATTR_TMP1);
1358  daniel1Params.insert(SUMO_ATTR_TMP2);
1359  daniel1Params.insert(SUMO_ATTR_TMP3);
1360  daniel1Params.insert(SUMO_ATTR_TMP4);
1361  daniel1Params.insert(SUMO_ATTR_TMP5);
1362  allowedCFModelAttrs[SUMO_TAG_CF_DANIEL1] = daniel1Params;
1363  allParams.insert(daniel1Params.begin(), daniel1Params.end());
1364  // Peter Wagner
1365  std::set<SumoXMLAttr> pwagParams(genericParams);
1366  pwagParams.insert(SUMO_ATTR_SIGMA);
1367  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
1368  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
1370  allParams.insert(pwagParams.begin(), pwagParams.end());
1371  // IDM params
1372  std::set<SumoXMLAttr> idmParams(genericParams);
1373  idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1374  idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1375  allowedCFModelAttrs[SUMO_TAG_CF_IDM] = idmParams;
1376  allParams.insert(idmParams.begin(), idmParams.end());
1377  // EIDM
1378  std::set<SumoXMLAttr> eidmParams(genericParams);
1379  eidmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
1380  eidmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1381  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_LOOK_AHEAD);
1382  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_DRIVE);
1383  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_REACTION);
1384  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_PERSISTENCE_ESTIMATE);
1385  eidmParams.insert(SUMO_ATTR_CF_EIDM_C_COOLNESS);
1386  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_LEADER);
1387  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_GAP);
1388  eidmParams.insert(SUMO_ATTR_CF_EIDM_SIG_ERROR);
1389  eidmParams.insert(SUMO_ATTR_CF_EIDM_JERK_MAX);
1390  eidmParams.insert(SUMO_ATTR_CF_EIDM_EPSILON_ACC);
1391  eidmParams.insert(SUMO_ATTR_CF_EIDM_T_ACC_MAX);
1392  eidmParams.insert(SUMO_ATTR_CF_EIDM_M_FLATNESS);
1393  eidmParams.insert(SUMO_ATTR_CF_EIDM_M_BEGIN);
1394  eidmParams.insert(SUMO_ATTR_CF_EIDM_USEVEHDYNAMICS);
1395  eidmParams.insert(SUMO_ATTR_CF_EIDM_MAX_VEH_PREVIEW);
1396  allowedCFModelAttrs[SUMO_TAG_CF_EIDM] = eidmParams;
1397  allParams.insert(eidmParams.begin(), eidmParams.end());
1398  // IDMM
1399  std::set<SumoXMLAttr> idmmParams(genericParams);
1400  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
1401  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
1402  idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
1403  allowedCFModelAttrs[SUMO_TAG_CF_IDMM] = idmmParams;
1404  allParams.insert(idmmParams.begin(), idmmParams.end());
1405  // Bieker
1406  std::set<SumoXMLAttr> bkernerParams(genericParams);
1407  bkernerParams.insert(SUMO_ATTR_K);
1408  bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
1409  allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams;
1410  allParams.insert(bkernerParams.begin(), bkernerParams.end());
1411  // Wiedemann
1412  std::set<SumoXMLAttr> wiedemannParams(genericParams);
1413  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
1414  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
1415  allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
1416  allParams.insert(wiedemannParams.begin(), wiedemannParams.end());
1417  // W99
1418  std::set<SumoXMLAttr> w99Params(genericParams);
1419  w99Params.insert(SUMO_ATTR_CF_W99_CC1);
1420  w99Params.insert(SUMO_ATTR_CF_W99_CC2);
1421  w99Params.insert(SUMO_ATTR_CF_W99_CC3);
1422  w99Params.insert(SUMO_ATTR_CF_W99_CC4);
1423  w99Params.insert(SUMO_ATTR_CF_W99_CC5);
1424  w99Params.insert(SUMO_ATTR_CF_W99_CC6);
1425  w99Params.insert(SUMO_ATTR_CF_W99_CC7);
1426  w99Params.insert(SUMO_ATTR_CF_W99_CC8);
1427  w99Params.insert(SUMO_ATTR_CF_W99_CC9);
1428  allowedCFModelAttrs[SUMO_TAG_CF_W99] = w99Params;
1429  allParams.insert(w99Params.begin(), w99Params.end());
1430  // Rail
1431  std::set<SumoXMLAttr> railParams(genericParams);
1432  railParams.insert(SUMO_ATTR_TRAIN_TYPE);
1433  railParams.insert(SUMO_ATTR_SPEED_TABLE);
1434  railParams.insert(SUMO_ATTR_TRACTION_TABLE);
1435  railParams.insert(SUMO_ATTR_RESISTANCE_TABLE);
1436  railParams.insert(SUMO_ATTR_MASSFACTOR);
1437  railParams.insert(SUMO_ATTR_MAXPOWER);
1438  railParams.insert(SUMO_ATTR_MAXTRACTION);
1439  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_CONSTANT);
1440  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_LINEAR);
1441  railParams.insert(SUMO_ATTR_RESISTANCE_COEFFICIENT_QUADRATIC);
1442  allowedCFModelAttrs[SUMO_TAG_CF_RAIL] = railParams;
1443  allParams.insert(railParams.begin(), railParams.end());
1444  // ACC
1445  std::set<SumoXMLAttr> ACCParams(genericParams);
1446  ACCParams.insert(SUMO_ATTR_SC_GAIN);
1447  ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1448  ACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1449  ACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1450  ACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1451  ACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1452  ACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1453  ACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1454  ACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1455  allowedCFModelAttrs[SUMO_TAG_CF_ACC] = ACCParams;
1456  allParams.insert(ACCParams.begin(), ACCParams.end());
1457  // CACC
1458  std::set<SumoXMLAttr> CACCParams(genericParams);
1459  CACCParams.insert(SUMO_ATTR_SC_GAIN_CACC);
1460  CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_CACC);
1461  CACCParams.insert(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC);
1462  CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_CACC);
1463  CACCParams.insert(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC);
1464  CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_CACC);
1465  CACCParams.insert(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC);
1466  CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPEED);
1467  CACCParams.insert(SUMO_ATTR_GCC_GAIN_SPACE);
1468  CACCParams.insert(SUMO_ATTR_GC_GAIN_SPEED);
1469  CACCParams.insert(SUMO_ATTR_GC_GAIN_SPACE);
1470  CACCParams.insert(SUMO_ATTR_CA_GAIN_SPEED);
1471  CACCParams.insert(SUMO_ATTR_CA_GAIN_SPACE);
1472  CACCParams.insert(SUMO_ATTR_CA_OVERRIDE);
1473  CACCParams.insert(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC);
1474  CACCParams.insert(SUMO_ATTR_APPLYDRIVERSTATE);
1475  CACCParams.insert(SUMO_ATTR_SC_MIN_GAP);
1476  allowedCFModelAttrs[SUMO_TAG_CF_CACC] = CACCParams;
1477  allParams.insert(CACCParams.begin(), CACCParams.end());
1478  // CC
1479  std::set<SumoXMLAttr> ccParams(genericParams);
1480  ccParams.insert(SUMO_ATTR_CF_CC_C1);
1481  ccParams.insert(SUMO_ATTR_CF_CC_CCDECEL);
1482  ccParams.insert(SUMO_ATTR_CF_CC_CONSTSPACING);
1483  ccParams.insert(SUMO_ATTR_CF_CC_KP);
1484  ccParams.insert(SUMO_ATTR_CF_CC_LAMBDA);
1485  ccParams.insert(SUMO_ATTR_CF_CC_OMEGAN);
1486  ccParams.insert(SUMO_ATTR_CF_CC_TAU);
1487  ccParams.insert(SUMO_ATTR_CF_CC_XI);
1488  ccParams.insert(SUMO_ATTR_CF_CC_LANES_COUNT);
1489  ccParams.insert(SUMO_ATTR_CF_CC_CCACCEL);
1490  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KP);
1491  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_KD);
1492  ccParams.insert(SUMO_ATTR_CF_CC_PLOEG_H);
1493  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KA);
1494  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KV);
1495  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_KP);
1496  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_D);
1497  ccParams.insert(SUMO_ATTR_CF_CC_FLATBED_H);
1498  allowedCFModelAttrs[SUMO_TAG_CF_CC] = ccParams;
1499  allParams.insert(ccParams.begin(), ccParams.end());
1500  // last element
1502  }
1503  return allowedCFModelAttrs;
1504 }
1505 
1506 
1507 bool
1509  if (allowedLCModelAttrs.size() == 0) {
1510  // lc2013
1511  std::set<SumoXMLAttr> lc2013Params;
1512  lc2013Params.insert(SUMO_ATTR_LCA_STRATEGIC_PARAM);
1513  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_PARAM);
1514  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_PARAM);
1515  lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_PARAM);
1516  lc2013Params.insert(SUMO_ATTR_LCA_OPPOSITE_PARAM);
1517  lc2013Params.insert(SUMO_ATTR_LCA_LOOKAHEADLEFT);
1518  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAINRIGHT);
1519  lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATSTANDING);
1520  lc2013Params.insert(SUMO_ATTR_LCA_MAXSPEEDLATFACTOR);
1521  lc2013Params.insert(SUMO_ATTR_LCA_MAXDISTLATSTANDING);
1522  lc2013Params.insert(SUMO_ATTR_LCA_ASSERTIVE);
1523  lc2013Params.insert(SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD);
1524  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT);
1525  lc2013Params.insert(SUMO_ATTR_LCA_COOPERATIVE_SPEED);
1526  lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_RIGHT);
1527  lc2013Params.insert(SUMO_ATTR_LCA_SIGMA);
1528  lc2013Params.insert(SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME);
1529  lc2013Params.insert(SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR);
1530  lc2013Params.insert(SUMO_ATTR_LCA_EXPERIMENTAL1);
1532  // sl2015 (extension of lc2013)
1533  std::set<SumoXMLAttr> sl2015Params = lc2013Params;
1534  sl2015Params.insert(SUMO_ATTR_LCA_PUSHY);
1535  sl2015Params.insert(SUMO_ATTR_LCA_PUSHYGAP);
1536  sl2015Params.insert(SUMO_ATTR_LCA_SUBLANE_PARAM);
1537  sl2015Params.insert(SUMO_ATTR_LCA_IMPATIENCE);
1538  sl2015Params.insert(SUMO_ATTR_LCA_TIME_TO_IMPATIENCE);
1539  sl2015Params.insert(SUMO_ATTR_LCA_ACCEL_LAT);
1540  sl2015Params.insert(SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE);
1541  sl2015Params.insert(SUMO_ATTR_LCA_LANE_DISCIPLINE);
1543  // DK2008
1544  std::set<SumoXMLAttr> noParams;
1546  // default model may be either LC2013 or SL2015
1547  // we allow both sets (sl2015 is a superset of lc2013Params)
1549  }
1550  std::set<SumoXMLAttr> allowed = allowedLCModelAttrs[model];
1551  // iterate over LCM attributes
1552  for (const auto& it : allowed) {
1553  if (attrs.hasAttribute(it)) {
1554  // first obtain CFM attribute in string format
1555  bool ok = true;
1556  std::string parsedLCMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1557  if (!ok) {
1558  return false;
1559  }
1560  // declare a double in wich save CFM attribute
1561  double LCMAttribute = -1;
1562  try {
1563  // obtain CFM attribute in double format
1564  LCMAttribute = StringUtils::toDouble(parsedLCMAttribute);
1565  } catch (...) {
1566  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Cannot be parsed to float"), toString(it));
1567  return false;
1568  }
1569  // check attributes of type "nonNegativeFloatType" (>= 0)
1570  switch (it) {
1581  case SUMO_ATTR_LCA_SIGMA:
1582  if (LCMAttribute < 0) {
1583  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be equal or greater than 0"), toString(it));
1584  return false;
1585  }
1586  break;
1587  default:
1588  break;
1589  }
1590  // check attributes of type "positiveFloatType" (> 0)
1591  switch (it) {
1593  if (LCMAttribute <= 0) {
1594  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be greater than 0"), toString(it));
1595  return false;
1596  }
1597  break;
1598  default:
1599  break;
1600  }
1601  // check limits of attributes
1602  switch (it) {
1604  if (LCMAttribute < -1 || LCMAttribute > 1) {
1605  WRITE_ERRORF(TL("Invalid Lane-Change-Model Attribute %. Must be between -1 and 1"), toString(it));
1606  return false;
1607  }
1608  break;
1609  default:
1610  break;
1611  }
1612  // add parsedLCMAttribute to cfParameter
1613  into->lcParameter[it] = parsedLCMAttribute;
1614  }
1615  }
1616  // all LCM parsed ok, then return true
1617  return true;
1618 }
1619 
1620 
1621 bool
1623  for (const auto& it : SUMOVTypeParameter::AllowedJMAttrs) {
1624  if (attrs.hasAttribute(it)) {
1625  // first obtain CFM attribute in string format
1626  bool ok = true;
1627  std::string parsedJMAttribute = attrs.get<std::string>(it, into->id.c_str(), ok);
1628  if (!ok) {
1629  return false;
1630  }
1631  // declare a double in wich save CFM attribute
1632  double JMAttribute = -1;
1633  try {
1634  // obtain CFM attribute in double format
1635  JMAttribute = StringUtils::toDouble(parsedJMAttribute);
1636  } catch (...) {
1637  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Cannot be parsed to float"), toString(it));
1638  return false;
1639  }
1640  // now continue checking other properties (-1 is the default value)
1641  if (JMAttribute != -1) {
1642  // special case for sigma minor
1643  if (it == SUMO_ATTR_JM_SIGMA_MINOR) {
1644  // check attributes sigma minor
1645  if ((JMAttribute < 0) || (JMAttribute > 1)) {
1646  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Only values between [0-1] are allowed"), toString(it));
1647  return false;
1648  }
1649  } else {
1650  // check attributes of type "nonNegativeFloatType" (>= 0)
1651  if (JMAttribute < 0) {
1652  WRITE_ERRORF(TL("Invalid Junction-Model Attribute %. Must be equal or greater than 0"), toString(it));
1653  return false;
1654  }
1655  }
1656  // add parsedJMAttribute to cfParameter
1657  into->jmParameter[it] = parsedJMAttribute;
1658  }
1659  }
1660  }
1661  // all JM parameters successfully parsed, then return true
1662  return true;
1663 }
1664 
1665 
1668  SUMOVehicleClass vclass = SVC_IGNORING;
1669  bool ok = true;
1670  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
1671  if (vclassS == "") {
1672  return vclass;
1673  }
1674  try {
1675  const SUMOVehicleClass result = getVehicleClassID(vclassS);
1676  const std::string& realName = SumoVehicleClassStrings.getString(result);
1677  if (realName != vclassS) {
1678  WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1679  }
1680  return result;
1681  } catch (...) {
1682  WRITE_ERRORF(TL("The vehicle class '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1683  }
1684  return vclass;
1685 }
1686 
1687 
1689 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
1690  bool ok = true;
1691  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
1692  if (SumoVehicleShapeStrings.hasString(vclassS)) {
1693  const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
1694  const std::string& realName = SumoVehicleShapeStrings.getString(result);
1695  if (realName != vclassS) {
1696  WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
1697  }
1698  return result;
1699  } else {
1700  WRITE_ERRORF(TL("The shape '%' for % '%' is not known."), vclassS, attrs.getObjectType(), id);
1702  }
1703 }
1704 
1705 
1706 double
1707 SUMOVehicleParserHelper::parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string& id, double maxPos, const std::string& val, SumoRNG* rng) {
1708  double result;
1709  std::string error;
1711  // only supports 'random' and 'max'
1712  if (!SUMOVehicleParameter::parseArrivalPos(val, toString(SUMO_TAG_WALK), id, result, proc, error)) {
1713  handleVehicleError(hardFail, nullptr, error);
1714  }
1715  if (proc == ArrivalPosDefinition::RANDOM) {
1716  result = RandHelper::rand(maxPos, rng);
1717  } else if (proc == ArrivalPosDefinition::CENTER) {
1718  result = maxPos / 2.;
1719  } else if (proc == ArrivalPosDefinition::MAX) {
1720  result = maxPos;
1721  }
1722  return SUMOVehicleParameter::interpretEdgePos(result, maxPos, attr, id);
1723 }
1724 
1725 
1726 SUMOTime
1728  const std::string defaultError = "The parameter action-step-length must be a non-negative multiple of the simulation step-length. ";
1729  SUMOTime result = TIME2STEPS(given);
1730  if (result <= 0) {
1731  if (result < 0) {
1732  WRITE_WARNING(defaultError + "Ignoring given value (=" + toString(STEPS2TIME(result)) + " s.)");
1733  }
1734  result = DELTA_T;
1735  } else if (result % DELTA_T != 0) {
1736  result = (SUMOTime)((double)DELTA_T * floor(double(result) / double(DELTA_T)));
1737  result = MAX2(DELTA_T, result);
1738  if (fabs(given * 1000. - double(result)) > NUMERICAL_EPS) {
1739  WRITE_WARNING(defaultError + "Parsing given value (" + toString(given) + " s.) to the adjusted value " + toString(STEPS2TIME(result)) + " s.");
1740  }
1741  }
1742  return result;
1743 }
1744 
1745 
1746 bool
1748  return id.substr(0, 1) == "!";
1749 }
1750 
1751 
1753 SUMOVehicleParserHelper::handleVehicleError(const bool hardFail, SUMOVehicleParameter* vehicleParameter, const std::string message) {
1754  if (vehicleParameter) {
1755  delete vehicleParameter;
1756  }
1757  if (hardFail) {
1758  throw ProcessError(message);
1759  } else if (message.size() > 0) {
1760  WRITE_ERROR(message);
1761  }
1762  return nullptr;
1763 }
1764 
1765 
1767 SUMOVehicleParserHelper::handleVehicleTypeError(const bool hardFail, SUMOVTypeParameter* vehicleTypeParameter, const std::string message) {
1768  if (vehicleTypeParameter) {
1769  delete vehicleTypeParameter;
1770  }
1771  if (hardFail) {
1772  throw ProcessError(message);
1773  } else if (message.size() > 0) {
1774  WRITE_ERROR(message);
1775  }
1776  return nullptr;
1777 }
1778 
1779 /****************************************************************************/
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_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
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_BOARDING_FACTOR
@ 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 boardingFactor
factor for boardingDuration / loadingDuration
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)