SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SUMOVehicleParserHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // Helper methods for parsing vehicle attributes
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
14 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <utils/common/ToString.h>
41 
42 #ifdef CHECK_MEMORY_LEAKS
43 #include <foreign/nvwa/debug_new.h>
44 #endif // CHECK_MEMORY_LEAKS
45 
46 
47 // ===========================================================================
48 // static members
49 // ===========================================================================
51 
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
58 SUMOVehicleParserHelper::parseFlowAttributes(const SUMOSAXAttributes& attrs, const SUMOTime beginDefault, const SUMOTime endDefault) {
59  bool ok = true;
60  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
62  throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
63  "' and '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
64  "' has to be given in the definition of flow '" + id + "'.");
65  }
68  throw ProcessError("If '" + attrs.getName(SUMO_ATTR_PERIOD) +
69  "' or '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
70  "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
71  "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
72  "' are allowed in flow '" + id + "'.");
73  }
74  } else {
75  if (!attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
76  throw ProcessError("At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
77  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
78  "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
79  "' is needed in flow '" + id + "'.");
80  }
81  }
83  ret->id = id;
84  parseCommonAttributes(attrs, ret, "flow");
85 
86  // parse repetition information
87  if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) {
89 #ifdef HAVE_SUBSECOND_TIMESTEPS
90  ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
91 #else
92  ret->repetitionOffset = attrs.get<SUMOReal>(SUMO_ATTR_PERIOD, id.c_str(), ok);
93 #endif
94  }
97  const SUMOReal vph = attrs.get<SUMOReal>(SUMO_ATTR_VEHSPERHOUR, id.c_str(), ok);
98  if (ok && vph <= 0) {
99  delete ret;
100  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
101  }
102  if (ok && vph != 0) {
103  ret->repetitionOffset = TIME2STEPS(3600. / vph);
104  }
105  }
106 
107  ret->depart = beginDefault;
108  if (attrs.hasAttribute(SUMO_ATTR_BEGIN)) {
109  ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok);
110  }
111  if (ok && ret->depart < 0) {
112  delete ret;
113  throw ProcessError("Negative begin time in the definition of flow '" + id + "'.");
114  }
115  SUMOTime end = endDefault;
116  if (end < 0) {
117  end = SUMOTime_MAX;
118  }
119  if (attrs.hasAttribute(SUMO_ATTR_END)) {
120  end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
121  }
122  if (ok && end <= ret->depart) {
123  delete ret;
124  throw ProcessError("Flow '" + id + "' ends before or at its begin time.");
125  }
126  if (attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
127  ret->repetitionNumber = attrs.get<int>(SUMO_ATTR_NUMBER, id.c_str(), ok);
129  if (ok && ret->repetitionNumber < 0) {
130  delete ret;
131  throw ProcessError("Negative repetition number in the definition of flow '" + id + "'.");
132  }
133  if (ok && ret->repetitionOffset < 0) {
134  ret->repetitionOffset = (end - ret->depart) / ret->repetitionNumber;
135  }
136  } else {
137  if (ok && ret->repetitionOffset <= 0) {
138  delete ret;
139  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
140  }
141  if (end == SUMOTime_MAX) {
142  ret->repetitionNumber = INT_MAX;
143  } else {
144  ret->repetitionNumber = static_cast<int>(static_cast<SUMOReal>(end - ret->depart) / ret->repetitionOffset + 0.5);
145  }
146  }
147  if (!ok) {
148  delete ret;
149  throw ProcessError();
150  }
151  return ret;
152 }
153 
154 
157  bool optionalID, bool skipDepart) {
158  bool ok = true;
159  std::string id, errorMsg;
160  if (optionalID) {
161  id = attrs.getOpt<std::string>(SUMO_ATTR_ID, 0, ok, "");
162  } else {
163  id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
164  }
166  throw ProcessError("The attributes '" + attrs.getName(SUMO_ATTR_PERIOD) +
167  "' and '" + attrs.getName(SUMO_ATTR_REPNUMBER) +
168  "' have to be given both in the definition of '" + id + "'.");
169  }
171  ret->id = id;
172  try {
173  parseCommonAttributes(attrs, ret, "vehicle");
174  } catch (ProcessError&) {
175  delete ret;
176  throw;
177  }
178  if (!skipDepart) {
179  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPART, 0, ok);
180  if (helper == "triggered") {
182  } else {
184  ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_DEPART, id.c_str(), ok);
185  if (ok && ret->depart < 0) {
186  errorMsg = "Negative departure time in the definition of '" + id + "'.";
187  ok = false;
188  }
189  }
190  }
191  // parse repetition information
192  if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) {
193  WRITE_WARNING("period and repno are deprecated in vehicle '" + id + "', use flows instead.");
195 #ifdef HAVE_SUBSECOND_TIMESTEPS
196  ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
197 #else
198  ret->repetitionOffset = attrs.get<SUMOReal>(SUMO_ATTR_PERIOD, id.c_str(), ok);
199 #endif
200  }
201  if (attrs.hasAttribute(SUMO_ATTR_REPNUMBER)) {
203  ret->repetitionNumber = attrs.get<int>(SUMO_ATTR_REPNUMBER, id.c_str(), ok);
204  }
205 
206  if (!ok) {
207  delete ret;
208  throw ProcessError(errorMsg);
209  }
210  return ret;
211 }
212 
213 
214 void
216  SUMOVehicleParameter* ret, std::string element) {
217  //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
218  bool ok = true;
219  // parse route information
220  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
221  ret->setParameter |= VEHPARS_ROUTE_SET; // !!! needed?
222  ret->routeid = attrs.get<std::string>(SUMO_ATTR_ROUTE, 0, ok);
223  }
224  // parse type information
225  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
226  ret->setParameter |= VEHPARS_VTYPE_SET; // !!! needed?
227  ret->vtypeid = attrs.get<std::string>(SUMO_ATTR_TYPE, 0, ok);
228  }
229  // parse line information
230  if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
231  ret->setParameter |= VEHPARS_LINE_SET; // !!! needed?
232  ret->line = attrs.get<std::string>(SUMO_ATTR_LINE, 0, ok);
233  }
234  // parse zone information
237  ret->fromTaz = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, 0, ok);
238  ret->toTaz = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, 0, ok);
239  }
240  // parse reroute information
241  if (attrs.getOpt<bool>(SUMO_ATTR_REROUTE, 0, ok, false)) {
243  }
244 
245  std::string error;
246  // parse depart lane information
247  if (attrs.hasAttribute(SUMO_ATTR_DEPARTLANE)) {
249  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTLANE, 0, ok);
250  if (!SUMOVehicleParameter::parseDepartLane(helper, element, ret->id, ret->departLane, ret->departLaneProcedure, error)) {
251  throw ProcessError(error);
252  }
253  }
254  // parse depart position information
255  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
257  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS, 0, ok);
258  if (!SUMOVehicleParameter::parseDepartPos(helper, element, ret->id, ret->departPos, ret->departPosProcedure, error)) {
259  throw ProcessError(error);
260  }
261  }
262  // parse depart speed information
263  if (attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED)) {
265  std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTSPEED, 0, ok);
266  if (!SUMOVehicleParameter::parseDepartSpeed(helper, element, ret->id, ret->departSpeed, ret->departSpeedProcedure, error)) {
267  throw ProcessError(error);
268  }
269  }
270 
271  // parse arrival lane information
272  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE)) {
274  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALLANE, 0, ok);
275  if (!SUMOVehicleParameter::parseArrivalLane(helper, element, ret->id, ret->arrivalLane, ret->arrivalLaneProcedure, error)) {
276  throw ProcessError(error);
277  }
278  }
279  // parse arrival position information
280  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
282  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, 0, ok);
283  if (!SUMOVehicleParameter::parseArrivalPos(helper, element, ret->id, ret->arrivalPos, ret->arrivalPosProcedure, error)) {
284  throw ProcessError(error);
285  }
286  }
287  // parse arrival speed information
290  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALSPEED, 0, ok);
291  if (!SUMOVehicleParameter::parseArrivalSpeed(helper, element, ret->id, ret->arrivalSpeed, ret->arrivalSpeedProcedure, error)) {
292  throw ProcessError(error);
293  }
294  }
295 
296  // parse color
297  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
299  ret->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, ret->id.c_str(), ok);
300  } else {
302  }
303  // parse person number
306  ret->personNumber = attrs.get<int>(SUMO_ATTR_PERSON_NUMBER, 0, ok);
307  }
308  // parse person capacity
311  ret->personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, 0, ok);
312  }
313 }
314 
315 
317 SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const std::string& file) {
318  SUMOVTypeParameter* vtype = new SUMOVTypeParameter();
319  bool ok = true;
320  vtype->id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
321  if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
322  vtype->length = attrs.get<SUMOReal>(SUMO_ATTR_LENGTH, vtype->id.c_str(), ok);
324  }
325  if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
326  vtype->minGap = attrs.get<SUMOReal>(SUMO_ATTR_MINGAP, vtype->id.c_str(), ok);
328  }
329  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
330  vtype->maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_MAXSPEED, vtype->id.c_str(), ok);
332  }
333  if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) {
334  vtype->speedFactor = attrs.get<SUMOReal>(SUMO_ATTR_SPEEDFACTOR, vtype->id.c_str(), ok);
336  }
337  if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
338  vtype->speedDev = attrs.get<SUMOReal>(SUMO_ATTR_SPEEDDEV, vtype->id.c_str(), ok);
340  }
342  vtype->emissionClass = parseEmissionClass(attrs, vtype->id);
344  }
345  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
346  vtype->vehicleClass = parseVehicleClass(attrs, vtype->id);
348  }
349  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
350  vtype->width = attrs.get<SUMOReal>(SUMO_ATTR_WIDTH, vtype->id.c_str(), ok);
352  }
353  if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
354  vtype->height = attrs.get<SUMOReal>(SUMO_ATTR_HEIGHT, vtype->id.c_str(), ok);
356  }
357  if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
358  vtype->shape = parseGuiShape(attrs, vtype->id);
360  }
361  if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
362  vtype->osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vtype->id.c_str(), ok);
364  }
365  if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
366  vtype->imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vtype->id.c_str(), ok);
367  if (vtype->imgFile != "" && !FileHelpers::isAbsolute(vtype->imgFile)) {
369  }
371  }
372  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
373  vtype->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vtype->id.c_str(), ok);
375  } else {
376  vtype->color = RGBColor::YELLOW;
377  }
378  if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
379  vtype->defaultProbability = attrs.get<SUMOReal>(SUMO_ATTR_PROB, vtype->id.c_str(), ok);
381  }
382  try {
383  parseVTypeEmbedded(*vtype, SUMO_TAG_CF_KRAUSS, attrs, true);
384  } catch (ProcessError&) {
385  throw;
386  }
387  if (!ok) {
388  delete vtype;
389  throw ProcessError();
390  }
391  return vtype;
392 }
393 
394 
395 void
397  int element, const SUMOSAXAttributes& attrs,
398  bool fromVType) {
399  const CFAttrMap& allowedAttrs = getAllowedCFModelAttrs();
400  CFAttrMap::const_iterator cf_it;
401  for (cf_it = allowedAttrs.begin(); cf_it != allowedAttrs.end(); cf_it++) {
402  if (cf_it->first == element) {
403  break;
404  }
405  }
406  if (cf_it == allowedAttrs.end()) {
407  if (SUMOXMLDefinitions::Tags.has(element)) {
408  WRITE_ERROR("Unknown cfmodel " + toString((SumoXMLTag)element) + " when parsing vtype '" + into.id + "'");
409  } else {
410  WRITE_ERROR("Unknown cfmodel when parsing vtype '" + into.id + "'");
411  }
412  throw ProcessError();
413  return;
414  }
415  if (!fromVType) {
416  into.cfModel = cf_it->first;
417  }
418  bool ok = true;
419  for (std::set<SumoXMLAttr>::const_iterator it = cf_it->second.begin(); it != cf_it->second.end(); it++) {
420  if (attrs.hasAttribute(*it)) {
421  into.cfParameter[*it] = attrs.get<SUMOReal>(*it, into.id.c_str(), ok);
422  if (*it == SUMO_ATTR_TAU && TIME2STEPS(into.cfParameter[*it]) < DELTA_T) {
423  WRITE_WARNING("Value of tau=" + toString(into.cfParameter[*it])
424  + " in car following model '" + toString(into.cfModel) + "' lower than simulation step size may cause collisions");
425  }
426  }
427  }
428  if (!ok) {
429  throw ProcessError();
430  }
431 }
432 
433 
436  // init on first use
437  if (allowedCFModelAttrs.size() == 0) {
438  std::set<SumoXMLAttr> krausParams;
439  krausParams.insert(SUMO_ATTR_ACCEL);
440  krausParams.insert(SUMO_ATTR_DECEL);
441  krausParams.insert(SUMO_ATTR_SIGMA);
442  krausParams.insert(SUMO_ATTR_TAU);
446 
447  std::set<SumoXMLAttr> smartSKParams;
448  smartSKParams.insert(SUMO_ATTR_ACCEL);
449  smartSKParams.insert(SUMO_ATTR_DECEL);
450  smartSKParams.insert(SUMO_ATTR_SIGMA);
451  smartSKParams.insert(SUMO_ATTR_TAU);
452  smartSKParams.insert(SUMO_ATTR_TMP1);
453  smartSKParams.insert(SUMO_ATTR_TMP2);
454  smartSKParams.insert(SUMO_ATTR_TMP3);
455  smartSKParams.insert(SUMO_ATTR_TMP4);
456  smartSKParams.insert(SUMO_ATTR_TMP5);
457  allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
458 
459  std::set<SumoXMLAttr> daniel1Params;
460  daniel1Params.insert(SUMO_ATTR_ACCEL);
461  daniel1Params.insert(SUMO_ATTR_DECEL);
462  daniel1Params.insert(SUMO_ATTR_SIGMA);
463  daniel1Params.insert(SUMO_ATTR_TAU);
464  daniel1Params.insert(SUMO_ATTR_TMP1);
465  daniel1Params.insert(SUMO_ATTR_TMP2);
466  daniel1Params.insert(SUMO_ATTR_TMP3);
467  daniel1Params.insert(SUMO_ATTR_TMP4);
468  daniel1Params.insert(SUMO_ATTR_TMP5);
469  allowedCFModelAttrs[SUMO_TAG_CF_DANIEL1] = daniel1Params;
470 
471  std::set<SumoXMLAttr> pwagParams;
472  pwagParams.insert(SUMO_ATTR_ACCEL);
473  pwagParams.insert(SUMO_ATTR_DECEL);
474  pwagParams.insert(SUMO_ATTR_SIGMA);
475  pwagParams.insert(SUMO_ATTR_TAU);
476  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
477  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
479 
480  std::set<SumoXMLAttr> idmParams;
481  idmParams.insert(SUMO_ATTR_ACCEL);
482  idmParams.insert(SUMO_ATTR_DECEL);
483  idmParams.insert(SUMO_ATTR_TAU);
484  idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
485  idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
487 
488  std::set<SumoXMLAttr> idmmParams;
489  idmmParams.insert(SUMO_ATTR_ACCEL);
490  idmmParams.insert(SUMO_ATTR_DECEL);
491  idmmParams.insert(SUMO_ATTR_TAU);
492  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
493  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
494  idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
496 
497  std::set<SumoXMLAttr> bkernerParams;
498  bkernerParams.insert(SUMO_ATTR_ACCEL);
499  bkernerParams.insert(SUMO_ATTR_DECEL);
500  bkernerParams.insert(SUMO_ATTR_TAU);
501  bkernerParams.insert(SUMO_ATTR_K);
502  bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
503  allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams;
504 
505  std::set<SumoXMLAttr> wiedemannParams;
506  wiedemannParams.insert(SUMO_ATTR_ACCEL);
507  wiedemannParams.insert(SUMO_ATTR_DECEL);
508  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
509  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
510  allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
511  }
512  return allowedCFModelAttrs;
513 }
514 
515 
518  const std::string& id) {
519  SUMOVehicleClass vclass = SVC_UNKNOWN;
520  try {
521  bool ok = true;
522  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
523  if (vclassS == "") {
524  return vclass;
525  }
526  return getVehicleClassID(vclassS);
527  } catch (...) {
528  WRITE_ERROR("The class for " + attrs.getObjectType() + " '" + id + "' is not known.");
529  }
530  return vclass;
531 }
532 
533 
536  try {
537  bool ok = true;
538  std::string eClassS = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
539  return getVehicleEmissionTypeID(eClassS);
540  } catch (...) {
541  WRITE_ERROR("The emission class for " + attrs.getObjectType() + " '" + id + "' is not known.");
542  return SVE_UNKNOWN;
543  }
544 }
545 
546 
548 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
549  bool ok = true;
550  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
551  if (SumoVehicleShapeStrings.hasString(vclassS)) {
552  return SumoVehicleShapeStrings.get(vclassS);
553  } else {
554  WRITE_ERROR("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is not known.");
555  return SVS_UNKNOWN;
556  }
557 }
558 
559 
560 void
562  stop.setParameter = 0;
563  if (attrs.hasAttribute(SUMO_ATTR_ENDPOS)) {
564  stop.setParameter |= STOP_END_SET;
565  }
566  if (attrs.hasAttribute(SUMO_ATTR_STARTPOS)) {
568  }
569  if (attrs.hasAttribute(SUMO_ATTR_TRIGGERED)) {
571  }
572  if (attrs.hasAttribute(SUMO_ATTR_PARKING)) {
574  }
575 }
576 
577 /****************************************************************************/
578