SUMO - Simulation of Urban MObility
MSRouteHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
18 // Parser and container for routes during their loading
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <string>
28 #include <map>
29 #include <vector>
30 #include <microsim/MSRoute.h>
31 #include <microsim/MSEdge.h>
32 #include <microsim/MSJunction.h>
33 #include <microsim/MSVehicleType.h>
34 #include <microsim/MSVehicle.h>
37 #include <microsim/MSLane.h>
38 #include "MSRouteHandler.h"
39 #include "MSTransportableControl.h"
49 #include "MSNet.h"
50 
51 #include "MSParkingArea.h"
52 #include "MSStoppingPlace.h"
53 #include <microsim/MSGlobals.h>
56 
57 
58 // ===========================================================================
59 // static members
60 // ===========================================================================
61 std::mt19937 MSRouteHandler::myParsingRNG;
62 
63 
64 // ===========================================================================
65 // method definitions
66 // ===========================================================================
67 MSRouteHandler::MSRouteHandler(const std::string& file,
68  bool addVehiclesDirectly) :
69  SUMORouteHandler(file, addVehiclesDirectly ? "" : "routes"),
70  myActivePlan(nullptr),
71  myActiveContainerPlan(nullptr),
72  myAddVehiclesDirectly(addVehiclesDirectly),
73  myCurrentVTypeDistribution(nullptr),
74  myCurrentRouteDistribution(nullptr),
75  myAmLoadingState(false) {
76  myActiveRoute.reserve(100);
77 }
78 
79 
81 }
82 
83 void
85  MSTransportable::MSTransportablePlan::iterator i;
86  if (myActivePlan != nullptr) {
87  for (i = myActivePlan->begin(); i != myActivePlan->end(); i++) {
88  delete *i;
89  }
90  delete myActivePlan;
91  myActivePlan = nullptr;
92  }
93  if (myActiveContainerPlan != nullptr) {
94  for (i = myActiveContainerPlan->begin(); i != myActiveContainerPlan->end(); i++) {
95  delete *i;
96  }
97  delete myActiveContainerPlan;
98  myActivePlan = nullptr;
99  }
100 }
101 
102 
103 void
104 MSRouteHandler::parseFromViaTo(std::string element,
105  const SUMOSAXAttributes& attrs) {
106  myActiveRoute.clear();
107  bool useTaz = OptionsCont::getOptions().getBool("with-taz");
109  WRITE_WARNING("Taz usage was requested but no taz present in " + element + " '" + myVehicleParameter->id + "'!");
110  useTaz = false;
111  }
112  bool ok = true;
114  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
115  if (fromTaz == nullptr) {
116  throw ProcessError("Source taz '" + myVehicleParameter->fromTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
117  } else if (fromTaz->getNumSuccessors() == 0) {
118  throw ProcessError("Source taz '" + myVehicleParameter->fromTaz + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
119  } else {
120  myActiveRoute.push_back(fromTaz);
121  }
122  } else {
123  MSEdge::parseEdgesList(attrs.getOpt<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok, "", true),
124  myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
125  }
126  if (!attrs.hasAttribute(SUMO_ATTR_VIA) && !attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
127  myInsertStopEdgesAt = (int)myActiveRoute.size();
128  }
129  MSEdge::parseEdgesList(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true),
130  myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
131  myVehicleParameter->via = StringTokenizer(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true)).getVector();
133  const MSEdge* toTaz = MSEdge::dictionary(myVehicleParameter->toTaz + "-sink");
134  if (toTaz == nullptr) {
135  throw ProcessError("Sink taz '" + myVehicleParameter->toTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
136  } else if (toTaz->getNumPredecessors() == 0) {
137  throw ProcessError("Sink taz '" + myVehicleParameter->toTaz + "' has no incoming edges for " + element + " '" + myVehicleParameter->id + "'!");
138  } else {
139  myActiveRoute.push_back(toTaz);
140  }
141  } else {
142  MSEdge::parseEdgesList(attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "", true),
143  myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
144  }
146  if (myVehicleParameter->routeid == "") {
148  }
149 }
150 
151 
152 void
154  const SUMOSAXAttributes& attrs) {
155  SUMORouteHandler::myStartElement(element, attrs);
156  try {
157  switch (element) {
158  case SUMO_TAG_PERSON:
159  if (!MSNet::getInstance()->getVehicleControl().hasVType(myVehicleParameter->vtypeid)) {
160  const std::string error = "The type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.";
161  delete myVehicleParameter;
162  myVehicleParameter = nullptr;
163  throw ProcessError(error);
164  }
166  break;
167  case SUMO_TAG_CONTAINER:
169  break;
170  case SUMO_TAG_RIDE: {
171  const std::string pid = myVehicleParameter->id;
172  bool ok = true;
173  MSEdge* from = nullptr;
174  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
175  StringTokenizer st(desc);
176  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
177  MSStoppingPlace* bs = nullptr;
178  MSEdge* to = nullptr;
179  if (bsID != "") {
181  if (bs == nullptr) {
182  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
183  }
184  to = &bs->getLane().getEdge();
185  }
186  double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok,
187  bs == nullptr ? -NUMERICAL_EPS : bs->getEndLanePosition());
188  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
189  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
190  from = MSEdge::dictionary(fromID);
191  if (from == nullptr) {
192  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
193  }
194  if (!myActivePlan->empty() && myActivePlan->back()->getDestination() != from) {
195  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination()->getID() + ").");
196  }
197  if (myActivePlan->empty()) {
199  from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start", true));
200  }
201  } else if (myActivePlan->empty()) {
202  throw ProcessError("The start edge for person '" + pid + "' is not known.");
203  }
204  if (to == nullptr) {
205  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
206  to = MSEdge::dictionary(toID);
207  if (to == nullptr) {
208  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
209  }
210  }
211  const std::string intendedVeh = attrs.getOpt<std::string>(SUMO_ATTR_INTENDED, nullptr, ok, "");
212  const SUMOTime intendedDepart = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DEPART, nullptr, ok, -1);
213  myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(to, bs, arrivalPos, st.getVector(), intendedVeh, intendedDepart));
214  break;
215  }
216  case SUMO_TAG_TRANSPORT:
217  try {
218  const std::string containerId = myVehicleParameter->id;
219  bool ok = true;
220  MSEdge* from = nullptr;
221  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, containerId.c_str(), ok);
222  StringTokenizer st(desc);
223  std::string csID = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
224  MSStoppingPlace* cs = nullptr;
225  if (csID != "") {
227  if (cs == nullptr) {
228  throw ProcessError("Unknown container stop '" + csID + "' for container '" + myVehicleParameter->id + "'.");
229  }
230  }
231  double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok,
232  cs == nullptr ? -NUMERICAL_EPS : cs->getEndLanePosition());
233  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
234  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, containerId.c_str(), ok);
235  from = MSEdge::dictionary(fromID);
236  if (from == nullptr) {
237  throw ProcessError("The from edge '" + fromID + "' within a transport of container '" + containerId + "' is not known.");
238  }
239  if (!myActiveContainerPlan->empty() && myActiveContainerPlan->back()->getDestination() != from) {
240  throw ProcessError("Disconnected plan for container '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActiveContainerPlan->back()->getDestination()->getID() + ").");
241  }
242  if (myActiveContainerPlan->empty()) {
244  from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start", true));
245  }
246  } else if (myActiveContainerPlan->empty()) {
247  throw ProcessError("The start edge within a transport of container '" + containerId + "' is not known.");
248  }
249  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, containerId.c_str(), ok);
250  MSEdge* to = MSEdge::dictionary(toID);
251  if (to == nullptr) {
252  throw ProcessError("The to edge '" + toID + "' within a transport of container '" + containerId + "' is not known.");
253  }
254  myActiveContainerPlan->push_back(new MSContainer::MSContainerStage_Driving(to, cs, arrivalPos, st.getVector()));
255 
256  } catch (ProcessError&) {
258  throw;
259  }
260  break;
261  case SUMO_TAG_TRANSHIP: {
262  myActiveRoute.clear();
263  bool ok = true;
264  double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
265  double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -NUMERICAL_EPS);
266  double speed = DEFAULT_CONTAINER_TRANSHIP_SPEED;
268  // need to check for explicitly set speed since we might have // DEFAULT_VEHTYPE
269  if (vtype != nullptr && vtype->wasSet(VTYPEPARS_MAXSPEED_SET)) {
270  speed = vtype->getMaxSpeed();
271  }
272  speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, speed);
273  if (speed <= 0) {
274  throw ProcessError("Non-positive tranship speed for container '" + myVehicleParameter->id + "'.");
275  }
276  std::string csID = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
277  MSStoppingPlace* cs = nullptr;
278  if (csID != "") {
280  if (cs == nullptr) {
281  throw ProcessError("Unknown container stop '" + csID + "' for container '" + myVehicleParameter->id + "'.");
282  }
283  arrivalPos = cs->getEndLanePosition();
284  }
285  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
287  } else {
288  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
289  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
290  MSEdge* from = MSEdge::dictionary(fromID);
291  if (from == nullptr) {
292  throw ProcessError("The from edge '" + fromID + "' within a tranship of container '" + myVehicleParameter->id + "' is not known.");
293  }
294  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
295  MSEdge* to = MSEdge::dictionary(toID);
296  if (to == nullptr) {
297  throw ProcessError("The to edge '" + toID + "' within a tranship of container '" + myVehicleParameter->id + "' is not known.");
298  }
299  //the route of the container's tranship stage consists only of the 'from' and the 'to' edge
300  myActiveRoute.push_back(from);
301  myActiveRoute.push_back(to);
302  if (myActiveRoute.empty()) {
303  const std::string error = "No connection found between '" + from->getID() + "' and '" + to->getID() + "' for container '" + myVehicleParameter->id + "'.";
305  myActiveRoute.push_back(from);
306  } else {
307  WRITE_ERROR(error);
308  }
309  }
310  }
311  }
312  if (myActiveRoute.empty()) {
313  throw ProcessError("No edges to tranship container '" + myVehicleParameter->id + "'.");
314  }
315  if (!myActiveContainerPlan->empty() && myActiveContainerPlan->back()->getDestination() != myActiveRoute.front()) {
316  throw ProcessError("Disconnected plan for container '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActiveContainerPlan->back()->getDestination()->getID() + ").");
317  }
318  if (myActiveContainerPlan->empty()) {
320  myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start", true));
321  }
322  myActiveContainerPlan->push_back(new MSContainer::MSContainerStage_Tranship(myActiveRoute, cs, speed, departPos, arrivalPos));
323  myActiveRoute.clear();
324  break;
325  }
326  case SUMO_TAG_FLOW:
327  parseFromViaTo("flow", attrs);
328  break;
329  case SUMO_TAG_TRIP:
330  parseFromViaTo("trip", attrs);
331  break;
332  default:
333  break;
334  }
335  } catch (ProcessError&) {
336  delete myVehicleParameter;
337  myVehicleParameter = nullptr;
338  throw;
339  }
340 }
341 
342 
343 void
345  bool ok = true;
346  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
347  if (ok) {
349  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
350  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
351  StringTokenizer st(vTypes);
352  while (st.hasNext()) {
353  std::string vtypeID = st.next();
355  if (type == nullptr) {
356  throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
357  }
359  }
360  }
361  }
362 }
363 
364 
365 void
367  if (myCurrentVTypeDistribution != nullptr) {
368  if (MSGlobals::gStateLoaded && MSNet::getInstance()->getVehicleControl().hasVTypeDistribution(myCurrentVTypeDistributionID)) {
370  return;
371  }
374  throw ProcessError("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
375  }
376  if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
378  throw ProcessError("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
379  }
380  myCurrentVTypeDistribution = nullptr;
381  }
382 }
383 
384 
385 void
387  myActiveRoute.clear();
388  myInsertStopEdgesAt = -1;
389  // check whether the id is really necessary
390  std::string rid;
391  if (myCurrentRouteDistribution != nullptr) {
393  rid = "distribution '" + myCurrentRouteDistributionID + "'";
394  } else if (myVehicleParameter != nullptr) {
395  // ok, a vehicle is wrapping the route,
396  // we may use this vehicle's id as default
397  myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
398  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
399  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
400  }
401  } else {
402  bool ok = true;
403  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok, false);
404  if (!ok) {
405  return;
406  }
407  rid = "'" + myActiveRouteID + "'";
408  }
409  if (myVehicleParameter != nullptr) { // have to do this here for nested route distributions
410  rid = "for vehicle '" + myVehicleParameter->id + "'";
411  }
412  bool ok = true;
413  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
414  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
415  }
416  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
418  WRITE_ERROR("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
419  }
422  myCurrentCosts = attrs.getOpt<double>(SUMO_ATTR_COST, myActiveRouteID.c_str(), ok, -1);
423  if (ok && myCurrentCosts != -1 && myCurrentCosts < 0) {
424  WRITE_ERROR("Invalid cost for route '" + myActiveRouteID + "'.");
425  }
426 }
427 
428 
429 void
432  switch (element) {
433  case SUMO_TAG_VTYPE: {
435  delete myCurrentVType;
436  myCurrentVType = nullptr;
437  if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
438  const std::string id = vehType->getID();
439  delete vehType;
441  throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
442  }
443  } else {
444  if (myCurrentVTypeDistribution != nullptr) {
446  }
447  }
448  }
449  break;
450  case SUMO_TAG_TRIP:
452  closeRoute(true);
453  closeVehicle();
454  delete myVehicleParameter;
455  myVehicleParameter = nullptr;
456  myInsertStopEdgesAt = -1;
457  break;
458  default:
459  break;
460  }
461 }
462 
463 
464 void
465 MSRouteHandler::closeRoute(const bool mayBeDisconnected) {
466  std::string type = "vehicle";
467  if (mayBeDisconnected) {
469  type = "flow";
470  } else {
471  type = "trip";
472  }
473  }
474 
475  try {
476  if (myActiveRoute.size() == 0) {
477  delete myActiveRouteColor;
478  myActiveRouteColor = nullptr;
479  if (myActiveRouteRefID != "" && myCurrentRouteDistribution != nullptr) {
481  if (route != nullptr) {
483  route->addReference();
484  }
485  }
486  myActiveRouteID = "";
487  myActiveRouteRefID = "";
488  return;
489  }
490  if (myVehicleParameter != nullptr) {
491  throw ProcessError("The route for " + type + " '" + myVehicleParameter->id + "' has no edges.");
492  } else {
493  throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
494  }
495  }
496  if (myActiveRoute.size() == 1 && myActiveRoute.front()->isTazConnector()) {
497  throw ProcessError("The routing information for " + type + " '" + myVehicleParameter->id + "' is insufficient.");
498  }
502  route->setCosts(myCurrentCosts);
503  myActiveRoute.clear();
504  if (!MSRoute::dictionary(myActiveRouteID, route)) {
505  delete route;
507  if (myVehicleParameter != nullptr) {
508  if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id) == nullptr) {
509  throw ProcessError("Another route for " + type + " '" + myVehicleParameter->id + "' exists.");
510  } else {
511  throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
512  }
513  } else {
514  throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
515  }
516  }
517  } else {
518  if (myCurrentRouteDistribution != nullptr) {
520  route->addReference();
521  }
522  }
523  }
524  myActiveRouteID = "";
525  myActiveRouteColor = nullptr;
526  myActiveRouteStops.clear();
527  } catch (ProcessError&) {
528  delete myVehicleParameter;
529  throw;
530  }
531 }
532 
533 
534 void
536  // check whether the id is really necessary
537  bool ok = true;
538  if (myVehicleParameter != nullptr) {
539  // ok, a vehicle is wrapping the route,
540  // we may use this vehicle's id as default
541  myCurrentRouteDistributionID = "!" + myVehicleParameter->id; // !!! document this
542  } else {
543  myCurrentRouteDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
544  if (!ok) {
545  return;
546  }
547  }
549  std::vector<double> probs;
550  if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
551  bool ok = true;
552  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentRouteDistributionID.c_str(), ok));
553  while (st.hasNext()) {
554  probs.push_back(StringUtils::toDoubleSecure(st.next(), 1.0));
555  }
556  }
557  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
558  bool ok = true;
559  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, myCurrentRouteDistributionID.c_str(), ok));
560  int probIndex = 0;
561  while (st.hasNext()) {
562  std::string routeID = st.next();
563  const MSRoute* route = MSRoute::dictionary(routeID, &myParsingRNG);
564  if (route == nullptr) {
565  throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
566  }
567  const double prob = ((int)probs.size() > probIndex ? probs[probIndex] : 1.0);
568  if (myCurrentRouteDistribution->add(route, prob, false)) {
569  route->addReference();
570  }
571  probIndex++;
572  }
573  if (probs.size() > 0 && probIndex != (int)probs.size()) {
574  WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
575  " routes in routeDistribution '" + myCurrentRouteDistributionID + "'");
576  }
577  }
578 }
579 
580 
581 void
583  if (myCurrentRouteDistribution != nullptr) {
584  const bool haveSameID = MSRoute::dictionary(myCurrentRouteDistributionID, &myParsingRNG) != nullptr;
585  if (MSGlobals::gStateLoaded && haveSameID) {
587  return;
588  }
589  if (haveSameID) {
591  throw ProcessError("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
592  }
595  throw ProcessError("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
596  }
598  myCurrentRouteDistribution = nullptr;
599  }
600 }
601 
602 
603 void
605  // get nested route
609  // let's check whether this vehicle had to depart before the simulation starts
611  if (route != nullptr) {
612  route->addReference();
613  route->release();
614  }
615  return;
616  }
617  }
618 
619  // get the vehicle's type
620  MSVehicleType* vtype = nullptr;
621 
622  try {
623  if (myVehicleParameter->vtypeid != "") {
624  vtype = vehControl.getVType(myVehicleParameter->vtypeid, &myParsingRNG);
625  if (vtype == nullptr) {
626  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
627  }
628  if (vtype->getVehicleClass() == SVC_PEDESTRIAN) {
629  WRITE_WARNING("Vehicle type '" + vtype->getID() + "' with vClass=pedestrian should only be used for persons and not for vehicle '" + myVehicleParameter->id + "'.");
630  }
631  } else {
632  // there should be one (at least the default one)
633  vtype = vehControl.getVType(DEFAULT_VTYPE_ID, &myParsingRNG);
634  }
636  // if the route id was given, prefer that one
637  if (route != nullptr && !myAmLoadingState) {
638  WRITE_WARNING("Ignoring child element 'route' for vehicle '" + myVehicleParameter->id + "' because attribute 'route' is set.");
639  }
641  }
642  if (route == nullptr) {
643  // nothing found? -> error
644  if (myVehicleParameter->routeid != "") {
645  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
646  } else {
647  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
648  }
649  }
650  myActiveRouteID = "";
651 
652  } catch (ProcessError&) {
653  delete myVehicleParameter;
654  throw;
655  }
656 
657  // try to build the vehicle
658  SUMOVehicle* vehicle = nullptr;
659  if (vehControl.getVehicle(myVehicleParameter->id) == nullptr) {
660  try {
661  vehicle = vehControl.buildVehicle(myVehicleParameter, route, vtype, !MSGlobals::gCheckRoutes);
662  } catch (const ProcessError& e) {
664  WRITE_WARNING(e.what());
665  vehControl.deleteVehicle(nullptr, true);
666  myVehicleParameter = nullptr;
667  vehicle = nullptr;
668  return;
669  } else {
670  throw e;
671  }
672  }
673  const SUMOTime origDepart = myVehicleParameter->depart;
674  // maybe we do not want this vehicle to be inserted due to scaling
675  int quota = myAmLoadingState ? 1 : vehControl.getQuota();
676  if (quota > 0) {
679  vehControl.addVehicle(myVehicleParameter->id, vehicle);
680  for (int i = 1; i < quota; i++) {
683  newPars->id = myVehicleParameter->id + "." + toString(i);
685  vehicle = vehControl.buildVehicle(newPars, route, vtype, !MSGlobals::gCheckRoutes);
686  vehControl.addVehicle(newPars->id, vehicle);
687  }
688  myVehicleParameter = nullptr;
689  } else {
690  vehControl.deleteVehicle(vehicle, true);
691  myVehicleParameter = nullptr;
692  vehicle = nullptr;
693  }
694  } else {
695  // strange: another vehicle with the same id already exists
697  // and was not loaded while loading a simulation state
698  // -> error
699  std::string veh_id = myVehicleParameter->id;
700  delete myVehicleParameter;
701  myVehicleParameter = nullptr;
702  throw ProcessError("Another vehicle with the id '" + veh_id + "' exists.");
703  } else {
704  // ok, it seems to be loaded previously while loading a simulation state
705  vehicle = nullptr;
706  }
707  }
708  // check whether the vehicle shall be added directly to the network or
709  // shall stay in the internal buffer
710  if (vehicle != nullptr) {
711  if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
713  }
714  }
715 }
716 
717 
718 void
720  if (myActivePlan->size() == 0) {
721  const std::string error = "Person '" + myVehicleParameter->id + "' has no plan.";
722  delete myVehicleParameter;
723  myVehicleParameter = nullptr;
725  throw ProcessError(error);
726  }
727  // let's check whether this person had to depart before the simulation starts
730  delete myVehicleParameter;
731  myVehicleParameter = nullptr;
733  return;
734  }
735  // type existence has been checked on opening
738  // @todo: consider myScale?
739  if (MSNet::getInstance()->getPersonControl().add(person)) {
741  } else {
742  ProcessError error("Another person with the id '" + myVehicleParameter->id + "' exists.");
743  delete person;
744  throw error;
745  }
746  myVehicleParameter = nullptr;
747  myActivePlan = nullptr;
748 }
749 
750 void
752  if (myActiveContainerPlan->size() == 0) {
753  throw ProcessError("Container '" + myVehicleParameter->id + "' has no plan.");
754  }
756  if (type == nullptr) {
757  throw ProcessError("The type '" + myVehicleParameter->vtypeid + "' for container '" + myVehicleParameter->id + "' is not known.");
758  }
760  // @todo: consider myScale?
762  if (MSNet::getInstance()->getContainerControl().add(container)) {
764  } else {
765  ProcessError error("Another container with the id '" + myVehicleParameter->id + "' exists.");
766  delete container;
767  throw error;
768  }
769  } else {
770  // warning already given
771  delete container;
772  }
773  myVehicleParameter = nullptr;
774  myActiveContainerPlan = nullptr;
775 }
776 
777 
778 void
780  myInsertStopEdgesAt = -1;
782  delete myVehicleParameter;
783  myVehicleParameter = nullptr;
784  return;
785  }
786  // let's check whether vehicles had to depart before the simulation starts
789  const SUMOTime offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
793  delete myVehicleParameter;
794  myVehicleParameter = nullptr;
795  return;
796  }
797  }
798  }
799  if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid, &myParsingRNG) == nullptr) {
800  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
801  }
804  closeRoute(true);
805  }
807  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
808  }
809  myActiveRouteID = "";
810 
811  // check whether the vehicle shall be added directly to the network or
812  // shall stay in the internal buffer
814  if (MSNet::getInstance()->getInsertionControl().addFlow(myVehicleParameter)) {
816  } else {
817  throw ProcessError("Another flow with the id '" + myVehicleParameter->id + "' exists.");
818  }
819  }
820  myVehicleParameter = nullptr;
821 }
822 
823 
824 void
826  std::string errorSuffix;
827  if (myActivePlan != nullptr) {
828  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
829  } else if (myVehicleParameter != nullptr) {
830  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
831  } else if (myActiveContainerPlan != nullptr) {
832  errorSuffix = " in container '" + myVehicleParameter->id + "'.";
833  } else {
834  errorSuffix = " in route '" + myActiveRouteID + "'.";
835  }
837  bool ok = parseStop(stop, attrs, errorSuffix, MsgHandler::getErrorInstance());
838  if (!ok) {
839  return;
840  }
841  const MSEdge* edge = nullptr;
842  // try to parse the assigned bus stop
843  if (stop.busstop != "") {
844  // ok, we have a bus stop
846  if (bs == nullptr) {
847  WRITE_ERROR("The busStop '" + stop.busstop + "' is not known" + errorSuffix);
848  return;
849  }
850  const MSLane& l = bs->getLane();
851  stop.lane = l.getID();
852  stop.endPos = bs->getEndLanePosition();
853  stop.startPos = bs->getBeginLanePosition();
854  edge = &l.getEdge();
855  } //try to parse the assigned container stop
856  else if (stop.containerstop != "") {
857  // ok, we have obviously a container stop
859  if (cs == nullptr) {
860  WRITE_ERROR("The containerStop '" + stop.containerstop + "' is not known" + errorSuffix);
861  return;
862  }
863  const MSLane& l = cs->getLane();
864  stop.lane = l.getID();
865  stop.endPos = cs->getEndLanePosition();
866  stop.startPos = cs->getBeginLanePosition();
867  edge = &l.getEdge();
868  } //try to parse the assigned parking area
869  else if (stop.parkingarea != "") {
870  // ok, we have obviously a parking area
872  if (pa == nullptr) {
873  WRITE_ERROR("The parkingArea '" + stop.parkingarea + "' is not known" + errorSuffix);
874  return;
875  }
876  const MSLane& l = pa->getLane();
877  stop.lane = l.getID();
878  stop.endPos = pa->getEndLanePosition();
879  stop.startPos = pa->getBeginLanePosition();
880  edge = &l.getEdge();
881  } else if (stop.chargingStation != "") {
882  // ok, we have a charging station
884  if (cs != nullptr) {
885  const MSLane& l = cs->getLane();
886  stop.lane = l.getID();
887  stop.endPos = cs->getEndLanePosition();
888  stop.startPos = cs->getBeginLanePosition();
889  } else {
890  WRITE_ERROR("The chargingStation '" + stop.chargingStation + "' is not known" + errorSuffix);
891  return;
892  }
893  } else {
894  // no, the lane and the position should be given
895  // get the lane
896  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, ok, "");
897  if (ok && stop.lane != "") {
898  if (MSLane::dictionary(stop.lane) == nullptr) {
899  WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
900  return;
901  }
902  } else {
903  if (myActivePlan && !myActivePlan->empty()) {
904  const MSStoppingPlace* bs = myActivePlan->back()->getDestinationStop();
905  if (bs != nullptr) {
906  edge = &bs->getLane().getEdge();
907  stop.lane = bs->getLane().getID();
908  stop.endPos = bs->getEndLanePosition();
909  stop.startPos = bs->getBeginLanePosition();
910  } else {
911  edge = myActivePlan->back()->getDestination();
912  stop.lane = edge->getLanes()[0]->getID();
913  stop.endPos = myActivePlan->back()->getArrivalPos();
914  stop.startPos = stop.endPos - POSITION_EPS;
915  }
916  } else {
917  WRITE_ERROR("A stop must be placed on a busStop, a chargingStation, a containerStop a parkingArea or a lane" + errorSuffix);
918  return;
919  }
920  }
921  edge = &MSLane::dictionary(stop.lane)->getEdge();
922  if (myActivePlan &&
923  !myActivePlan->empty() &&
924  myActivePlan->back()->getDestination() != edge) {
925  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + edge->getID() + "!=" + myActivePlan->back()->getDestination()->getID() + ").");
926  }
927  if (myActivePlan && myActivePlan->empty()) {
929  edge, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start", true));
930  }
931  if (myActiveContainerPlan &&
932  !myActiveContainerPlan->empty() &&
933  myActiveContainerPlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) {
934  throw ProcessError("Disconnected plan for container '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActiveContainerPlan->back()->getDestination()->getID() + ").");
935  }
938  &MSLane::dictionary(stop.lane)->getEdge(), -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start", true));
939  }
940  stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, ok, MSLane::dictionary(stop.lane)->getLength());
941  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
942  WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix);
943  stop.endPos = attrs.getOpt<double>(SUMO_ATTR_POSITION, nullptr, ok, stop.endPos);
944  }
945  stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, ok, MAX2(0., stop.endPos - 2 * POSITION_EPS));
946  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
947  if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) {
948  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.lane + "'" + errorSuffix);
949  return;
950  }
951  }
952  if (myActivePlan != nullptr) {
953  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, nullptr, ok, "waiting");
954  double pos = (stop.startPos + stop.endPos) / 2.;
955  if (!myActivePlan->empty()) {
956  pos = myActivePlan->back()->getArrivalPos();
957  }
959  &MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, pos, actType, false));
960  } else if (myActiveContainerPlan != nullptr) {
961  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, nullptr, ok, "waiting");
963  &MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, stop.startPos, actType, false));
964  } else if (myVehicleParameter != nullptr) {
965  myVehicleParameter->stops.push_back(stop);
966  } else {
967  myActiveRouteStops.push_back(stop);
968  }
969  if (myInsertStopEdgesAt >= 0) {
970  myActiveRoute.insert(myActiveRoute.begin() + myInsertStopEdgesAt, edge);
972  }
973 }
974 
975 
976 void
977 MSRouteHandler::parseWalkPositions(const SUMOSAXAttributes& attrs, const std::string& personID,
978  const MSEdge* fromEdge, const MSEdge*& toEdge,
979  double& departPos, double& arrivalPos, MSStoppingPlace*& bs,
980  const MSTransportable::Stage* const lastStage, bool& ok) {
981  const std::string description = "person '" + personID + "' walking from " + fromEdge->getID();
982 
983  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
984  WRITE_WARNING("The attribute departPos is no longer supported for walks, please use the person attribute, the arrivalPos of the previous step or explicit stops.");
985  }
986  departPos = 0.;
987  if (lastStage != nullptr) {
988  if (lastStage->getDestinationStop() != nullptr) {
989  departPos = lastStage->getDestinationStop()->getAccessPos(fromEdge);
990  } else if (lastStage->getDestination() == fromEdge) {
991  departPos = lastStage->getArrivalPos();
992  } else if (lastStage->getDestination()->getToJunction() == fromEdge->getToJunction()) {
993  departPos = fromEdge->getLength();
994  }
995  }
996 
997  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
998  if (bsID != "") {
1000  if (bs == nullptr) {
1001  throw ProcessError("Unknown bus stop '" + bsID + "' for " + description + ".");
1002  }
1003  arrivalPos = bs->getAccessPos(toEdge != nullptr ? toEdge : &bs->getLane().getEdge());
1004  if (arrivalPos < 0) {
1005  throw ProcessError("Bus stop '" + bsID + "' is not connected to arrival edge '" + toEdge->getID() + "' for " + description + ".");
1006  }
1007  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1008  const double length = toEdge != nullptr ? toEdge->getLength() : bs->getLane().getLength();
1009  const double arrPos = SUMOVehicleParserHelper::parseWalkPos(SUMO_ATTR_ARRIVALPOS, description, length,
1010  attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, description.c_str(), ok), &myParsingRNG);
1011  if (arrPos >= bs->getBeginLanePosition() && arrPos < bs->getEndLanePosition()) {
1012  arrivalPos = arrPos;
1013  } else {
1014  WRITE_WARNING("Ignoring arrivalPos for " + description + " because it is outside the given stop '" + toString(SUMO_ATTR_BUS_STOP) + "'.");
1015  arrivalPos = bs->getAccessPos(&bs->getLane().getEdge());
1016  }
1017  }
1018  } else {
1019  if (toEdge == nullptr) {
1020  throw ProcessError("No destination edge for " + description + ".");
1021  }
1022  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1023  arrivalPos = SUMOVehicleParserHelper::parseWalkPos(SUMO_ATTR_ARRIVALPOS, description, toEdge->getLength(),
1024  attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, description.c_str(), ok), &myParsingRNG);
1025  } else {
1026  arrivalPos = toEdge->getLength() / 2.;
1027  }
1028  }
1029 }
1030 
1031 
1032 void
1034  myActiveRoute.clear();
1035  bool ok = true;
1037  const char* const id = myVehicleParameter->id.c_str();
1038  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, id, ok, -1);
1039  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1040  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
1041  }
1042  const std::string fromID = attrs.getOpt<std::string>(SUMO_ATTR_FROM, id, ok, "");
1043  const MSEdge* from = fromID != "" || myActivePlan->empty() ? MSEdge::dictionary(fromID) : myActivePlan->back()->getDestination();
1044  if (from == nullptr) {
1045  throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
1046  }
1047  const std::string toID = attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "");
1048  const MSEdge* to = MSEdge::dictionary(toID);
1049  if (toID != "" && to == nullptr) {
1050  throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
1051  }
1052  double departPos = 0;
1053  double arrivalPos = 0;
1054  MSStoppingPlace* stoppingPlace = nullptr;
1055  parseWalkPositions(attrs, myVehicleParameter->id, from, to, departPos, arrivalPos, stoppingPlace, nullptr, ok);
1056 
1057  const std::string modes = attrs.getOpt<std::string>(SUMO_ATTR_MODES, id, ok, "");
1058  SVCPermissions modeSet = 0;
1059  for (StringTokenizer st(modes); st.hasNext();) {
1060  const std::string mode = st.next();
1061  if (mode == "car") {
1062  modeSet |= SVC_PASSENGER;
1063  } else if (mode == "bicycle") {
1064  modeSet |= SVC_BICYCLE;
1065  } else if (mode == "public") {
1066  modeSet |= SVC_BUS;
1067  } else {
1068  throw InvalidArgument("Unknown person mode '" + mode + "'.");
1069  }
1070  }
1071  const std::string types = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id, ok, "");
1072  for (StringTokenizer st(types); st.hasNext();) {
1073  const std::string vtypeid = st.next();
1074  if (vehControl.getVType(vtypeid) == nullptr) {
1075  throw InvalidArgument("The vehicle type '" + vtypeid + "' in a trip for person '" + myVehicleParameter->id + "' is not known.");
1076  }
1077  modeSet |= SVC_PASSENGER;
1078  }
1079  const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, id, ok, -1.);
1080  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && speed <= 0) {
1081  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
1082  }
1083  const double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, id, ok, OptionsCont::getOptions().getFloat("persontrip.walkfactor"));
1084  const double departPosLat = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS_LAT, nullptr, ok, 0);
1085  if (ok) {
1087  myActivePlan->push_back(new MSTransportable::Stage_Trip(from, to == nullptr ? &stoppingPlace->getLane().getEdge() : to, stoppingPlace, duration, modeSet, types, speed, walkFactor, departPosLat, attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS), arrivalPos));
1088  }
1089  myActiveRoute.clear();
1090 }
1091 
1092 
1093 void
1095  try {
1096  myActiveRoute.clear();
1097  bool ok = true;
1098  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, nullptr, ok, -1);
1099  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1100  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
1101  }
1102  double speed = -1; // default to vType speed
1103  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
1104  speed = attrs.get<double>(SUMO_ATTR_SPEED, nullptr, ok);
1105  if (speed <= 0) {
1106  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
1107  }
1108  }
1109  double departPos = 0;
1110  double arrivalPos = 0;
1111  MSStoppingPlace* bs = nullptr;
1112  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
1113  const std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, myVehicleParameter->id.c_str(), ok);
1114  const MSRoute* route = MSRoute::dictionary(routeID, &myParsingRNG);
1115  if (route == nullptr) {
1116  throw ProcessError("The route '" + routeID + "' for walk of person '" + myVehicleParameter->id + "' is not known.");
1117  }
1118  myActiveRoute = route->getEdges();
1119  } else {
1121  }
1122  if (myActivePlan->empty()) {
1123  double initialDepartPos = myVehicleParameter->departPos;
1125  initialDepartPos = RandHelper::rand(myActiveRoute.front()->getLength(), &myParsingRNG);
1126  }
1127  myActivePlan->push_back(new MSTransportable::Stage_Waiting(myActiveRoute.front(), -1, myVehicleParameter->depart, initialDepartPos, "start", true));
1128  }
1129  parseWalkPositions(attrs, myVehicleParameter->id, myActiveRoute.front(), myActiveRoute.back(), departPos, arrivalPos, bs, myActivePlan->back(), ok);
1130  if (myActiveRoute.empty()) {
1131  throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
1132  }
1133  if (myActivePlan->back()->getDestination() != myActiveRoute.front() &&
1134  myActivePlan->back()->getDestination()->getToJunction() != myActiveRoute.front()->getFromJunction() &&
1135  myActivePlan->back()->getDestination()->getToJunction() != myActiveRoute.front()->getToJunction()) {
1136  if (myActivePlan->back()->getDestinationStop() == nullptr || myActivePlan->back()->getDestinationStop()->getAccessPos(myActiveRoute.front()) < 0.) {
1137  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + " not connected to " + myActivePlan->back()->getDestination()->getID() + ").");
1138  }
1139  }
1140  const double departPosLat = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS_LAT, nullptr, ok, 0);
1141  myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myVehicleParameter->id, myActiveRoute, bs, duration, speed, departPos, arrivalPos, departPosLat));
1142  myActiveRoute.clear();
1143  } catch (ProcessError&) {
1145  throw;
1146  }
1147 }
1148 
1149 
1150 /****************************************************************************/
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
const int VTYPEPARS_MAXSPEED_SET
const int VEHPARS_TO_TAZ_SET
MSRouteHandler(const std::string &file, bool addVehiclesDirectly)
standard constructor
double getAccessPos(const MSEdge *edge) const
the position on the given edge which is connected to this stop, -1 on failure
int getNumPredecessors() const
Returns the number of edges this edge is connected to.
Definition: MSEdge.h:330
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:76
virtual void myEndElement(int element)
Called when a closing tag occurs.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:640
ConstMSEdgeVector myActiveRoute
The current route.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
long long int SUMOTime
Definition: SUMOTime.h:36
const int VEHPARS_FORCE_REROUTE
double getBeginLanePosition() const
Returns the begin position of this stop.
void parseFromViaTo(std::string element, const SUMOSAXAttributes &attrs)
Called for parsing from and to and the corresponding taz attributes.
description of a vehicle type
RandomDistributor< const MSRoute * > * myCurrentRouteDistribution
The currently parsed distribution of routes (probability->route)
The time is given.
is a pedestrian
std::string next()
std::string containerstop
(Optional) container stop if one is assigned to the stop
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
std::string vtypeid
The vehicle&#39;s type id.
virtual void closeVehicle()
Ends the processing of a vehicle.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:101
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:869
a flow definition (used by router)
A lane area vehicles can halt at.
Represents a generic random distribution.
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, container or flow.
const MSEdge * getDestination() const
returns the destination edge
vehicle is a bicycle
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
double repetitionProbability
The probability for emitting a vehicle per second.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:61
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
static bool gStateLoaded
Information whether a state has been loaded.
Definition: MSGlobals.h:88
int parametersSet
Information for the router which parameter were set, TraCI may modify this (whe changing color) ...
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.
int getQuota(double frac=-1) const
Returns the number of instances of the current vehicle that shall be emitted considering that "frac" ...
void openRoute(const SUMOSAXAttributes &attrs)
double myActiveRouteProbability
The probability of the current route.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:162
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
T MAX2(T a, T b)
Definition: StdDefs.h:76
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:514
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:788
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)
const double DEFAULT_VEH_PROB
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void addWalk(const SUMOSAXAttributes &attrs)
add a fully specified walk
const std::string & getID() const
Returns the id.
Definition: Named.h:78
std::string myActiveRouteID
The id of the current route.
void setCosts(double costs)
Sets the costs of the route.
Definition: MSRoute.h:176
int myInsertStopEdgesAt
where stop edges can be inserted into the current route (-1 means no insertion)
double getLength() const
return the length of the edge
Definition: MSEdge.h:568
const MSJunction * getToJunction() const
Definition: MSEdge.h:347
const std::string DEFAULT_VTYPE_ID
The position is chosen randomly.
void parseWalkPositions(const SUMOSAXAttributes &attrs, const std::string &personID, const MSEdge *fromEdge, const MSEdge *&toEdge, double &departPos, double &arrivalPos, MSStoppingPlace *&bs, const MSTransportable::Stage *const lastStage, bool &ok)
@ brief parse depart- and arrival positions of a walk
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
virtual MSTransportable * buildContainer(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan) const
Builds a new container.
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
static double parseWalkPos(SumoXMLAttr attr, const std::string &id, double maxPos, const std::string &val, std::mt19937 *rng=0)
parse departPos or arrivalPos for a walk
std::string parkingarea
(Optional) parking area if one is assigned to the stop
void error(const XERCES_CPP_NAMESPACE::SAXParseException &exception)
Handler for XML-errors.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
The car-following model and parameter.
Definition: MSVehicleType.h:66
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
std::string toTaz
The vehicle&#39;s destination zone (district)
bool wasSet(int what) const
Returns whether the given parameter was set.
Definition: MSVehicleType.h:83
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
int getNumSuccessors() const
Returns the number of edges that may be reached from this edge.
Definition: MSEdge.h:308
void addPersonTrip(const SUMOSAXAttributes &attrs)
add a routing request for a walking or intermodal person
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:784
double getDefaultProbability() const
Get the default probability of this vehicle type.
std::string busstop
(Optional) bus stop if one is assigned to the stop
A road/street connecting two junctions.
Definition: MSEdge.h:75
std::vector< MSTransportable::Stage * > MSTransportablePlan
the structure holding the plan of a transportable
double getEndLanePosition() const
Returns the end position of this stop.
RandomDistributor< MSVehicleType * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability->vehicle type)
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
void closeRouteDistribution()
std::string routeid
The vehicle&#39;s route id.
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
static bool gCheckRoutes
Definition: MSGlobals.h:79
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Encapsulated SAX-Attributes.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:776
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
std::string chargingStation
(Optional) charging station if one is assigned to the stop
void deleteActivePlans()
delete already created MSTransportablePlans if error occurs before handing over responsibility to a M...
void closeContainer()
Ends the processing of a container.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:316
void closeVehicleTypeDistribution()
const double DEFAULT_CONTAINER_TRANSHIP_SPEED
SUMOTime depart
The vehicle&#39;s departure time.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
double getArrivalPos() const
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
const int VEHPARS_ROUTE_SET
#define POSITION_EPS
Definition: config.h:172
std::string fromTaz
The vehicle&#39;s origin zone (district)
double endPos
The stopping position end.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
vehicle is a passenger car (a "normal" car)
const int VEHPARS_FROM_TAZ_SET
MSTransportable::MSTransportablePlan * myActivePlan
The plan of the current person.
std::string lane
The lane to stop at.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, std::mt19937 *rng=0)
Returns the named vehicle type or a sample from the named distribution.
Parser for routes during their loading.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
std::string myCurrentRouteDistributionID
The id of the currently parsed route distribution.
std::vector< std::string > getVector()
void openRouteDistribution(const SUMOSAXAttributes &attrs)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
virtual void myEndElement(int element)
Called when a closing tag occurs.
vehicle is a bus
double departPos
(optional) The position the vehicle shall depart from
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1730
static bool checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
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.
Structure representing possible vehicle parameter.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
bool myAmLoadingState
whether a state file is being loaded
static std::mt19937 myParsingRNG
A random number generator used to choose from vtype/route distributions and computing the speed facto...
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:369
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.
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.
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
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:95
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
bool wasSet(int what) const
Returns whether the given parameter was set.
const RGBColor * myActiveRouteColor
The currently parsed route&#39;s color.
double myCurrentCosts
The currently parsed route costs.
virtual MSTransportable * buildPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, std::mt19937 *rng) const
Builds a new person.
#define NUMERICAL_EPS
Definition: config.h:148
virtual ~MSRouteHandler()
standard destructor
a single trip definition (used by router)
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
The class responsible for building and deletion of vehicles.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
const MSLane & getLane() const
Returns the lane this stop is located at.
static double toDoubleSecure(const std::string &sData, const double def)
converts a string into the integer value described by it
SUMOTime computeRandomDepartOffset() const
compute (optional) random offset to the departure time
bool add(T val, double prob, 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:78
A color information.
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:845
void closeRoute(const bool mayBeDisconnected=false)
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
void closeFlow()
Ends the processing of a flow.
MSTransportable::MSTransportablePlan * myActiveContainerPlan
The plan of the current container.
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:114