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-sim.org/
13 // Copyright (C) 2001-2013 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/MSVehicleType.h>
40 #include <microsim/MSVehicle.h>
43 #include <microsim/MSLane.h>
44 #include "MSRouteHandler.h"
45 #include "MSPersonControl.h"
53 #include "MSNet.h"
54 
56 #include <microsim/MSGlobals.h>
58 
59 #ifdef CHECK_MEMORY_LEAKS
60 #include <foreign/nvwa/debug_new.h>
61 #endif // CHECK_MEMORY_LEAKS
62 
63 
64 // ===========================================================================
65 // method definitions
66 // ===========================================================================
67 MSRouteHandler::MSRouteHandler(const std::string& file,
68  bool addVehiclesDirectly) :
69  SUMORouteHandler(file),
70  myActivePlan(0),
71  myAddVehiclesDirectly(addVehiclesDirectly),
72  myCurrentVTypeDistribution(0),
73  myCurrentRouteDistribution(0) {
74  myActiveRoute.reserve(100);
75 }
76 
77 
79 }
80 
81 
82 void
84  const SUMOSAXAttributes& attrs) {
85  SUMORouteHandler::myStartElement(element, attrs);
86  switch (element) {
87  case SUMO_TAG_PERSON:
89  break;
90  case SUMO_TAG_RIDE: {
91  const std::string pid = myVehicleParameter->id;
92  bool ok = true;
93  MSEdge* from = 0;
94  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
95  StringTokenizer st(desc);
96  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
97  MSBusStop* bs = 0;
98  if (bsID != "") {
99  bs = MSNet::getInstance()->getBusStop(bsID);
100  if (bs == 0) {
101  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
102  }
103  }
104  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
105  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
106  from = MSEdge::dictionary(fromID);
107  if (from == 0) {
108  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
109  }
110  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
111  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
112  }
113  if (myActivePlan->empty()) {
115  *from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
116  }
117  } else if (myActivePlan->empty()) {
118  throw ProcessError("The start edge within for person '" + pid + "' is not known.");
119  }
120  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
121  MSEdge* to = MSEdge::dictionary(toID);
122  if (to == 0) {
123  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
124  }
125  myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, bs, st.getVector()));
126  break;
127  }
128  case SUMO_TAG_WALK: {
129  myActiveRoute.clear();
130  bool ok = true;
131  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
133  } else {
134  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
135  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
136  MSEdge* from = MSEdge::dictionary(fromID);
137  if (from == 0) {
138  throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
139  }
140  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
141  MSEdge* to = MSEdge::dictionary(toID);
142  if (to == 0) {
143  throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
144  }
145  MSNet::getInstance()->getRouterTT().compute(from, to, 0, 0, myActiveRoute); // @todo: only footways, current time?
146  }
147  }
148  if (myActiveRoute.empty()) {
149  throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
150  }
151  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
152  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
153  }
154  SUMOReal departPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
155  SUMOReal arrivalPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -1);
156  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
158  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
159  speed = attrs.getOpt<SUMOReal>(SUMO_ATTR_SPEED, 0, ok, speed);
160  if (speed < 0) {
161  throw ProcessError("Negative walking speed for '" + myVehicleParameter->id + "'.");
162  }
163  }
164  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
165  MSBusStop* bs = 0;
166  if (bsID != "") {
167  bs = MSNet::getInstance()->getBusStop(bsID);
168  if (bs == 0) {
169  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
170  }
171  }
172  if (myActivePlan->empty()) {
174  *myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start"));
175  }
176  myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, bs, duration, speed, departPos, arrivalPos));
177  myActiveRoute.clear();
178  break;
179  }
180  case SUMO_TAG_FLOW:
181  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
183  bool ok = true;
184  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
185  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
186  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
187  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
188  closeRoute(true);
189  }
190  break;
191  case SUMO_TAG_TRIP: {
192  bool ok = true;
194  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
195  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
196  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
197  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
198  } else {
199  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
200  if (fromTaz == 0) {
201  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
202  } else if (fromTaz->getNoFollowing() == 0) {
203  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
204  } else {
205  myActiveRoute.push_back(fromTaz->getFollower(0));
206  }
207  }
208  closeRoute(true);
209  closeVehicle();
210  }
211  break;
212  default:
213  break;
214  }
215  // parse embedded vtype information
216  if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_PARAM) {
218  return;
219  }
220 }
221 
222 
223 void
225  bool ok = true;
226  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
227  if (ok) {
229  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
230  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
231  StringTokenizer st(vTypes);
232  while (st.hasNext()) {
233  std::string vtypeID = st.next();
235  if (type == 0) {
236  throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
237  }
239  }
240  }
241  }
242 }
243 
244 
245 void
247  if (myCurrentVTypeDistribution != 0) {
250  WRITE_ERROR("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
251  } else if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
253  WRITE_ERROR("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
254  }
256  }
257 }
258 
259 
260 void
262  // check whether the id is really necessary
263  std::string rid;
264  if (myCurrentRouteDistribution != 0) {
266  rid = "distribution '" + myCurrentRouteDistributionID + "'";
267  } else if (myVehicleParameter != 0) {
268  // ok, a vehicle is wrapping the route,
269  // we may use this vehicle's id as default
270  myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
271  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
272  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
273  }
274  } else {
275  bool ok = true;
276  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok, false);
277  if (!ok) {
278  return;
279  }
280  rid = "'" + myActiveRouteID + "'";
281  }
282  if (myVehicleParameter != 0) { // have to do this here for nested route distributions
283  rid = "for vehicle '" + myVehicleParameter->id + "'";
284  }
285  bool ok = true;
286  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
287  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
288  }
289  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
291  WRITE_ERROR("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
292  }
295 }
296 
297 
298 void
301  switch (element) {
302  case SUMO_TAG_VTYPE: {
304  delete myCurrentVType;
305  myCurrentVType = 0;
306  if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
307  const std::string id = vehType->getID();
308  delete vehType;
310  throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
311  }
312  } else {
313  if (myCurrentVTypeDistribution != 0) {
315  }
316  }
317  }
318  break;
319  default:
320  break;
321  }
322 }
323 
324 
325 void
326 MSRouteHandler::closeRoute(const bool /* mayBeDisconnected */) {
327  if (myActiveRoute.size() == 0) {
328  delete myActiveRouteColor;
329  myActiveRouteColor = 0;
332  myActiveRouteID = "";
333  myActiveRouteRefID = "";
334  return;
335  }
336  if (myVehicleParameter != 0) {
337  throw ProcessError("Vehicle's '" + myVehicleParameter->id + "' route has no edges.");
338  } else {
339  throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
340  }
341  }
345  myActiveRoute.clear();
346  if (!MSRoute::dictionary(myActiveRouteID, route)) {
347  delete route;
349  if (myVehicleParameter != 0) {
350  if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id) == 0) {
351  throw ProcessError("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
352  } else {
353  throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
354  }
355  } else {
356  throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
357  }
358  }
359  } else {
360  if (myCurrentRouteDistribution != 0) {
362  }
363  }
364  myActiveRouteID = "";
365  myActiveRouteColor = 0;
366  myActiveRouteStops.clear();
367 }
368 
369 
370 void
372  // check whether the id is really necessary
373  bool ok = true;
374  if (myVehicleParameter != 0) {
375  // ok, a vehicle is wrapping the route,
376  // we may use this vehicle's id as default
377  myCurrentRouteDistributionID = "!" + myVehicleParameter->id; // !!! document this
378  } else {
379  myCurrentRouteDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
380  if (!ok) {
381  return;
382  }
383  }
385  std::vector<SUMOReal> probs;
386  if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
387  bool ok = true;
388  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentRouteDistributionID.c_str(), ok));
389  while (st.hasNext()) {
390  probs.push_back(TplConvert::_2SUMORealSec(st.next().c_str(), 1.0));
391  }
392  }
393  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
394  bool ok = true;
395  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, myCurrentRouteDistributionID.c_str(), ok));
396  size_t probIndex = 0;
397  while (st.hasNext()) {
398  std::string routeID = st.next();
399  const MSRoute* route = MSRoute::dictionary(routeID);
400  if (route == 0) {
401  throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
402  }
403  const SUMOReal prob = (probs.size() > probIndex ? probs[probIndex] : 1.0);
404  myCurrentRouteDistribution->add(prob, route, false);
405  probIndex++;
406  }
407  if (probs.size() > 0 && probIndex != probs.size()) {
408  WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
409  " routes in routeDistribution '" + myCurrentRouteDistributionID + "'");
410  }
411  }
412 }
413 
414 
415 void
417  if (myCurrentRouteDistribution != 0) {
420  WRITE_ERROR("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
423  WRITE_ERROR("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
424  }
426  }
427 }
428 
429 
430 void
432  // get nested route
433  const MSRoute* route = MSRoute::dictionary("!" + myVehicleParameter->id);
436  // let's check whether this vehicle had to depart before the simulation starts
438  if (route != 0) {
439  route->addReference();
440  route->release();
441  }
442  return;
443  }
444  }
445  // get the vehicle's type
446  MSVehicleType* vtype = 0;
447  if (myVehicleParameter->vtypeid != "") {
448  vtype = vehControl.getVType(myVehicleParameter->vtypeid);
449  if (vtype == 0) {
450  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
451  }
452  } else {
453  // there should be one (at least the default one)
454  vtype = vehControl.getVType();
455  }
456  if (route == 0) {
457  // if there is no nested route, try via the (hopefully) given route-id
459  }
460  if (route == 0) {
461  // nothing found? -> error
462  if (myVehicleParameter->routeid != "") {
463  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
464  } else {
465  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
466  }
467  }
468  myActiveRouteID = "";
469 
470  // try to build the vehicle
471  SUMOVehicle* vehicle = 0;
472  if (vehControl.getVehicle(myVehicleParameter->id) == 0) {
473  vehicle = vehControl.buildVehicle(myVehicleParameter, route, vtype);
474  // maybe we do not want this vehicle to be inserted due to scaling
475  if (vehControl.isInQuota()) {
476  // add the vehicle to the vehicle control
477  vehControl.addVehicle(myVehicleParameter->id, vehicle);
479  vehControl.addWaiting(*route->begin(), vehicle);
480  vehControl.registerOneWaitingForPerson();
481  }
483  myVehicleParameter = 0;
484  } else {
485  vehControl.deleteVehicle(vehicle, true);
486  myVehicleParameter = 0;
487  vehicle = 0;
488  }
489  } else {
490  // strange: another vehicle with the same id already exists
492  // and was not loaded while loading a simulation state
493  // -> error
494  throw ProcessError("Another vehicle with the id '" + myVehicleParameter->id + "' exists.");
495  } else {
496  // ok, it seems to be loaded previously while loading a simulation state
497  vehicle = 0;
498  }
499  }
500  // check whether the vehicle shall be added directly to the network or
501  // shall stay in the internal buffer
502  if (vehicle != 0) {
503  if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
505  }
506  }
507 }
508 
509 
510 void
512  if (myActivePlan->size() == 0) {
513  throw ProcessError("Person '" + myVehicleParameter->id + "' has no plan.");
514  }
516  if (type == 0) {
517  throw ProcessError("The type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
518  }
520  // @todo: consider myScale?
521  if ((myAddVehiclesDirectly || checkLastDepart()) && MSNet::getInstance()->getPersonControl().add(myVehicleParameter->id, person)) {
524  } else {
525  delete person;
526  }
527  myVehicleParameter = 0;
528  myActivePlan = 0;
529 }
530 
531 
532 void
534  // let's check whether vehicles had to depart before the simulation starts
536  SUMOTime offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
540  return;
541  }
542  }
543  if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid) == 0) {
544  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
545  }
546  if (MSRoute::dictionary("!" + myVehicleParameter->id) == 0) {
547  // if not, try via the (hopefully) given route-id
549  if (myVehicleParameter->routeid != "") {
550  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
551  } else {
552  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
553  }
554  }
555  } else {
557  }
558  myActiveRouteID = "";
559 
560  // check whether the vehicle shall be added directly to the network or
561  // shall stay in the internal buffer
565  }
566  myVehicleParameter = 0;
567 }
568 
569 
570 void
572  bool ok = true;
573  std::string errorSuffix;
574  if (myActiveRouteID != "") {
575  errorSuffix = " in route '" + myActiveRouteID + "'.";
576  } else if (myActivePlan) {
577  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
578  } else {
579  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
580  }
583  // try to parse the assigned bus stop
584  stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
585  if (stop.busstop != "") {
586  // ok, we have obviously a bus stop
588  if (bs != 0) {
589  const MSLane& l = bs->getLane();
590  stop.lane = l.getID();
591  stop.endPos = bs->getEndLanePosition();
592  stop.startPos = bs->getBeginLanePosition();
593  } else {
594  WRITE_ERROR("The bus stop '" + stop.busstop + "' is not known" + errorSuffix);
595  return;
596  }
597  } else {
598  // no, the lane and the position should be given
599  // get the lane
600  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, 0, ok, "");
601  if (ok && stop.lane != "") {
602  if (MSLane::dictionary(stop.lane) == 0) {
603  WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
604  return;
605  }
606  } else {
607  WRITE_ERROR("A stop must be placed on a bus stop or a lane" + errorSuffix);
608  return;
609  }
610  if (myActivePlan &&
611  !myActivePlan->empty() &&
612  &myActivePlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) {
613  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
614  }
615  if (myActivePlan && myActivePlan->empty()) {
617  MSLane::dictionary(stop.lane)->getEdge(), -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
618  }
619  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, 0, ok, MSLane::dictionary(stop.lane)->getLength());
620  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
621  WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix);
622  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_POSITION, 0, ok, stop.endPos);
623  }
624  stop.startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, 0, ok, MAX2(0., stop.endPos - 2 * POSITION_EPS));
625  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
626  if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) {
627  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.lane + "'" + errorSuffix);
628  return;
629  }
630  }
631 
632  // get the standing duration
634  stop.triggered = attrs.getOpt<bool>(SUMO_ATTR_TRIGGERED, 0, ok, true);
635  stop.duration = -1;
636  stop.until = -1;
637  } else {
638  stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
639  stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, 0, ok, -1);
640  if (!ok || (stop.duration < 0 && stop.until < 0)) {
641  WRITE_ERROR("Invalid duration or end time is given for a stop on lane '" + stop.lane + "'" + errorSuffix);
642  return;
643  }
644  stop.triggered = attrs.getOpt<bool>(SUMO_ATTR_TRIGGERED, 0, ok, false);
645  }
646  stop.parking = attrs.getOpt<bool>(SUMO_ATTR_PARKING, 0, ok, stop.triggered);
647  if (!ok) {
648  WRITE_ERROR("Invalid bool for 'triggered' or 'parking' for stop on lane '" + stop.lane + "'" + errorSuffix);
649  return;
650  }
651 
652  // expected persons
653  std::string expectedStr = attrs.getOpt<std::string>(SUMO_ATTR_EXPECTED, 0, ok, "");
654  std::set<std::string> personIDs;
655  SUMOSAXAttributes::parseStringSet(expectedStr, personIDs);
656  stop.awaitedPersons = personIDs;
657 
658  const std::string idx = attrs.getOpt<std::string>(SUMO_ATTR_INDEX, 0, ok, "end");
659  if (idx == "end") {
660  stop.index = STOP_INDEX_END;
661  } else if (idx == "fit") {
662  stop.index = STOP_INDEX_FIT;
663  } else {
664  stop.index = attrs.get<int>(SUMO_ATTR_INDEX, 0, ok);
665  if (!ok || stop.index < 0) {
666  WRITE_ERROR("Invalid 'index' for stop on lane '" + stop.lane + "'" + errorSuffix);
667  return;
668  }
669  }
670  if (myActiveRouteID != "") {
671  myActiveRouteStops.push_back(stop);
672  } else if (myActivePlan) {
673  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, 0, ok, "waiting");
675  MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, stop.startPos, actType));
676  } else {
677  myVehicleParameter->stops.push_back(stop);
678  }
679 }
680 
681 
682 /****************************************************************************/
The departure is person triggered.
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
MSRouteHandler(const std::string &file, bool addVehiclesDirectly)
standard constructor
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
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.
static void parseStringSet(const std::string &def, std::set< std::string > &into)
Splits the given string, stores it in a set.
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.
bool parking
whether the vehicle is removed from the net while stopping
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.
static bool dictionary(std::string id, MSLane *lane)
Inserts a MSLane into the static dictionary Returns true if the key id isn&#39;t already in the dictionar...
Definition: MSLane.cpp:807
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID)
Returns the named vehicle type or a sample from the named distribution.
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:82
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.
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:150
T MAX2(T a, T b)
Definition: StdDefs.h:63
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&#39;t already in the dictionary...
Definition: MSEdge.cpp:461
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.
const int STOP_INDEX_FIT
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
std::string myActiveRouteID
The id of the current route.
SUMOReal getEndLanePosition() const
Returns the end position of this bus stop.
Definition: MSBusStop.cpp:71
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 void releaseRoute(const MSRoute *route)
release the route (to be used as function pointer with RandomDistributor)
Definition: MSRoute.h:192
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
SUMOReal getBeginLanePosition() const
Returns the begin position of this bus stop.
Definition: MSBusStop.cpp:65
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:59
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 unsigned int getMaxRouteDistSize()
Definition: MSRoute.h:200
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 SUMOReal DEFAULT_PERSON_SPEED
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:73
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:524
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:63
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:63
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:248
void closeVehicleTypeDistribution()
bool triggered
whether an arriving person lets the vehicle continue
unsigned int getNoFollowing() const
Returns the number of edges that may be reached from this edge.
Definition: MSEdge.h:247
const int STOP_INDEX_END
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:192
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:684
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
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:201
virtual void myEndElement(int element)
Called when a closing tag occurs.
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static void parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs)
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:602
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:279
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)
SUMOReal getDefaultProbability() const
Get the default probability of this vehicle type.
int index
at which position in the stops list
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
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:703
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:255
const int VEHPARS_TAZ_SET
bool isInQuota(SUMOReal frac=-1) const
Returns the information whether the currently vehicle number shall be emitted considering that only f...
const RGBColor * myActiveRouteColor
The currently parsed route&#39;s color.
#define SUMOReal
Definition: config.h:221
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
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
void add(SUMOReal prob, T val, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
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:73
std::vector< MSPersonStage * > MSPersonPlan
the structure holding the plan of a person
Definition: MSPerson.h:475
A color information.
void closeRoute(const bool mayBeDisconnected=false)
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