SUMO - Simulation of Urban MObility
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-sim.org/
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 // method definitions
67 // ===========================================================================
68 MSRouteHandler::MSRouteHandler(const std::string& file,
69  bool addVehiclesDirectly) :
70  SUMORouteHandler(file),
71  myActivePlan(0),
72  myAddVehiclesDirectly(addVehiclesDirectly),
73  myCurrentVTypeDistribution(0),
74  myCurrentRouteDistribution(0) {
75  myActiveRoute.reserve(100);
76 }
77 
78 
80 }
81 
82 
83 void
85  const SUMOSAXAttributes& attrs) {
86  SUMORouteHandler::myStartElement(element, attrs);
87  switch (element) {
88  case SUMO_TAG_PERSON:
90  break;
91  case SUMO_TAG_RIDE: {
92  const std::string pid = myVehicleParameter->id;
93  bool ok = true;
94  MSEdge* from = 0;
95  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
96  StringTokenizer st(desc);
97  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
98  MSBusStop* bs = 0;
99  if (bsID != "") {
100  bs = MSNet::getInstance()->getBusStop(bsID);
101  if (bs == 0) {
102  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
103  }
104  }
105  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
106  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
107  from = MSEdge::dictionary(fromID);
108  if (from == 0) {
109  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
110  }
111  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
112  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
113  }
114  if (myActivePlan->empty()) {
116  *from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
117  }
118  } else if (myActivePlan->empty()) {
119  throw ProcessError("The start edge within for person '" + pid + "' is not known.");
120  }
121  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
122  MSEdge* to = MSEdge::dictionary(toID);
123  if (to == 0) {
124  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
125  }
126  myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, bs, st.getVector()));
127  break;
128  }
129  case SUMO_TAG_WALK: {
130  myActiveRoute.clear();
131  bool ok = true;
132  SUMOReal departPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
133  SUMOReal arrivalPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -NUMERICAL_EPS);
134  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
135  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
136  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
137  }
140  // need to check for explicitly set speed since we might have // DEFAULT_VEHTYPE
141  if (vtype != 0 && vtype->wasSet(VTYPEPARS_MAXSPEED_SET)) {
142  speed = vtype->getMaxSpeed();
143  }
144  speed = attrs.getOpt<SUMOReal>(SUMO_ATTR_SPEED, 0, ok, speed);
145  if (speed <= 0) {
146  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
147  }
148  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
149  MSBusStop* bs = 0;
150  if (bsID != "") {
151  bs = MSNet::getInstance()->getBusStop(bsID);
152  if (bs == 0) {
153  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
154  }
155  arrivalPos = bs->getEndLanePosition();
156  }
157  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
159  } else {
160  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
161  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
162  MSEdge* from = MSEdge::dictionary(fromID);
163  if (from == 0) {
164  throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
165  }
166  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
167  MSEdge* to = MSEdge::dictionary(toID);
168  if (to == 0) {
169  throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
170  }
172  SUMOVehicleParameter::interpretEdgePos(departPos, from->getLength(), SUMO_ATTR_DEPARTPOS, "person walking from " + from->getID()),
173  SUMOVehicleParameter::interpretEdgePos(arrivalPos, to->getLength(), SUMO_ATTR_ARRIVALPOS, "person walking to " + to->getID()),
174  speed, 0, 0, myActiveRoute);
175  if (myActiveRoute.empty()) {
176  const std::string error = "No connection found between '" + from->getID() + "' and '" + to->getID() + "' for person '" + myVehicleParameter->id + "'.";
177  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
178  myActiveRoute.push_back(from);
179  // XXX
180  //myActiveRoute.push_back(to);
181  //WRITE_WARNING(error);
182  } else {
183  WRITE_ERROR(error);
184  }
185  }
186  //std::cout << myVehicleParameter->id << " edges=" << toString(myActiveRoute) << "\n";
187  }
188  }
189  if (myActiveRoute.empty()) {
190  throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
191  }
192  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
193  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
194  }
195  if (myActivePlan->empty()) {
197  *myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start"));
198  }
199  myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, bs, duration, speed, departPos, arrivalPos));
200  myActiveRoute.clear();
201  break;
202  }
203  case SUMO_TAG_FLOW:
204  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
206  bool ok = true;
207  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
208  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
209  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
210  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
211  closeRoute(true);
212  }
213  break;
214  case SUMO_TAG_TRIP: {
215  bool ok = true;
217  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
218  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
219  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
220  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
221  } else {
222  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
223  if (fromTaz == 0) {
224  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
225  } else if (fromTaz->getNoFollowing() == 0) {
226  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
227  } else {
228  myActiveRoute.push_back(fromTaz->getFollower(0));
229  }
230  }
231  closeRoute(true);
232  closeVehicle();
233  }
234  break;
235  default:
236  break;
237  }
238  // parse embedded vtype information
239  if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_PARAM) {
241  return;
242  }
243 }
244 
245 
246 void
248  bool ok = true;
249  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
250  if (ok) {
252  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
253  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
254  StringTokenizer st(vTypes);
255  while (st.hasNext()) {
256  std::string vtypeID = st.next();
258  if (type == 0) {
259  throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
260  }
262  }
263  }
264  }
265 }
266 
267 
268 void
270  if (myCurrentVTypeDistribution != 0) {
271  if (MSGlobals::gStateLoaded && MSNet::getInstance()->getVehicleControl().hasVTypeDistribution(myCurrentVTypeDistributionID)) {
273  return;
274  }
277  throw ProcessError("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
278  }
279  if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
281  throw ProcessError("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
282  }
284  }
285 }
286 
287 
288 void
290  // check whether the id is really necessary
291  std::string rid;
292  if (myCurrentRouteDistribution != 0) {
294  rid = "distribution '" + myCurrentRouteDistributionID + "'";
295  } else if (myVehicleParameter != 0) {
296  // ok, a vehicle is wrapping the route,
297  // we may use this vehicle's id as default
298  myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
299  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
300  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
301  }
302  } else {
303  bool ok = true;
304  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok, false);
305  if (!ok) {
306  return;
307  }
308  rid = "'" + myActiveRouteID + "'";
309  }
310  if (myVehicleParameter != 0) { // have to do this here for nested route distributions
311  rid = "for vehicle '" + myVehicleParameter->id + "'";
312  }
313  bool ok = true;
314  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
315  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
316  }
317  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
319  WRITE_ERROR("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
320  }
323 }
324 
325 
326 void
329  switch (element) {
330  case SUMO_TAG_VTYPE: {
332  delete myCurrentVType;
333  myCurrentVType = 0;
334  if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
335  const std::string id = vehType->getID();
336  delete vehType;
338  throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
339  }
340  } else {
341  if (myCurrentVTypeDistribution != 0) {
343  }
344  }
345  }
346  break;
347  default:
348  break;
349  }
350 }
351 
352 
353 void
354 MSRouteHandler::closeRoute(const bool /* mayBeDisconnected */) {
355  if (myActiveRoute.size() == 0) {
356  delete myActiveRouteColor;
357  myActiveRouteColor = 0;
360  if (route != 0) {
362  route->addReference();
363  }
364  }
365  myActiveRouteID = "";
366  myActiveRouteRefID = "";
367  return;
368  }
369  if (myVehicleParameter != 0) {
370  throw ProcessError("Vehicle's '" + myVehicleParameter->id + "' route has no edges.");
371  } else {
372  throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
373  }
374  }
378  myActiveRoute.clear();
379  if (!MSRoute::dictionary(myActiveRouteID, route)) {
380  delete route;
382  if (myVehicleParameter != 0) {
383  if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id) == 0) {
384  throw ProcessError("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
385  } else {
386  throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
387  }
388  } else {
389  throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
390  }
391  }
392  } else {
393  if (myCurrentRouteDistribution != 0) {
395  route->addReference();
396  }
397  }
398  }
399  myActiveRouteID = "";
400  myActiveRouteColor = 0;
401  myActiveRouteStops.clear();
402 }
403 
404 
405 void
407  // check whether the id is really necessary
408  bool ok = true;
409  if (myVehicleParameter != 0) {
410  // ok, a vehicle is wrapping the route,
411  // we may use this vehicle's id as default
412  myCurrentRouteDistributionID = "!" + myVehicleParameter->id; // !!! document this
413  } else {
414  myCurrentRouteDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
415  if (!ok) {
416  return;
417  }
418  }
420  std::vector<SUMOReal> probs;
421  if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
422  bool ok = true;
423  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentRouteDistributionID.c_str(), ok));
424  while (st.hasNext()) {
425  probs.push_back(TplConvert::_2SUMORealSec(st.next().c_str(), 1.0));
426  }
427  }
428  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
429  bool ok = true;
430  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, myCurrentRouteDistributionID.c_str(), ok));
431  size_t probIndex = 0;
432  while (st.hasNext()) {
433  std::string routeID = st.next();
434  const MSRoute* route = MSRoute::dictionary(routeID);
435  if (route == 0) {
436  throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
437  }
438  const SUMOReal prob = (probs.size() > probIndex ? probs[probIndex] : 1.0);
439  if (myCurrentRouteDistribution->add(prob, route, false)) {
440  route->addReference();
441  }
442  probIndex++;
443  }
444  if (probs.size() > 0 && probIndex != probs.size()) {
445  WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
446  " routes in routeDistribution '" + myCurrentRouteDistributionID + "'");
447  }
448  }
449 }
450 
451 
452 void
454  if (myCurrentRouteDistribution != 0) {
455  const bool haveSameID = MSRoute::dictionary(myCurrentRouteDistributionID) != 0;
456  if (MSGlobals::gStateLoaded && haveSameID) {
458  return;
459  }
460  if (haveSameID) {
462  throw ProcessError("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
463  }
466  throw ProcessError("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
467  }
470  }
471 }
472 
473 
474 void
476  // get nested route
477  const MSRoute* route = MSRoute::dictionary("!" + myVehicleParameter->id);
480  // let's check whether this vehicle had to depart before the simulation starts
482  if (route != 0) {
483  route->addReference();
484  route->release();
485  }
486  return;
487  }
488  }
489  // get the vehicle's type
490  MSVehicleType* vtype = 0;
491  if (myVehicleParameter->vtypeid != "") {
492  vtype = vehControl.getVType(myVehicleParameter->vtypeid);
493  if (vtype == 0) {
494  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
495  }
496  } else {
497  // there should be one (at least the default one)
498  vtype = vehControl.getVType();
499  }
500  if (route == 0) {
501  // if there is no nested route, try via the (hopefully) given route-id
503  }
504  if (route == 0) {
505  // nothing found? -> error
506  if (myVehicleParameter->routeid != "") {
507  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
508  } else {
509  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
510  }
511  }
512  myActiveRouteID = "";
513 
514  // try to build the vehicle
515  SUMOVehicle* vehicle = 0;
516  if (vehControl.getVehicle(myVehicleParameter->id) == 0) {
517  vehicle = vehControl.buildVehicle(myVehicleParameter, route, vtype);
518  // maybe we do not want this vehicle to be inserted due to scaling
519  unsigned int quota = vehControl.getQuota();
520  if (quota > 0) {
521  vehControl.addVehicle(myVehicleParameter->id, vehicle);
523  vehControl.addWaiting(*route->begin(), vehicle);
524  vehControl.registerOneWaitingForPerson();
525  } else {
526  // !!! no scaling for triggered vehicles yet
527  for (unsigned int i = 1; i < quota; i++) {
530  newPars->id = myVehicleParameter->id + "." + toString(i);
531  vehicle = vehControl.buildVehicle(newPars, route, vtype);
532  vehControl.addVehicle(newPars->id, vehicle);
533  }
534  }
536  myVehicleParameter = 0;
537  } else {
538  vehControl.deleteVehicle(vehicle, true);
539  myVehicleParameter = 0;
540  vehicle = 0;
541  }
542  } else {
543  // strange: another vehicle with the same id already exists
545  // and was not loaded while loading a simulation state
546  // -> error
547  throw ProcessError("Another vehicle with the id '" + myVehicleParameter->id + "' exists.");
548  } else {
549  // ok, it seems to be loaded previously while loading a simulation state
550  vehicle = 0;
551  }
552  }
553  // check whether the vehicle shall be added directly to the network or
554  // shall stay in the internal buffer
555  if (vehicle != 0) {
556  if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
558  }
559  }
560 }
561 
562 
563 void
565  if (myActivePlan->size() == 0) {
566  throw ProcessError("Person '" + myVehicleParameter->id + "' has no plan.");
567  }
569  if (type == 0) {
570  throw ProcessError("The type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
571  }
573  // @todo: consider myScale?
575  if (MSNet::getInstance()->getPersonControl().add(myVehicleParameter->id, person)) {
578  } else {
579  delete person;
580  throw ProcessError("Another person with the id '" + myVehicleParameter->id + "' exists.");
581  }
582  } else {
583  // warning already given
584  delete person;
585  }
586  myVehicleParameter = 0;
587  myActivePlan = 0;
588 }
589 
590 
591 void
594  return;
595  }
596  // let's check whether vehicles had to depart before the simulation starts
598  const SUMOTime offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
602  return;
603  }
604  }
605  if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid) == 0) {
606  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
607  }
608  if (MSRoute::dictionary("!" + myVehicleParameter->id) == 0) {
609  // if not, try via the (hopefully) given route-id
611  if (myVehicleParameter->routeid != "") {
612  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
613  } else {
614  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
615  }
616  }
617  } else {
619  }
620  myActiveRouteID = "";
621 
622  // check whether the vehicle shall be added directly to the network or
623  // shall stay in the internal buffer
627  }
628  myVehicleParameter = 0;
629 }
630 
631 
632 void
634  std::string errorSuffix;
635  if (myActiveRouteID != "") {
636  errorSuffix = " in route '" + myActiveRouteID + "'.";
637  } else if (myActivePlan) {
638  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
639  } else {
640  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
641  }
643  bool ok = parseStop(stop, attrs, errorSuffix, MsgHandler::getErrorInstance());
644  if (!ok) {
645  return;
646  }
647  // try to parse the assigned bus stop
648  if (stop.busstop != "") {
649  // ok, we have obviously a bus stop
651  if (bs != 0) {
652  const MSLane& l = bs->getLane();
653  stop.lane = l.getID();
654  stop.endPos = bs->getEndLanePosition();
655  stop.startPos = bs->getBeginLanePosition();
656  } else {
657  WRITE_ERROR("The bus stop '" + stop.busstop + "' is not known" + errorSuffix);
658  return;
659  }
660  } else {
661  // no, the lane and the position should be given
662  // get the lane
663  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, 0, ok, "");
664  if (ok && stop.lane != "") {
665  if (MSLane::dictionary(stop.lane) == 0) {
666  WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
667  return;
668  }
669  } else {
670  WRITE_ERROR("A stop must be placed on a bus stop or a lane" + errorSuffix);
671  return;
672  }
673  if (myActivePlan &&
674  !myActivePlan->empty() &&
675  &myActivePlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) {
676  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
677  }
678  if (myActivePlan && myActivePlan->empty()) {
680  MSLane::dictionary(stop.lane)->getEdge(), -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
681  }
682  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, 0, ok, MSLane::dictionary(stop.lane)->getLength());
683  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
684  WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix);
685  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_POSITION, 0, ok, stop.endPos);
686  }
687  stop.startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, 0, ok, MAX2((SUMOReal)0., stop.endPos - 2 * POSITION_EPS));
688  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
689  if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) {
690  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.lane + "'" + errorSuffix);
691  return;
692  }
693  }
694  if (myActiveRouteID != "") {
695  myActiveRouteStops.push_back(stop);
696  } else if (myActivePlan) {
697  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, 0, ok, "waiting");
699  MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, stop.startPos, actType));
700  } else {
701  myVehicleParameter->stops.push_back(stop);
702  }
703 }
704 
705 
706 /****************************************************************************/
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
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
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's maximum speed [m/s].
RandomDistributor< const MSRoute * > * myCurrentRouteDistribution
The currently parsed distribution of routes (probability->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's type id.
void closeVehicle()
Ends the processing of a vehicle.
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.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID)
Returns the named vehicle type or a sample from the named 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:159
T MAX2(T a, T b)
Definition: StdDefs.h:72
const SUMOReal DEFAULT_VEH_PROB
SUMOReal myActiveRouteProbability
The id 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't already in the dictionary...
Definition: MSEdge.cpp:473
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.
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.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type)
Builds a vehicle, increases the number of built vehicles.
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:74
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:536
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->vehicle type)
SUMOReal startPos
The stopping position start.
the edges of a route
void closeRouteDistribution()
std::string routeid
The vehicle'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:269
void closeVehicleTypeDistribution()
unsigned int getNoFollowing() const
Returns the number of edges that may be reached from this edge.
Definition: MSEdge.h:279
SUMOTime depart
The vehicle'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:186
std::string fromTaz
The vehicle's origin zone (district)
MSBusStop * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:709
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:828
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:627
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:300
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle'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
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 MSEdge * getFollower(unsigned int n) const
Returns the n-th of the following edges.
Definition: MSEdge.h:288
const int VEHPARS_TAZ_SET
const RGBColor * myActiveRouteColor
The currently parsed route's color.
#define SUMOReal
Definition: config.h:215
#define NUMERICAL_EPS
Definition: config.h:159
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
MSPedestrianRouterDijkstra & getPedestrianRouter(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:766
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 "frac" ...
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's id.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116