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