Eclipse SUMO - Simulation of Urban MObility
RONet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // The router's network representation
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <algorithm>
30 #include <utils/common/ToString.h>
35 #include "ROEdge.h"
36 #include "ROLane.h"
37 #include "RONode.h"
38 #include "ROPerson.h"
39 #include "RORoute.h"
40 #include "RORouteDef.h"
41 #include "ROVehicle.h"
42 #include "ROAbstractEdgeBuilder.h"
43 #include "RONet.h"
44 
45 
46 // ===========================================================================
47 // static member definitions
48 // ===========================================================================
49 RONet* RONet::myInstance = nullptr;
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 RONet*
57  if (myInstance != nullptr) {
58  return myInstance;
59  }
60  throw ProcessError(TL("A network was not yet constructed."));
61 }
62 
63 
65  myVehicleTypes(), myDefaultVTypeMayBeDeleted(true),
66  myDefaultPedTypeMayBeDeleted(true),
67  myDefaultBikeTypeMayBeDeleted(true),
68  myDefaultTaxiTypeMayBeDeleted(true),
69  myDefaultRailTypeMayBeDeleted(true),
70  myHaveActiveFlows(true),
71  myRoutesOutput(nullptr), myRouteAlternativesOutput(nullptr), myTypesOutput(nullptr),
72  myReadRouteNo(0), myDiscardedRouteNo(0), myWrittenRouteNo(0),
73  myHavePermissions(false),
74  myNumInternalEdges(0),
75  myErrorHandler(OptionsCont::getOptions().exists("ignore-errors")
76  && OptionsCont::getOptions().getBool("ignore-errors") ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
77  myKeepVTypeDist(OptionsCont::getOptions().exists("keep-vtype-distributions")
78  && OptionsCont::getOptions().getBool("keep-vtype-distributions")),
79  myDoPTRouting(!OptionsCont::getOptions().exists("ptline-routing")
80  || OptionsCont::getOptions().getBool("ptline-routing")),
81  myHasBidiEdges(false) {
82  if (myInstance != nullptr) {
83  throw ProcessError(TL("A network was already constructed."));
84  }
86  type->onlyReferenced = true;
87  myVehicleTypes.add(type->id, type);
88 
90  defPedType->onlyReferenced = true;
92  myVehicleTypes.add(defPedType->id, defPedType);
93 
95  defBikeType->onlyReferenced = true;
97  myVehicleTypes.add(defBikeType->id, defBikeType);
98 
100  defTaxiType->onlyReferenced = true;
102  myVehicleTypes.add(defTaxiType->id, defTaxiType);
103 
105  defRailType->onlyReferenced = true;
107  myVehicleTypes.add(defRailType->id, defRailType);
108 
109  myInstance = this;
110 }
111 
112 
114  for (const auto& routables : myRoutables) {
115  for (RORoutable* const r : routables.second) {
116  const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
117  // delete routes and the vehicle
118  if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
119  if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
120  delete veh->getRouteDefinition();
121  }
122  }
123  delete r;
124  }
125  }
126  for (const RORoutable* const r : myPTVehicles) {
127  const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
128  // delete routes and the vehicle
129  if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
130  if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
131  delete veh->getRouteDefinition();
132  }
133  }
134  delete r;
135  }
136  myRoutables.clear();
137  for (const auto& vTypeDist : myVTypeDistDict) {
138  delete vTypeDist.second;
139  }
140 }
141 
142 
143 void
144 RONet::addRestriction(const std::string& id, const SUMOVehicleClass svc, const double speed) {
145  myRestrictions[id][svc] = speed;
146 }
147 
148 
149 const std::map<SUMOVehicleClass, double>*
150 RONet::getRestrictions(const std::string& id) const {
151  std::map<std::string, std::map<SUMOVehicleClass, double> >::const_iterator i = myRestrictions.find(id);
152  if (i == myRestrictions.end()) {
153  return nullptr;
154  }
155  return &i->second;
156 }
157 
158 
159 bool
161  if (!myEdges.add(edge->getID(), edge)) {
162  WRITE_ERRORF(TL("The edge '%' occurs at least twice."), edge->getID());
163  delete edge;
164  return false;
165  }
166  if (edge->isInternal()) {
167  myNumInternalEdges += 1;
168  }
169  return true;
170 }
171 
172 
173 bool
174 RONet::addDistrict(const std::string id, ROEdge* source, ROEdge* sink) {
175  if (myDistricts.count(id) > 0) {
176  WRITE_ERRORF(TL("The TAZ '%' occurs at least twice."), id);
177  delete source;
178  delete sink;
179  return false;
180  }
182  if (!addEdge(sink)) {
183  return false;
184  }
186  if (!addEdge(source)) {
187  return false;
188  }
189  sink->setOtherTazConnector(source);
190  source->setOtherTazConnector(sink);
191  myDistricts[id] = std::make_pair(std::vector<std::string>(), std::vector<std::string>());
192  return true;
193 }
194 
195 
196 bool
197 RONet::addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource) {
198  if (myDistricts.count(tazID) == 0) {
199  WRITE_ERRORF(TL("The TAZ '%' is unknown."), tazID);
200  return false;
201  }
202  ROEdge* edge = getEdge(edgeID);
203  if (edge == nullptr) {
204  WRITE_ERRORF(TL("The edge '%' for TAZ '%' is unknown."), edgeID, tazID);
205  return false;
206  }
207  if (isSource) {
208  getEdge(tazID + "-source")->addSuccessor(edge);
209  myDistricts[tazID].first.push_back(edgeID);
210  } else {
211  edge->addSuccessor(getEdge(tazID + "-sink"));
212  myDistricts[tazID].second.push_back(edgeID);
213  }
214  return true;
215 }
216 
217 
218 void
220  for (auto item : myNodes) {
221  const std::string tazID = item.first;
222  if (myDistricts.count(tazID) != 0) {
223  WRITE_WARNINGF(TL("A TAZ with id '%' already exists. Not building junction TAZ."), tazID);
224  continue;
225  }
226  const std::string sourceID = tazID + "-source";
227  const std::string sinkID = tazID + "-sink";
228  // sink must be added before source
229  ROEdge* sink = eb.buildEdge(sinkID, nullptr, nullptr, 0);
230  ROEdge* source = eb.buildEdge(sourceID, nullptr, nullptr, 0);
231  sink->setOtherTazConnector(source);
232  source->setOtherTazConnector(sink);
233  if (!addDistrict(tazID, source, sink)) {
234  continue;
235  }
236  auto& district = myDistricts[tazID];
237  const RONode* junction = item.second;
238  for (const ROEdge* edge : junction->getIncoming()) {
239  if (!edge->isInternal()) {
240  const_cast<ROEdge*>(edge)->addSuccessor(sink);
241  district.second.push_back(edge->getID());
242  }
243  }
244  for (const ROEdge* edge : junction->getOutgoing()) {
245  if (!edge->isInternal()) {
246  source->addSuccessor(const_cast<ROEdge*>(edge));
247  district.first.push_back(edge->getID());
248  }
249  }
250  }
251 }
252 
253 
254 void
255 RONet::setBidiEdges(const std::map<ROEdge*, std::string>& bidiMap) {
256  for (const auto& item : bidiMap) {
257  ROEdge* bidi = myEdges.get(item.second);
258  if (bidi == nullptr) {
259  WRITE_ERRORF(TL("The bidi edge '%' is not known."), item.second);
260  }
261  item.first->setBidiEdge(bidi);
262  myHasBidiEdges = true;
263  }
264 }
265 
266 
267 void
269  if (!myNodes.add(node->getID(), node)) {
270  WRITE_ERRORF(TL("The node '%' occurs at least twice."), node->getID());
271  delete node;
272  }
273 }
274 
275 
276 void
277 RONet::addStoppingPlace(const std::string& id, const SumoXMLTag category, SUMOVehicleParameter::Stop* stop) {
278  if (!myStoppingPlaces[category == SUMO_TAG_TRAIN_STOP ? SUMO_TAG_BUS_STOP : category].add(id, stop)) {
279  WRITE_ERRORF(TL("The % '%' occurs at least twice."), toString(category), id);
280  delete stop;
281  }
282 }
283 
284 
285 bool
287  return myRoutes.add(def->getID(), def);
288 }
289 
290 
291 void
293  if (options.isSet("output-file") && options.getString("output-file") != "") {
294  myRoutesOutput = &OutputDevice::getDevice(options.getString("output-file"));
295  if (myRoutesOutput->isNull()) {
296  myRoutesOutput = nullptr;
297  } else {
299  myRoutesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
300  }
301  }
302  if (options.exists("alternatives-output") && options.isSet("alternatives-output")
303  && !(options.exists("write-trips") && options.getBool("write-trips"))) {
304  myRouteAlternativesOutput = &OutputDevice::getDevice(options.getString("alternatives-output"));
306  myRouteAlternativesOutput = nullptr;
307  } else {
309  myRouteAlternativesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
310  }
311  }
312  if (options.isSet("vtype-output")) {
313  myTypesOutput = &OutputDevice::getDevice(options.getString("vtype-output"));
315  myTypesOutput->writeAttr("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance").writeAttr("xsi:noNamespaceSchemaLocation", "http://sumo.dlr.de/xsd/routes_file.xsd");
316  }
317 }
318 
319 
320 void
321 RONet::writeIntermodal(const OptionsCont& options, ROIntermodalRouter& router) const {
322  if (options.exists("intermodal-network-output") && options.isSet("intermodal-network-output")) {
323  OutputDevice::createDeviceByOption("intermodal-network-output", "intermodal");
324  router.writeNetwork(OutputDevice::getDevice(options.getString("intermodal-network-output")));
325  }
326  if (options.exists("intermodal-weight-output") && options.isSet("intermodal-weight-output")) {
327  OutputDevice::createDeviceByOption("intermodal-weight-output", "weights", "meandata_file.xsd");
328  OutputDevice& dev = OutputDevice::getDeviceByOption("intermodal-weight-output");
330  dev.writeAttr(SUMO_ATTR_ID, "intermodalweights");
331  dev.writeAttr(SUMO_ATTR_BEGIN, 0);
333  router.writeWeights(dev);
334  dev.closeTag();
335  }
336 }
337 
338 
339 void
341  // end writing
342  if (myRoutesOutput != nullptr) {
344  }
345  // only if opened
346  if (myRouteAlternativesOutput != nullptr) {
348  }
349  // only if opened
350  if (myTypesOutput != nullptr) {
351  myTypesOutput->close();
352  }
354 #ifdef HAVE_FOX
355  if (myThreadPool.size() > 0) {
356  myThreadPool.clear();
357  }
358 #endif
359 }
360 
361 
362 
364 RONet::getVehicleTypeSecure(const std::string& id) {
365  // check whether the type was already known
367  if (id == DEFAULT_VTYPE_ID) {
369  } else if (id == DEFAULT_PEDTYPE_ID) {
371  } else if (id == DEFAULT_BIKETYPE_ID) {
373  } else if (id == DEFAULT_TAXITYPE_ID) {
375  } else if (id == DEFAULT_RAILTYPE_ID) {
377  }
378  if (type != nullptr) {
379  return type;
380  }
381  VTypeDistDictType::iterator it2 = myVTypeDistDict.find(id);
382  if (it2 != myVTypeDistDict.end()) {
383  return it2->second->get();
384  }
385  if (id == "") {
386  // ok, no vehicle type or an unknown type was given within the user input
387  // return the default type
390  }
391  return type;
392 }
393 
394 
395 bool
396 RONet::checkVType(const std::string& id) {
397  if (id == DEFAULT_VTYPE_ID) {
401  } else {
402  return false;
403  }
404  } else if (id == DEFAULT_PEDTYPE_ID) {
408  } else {
409  return false;
410  }
411  } else if (id == DEFAULT_BIKETYPE_ID) {
415  } else {
416  return false;
417  }
418  } else if (id == DEFAULT_TAXITYPE_ID) {
422  } else {
423  return false;
424  }
425  } else if (id == DEFAULT_RAILTYPE_ID) {
429  } else {
430  return false;
431  }
432  } else {
433  if (myVehicleTypes.get(id) != 0 || myVTypeDistDict.find(id) != myVTypeDistDict.end()) {
434  return false;
435  }
436  }
437  return true;
438 }
439 
440 
441 bool
443  if (checkVType(type->id)) {
444  myVehicleTypes.add(type->id, type);
445  } else {
446  WRITE_ERRORF(TL("The vehicle type '%' occurs at least twice."), type->id);
447  delete type;
448  return false;
449  }
450  return true;
451 }
452 
453 
454 bool
455 RONet::addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution) {
456  if (checkVType(id)) {
457  myVTypeDistDict[id] = vehTypeDistribution;
458  return true;
459  }
460  delete vehTypeDistribution;
461  return false;
462 }
463 
464 
465 bool
466 RONet::addVehicle(const std::string& id, ROVehicle* veh) {
467  if (myVehIDs.find(id) == myVehIDs.end()) {
469 
470  if (veh->isPublicTransport()) {
471  if (!veh->isPartOfFlow()) {
472  myPTVehicles.push_back(veh);
473  }
474  if (!myDoPTRouting) {
475  return true;
476  }
477  }
478  myRoutables[veh->getDepart()].push_back(veh);
479  return true;
480  }
481  WRITE_ERRORF(TL("Another vehicle with the id '%' exists."), id);
482  delete veh;
483  return false;
484 }
485 
486 
487 bool
488 RONet::knowsVehicle(const std::string& id) const {
489  return myVehIDs.find(id) != myVehIDs.end();
490 }
491 
492 SUMOTime
493 RONet::getDeparture(const std::string& vehID) const {
494  auto it = myVehIDs.find(vehID);
495  if (it != myVehIDs.end()) {
496  return it->second;
497  } else {
498  throw ProcessError(TLF("Requesting departure time for unknown vehicle '%'", vehID));
499  }
500 }
501 
502 
503 bool
504 RONet::addFlow(SUMOVehicleParameter* flow, const bool randomize) {
505  if (randomize && flow->repetitionOffset >= 0) {
506  myDepartures[flow->id].reserve(flow->repetitionNumber);
507  for (int i = 0; i < flow->repetitionNumber; ++i) {
508  myDepartures[flow->id].push_back(flow->depart + RandHelper::rand(flow->repetitionNumber * flow->repetitionOffset));
509  }
510  std::sort(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
511  std::reverse(myDepartures[flow->id].begin(), myDepartures[flow->id].end());
512  }
513  const bool added = myFlows.add(flow->id, flow);
514  if (added) {
515  myHaveActiveFlows = true;
516  }
517  return added;
518 }
519 
520 
521 bool
523  if (myPersonIDs.count(person->getID()) == 0) {
524  myPersonIDs.insert(person->getID());
525  myRoutables[person->getDepart()].push_back(person);
526  return true;
527  }
528  WRITE_ERRORF(TL("Another person with the id '%' exists."), person->getID());
529  return false;
530 }
531 
532 
533 void
534 RONet::addContainer(const SUMOTime depart, const std::string desc) {
535  myContainers.insert(std::pair<const SUMOTime, const std::string>(depart, desc));
536 }
537 
538 
539 void
540 RONet::checkFlows(SUMOTime time, MsgHandler* errorHandler) {
541  myHaveActiveFlows = false;
542  for (const auto& i : myFlows) {
543  SUMOVehicleParameter* const pars = i.second;
544  if (pars->line != "" && !myDoPTRouting) {
545  continue;
546  }
547  if (pars->repetitionProbability > 0) {
548  if (pars->repetitionEnd > pars->depart && pars->repetitionsDone < pars->repetitionNumber) {
549  myHaveActiveFlows = true;
550  }
551  const SUMOTime origDepart = pars->depart;
552  while (pars->depart < time && pars->repetitionsDone < pars->repetitionNumber) {
553  if (pars->repetitionEnd <= pars->depart) {
554  break;
555  }
556  // only call rand if all other conditions are met
557  if (RandHelper::rand() < (pars->repetitionProbability * TS)) {
558  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
559  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
560  newPars->depart = pars->depart;
561  for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
562  if (stop->until >= 0) {
563  stop->until += pars->depart - origDepart;
564  }
565  }
566  pars->repetitionsDone++;
567  // try to build the vehicle
568  const SUMOVTypeParameter* type = getVehicleTypeSecure(pars->vtypeid);
569  if (type == nullptr) {
571  } else if (!myKeepVTypeDist) {
572  // fix the type id in case we used a distribution
573  newPars->vtypeid = type->id;
574  }
575  const SUMOTime stopOffset = pars->routeid[0] == '!' ? pars->depart - origDepart : pars->depart;
576  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
577  ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
578  addVehicle(newPars->id, veh);
579  delete newPars;
580  }
581  pars->depart += DELTA_T;
582  }
583  } else {
584  SUMOTime depart = static_cast<SUMOTime>(pars->depart + pars->repetitionTotalOffset);
585  while (pars->repetitionsDone < pars->repetitionNumber && pars->repetitionEnd >= depart) {
586  myHaveActiveFlows = true;
587  depart = static_cast<SUMOTime>(pars->depart + pars->repetitionTotalOffset);
588  if (myDepartures.find(pars->id) != myDepartures.end()) {
589  depart = myDepartures[pars->id].back();
590  }
591  if (depart >= time + DELTA_T) {
592  break;
593  }
594  if (myDepartures.find(pars->id) != myDepartures.end()) {
595  myDepartures[pars->id].pop_back();
596  }
597  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
598  newPars->id = pars->id + "." + toString(pars->repetitionsDone);
599  newPars->depart = depart;
600  for (std::vector<SUMOVehicleParameter::Stop>::iterator stop = newPars->stops.begin(); stop != newPars->stops.end(); ++stop) {
601  if (stop->until >= 0) {
602  stop->until += depart - pars->depart;
603  }
604  }
605  pars->incrementFlow(1);
606  // try to build the vehicle
607  const SUMOVTypeParameter* type = getVehicleTypeSecure(pars->vtypeid);
608  if (type == nullptr) {
610  } else {
611  // fix the type id in case we used a distribution
612  newPars->vtypeid = type->id;
613  }
614  const SUMOTime stopOffset = pars->routeid[0] == '!' ? depart - pars->depart : depart;
615  RORouteDef* route = getRouteDef(pars->routeid)->copy("!" + newPars->id, stopOffset);
616  ROVehicle* veh = new ROVehicle(*newPars, route, type, this, errorHandler);
617  addVehicle(newPars->id, veh);
618  delete newPars;
619  }
620  }
621  }
622 }
623 
624 
625 void
626 RONet::createBulkRouteRequests(const RORouterProvider& provider, const SUMOTime time, const bool removeLoops) {
627  std::map<const int, std::vector<RORoutable*> > bulkVehs;
628  for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
629  if (i->first >= time) {
630  break;
631  }
632  for (RORoutable* const routable : i->second) {
633  const ROEdge* const depEdge = routable->getDepartEdge();
634  bulkVehs[depEdge->getNumericalID()].push_back(routable);
635  RORoutable* const first = bulkVehs[depEdge->getNumericalID()].front();
636  if (first->getMaxSpeed() != routable->getMaxSpeed()) {
637  WRITE_WARNINGF(TL("Bulking different maximum speeds ('%' and '%') may lead to suboptimal routes."), first->getID(), routable->getID());
638  }
639  if (first->getVClass() != routable->getVClass()) {
640  WRITE_WARNINGF(TL("Bulking different vehicle classes ('%' and '%') may lead to invalid routes."), first->getID(), routable->getID());
641  }
642  }
643  }
644 #ifdef HAVE_FOX
645  int workerIndex = 0;
646 #endif
647  for (std::map<const int, std::vector<RORoutable*> >::const_iterator i = bulkVehs.begin(); i != bulkVehs.end(); ++i) {
648 #ifdef HAVE_FOX
649  if (myThreadPool.size() > 0) {
650  bool bulk = true;
651  for (RORoutable* const r : i->second) {
652  myThreadPool.add(new RoutingTask(r, removeLoops, myErrorHandler), workerIndex);
653  if (bulk) {
654  myThreadPool.add(new BulkmodeTask(true), workerIndex);
655  bulk = false;
656  }
657  }
658  myThreadPool.add(new BulkmodeTask(false), workerIndex);
659  workerIndex++;
660  if (workerIndex == (int)myThreadPool.size()) {
661  workerIndex = 0;
662  }
663  continue;
664  }
665 #endif
666  for (RORoutable* const r : i->second) {
667  r->computeRoute(provider, removeLoops, myErrorHandler);
668  provider.setBulkMode(true);
669  }
670  provider.setBulkMode(false);
671  }
672 }
673 
674 
675 SUMOTime
677  SUMOTime time) {
678  MsgHandler* mh = (options.getBool("ignore-errors") ?
680  if (myHaveActiveFlows) {
681  checkFlows(time, mh);
682  }
683  SUMOTime lastTime = -1;
684  const bool removeLoops = options.getBool("remove-loops");
685 #ifdef HAVE_FOX
686  const int maxNumThreads = options.getInt("routing-threads");
687 #endif
688  if (myRoutables.size() != 0) {
689  if (options.getBool("bulk-routing")) {
690 #ifdef HAVE_FOX
691  while ((int)myThreadPool.size() < maxNumThreads) {
692  new WorkerThread(myThreadPool, provider);
693  }
694 #endif
695  createBulkRouteRequests(provider, time, removeLoops);
696  } else {
697  for (RoutablesMap::const_iterator i = myRoutables.begin(); i != myRoutables.end(); ++i) {
698  if (i->first >= time) {
699  break;
700  }
701  for (RORoutable* const routable : i->second) {
702 #ifdef HAVE_FOX
703  // add task
704  if (maxNumThreads > 0) {
705  const int numThreads = (int)myThreadPool.size();
706  if (numThreads == 0) {
707  // This is the very first routing. Since at least the CHRouter needs initialization
708  // before it gets cloned, we do not do this in parallel
709  routable->computeRoute(provider, removeLoops, myErrorHandler);
710  new WorkerThread(myThreadPool, provider);
711  } else {
712  // add thread if necessary
713  if (numThreads < maxNumThreads && myThreadPool.isFull()) {
714  new WorkerThread(myThreadPool, provider);
715  }
716  myThreadPool.add(new RoutingTask(routable, removeLoops, myErrorHandler));
717  }
718  continue;
719  }
720 #endif
721  routable->computeRoute(provider, removeLoops, myErrorHandler);
722  }
723  }
724  }
725 #ifdef HAVE_FOX
726  myThreadPool.waitAll();
727 #endif
728  }
729  // write all vehicles (and additional structures)
730  while (myRoutables.size() != 0 || myContainers.size() != 0) {
731  // get the next vehicle, person or container
732  RoutablesMap::iterator routables = myRoutables.begin();
733  const SUMOTime routableTime = routables == myRoutables.end() ? SUMOTime_MAX : routables->first;
734  ContainerMap::iterator container = myContainers.begin();
735  const SUMOTime containerTime = container == myContainers.end() ? SUMOTime_MAX : container->first;
736  // check whether it shall not yet be computed
737  if (routableTime >= time && containerTime >= time) {
738  lastTime = MIN2(routableTime, containerTime);
739  break;
740  }
741  const SUMOTime minTime = MIN2(routableTime, containerTime);
742  if (routableTime == minTime) {
743  // check whether to print the output
744  if (lastTime != routableTime && lastTime != -1) {
745  // report writing progress
746  if (options.getInt("stats-period") >= 0 && ((int)routableTime % options.getInt("stats-period")) == 0) {
747  WRITE_MESSAGE("Read: " + toString(myVehIDs.size()) + ", Discarded: " + toString(myDiscardedRouteNo) + ", Written: " + toString(myWrittenRouteNo));
748  }
749  }
750  lastTime = routableTime;
751  for (const RORoutable* const r : routables->second) {
752  // ok, check whether it has been routed
753  if (r->getRoutingSuccess()) {
754  // write the route
757  } else {
759  }
760  // we need to keep individual public transport vehicles but not the flows
761  if (!r->isPublicTransport() || r->isPartOfFlow()) {
762  // delete routes and the vehicle
763  const ROVehicle* const veh = dynamic_cast<const ROVehicle*>(r);
764  if (veh != nullptr && veh->getRouteDefinition()->getID()[0] == '!') {
765  if (!myRoutes.remove(veh->getRouteDefinition()->getID())) {
766  delete veh->getRouteDefinition();
767  }
768  }
769  delete r;
770  }
771  }
772  myRoutables.erase(routables);
773  }
774  if (containerTime == minTime) {
775  myRoutesOutput->writePreformattedTag(container->second);
776  if (myRouteAlternativesOutput != nullptr) {
778  }
779  myContainers.erase(container);
780  }
781  }
782  return lastTime;
783 }
784 
785 
786 bool
788  return myRoutables.size() > 0 || (myFlows.size() > 0 && myHaveActiveFlows) || myContainers.size() > 0;
789 }
790 
791 
792 int
794  return myEdges.size();
795 }
796 
797 
798 int
800  return myNumInternalEdges;
801 }
802 
803 
804 ROEdge*
805 RONet::getEdgeForLaneID(const std::string& laneID) const {
807 }
808 
809 
810 ROLane*
811 RONet::getLane(const std::string& laneID) const {
812  int laneIndex = SUMOXMLDefinitions::getIndexFromLane(laneID);
813  return getEdgeForLaneID(laneID)->getLanes()[laneIndex];
814 }
815 
816 
817 void
819  double taxiWait = STEPS2TIME(string2time(OptionsCont::getOptions().getString("persontrip.taxi.waiting-time")));
820  for (const auto& stopType : myInstance->myStoppingPlaces) {
821  // add access to all stopping places
822  const SumoXMLTag element = stopType.first;
823  for (const auto& stop : stopType.second) {
824  router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(stop.second->lane),
825  stop.second->startPos, stop.second->endPos, 0., element, false, taxiWait);
826  // add access to all public transport stops
827  if (element == SUMO_TAG_BUS_STOP) {
828  for (const auto& a : stop.second->accessPos) {
829  router.getNetwork()->addAccess(stop.first, myInstance->getEdgeForLaneID(std::get<0>(a)),
830  std::get<1>(a), std::get<1>(a), std::get<2>(a), SUMO_TAG_BUS_STOP, true, taxiWait);
831  }
832  }
833  }
834  }
835  // fill the public transport router with pre-parsed public transport lines
836  for (const auto& i : myInstance->myFlows) {
837  if (i.second->line != "") {
838  const RORouteDef* const route = myInstance->getRouteDef(i.second->routeid);
839  const std::vector<SUMOVehicleParameter::Stop>* addStops = nullptr;
840  if (route != nullptr && route->getFirstRoute() != nullptr) {
841  addStops = &route->getFirstRoute()->getStops();
842  }
843  router.getNetwork()->addSchedule(*i.second, addStops);
844  }
845  }
846  for (const RORoutable* const veh : myInstance->myPTVehicles) {
847  // add single vehicles with line attribute which are not part of a flow
848  // no need to add route stops here, they have been added to the vehicle before
849  router.getNetwork()->addSchedule(veh->getParameter());
850  }
851  // add access to transfer from walking to taxi-use
853  for (const ROEdge* edge : ROEdge::getAllEdges()) {
854  if ((edge->getPermissions() & SVC_PEDESTRIAN) != 0 && (edge->getPermissions() & SVC_TAXI) != 0) {
855  router.getNetwork()->addCarAccess(edge, SVC_TAXI, taxiWait);
856  }
857  }
858  }
859 }
860 
861 
862 bool
864  return myHavePermissions;
865 }
866 
867 
868 void
870  myHavePermissions = true;
871 }
872 
873 bool
875  for (const auto& item : myEdges) {
876  if (item.second->hasStoredEffort()) {
877  return true;
878  }
879  }
880  return false;
881 }
882 
883 const std::string
884 RONet::getStoppingPlaceName(const std::string& id) const {
885  for (const auto& mapItem : myStoppingPlaces) {
886  SUMOVehicleParameter::Stop* stop = mapItem.second.get(id);
887  if (stop != nullptr) {
888  // see RONetHandler::parseStoppingPlace
889  return stop->busstop;
890  }
891  }
892  return "";
893 }
894 
895 const std::string
896 RONet::getStoppingPlaceElement(const std::string& id) const {
897  for (const auto& mapItem : myStoppingPlaces) {
898  SUMOVehicleParameter::Stop* stop = mapItem.second.get(id);
899  if (stop != nullptr) {
900  // see RONetHandler::parseStoppingPlace
901  return stop->actType;
902  }
903  }
904  return toString(SUMO_TAG_BUS_STOP);
905 }
906 
907 
908 #ifdef HAVE_FOX
909 // ---------------------------------------------------------------------------
910 // RONet::RoutingTask-methods
911 // ---------------------------------------------------------------------------
912 void
913 RONet::RoutingTask::run(MFXWorkerThread* context) {
914  myRoutable->computeRoute(*static_cast<WorkerThread*>(context), myRemoveLoops, myErrorHandler);
915 }
916 #endif
917 
918 
919 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define TS
Definition: SUMOTime.h:42
const long long int VTYPEPARS_VEHICLECLASS_SET
const std::string DEFAULT_TAXITYPE_ID
const std::string DEFAULT_RAILTYPE_ID
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_TAXI
vehicle is a taxi
@ SVC_PEDESTRIAN
pedestrian
const std::string DEFAULT_BIKETYPE_ID
@ TRIGGERED
The departure is person triggered.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_ROUTES
root element of a route file
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop)
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
T MIN2(T a, T b)
Definition: StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void addCarAccess(const E *edge, SUMOVehicleClass svc, double traveltime)
Adds access edges for transfering from walking to vehicle use.
void addAccess(const std::string &stopId, const E *stopEdge, const double startPos, const double endPos, const double length, const SumoXMLTag category, bool isAccess, double taxiWait)
Adds access edges for stopping places to the intermodal network.
@ TAXI_PICKUP_ANYWHERE
taxi customer may be picked up anywhere
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=nullptr)
Network * getNetwork() const
void writeWeights(OutputDevice &dev)
int getCarWalkTransfer() const
void writeNetwork(OutputDevice &dev)
A thread repeatingly calculating incoming tasks.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:92
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:79
const std::string & getID() const
Returns the id.
Definition: Named.h:74
T get(const std::string &id) const
Retrieves an item.
int size() const
Returns the number of stored items within the container.
bool remove(const std::string &id, const bool del=true)
Removes an item.
bool add(const std::string &id, T item)
Adds an item.
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writePreformattedTag(const std::string &val)
writes a preformatted tag to the device but ensures that any pending tags are closed
Definition: OutputDevice.h:319
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
virtual bool isNull()
returns the information whether the device will discard all output
Definition: OutputDevice.h:155
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeHeader(const SumoXMLTag &rootElement)
Definition: OutputDevice.h:199
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
Interface for building instances of router-edges.
virtual ROEdge * buildEdge(const std::string &name, RONode *from, RONode *to, const int priority)=0
Builds an edge with the given name.
A basic edge for routing applications.
Definition: ROEdge.h:70
int getNumericalID() const
Returns the index (numeric id) of the edge.
Definition: ROEdge.h:226
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition: ROEdge.h:112
bool isInternal() const
return whether this edge is an internal edge
Definition: ROEdge.h:154
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition: ROEdge.h:524
void setOtherTazConnector(const ROEdge *edge)
Definition: ROEdge.h:172
virtual void addSuccessor(ROEdge *s, ROEdge *via=nullptr, std::string dir="")
Adds information about a connected edge.
Definition: ROEdge.cpp:111
static const ROEdgeVector & getAllEdges()
Returns all ROEdges.
Definition: ROEdge.cpp:352
A single lane the router may use.
Definition: ROLane.h:48
The router's network representation.
Definition: RONet.h:62
void createBulkRouteRequests(const RORouterProvider &provider, const SUMOTime time, const bool removeLoops)
Definition: RONet.cpp:626
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition: RONet.cpp:364
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
Definition: RONet.cpp:56
int myNumInternalEdges
The number of internal edges in the dictionary.
Definition: RONet.h:574
bool myDefaultPedTypeMayBeDeleted
Whether the default pedestrian type was already used or can still be replaced.
Definition: RONet.h:513
void setPermissionsFound()
Definition: RONet.cpp:869
bool myDefaultRailTypeMayBeDeleted
Whether the default rail type was already used or can still be replaced.
Definition: RONet.h:522
bool myDefaultVTypeMayBeDeleted
Whether the default vehicle type was already used or can still be replaced.
Definition: RONet.h:510
void checkFlows(SUMOTime time, MsgHandler *errorHandler)
Definition: RONet.cpp:540
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: RONet.cpp:150
ContainerMap myContainers
Definition: RONet.h:538
std::set< std::string > myPersonIDs
Known person ids.
Definition: RONet.h:490
std::map< std::string, std::pair< std::vector< std::string >, std::vector< std::string > > > myDistricts
traffic assignment zones with sources and sinks
Definition: RONet.h:547
bool addRouteDef(RORouteDef *def)
Definition: RONet.cpp:286
void addStoppingPlace(const std::string &id, const SumoXMLTag category, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:277
bool knowsVehicle(const std::string &id) const
returns whether a vehicle with the given id was already loaded
Definition: RONet.cpp:488
void cleanup()
closes the file output for computed routes and deletes associated threads if necessary
Definition: RONet.cpp:340
bool myHaveActiveFlows
whether any flows are still active
Definition: RONet.h:534
std::map< std::string, SUMOTime > myVehIDs
Known vehicle ids and their departure.
Definition: RONet.h:487
void openOutput(const OptionsCont &options)
Opens the output for computed routes.
Definition: RONet.cpp:292
NamedObjectCont< SUMOVehicleParameter * > myFlows
Known flows.
Definition: RONet.h:531
OutputDevice * myRouteAlternativesOutput
The file to write the computed route alternatives into.
Definition: RONet.h:553
bool myDefaultBikeTypeMayBeDeleted
Whether the default bicycle type was already used or can still be replaced.
Definition: RONet.h:516
RoutablesMap myRoutables
Known routables.
Definition: RONet.h:528
int getInternalEdgeNumber() const
Returns the number of internal edges the network contains.
Definition: RONet.cpp:799
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition: RONet.cpp:466
SUMOTime getDeparture(const std::string &vehID) const
returns departure time for the given vehicle id
Definition: RONet.cpp:493
bool myHasBidiEdges
whether the network contains bidirectional railway edges
Definition: RONet.h:586
bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource)
Definition: RONet.cpp:197
MsgHandler * myErrorHandler
handler for ignorable error messages
Definition: RONet.h:577
void writeIntermodal(const OptionsCont &options, ROIntermodalRouter &router) const
Writes the intermodal network and weights if requested.
Definition: RONet.cpp:321
RONet()
Constructor.
Definition: RONet.cpp:64
NamedObjectCont< RONode * > myNodes
Known nodes.
Definition: RONet.h:493
const std::string getStoppingPlaceElement(const std::string &id) const
return the element name for the given stopping place id
Definition: RONet.cpp:896
void addContainer(const SUMOTime depart, const std::string desc)
Definition: RONet.cpp:534
static void adaptIntermodalRouter(ROIntermodalRouter &router)
Definition: RONet.cpp:818
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: RONet.cpp:144
NamedObjectCont< RORouteDef * > myRoutes
Known routes.
Definition: RONet.h:525
bool furtherStored()
Returns the information whether further vehicles, persons or containers are stored.
Definition: RONet.cpp:787
bool checkVType(const std::string &id)
Checks whether the vehicle type (distribution) may be added.
Definition: RONet.cpp:396
OutputDevice * myRoutesOutput
The file to write the computed routes into.
Definition: RONet.h:550
bool addPerson(ROPerson *person)
Definition: RONet.cpp:522
int myWrittenRouteNo
The number of written routes.
Definition: RONet.h:565
static RONet * myInstance
Unique instance of RONet.
Definition: RONet.h:484
SUMOTime saveAndRemoveRoutesUntil(OptionsCont &options, const RORouterProvider &provider, SUMOTime time)
Computes routes described by their definitions and saves them.
Definition: RONet.cpp:676
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:160
bool myDefaultTaxiTypeMayBeDeleted
Whether the default taxi type was already used or can still be replaced.
Definition: RONet.h:519
std::map< std::string, std::map< SUMOVehicleClass, double > > myRestrictions
The vehicle class specific speed restrictions.
Definition: RONet.h:571
std::map< SumoXMLTag, NamedObjectCont< SUMOVehicleParameter::Stop * > > myStoppingPlaces
Known bus / train / container stops and parking areas.
Definition: RONet.h:499
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition: RONet.cpp:442
bool myHavePermissions
Whether the network contains edges which not all vehicles may pass.
Definition: RONet.h:568
bool hasPermissions() const
Definition: RONet.cpp:863
void setBidiEdges(const std::map< ROEdge *, std::string > &bidiMap)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:255
ROLane * getLane(const std::string &laneID) const
Retrieves a lane rom the network given its id.
Definition: RONet.cpp:811
int myDiscardedRouteNo
The number of discarded routes.
Definition: RONet.h:562
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition: RONet.h:318
VTypeDistDictType myVTypeDistDict
A distribution of vehicle types (probability->vehicle type)
Definition: RONet.h:507
std::vector< const RORoutable * > myPTVehicles
vehicles to keep for public transport routing
Definition: RONet.h:541
NamedObjectCont< ROEdge * > myEdges
Known edges.
Definition: RONet.h:496
void addNode(RONode *node)
Definition: RONet.cpp:268
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter * > *vehTypeDistribution)
Adds a vehicle type distribution.
Definition: RONet.cpp:455
void addJunctionTaz(ROAbstractEdgeBuilder &eb)
add a taz for every junction unless a taz with the same id already exists
Definition: RONet.cpp:219
OutputDevice * myTypesOutput
The file to write the vehicle types into.
Definition: RONet.h:556
const bool myDoPTRouting
whether to calculate routes for public transport
Definition: RONet.h:583
const bool myKeepVTypeDist
whether to keep the the vtype distribution in output
Definition: RONet.h:580
virtual ~RONet()
Destructor.
Definition: RONet.cpp:113
const std::string getStoppingPlaceName(const std::string &id) const
return the name for the given stopping place id
Definition: RONet.cpp:884
std::map< std::string, std::vector< SUMOTime > > myDepartures
Departure times for randomized flows.
Definition: RONet.h:544
int getEdgeNumber() const
Returns the total number of edges the network contains including internal edges.
Definition: RONet.cpp:793
ROEdge * getEdgeForLaneID(const std::string &laneID) const
Retrieves an edge from the network when the lane id is given.
Definition: RONet.cpp:805
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition: RONet.cpp:504
bool hasLoadedEffort() const
whether efforts were loaded from file
Definition: RONet.cpp:874
NamedObjectCont< SUMOVTypeParameter * > myVehicleTypes
Known vehicle types.
Definition: RONet.h:502
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition: RONet.cpp:174
Base class for nodes used by the router.
Definition: RONode.h:43
const ConstROEdgeVector & getIncoming() const
Definition: RONode.h:69
const ConstROEdgeVector & getOutgoing() const
Definition: RONode.h:73
A person as used by router.
Definition: ROPerson.h:50
A routable thing such as a vehicle or person.
Definition: RORoutable.h:52
bool getRoutingSuccess() const
Definition: RORoutable.h:163
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Definition: RORoutable.h:71
const std::string & getID() const
Returns the id of the routable.
Definition: RORoutable.h:91
SUMOVehicleClass getVClass() const
Definition: RORoutable.h:109
bool isPublicTransport() const
Definition: RORoutable.h:129
bool isPartOfFlow() const
Definition: RORoutable.h:133
virtual void computeRoute(const RORouterProvider &provider, const bool removeLoops, MsgHandler *errorHandler)=0
SUMOTime getDepart() const
Returns the time the vehicle starts at, -1 for triggered vehicles.
Definition: RORoutable.h:100
virtual const ROEdge * getDepartEdge() const =0
void write(OutputDevice *os, OutputDevice *const altos, OutputDevice *const typeos, OptionsCont &options) const
Saves the routable including the vehicle type (if it was not saved before).
Definition: RORoutable.h:148
double getMaxSpeed() const
Returns the vehicle's maximum speed.
Definition: RORoutable.h:121
Base class for a vehicle's route definition.
Definition: RORouteDef.h:53
const RORoute * getFirstRoute() const
Definition: RORouteDef.h:98
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
Definition: RORouteDef.cpp:418
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the list of stops this route contains.
Definition: RORoute.h:187
A vehicle as used by router.
Definition: ROVehicle.h:50
RORouteDef * getRouteDefinition() const
Returns the definition of the route the vehicle takes.
Definition: ROVehicle.h:73
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
Definition: ROVehicle.h:92
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
void setBulkMode(const bool mode) const
Structure representing possible vehicle parameter.
long long int parametersSet
Information for the router which parameter were set.
bool onlyReferenced
Information whether this is a type-stub, being only referenced but not defined (needed by routers)
std::string id
The vehicle type's id.
Definition of vehicle stop (position and duration)
std::string actType
act Type (only used by Persons) (used by netedit)
std::string busstop
(Optional) bus stop if one is assigned to the stop
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
void incrementFlow(double scale, SumoRNG *rng=nullptr)
increment flow
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOTime repetitionTotalOffset
The offset between depart and the time for the next vehicle insertions.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
std::string line
The vehicle's line (mainly for public transport)
static std::string getEdgeIDFromLane(const std::string laneID)
return edge id when given the lane ID
static int getIndexFromLane(const std::string laneID)
return lane index when given the lane ID