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-2012 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>
42 
43 #ifdef CHECK_MEMORY_LEAKS
44 #include <foreign/nvwa/debug_new.h>
45 #endif // CHECK_MEMORY_LEAKS
46 
47 
48 // ===========================================================================
49 // static members
50 // ===========================================================================
52 
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
60  bool ok = true;
61  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
63  throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
64  "' and '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
65  "' has to be given in the definition of flow '" + id + "'.");
66  }
69  throw ProcessError("If '" + attrs.getName(SUMO_ATTR_PERIOD) +
70  "' or '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
71  "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
72  "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
73  "' are allowed in flow '" + id + "'.");
74  }
75  } else {
76  if (!attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
77  throw ProcessError("At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
78  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
79  "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
80  "' is needed in flow '" + id + "'.");
81  }
82  }
84  ret->id = id;
85  parseCommonAttributes(attrs, ret, "flow");
86 
87  // parse repetition information
88  if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) {
90 #ifdef HAVE_SUBSECOND_TIMESTEPS
91  ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
92 #else
93  ret->repetitionOffset = attrs.getSUMORealReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
94 #endif
95  }
98  const SUMOReal vph = attrs.getSUMORealReporting(SUMO_ATTR_VEHSPERHOUR, id.c_str(), ok);
99  if (ok && vph <= 0) {
100  delete ret;
101  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
102  }
103  if (ok && vph != 0) {
104  ret->repetitionOffset = TIME2STEPS(3600. / vph);
105  }
106  }
107 
108  ret->depart = string2time(OptionsCont::getOptions().getString("begin"));
109  if (attrs.hasAttribute(SUMO_ATTR_BEGIN)) {
110  ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok);
111  }
112  if (ok && ret->depart < 0) {
113  delete ret;
114  throw ProcessError("Negative begin time in the definition of flow '" + id + "'.");
115  }
116  SUMOTime end = string2time(OptionsCont::getOptions().getString("end"));
117  if (end < 0) {
118  end = SUMOTime_MAX;
119  }
120  if (attrs.hasAttribute(SUMO_ATTR_END)) {
121  end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
122  }
123  if (ok && end <= ret->depart) {
124  delete ret;
125  throw ProcessError("Flow '" + id + "' ends before or at its begin time.");
126  }
127  if (attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
128  ret->repetitionNumber = attrs.getIntReporting(SUMO_ATTR_NUMBER, id.c_str(), ok);
130  if (ok && ret->repetitionNumber < 0) {
131  delete ret;
132  throw ProcessError("Negative repetition number in the definition of flow '" + id + "'.");
133  }
134  if (ok && ret->repetitionOffset < 0) {
135  ret->repetitionOffset = (end - ret->depart) / ret->repetitionNumber;
136  }
137  } else {
138  if (ok && ret->repetitionOffset <= 0) {
139  delete ret;
140  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
141  }
142  if (end == SUMOTime_MAX) {
143  ret->repetitionNumber = INT_MAX;
144  } else {
145  ret->repetitionNumber = static_cast<int>(static_cast<SUMOReal>(end - ret->depart) / ret->repetitionOffset + 0.5);
146  }
147  }
148  if (!ok) {
149  delete ret;
150  throw ProcessError();
151  }
152  return ret;
153 }
154 
155 
158  bool skipID, bool skipDepart) {
159  bool ok = true;
160  std::string id, errorMsg;
161  if (!skipID) {
162  id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
163  }
165  throw ProcessError("The attributes '" + attrs.getName(SUMO_ATTR_PERIOD) +
166  "' and '" + attrs.getName(SUMO_ATTR_REPNUMBER) +
167  "' have to be given both in the definition of '" + id + "'.");
168  }
170  ret->id = id;
171  try {
172  parseCommonAttributes(attrs, ret, "vehicle");
173  } catch (ProcessError&) {
174  delete ret;
175  throw;
176  }
177  if (!skipDepart) {
178  const std::string helper = attrs.getStringReporting(SUMO_ATTR_DEPART, 0, ok);
179  if (helper == "triggered") {
181  } else {
183  ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_DEPART, id.c_str(), ok);
184  if (ok && ret->depart < 0) {
185  errorMsg = "Negative departure time in the definition of '" + id + "'.";
186  ok = false;
187  }
188  }
189  }
190  // parse repetition information
191  if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) {
192  WRITE_WARNING("period and repno are deprecated in vehicle '" + id + "', use flows instead.");
194 #ifdef HAVE_SUBSECOND_TIMESTEPS
195  ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
196 #else
197  ret->repetitionOffset = attrs.getSUMORealReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
198 #endif
199  }
200  if (attrs.hasAttribute(SUMO_ATTR_REPNUMBER)) {
202  ret->repetitionNumber = attrs.getIntReporting(SUMO_ATTR_REPNUMBER, id.c_str(), ok);
203  }
204 
205  if (!ok) {
206  delete ret;
207  throw ProcessError(errorMsg);
208  }
209  return ret;
210 }
211 
212 
213 void
215  SUMOVehicleParameter* ret, std::string element) {
216  //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
217  bool ok = true;
218  // parse route information
219  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
220  ret->setParameter |= VEHPARS_ROUTE_SET; // !!! needed?
221  ret->routeid = attrs.getStringReporting(SUMO_ATTR_ROUTE, 0, ok);
222  }
223  // parse type information
224  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
225  ret->setParameter |= VEHPARS_VTYPE_SET; // !!! needed?
226  ret->vtypeid = attrs.getStringReporting(SUMO_ATTR_TYPE, 0, ok);
227  }
228  // parse line information
229  if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
230  ret->setParameter |= VEHPARS_LINE_SET; // !!! needed?
231  ret->line = attrs.getStringReporting(SUMO_ATTR_LINE, 0, ok);
232  }
233  // parse zone information
236  ret->fromTaz = attrs.getStringReporting(SUMO_ATTR_FROM_TAZ, 0, ok);
237  ret->toTaz = attrs.getStringReporting(SUMO_ATTR_TO_TAZ, 0, ok);
238  }
239  // parse reroute information
240  if (attrs.getOptBoolReporting(SUMO_ATTR_REROUTE, 0, ok, false)) {
242  }
243 
244  std::string error;
245  // parse depart lane information
246  if (attrs.hasAttribute(SUMO_ATTR_DEPARTLANE)) {
248  const std::string helper = attrs.getStringReporting(SUMO_ATTR_DEPARTLANE, 0, ok);
249  if (!SUMOVehicleParameter::parseDepartLane(helper, element, ret->id, ret->departLane, ret->departLaneProcedure, error)) {
250  throw ProcessError(error);
251  }
252  }
253  // parse depart position information
254  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
256  const std::string helper = attrs.getStringReporting(SUMO_ATTR_DEPARTPOS, 0, ok);
257  if (!SUMOVehicleParameter::parseDepartPos(helper, element, ret->id, ret->departPos, ret->departPosProcedure, error)) {
258  throw ProcessError(error);
259  }
260  }
261  // parse depart speed information
262  if (attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED)) {
264  std::string helper = attrs.getStringReporting(SUMO_ATTR_DEPARTSPEED, 0, ok);
265  if (!SUMOVehicleParameter::parseDepartSpeed(helper, element, ret->id, ret->departSpeed, ret->departSpeedProcedure, error)) {
266  throw ProcessError(error);
267  }
268  }
269 
270  // parse arrival lane information
271  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE)) {
273  std::string helper = attrs.getStringReporting(SUMO_ATTR_ARRIVALLANE, 0, ok);
274  if (!SUMOVehicleParameter::parseArrivalLane(helper, element, ret->id, ret->arrivalLane, ret->arrivalLaneProcedure, error)) {
275  throw ProcessError(error);
276  }
277  }
278  // parse arrival position information
279  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
281  std::string helper = attrs.getStringReporting(SUMO_ATTR_ARRIVALPOS, 0, ok);
282  if (!SUMOVehicleParameter::parseArrivalPos(helper, element, ret->id, ret->arrivalPos, ret->arrivalPosProcedure, error)) {
283  throw ProcessError(error);
284  }
285  }
286  // parse arrival speed information
289  std::string helper = attrs.getStringReporting(SUMO_ATTR_ARRIVALSPEED, 0, ok);
290  if (!SUMOVehicleParameter::parseArrivalSpeed(helper, element, ret->id, ret->arrivalSpeed, ret->arrivalSpeedProcedure, error)) {
291  throw ProcessError(error);
292  }
293  }
294 
295  // parse color
296  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
298  ret->color = attrs.getColorReporting(ret->id.c_str(), ok);
299  } else {
301  }
302  // parse person number
306  }
307  // parse person capacity
311  }
312 }
313 
314 
316 SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const std::string& file) {
317  SUMOVTypeParameter* vtype = new SUMOVTypeParameter();
318  bool ok = true;
319  vtype->id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
320  if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
321  vtype->length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, vtype->id.c_str(), ok);
323  }
324  if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
325  vtype->minGap = attrs.getSUMORealReporting(SUMO_ATTR_MINGAP, vtype->id.c_str(), ok);
327  }
328  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
329  vtype->maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED, vtype->id.c_str(), ok);
331  }
332  if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) {
333  vtype->speedFactor = attrs.getSUMORealReporting(SUMO_ATTR_SPEEDFACTOR, vtype->id.c_str(), ok);
335  }
336  if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
337  vtype->speedDev = attrs.getSUMORealReporting(SUMO_ATTR_SPEEDDEV, vtype->id.c_str(), ok);
339  }
341  vtype->emissionClass = parseEmissionClass(attrs, vtype->id);
343  }
344  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
345  vtype->vehicleClass = parseVehicleClass(attrs, vtype->id);
347  }
348  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
349  vtype->width = attrs.getSUMORealReporting(SUMO_ATTR_WIDTH, vtype->id.c_str(), ok);
351  }
352  if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
353  vtype->height = attrs.getSUMORealReporting(SUMO_ATTR_HEIGHT, vtype->id.c_str(), ok);
355  }
356  if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
357  vtype->shape = parseGuiShape(attrs, vtype->id);
359  }
360  if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
361  vtype->osgFile = attrs.getStringReporting(SUMO_ATTR_OSGFILE, vtype->id.c_str(), ok);
363  }
364  if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
365  vtype->imgFile = attrs.getStringReporting(SUMO_ATTR_IMGFILE, vtype->id.c_str(), ok);
366  if (vtype->imgFile != "" && !FileHelpers::isAbsolute(vtype->imgFile)) {
368  }
370  }
371  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
372  vtype->color = attrs.getColorReporting(vtype->id.c_str(), ok);
374  } else {
375  vtype->color = RGBColor(1, 1, 0);
376  }
377  if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
378  vtype->defaultProbability = attrs.getSUMORealReporting(SUMO_ATTR_PROB, vtype->id.c_str(), ok);
380  }
381  try {
382  parseVTypeEmbedded(*vtype, SUMO_TAG_CF_KRAUSS, attrs, true);
383  } catch (ProcessError&) {
384  throw;
385  }
386  if (!ok) {
387  delete vtype;
388  throw ProcessError();
389  }
390  return vtype;
391 }
392 
393 
394 void
396  int element, const SUMOSAXAttributes& attrs,
397  bool fromVType) {
398  const CFAttrMap& allowedAttrs = getAllowedCFModelAttrs();
399  CFAttrMap::const_iterator cf_it;
400  for (cf_it = allowedAttrs.begin(); cf_it != allowedAttrs.end(); cf_it++) {
401  if (cf_it->first == element) {
402  break;
403  }
404  }
405  if (cf_it == allowedAttrs.end()) {
406  if (SUMOXMLDefinitions::Tags.has(element)) {
407  WRITE_WARNING("Unknown cfmodel " + toString((SumoXMLTag)element) + " when parsing vtype '" + into.id + "'");
408  } else {
409  WRITE_WARNING("Unknown cfmodel when parsing vtype '" + into.id + "'");
410  }
411  }
412  if (!fromVType) {
413  into.cfModel = cf_it->first;
414  }
415  bool ok = true;
416  for (std::set<SumoXMLAttr>::const_iterator it = cf_it->second.begin(); it != cf_it->second.end(); it++) {
417  if (attrs.hasAttribute(*it)) {
418  into.cfParameter[*it] = attrs.getSUMORealReporting(*it, into.id.c_str(), ok);
419  }
420  }
421  if (!ok) {
422  throw ProcessError();
423  }
424 }
425 
426 
429  // init on first use
430  if (allowedCFModelAttrs.size() == 0) {
431  std::set<SumoXMLAttr> krausParams;
432  krausParams.insert(SUMO_ATTR_ACCEL);
433  krausParams.insert(SUMO_ATTR_DECEL);
434  krausParams.insert(SUMO_ATTR_SIGMA);
435  krausParams.insert(SUMO_ATTR_TAU);
438 
439  std::set<SumoXMLAttr> smartSKParams;
440  smartSKParams.insert(SUMO_ATTR_ACCEL);
441  smartSKParams.insert(SUMO_ATTR_DECEL);
442  smartSKParams.insert(SUMO_ATTR_SIGMA);
443  smartSKParams.insert(SUMO_ATTR_TAU);
444  smartSKParams.insert(SUMO_ATTR_TMP1);
445  smartSKParams.insert(SUMO_ATTR_TMP2);
446  smartSKParams.insert(SUMO_ATTR_TMP3);
447  smartSKParams.insert(SUMO_ATTR_TMP4);
448  smartSKParams.insert(SUMO_ATTR_TMP5);
449  allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
450 
451  std::set<SumoXMLAttr> daniel1Params;
452  daniel1Params.insert(SUMO_ATTR_ACCEL);
453  daniel1Params.insert(SUMO_ATTR_DECEL);
454  daniel1Params.insert(SUMO_ATTR_SIGMA);
455  daniel1Params.insert(SUMO_ATTR_TAU);
456  daniel1Params.insert(SUMO_ATTR_TMP1);
457  daniel1Params.insert(SUMO_ATTR_TMP2);
458  daniel1Params.insert(SUMO_ATTR_TMP3);
459  daniel1Params.insert(SUMO_ATTR_TMP4);
460  daniel1Params.insert(SUMO_ATTR_TMP5);
461  allowedCFModelAttrs[SUMO_TAG_CF_DANIEL1] = daniel1Params;
462 
463  std::set<SumoXMLAttr> pwagParams;
464  pwagParams.insert(SUMO_ATTR_ACCEL);
465  pwagParams.insert(SUMO_ATTR_DECEL);
466  pwagParams.insert(SUMO_ATTR_SIGMA);
467  pwagParams.insert(SUMO_ATTR_TAU);
468  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
469  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
471 
472  std::set<SumoXMLAttr> idmParams;
473  idmParams.insert(SUMO_ATTR_ACCEL);
474  idmParams.insert(SUMO_ATTR_DECEL);
475  idmParams.insert(SUMO_ATTR_TAU);
476  idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
477  idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
479 
480  std::set<SumoXMLAttr> idmmParams;
481  idmmParams.insert(SUMO_ATTR_ACCEL);
482  idmmParams.insert(SUMO_ATTR_DECEL);
483  idmmParams.insert(SUMO_ATTR_TAU);
484  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
485  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
486  idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
488 
489  std::set<SumoXMLAttr> bkernerParams;
490  bkernerParams.insert(SUMO_ATTR_ACCEL);
491  bkernerParams.insert(SUMO_ATTR_DECEL);
492  bkernerParams.insert(SUMO_ATTR_TAU);
493  bkernerParams.insert(SUMO_ATTR_K);
494  bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
495  allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams;
496 
497  std::set<SumoXMLAttr> wiedemannParams;
498  wiedemannParams.insert(SUMO_ATTR_ACCEL);
499  wiedemannParams.insert(SUMO_ATTR_DECEL);
500  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
501  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
502  allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
503  }
504  return allowedCFModelAttrs;
505 }
506 
507 
510  const std::string& id) {
511  SUMOVehicleClass vclass = SVC_UNKNOWN;
512  try {
513  bool ok = true;
514  std::string vclassS = attrs.getOptStringReporting(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
515  if (vclassS == "") {
516  return vclass;
517  }
518  return getVehicleClassID(vclassS);
519  } catch (...) {
520  WRITE_ERROR("The class for " + attrs.getObjectType() + " '" + id + "' is not known.");
521  }
522  return vclass;
523 }
524 
525 
529  try {
530  bool ok = true;
531  std::string vclassS = attrs.getOptStringReporting(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
532  if (vclassS == "") {
533  return vclass;
534  }
535  return getVehicleEmissionTypeID(vclassS);
536  } catch (...) {
537  WRITE_ERROR("The emission class for " + attrs.getObjectType() + " '" + id + "' is not known.");
538  }
539  return vclass;
540 }
541 
542 
544 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
545  bool ok = true;
546  std::string vclassS = attrs.getOptStringReporting(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
547  if (SumoVehicleShapeStrings.hasString(vclassS)) {
548  return SumoVehicleShapeStrings.get(vclassS);
549  } else {
550  WRITE_ERROR("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is not known.");
551  return SVS_UNKNOWN;
552  }
553 }
554 
555 
556 /****************************************************************************/
557