SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSRouteHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Parser and container for routes during their loading
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <map>
36 #include <vector>
37 #include <microsim/MSRoute.h>
38 #include <microsim/MSEdge.h>
39 #include <microsim/MSJunction.h>
40 #include <microsim/MSVehicleType.h>
41 #include <microsim/MSVehicle.h>
44 #include <microsim/MSLane.h>
45 #include "MSRouteHandler.h"
46 #include "MSPersonControl.h"
54 #include "MSNet.h"
55 
57 #include <microsim/MSGlobals.h>
59 
60 #ifdef CHECK_MEMORY_LEAKS
61 #include <foreign/nvwa/debug_new.h>
62 #endif // CHECK_MEMORY_LEAKS
63 
64 
65 // ===========================================================================
66 // static members
67 // ===========================================================================
69 
70 
71 // ===========================================================================
72 // method definitions
73 // ===========================================================================
74 MSRouteHandler::MSRouteHandler(const std::string& file,
75  bool addVehiclesDirectly) :
76  SUMORouteHandler(file),
77  myActivePlan(0),
78  myAddVehiclesDirectly(addVehiclesDirectly),
79  myCurrentVTypeDistribution(0),
80  myCurrentRouteDistribution(0) {
81  myActiveRoute.reserve(100);
82 }
83 
84 
86 }
87 
88 
89 void
91  const SUMOSAXAttributes& attrs) {
92  SUMORouteHandler::myStartElement(element, attrs);
93  switch (element) {
94  case SUMO_TAG_PERSON:
96  break;
97  case SUMO_TAG_RIDE: {
98  const std::string pid = myVehicleParameter->id;
99  bool ok = true;
100  MSEdge* from = 0;
101  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
102  StringTokenizer st(desc);
103  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
104  MSBusStop* bs = 0;
105  if (bsID != "") {
106  bs = MSNet::getInstance()->getBusStop(bsID);
107  if (bs == 0) {
108  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
109  }
110  }
111  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
112  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
113  from = MSEdge::dictionary(fromID);
114  if (from == 0) {
115  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
116  }
117  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
118  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
119  }
120  if (myActivePlan->empty()) {
122  *from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
123  }
124  } else if (myActivePlan->empty()) {
125  throw ProcessError("The start edge within for person '" + pid + "' is not known.");
126  }
127  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
128  MSEdge* to = MSEdge::dictionary(toID);
129  if (to == 0) {
130  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
131  }
132  myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, bs, st.getVector()));
133  break;
134  }
135  case SUMO_TAG_WALK: {
136  myActiveRoute.clear();
137  bool ok = true;
138  SUMOReal departPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
139  SUMOReal arrivalPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -NUMERICAL_EPS);
140  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
141  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
142  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
143  }
146  // need to check for explicitly set speed since we might have // DEFAULT_VEHTYPE
147  if (vtype != 0 && vtype->wasSet(VTYPEPARS_MAXSPEED_SET)) {
148  speed = vtype->getMaxSpeed();
149  }
150  speed = attrs.getOpt<SUMOReal>(SUMO_ATTR_SPEED, 0, ok, speed);
151  if (speed <= 0) {
152  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
153  }
154  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
155  MSBusStop* bs = 0;
156  if (bsID != "") {
157  bs = MSNet::getInstance()->getBusStop(bsID);
158  if (bs == 0) {
159  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
160  }
161  arrivalPos = bs->getEndLanePosition();
162  }
163  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
165  } else {
166  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
167  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
168  MSEdge* from = MSEdge::dictionary(fromID);
169  if (from == 0) {
170  throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
171  }
172  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
173  MSEdge* to = MSEdge::dictionary(toID);
174  if (to == 0) {
175  throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
176  }
178  SUMOVehicleParameter::interpretEdgePos(departPos, from->getLength(), SUMO_ATTR_DEPARTPOS, "person walking from " + from->getID()),
179  SUMOVehicleParameter::interpretEdgePos(arrivalPos, to->getLength(), SUMO_ATTR_ARRIVALPOS, "person walking to " + to->getID()),
180  speed, 0, 0, myActiveRoute);
181  if (myActiveRoute.empty()) {
182  const std::string error = "No connection found between '" + from->getID() + "' and '" + to->getID() + "' for person '" + myVehicleParameter->id + "'.";
183  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
184  myActiveRoute.push_back(from);
185  // XXX
186  //myActiveRoute.push_back(to);
187  //WRITE_WARNING(error);
188  } else {
189  WRITE_ERROR(error);
190  }
191  }
192  //std::cout << myVehicleParameter->id << " edges=" << toString(myActiveRoute) << "\n";
193  }
194  }
195  if (myActiveRoute.empty()) {
196  throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
197  }
198  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
199  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
200  }
201  if (myActivePlan->empty()) {
203  *myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start"));
204  }
205  myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, bs, duration, speed, departPos, arrivalPos));
206  myActiveRoute.clear();
207  break;
208  }
209  case SUMO_TAG_FLOW:
210  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
212  bool ok = true;
213  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
214  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
215  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
216  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
217  closeRoute(true);
219  }
220  break;
221  case SUMO_TAG_TRIP: {
222  bool ok = true;
224  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
225  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
226  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
227  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
228  } else {
229  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
230  if (fromTaz == 0) {
231  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
232  } else if (fromTaz->getNumSuccessors() == 0) {
233  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
234  } else {
235  myActiveRoute.push_back(fromTaz->getSuccessor(0));
236  }
237  }
238  closeRoute(true);
239  closeVehicle();
240  }
241  break;
242  default:
243  break;
244  }
245  // parse embedded vtype information
246  if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_PARAM) {
248  return;
249  }
250 }
251 
252 
253 void
255  bool ok = true;
256  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
257  if (ok) {
259  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
260  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
261  StringTokenizer st(vTypes);
262  while (st.hasNext()) {
263  std::string vtypeID = st.next();
265  if (type == 0) {
266  throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
267  }
269  }
270  }
271  }
272 }
273 
274 
275 void
277  if (myCurrentVTypeDistribution != 0) {
278  if (MSGlobals::gStateLoaded && MSNet::getInstance()->getVehicleControl().hasVTypeDistribution(myCurrentVTypeDistributionID)) {
280  return;
281  }
284  throw ProcessError("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
285  }
286  if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
288  throw ProcessError("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
289  }
291  }
292 }
293 
294 
295 void
297  // check whether the id is really necessary
298  std::string rid;
299  if (myCurrentRouteDistribution != 0) {
301  rid = "distribution '" + myCurrentRouteDistributionID + "'";
302  } else if (myVehicleParameter != 0) {
303  // ok, a vehicle is wrapping the route,
304  // we may use this vehicle's id as default
305  myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
306  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
307  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
308  }
309  } else {
310  bool ok = true;
311  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok, false);
312  if (!ok) {
313  return;
314  }
315  rid = "'" + myActiveRouteID + "'";
316  }
317  if (myVehicleParameter != 0) { // have to do this here for nested route distributions
318  rid = "for vehicle '" + myVehicleParameter->id + "'";
319  }
320  bool ok = true;
321  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
322  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
323  }
324  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
326  WRITE_ERROR("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
327  }
330  myCurrentCosts = attrs.getOpt<SUMOReal>(SUMO_ATTR_COST, myActiveRouteID.c_str(), ok, -1);
331  if (ok && myCurrentCosts != -1 && myCurrentCosts < 0) {
332  WRITE_ERROR("Invalid cost for route '" + myActiveRouteID + "'.");
333  }
334 }
335 
336 
337 void
340  switch (element) {
341  case SUMO_TAG_VTYPE: {
343  delete myCurrentVType;
344  myCurrentVType = 0;
345  if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
346  const std::string id = vehType->getID();
347  delete vehType;
349  throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
350  }
351  } else {
352  if (myCurrentVTypeDistribution != 0) {
354  }
355  }
356  }
357  break;
358  default:
359  break;
360  }
361 }
362 
363 
364 void
365 MSRouteHandler::closeRoute(const bool /* mayBeDisconnected */) {
366  if (myActiveRoute.size() == 0) {
367  delete myActiveRouteColor;
368  myActiveRouteColor = 0;
371  if (route != 0) {
373  route->addReference();
374  }
375  }
376  myActiveRouteID = "";
377  myActiveRouteRefID = "";
378  return;
379  }
380  if (myVehicleParameter != 0) {
381  throw ProcessError("Vehicle's '" + myVehicleParameter->id + "' route has no edges.");
382  } else {
383  throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
384  }
385  }
389  route->setCosts(myCurrentCosts);
390  myActiveRoute.clear();
391  if (!MSRoute::dictionary(myActiveRouteID, route)) {
392  delete route;
394  if (myVehicleParameter != 0) {
395  if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id) == 0) {
396  throw ProcessError("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
397  } else {
398  throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
399  }
400  } else {
401  throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
402  }
403  }
404  } else {
405  if (myCurrentRouteDistribution != 0) {
407  route->addReference();
408  }
409  }
410  }
411  myActiveRouteID = "";
412  myActiveRouteColor = 0;
413  myActiveRouteStops.clear();
414 }
415 
416 
417 void
419  // check whether the id is really necessary
420  bool ok = true;
421  if (myVehicleParameter != 0) {
422  // ok, a vehicle is wrapping the route,
423  // we may use this vehicle's id as default
424  myCurrentRouteDistributionID = "!" + myVehicleParameter->id; // !!! document this
425  } else {
426  myCurrentRouteDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
427  if (!ok) {
428  return;
429  }
430  }
432  std::vector<SUMOReal> probs;
433  if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
434  bool ok = true;
435  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentRouteDistributionID.c_str(), ok));
436  while (st.hasNext()) {
437  probs.push_back(TplConvert::_2SUMORealSec(st.next().c_str(), 1.0));
438  }
439  }
440  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
441  bool ok = true;
442  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, myCurrentRouteDistributionID.c_str(), ok));
443  size_t probIndex = 0;
444  while (st.hasNext()) {
445  std::string routeID = st.next();
446  const MSRoute* route = MSRoute::dictionary(routeID, &myParsingRNG);
447  if (route == 0) {
448  throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
449  }
450  const SUMOReal prob = (probs.size() > probIndex ? probs[probIndex] : 1.0);
451  if (myCurrentRouteDistribution->add(prob, route, false)) {
452  route->addReference();
453  }
454  probIndex++;
455  }
456  if (probs.size() > 0 && probIndex != probs.size()) {
457  WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
458  " routes in routeDistribution '" + myCurrentRouteDistributionID + "'");
459  }
460  }
461 }
462 
463 
464 void
466  if (myCurrentRouteDistribution != 0) {
467  const bool haveSameID = MSRoute::dictionary(myCurrentRouteDistributionID, &myParsingRNG) != 0;
468  if (MSGlobals::gStateLoaded && haveSameID) {
470  return;
471  }
472  if (haveSameID) {
474  throw ProcessError("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
475  }
478  throw ProcessError("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
479  }
482  }
483 }
484 
485 
486 void
488  // get nested route
492  // let's check whether this vehicle had to depart before the simulation starts
494  if (route != 0) {
495  route->addReference();
496  route->release();
497  }
498  return;
499  }
500  }
501  // get the vehicle's type
502  MSVehicleType* vtype = 0;
503  if (myVehicleParameter->vtypeid != "") {
504  vtype = vehControl.getVType(myVehicleParameter->vtypeid, &myParsingRNG);
505  if (vtype == 0) {
506  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
507  }
508  } else {
509  // there should be one (at least the default one)
510  vtype = vehControl.getVType(DEFAULT_VTYPE_ID, &myParsingRNG);
511  }
512  if (route == 0) {
513  // if there is no nested route, try via the (hopefully) given route-id
515  }
516  if (route == 0) {
517  // nothing found? -> error
518  if (myVehicleParameter->routeid != "") {
519  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
520  } else {
521  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
522  }
523  }
524  myActiveRouteID = "";
525 
526  // try to build the vehicle
527  SUMOVehicle* vehicle = 0;
528  if (vehControl.getVehicle(myVehicleParameter->id) == 0) {
529  vehicle = vehControl.buildVehicle(myVehicleParameter, route, vtype, OptionsCont::getOptions().getBool("ignore-route-errors"));
530  // maybe we do not want this vehicle to be inserted due to scaling
531  unsigned int quota = vehControl.getQuota();
532  if (quota > 0) {
533  vehControl.addVehicle(myVehicleParameter->id, vehicle);
535  vehControl.addWaiting(*route->begin(), vehicle);
536  vehControl.registerOneWaitingForPerson();
537  } else {
538  // !!! no scaling for triggered vehicles yet
539  for (unsigned int i = 1; i < quota; i++) {
542  newPars->id = myVehicleParameter->id + "." + toString(i);
543  vehicle = vehControl.buildVehicle(newPars, route, vtype, OptionsCont::getOptions().getBool("ignore-route-errors"));
544  vehControl.addVehicle(newPars->id, vehicle);
545  }
546  }
548  myVehicleParameter = 0;
549  } else {
550  vehControl.deleteVehicle(vehicle, true);
551  myVehicleParameter = 0;
552  vehicle = 0;
553  }
554  } else {
555  // strange: another vehicle with the same id already exists
557  // and was not loaded while loading a simulation state
558  // -> error
559  throw ProcessError("Another vehicle with the id '" + myVehicleParameter->id + "' exists.");
560  } else {
561  // ok, it seems to be loaded previously while loading a simulation state
562  vehicle = 0;
563  }
564  }
565  // check whether the vehicle shall be added directly to the network or
566  // shall stay in the internal buffer
567  if (vehicle != 0) {
568  if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
570  }
571  }
572 }
573 
574 
575 void
577  if (myActivePlan->size() == 0) {
578  throw ProcessError("Person '" + myVehicleParameter->id + "' has no plan.");
579  }
581  if (type == 0) {
582  throw ProcessError("The type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
583  }
585  // @todo: consider myScale?
587  if (MSNet::getInstance()->getPersonControl().add(myVehicleParameter->id, person)) {
590  } else {
591  delete person;
592  throw ProcessError("Another person with the id '" + myVehicleParameter->id + "' exists.");
593  }
594  } else {
595  // warning already given
596  delete person;
597  }
598  myVehicleParameter = 0;
599  myActivePlan = 0;
600 }
601 
602 
603 void
606  return;
607  }
608  // let's check whether vehicles had to depart before the simulation starts
611  const SUMOTime offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
615  return;
616  }
617  }
618  }
619  if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid, &myParsingRNG) == 0) {
620  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
621  }
623  // if not, try via the (hopefully) given route-id
625  if (myVehicleParameter->routeid != "") {
626  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
627  } else {
630  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
631  if (fromTaz == 0) {
632  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
633  } else if (fromTaz->getNumSuccessors() == 0) {
634  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
635  } else {
636  myActiveRoute.push_back(fromTaz->getSuccessor(0));
637  }
638  closeRoute(true);
640  } else {
641  throw ProcessError("Flow '" + myVehicleParameter->id + "' has no route.");
642  }
643  }
644  }
645  } else {
647  }
648  myActiveRouteID = "";
649 
650  // check whether the vehicle shall be added directly to the network or
651  // shall stay in the internal buffer
655  }
656  myVehicleParameter = 0;
657 }
658 
659 
660 void
662  std::string errorSuffix;
663  if (myActiveRouteID != "") {
664  errorSuffix = " in route '" + myActiveRouteID + "'.";
665  } else if (myActivePlan) {
666  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
667  } else {
668  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
669  }
671  bool ok = parseStop(stop, attrs, errorSuffix, MsgHandler::getErrorInstance());
672  if (!ok) {
673  return;
674  }
675  // try to parse the assigned bus stop
676  if (stop.busstop != "") {
677  // ok, we have obviously a bus stop
679  if (bs != 0) {
680  const MSLane& l = bs->getLane();
681  stop.lane = l.getID();
682  stop.endPos = bs->getEndLanePosition();
683  stop.startPos = bs->getBeginLanePosition();
684  } else {
685  WRITE_ERROR("The bus stop '" + stop.busstop + "' is not known" + errorSuffix);
686  return;
687  }
688  } else {
689  // no, the lane and the position should be given
690  // get the lane
691  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, 0, ok, "");
692  if (ok && stop.lane != "") {
693  if (MSLane::dictionary(stop.lane) == 0) {
694  WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
695  return;
696  }
697  } else {
698  WRITE_ERROR("A stop must be placed on a bus stop or a lane" + errorSuffix);
699  return;
700  }
701  if (myActivePlan &&
702  !myActivePlan->empty() &&
703  &myActivePlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) {
704  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
705  }
706  if (myActivePlan && myActivePlan->empty()) {
708  MSLane::dictionary(stop.lane)->getEdge(), -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
709  }
710  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, 0, ok, MSLane::dictionary(stop.lane)->getLength());
711  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
712  WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix);
713  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_POSITION, 0, ok, stop.endPos);
714  }
715  stop.startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, 0, ok, MAX2((SUMOReal)0., stop.endPos - 2 * POSITION_EPS));
716  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
717  if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) {
718  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.lane + "'" + errorSuffix);
719  return;
720  }
721  }
722  if (myActiveRouteID != "") {
723  myActiveRouteStops.push_back(stop);
724  } else if (myActivePlan) {
725  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, 0, ok, "waiting");
727  MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, stop.startPos, actType));
728  } else {
729  myVehicleParameter->stops.push_back(stop);
730  }
731 }
732 
733 
734 /****************************************************************************/
The departure is person triggered.
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
const int VTYPEPARS_MAXSPEED_SET
MSRouteHandler(const std::string &file, bool addVehiclesDirectly)
standard constructor
bool wasSet(int what) const
Returns whether the given parameter was set.
Definition: MSVehicleType.h:91
SUMOReal repetitionProbability
The probability for emitting a vehicle per second.
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
SUMOReal myCurrentCosts
The currently parsed route costs.
virtual MSPerson * buildPerson(const SUMOVehicleParameter *pars, const MSVehicleType *vtype, MSPerson::MSPersonPlan *plan) const
Builds a new person.
virtual void myEndElement(int element)
Called when a closing tag occurs.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
SUMOReal getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
const int VEHPARS_FORCE_REROUTE
RandomDistributor< const MSRoute * > * myCurrentRouteDistribution
The currently parsed distribution of routes (probability-&gt;route)
const std::vector< SUMOReal > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
The time is given.
std::string next()
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
MSPerson::MSPersonPlan * myActivePlan
The plan of the current person.
std::string vtypeid
The vehicle&#39;s type id.
void closeVehicle()
Ends the processing of a vehicle.
static MTRand myParsingRNG
A random number generator used to choose from vtype/route distributions and computing the speed facto...
static void parseVTypeEmbedded(SUMOVTypeParameter &into, int element, const SUMOSAXAttributes &attrs, bool fromVType=false)
Parses an element embedded in vtype definition.
bool myAddVehiclesDirectly
Information whether vehicles shall be directly added to the network or kept within the buffer...
SUMOTime duration
The stopping duration.
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, or flow.
bool add(SUMOReal prob, T val, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
static bool checkStopPos(SUMOReal &startPos, SUMOReal &endPos, const SUMOReal laneLength, const SUMOReal minLength, const bool friendlyPos)
check start and end position of a stop
static bool gStateLoaded
Information whether a state has been loaded.
Definition: MSGlobals.h:86
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
void closePerson()
Ends the processing of a person.
int repetitionsDone
The number of times the vehicle was already inserted.
const SUMOReal DEFAULT_PEDESTRIAN_SPEED
void openRoute(const SUMOSAXAttributes &attrs)
static SUMOReal _2SUMORealSec(const E *const data, SUMOReal def)
Definition: TplConvert.h:336
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:156
T MAX2(T a, T b)
Definition: StdDefs.h:74
void setCosts(SUMOReal costs)
Sets the costs of the route.
Definition: MSRoute.h:155
const SUMOReal DEFAULT_VEH_PROB
SUMOReal myActiveRouteProbability
The probability of the current route.
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:523
SUMOTime until
The time at which the vehicle may continue its journey.
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
std::string myActiveRouteID
The id of the current route.
SUMOReal getEndLanePosition() const
Returns the end position of this bus stop.
Definition: MSBusStop.cpp:72
SUMOReal repetitionOffset
The time offset between vehicle reinsertions.
MSEdgeVector myActiveRoute
The current route.
const MSEdge * getSuccessor(unsigned int n) const
Returns the n-th of the following edges.
Definition: MSEdge.h:301
const std::string DEFAULT_VTYPE_ID
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
SUMOReal getBeginLanePosition() const
Returns the begin position of this bus stop.
Definition: MSBusStop.cpp:66
The car-following model and parameter.
Definition: MSVehicleType.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
const MSLane & getLane() const
Returns the lane this bus stop is located at.
Definition: MSBusStop.cpp:60
std::vector< Stop > stops
List of the stops the vehicle will make.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
static SUMOReal interpretEdgePos(SUMOReal pos, SUMOReal maximumValue, SumoXMLAttr attr, const std::string &id)
Interprets negative edge positions and fits them onto a given edge.
std::string busstop
(Optional) bus stop if one is assigned to the stop
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:75
static void parseEdgesList(const std::string &desc, std::vector< const MSEdge * > &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:586
void compute(const E *from, const E *to, SUMOReal departPos, SUMOReal arrivalPos, SUMOReal speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
RandomDistributor< MSVehicleType * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability-&gt;vehicle type)
SUMOReal startPos
The stopping position start.
the edges of a route
void closeRouteDistribution()
std::string routeid
The vehicle&#39;s route id.
Representation of a vehicle.
Definition: SUMOVehicle.h:64
Encapsulated SAX-Attributes.
bool wasSet(int what) const
Returns whether the given parameter was set.
SUMOReal endPos
The stopping position end.
A lane area vehicles can halt at.
Definition: MSBusStop.h:64
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:283
void closeVehicleTypeDistribution()
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
SUMOTime depart
The vehicle&#39;s departure time.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:48
#define POSITION_EPS
Definition: config.h:189
std::string fromTaz
The vehicle&#39;s origin zone (district)
MSBusStop * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:720
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:100
void registerOneWaitingForPerson()
increases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
std::string lane
The lane to stop at.
Parser for routes during their loading.
std::string myCurrentRouteDistributionID
The id of the currently parsed route distribution.
void openRouteDistribution(const SUMOSAXAttributes &attrs)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
virtual void myEndElement(int element)
Called when a closing tag occurs.
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:869
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
Structure representing possible vehicle parameter.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:638
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:314
int setParameter
Information for the router which parameter were set.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
std::string myCurrentVTypeDistributionID
The id of the currently parsed vehicle type distribution.
Definition of vehicle stop (position and duration)
bool parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs, std::string errorSuffix, MsgHandler *const errorOutput)
parses attributes common to all stops
SUMOReal getDefaultProbability() const
Get the default probability of this vehicle type.
const std::string & getID() const
Returns the name of the vehicle type.
void setDeparture(SUMOTime time, MSPerson *person)
sets the arrival time for a waiting or walking person
int SUMOTime
Definition: SUMOTime.h:43
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
const int VEHPARS_TAZ_SET
const RGBColor * myActiveRouteColor
The currently parsed route&#39;s color.
#define SUMOReal
Definition: config.h:218
unsigned int getNumSuccessors() const
Returns the number of edges that may be reached from this edge.
Definition: MSEdge.h:292
#define NUMERICAL_EPS
Definition: config.h:162
virtual ~MSRouteHandler()
standard destructor
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
The class responsible for building and deletion of vehicles.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:106
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, MTRand *rng=0)
Returns the named vehicle type or a sample from the named distribution.
MSPedestrianRouterDijkstra & getPedestrianRouter(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:777
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
bool checkLastDepart()
Checks whether the route file is sorted by departure time if needed.
std::string myActiveRouteRefID
The id of the route the current route references to.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
std::vector< MSPersonStage * > MSPersonPlan
the structure holding the plan of a person
Definition: MSPerson.h:515
A color information.
void closeRoute(const bool mayBeDisconnected=false)
unsigned int getQuota(SUMOReal frac=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that &quot;frac&quot; ...
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
void closeFlow()
Ends the processing of a flow.
std::string id
The vehicle&#39;s id.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116