Eclipse SUMO - Simulation of Urban MObility
IntermodalRouter.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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 /****************************************************************************/
19 // The IntermodalRouter builds a special network and (delegates to a SUMOAbstractRouter)
20 /****************************************************************************/
21 #pragma once
22 #include <config.h>
23 
24 #include <string>
25 #include <vector>
26 #include <algorithm>
27 #include <assert.h>
29 #include <utils/common/SUMOTime.h>
30 #include <utils/common/ToString.h>
32 #include "SUMOAbstractRouter.h"
33 #include "DijkstraRouter.h"
34 #include "AStarRouter.h"
35 #include "IntermodalNetwork.h"
36 #include "EffortCalculator.h"
37 #include "CarEdge.h"
38 #include "StopEdge.h"
39 #include "PedestrianRouter.h"
40 
41 //#define IntermodalRouter_DEBUG_ROUTES
42 
43 
44 // ===========================================================================
45 // class definitions
46 // ===========================================================================
51 template<class E, class L, class N, class V>
52 class IntermodalRouter : public SUMOAbstractRouter<E, IntermodalTrip<E, N, V> > {
53 public:
55 
56 private:
63 
64 public:
65  struct TripItem {
66  TripItem(const std::string& _line = "") :
67  line(_line), intended(_line) {}
68  std::string line;
69  std::string vType = "";
70  std::string destStop = "";
71  std::string intended; // intended public transport vehicle id
72  double depart = -1.; // intended public transport departure
73  std::vector<const E*> edges;
74  double traveltime = 0.;
75  double cost = 0.;
76  double length = 0.;
79  std::string description = "";
80  };
81 
83  IntermodalRouter(CreateNetCallback callback, const int carWalkTransfer, double taxiWait, const std::string& routingAlgorithm,
84  const int routingMode = 0, EffortCalculator* calc = nullptr) :
85  SUMOAbstractRouter<E, _IntermodalTrip>("IntermodalRouter", true, nullptr, nullptr, false, false),
86  myAmClone(false), myInternalRouter(nullptr), myIntermodalNet(nullptr),
87  myCallback(callback), myCarWalkTransfer(carWalkTransfer), myTaxiWait(taxiWait),
88  myRoutingAlgorithm(routingAlgorithm),
89  myRoutingMode(routingMode), myExternalEffort(calc) {
90  }
91 
93  virtual ~IntermodalRouter() {
94  delete myInternalRouter;
95  if (!myAmClone) {
96  delete myIntermodalNet;
97  }
98  }
99 
101  createNet();
103  }
104 
105  int getCarWalkTransfer() const {
106  return myCarWalkTransfer;
107  }
108 
111  bool compute(const E* from, const E* to, const double departPos, const double arrivalPos,
112  const std::string stopID, const double speed,
113  const V* const vehicle, const SVCPermissions modeSet, const SUMOTime msTime,
114  std::vector<TripItem>& into, const double externalFactor = 0.) {
115  createNet();
116  _IntermodalTrip trip(from, to, departPos, arrivalPos, speed, msTime, 0, vehicle, modeSet, myExternalEffort, externalFactor);
117  std::vector<const _IntermodalEdge*> intoEdges;
118  //std::cout << "compute from=" << from->getID() << " to=" << to->getID() << " dPos=" << departPos << " aPos=" << arrivalPos << " stopID=" << stopID << " speed=" << speed << " veh=" << Named::getIDSecure(vehicle) << " modeSet=" << modeSet << " t=" << msTime << " iFrom=" << myIntermodalNet->getDepartEdge(from, trip.departPos)->getID() << " iTo=" << (stopID != "" ? myIntermodalNet->getStopEdge(stopID) : myIntermodalNet->getArrivalEdge(to, trip.arrivalPos))->getID() << "\n";
119  const bool success = myInternalRouter->compute(myIntermodalNet->getDepartEdge(from, trip.departPos),
120  stopID != "" ? myIntermodalNet->getStopEdge(stopID) : myIntermodalNet->getArrivalEdge(to, trip.arrivalPos),
121  &trip, msTime, intoEdges);
122  if (success) {
123  std::string lastLine = "";
124  double time = STEPS2TIME(msTime);
125  double effort = 0.;
126  double length = 0.;
127  const _IntermodalEdge* prev = nullptr;
128  for (const _IntermodalEdge* iEdge : intoEdges) {
129  if (iEdge->includeInRoute(false)) {
130  if (iEdge->getLine() == "!stop") {
131  if (into.size() > 0) {
132  // previous stage ends at stop
133  into.back().destStop = iEdge->getID();
134  if (myExternalEffort != nullptr) {
135  into.back().description = myExternalEffort->output(iEdge->getNumericalID());
136  }
137  if (lastLine == "!ped") {
138  lastLine = ""; // a stop always starts a new trip item
139  }
140  } else {
141  // trip starts at stop
142  lastLine = "";
143  into.push_back(TripItem("!stop"));
144  into.back().destStop = iEdge->getID();
145  }
146  } else {
147  if (iEdge->getLine() != lastLine) {
148  lastLine = iEdge->getLine();
149  if (lastLine == "!car") {
150  into.push_back(TripItem(vehicle->getID()));
151  into.back().vType = vehicle->getParameter().vtypeid;
152  } else if (lastLine == "!ped") {
153  into.push_back(TripItem());
154  } else {
155  into.push_back(TripItem(lastLine));
156  into.back().depart = iEdge->getIntended(time, into.back().intended);
157  }
158  into.back().departPos = iEdge->getStartPos();
159  }
160  if (into.back().edges.empty() || into.back().edges.back() != iEdge->getEdge()) {
161  into.back().edges.push_back(iEdge->getEdge());
162  into.back().arrivalPos = iEdge->getEndPos();
163  }
164  }
165  }
166  const double prevTime = time, prevEffort = effort, prevLength = length;
167  myInternalRouter->updateViaCost(prev, iEdge, &trip, time, effort, length);
168  // correct intermodal length:
169  length += iEdge->getPartialLength(&trip) - iEdge->getLength();
170  prev = iEdge;
171  if (!into.empty()) {
172  into.back().traveltime += time - prevTime;
173  into.back().cost += effort - prevEffort;
174  into.back().length += length - prevLength;
175  if (into.back().depart < 0) {
176  into.back().depart = prevTime;
177  }
178  }
179  }
180  }
181  if (into.size() > 0) {
182  into.back().arrivalPos = arrivalPos;
183  }
184 #ifdef IntermodalRouter_DEBUG_ROUTES
185  double time = STEPS2TIME(msTime);
186  for (const _IntermodalEdge* iEdge : intoEdges) {
187  const double edgeEffort = myInternalRouter->getEffort(iEdge, &trip, time);
188  time += edgeEffort;
189  std::cout << iEdge->getID() << "(" << iEdge->getLine() << "): " << edgeEffort << " l=" << iEdge->getLength() << " pL=" << iEdge->getPartialLength(&trip) << "\n";
190  }
191  std::cout << TIME2STEPS(msTime) << " trip from " << from->getID() << " to " << (to != nullptr ? to->getID() : stopID)
192  << " departPos=" << trip.departPos
193  << " arrivalPos=" << trip.arrivalPos
194  << " modes=" << getVehicleClassNames(modeSet)
195  << " edges=" << toString(intoEdges)
196 // << " resultEdges=" << toString(into)
197  << " time=" << time
198  << "\n";
199 #endif
200  return success;
201  }
202 
205  bool compute(const E*, const E*, const _IntermodalTrip* const,
206  SUMOTime, std::vector<const E*>&, bool) {
207  throw ProcessError("Do not use this method");
208  }
209 
210  void prohibit(const std::vector<E*>& toProhibit) {
211  createNet();
212  std::vector<_IntermodalEdge*> toProhibitPE;
213  for (typename std::vector<E*>::const_iterator it = toProhibit.begin(); it != toProhibit.end(); ++it) {
214  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).first);
215  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).second);
216  toProhibitPE.push_back(myIntermodalNet->getCarEdge(*it));
217  }
218  myInternalRouter->prohibit(toProhibitPE);
219  }
220 
222  createNet();
224  dev.openTag(SUMO_TAG_EDGE);
225  dev.writeAttr(SUMO_ATTR_ID, e->getID());
226  dev.writeAttr(SUMO_ATTR_LINE, e->getLine());
227  dev.writeAttr(SUMO_ATTR_LENGTH, e->getLength());
228  dev.writeAttr("successors", toString(e->getSuccessors(SVC_IGNORING)));
229  dev.closeTag();
230  }
231  }
232 
234  createNet();
235  _IntermodalTrip trip(nullptr, nullptr, 0., 0., DEFAULT_PEDESTRIAN_SPEED, 0, 0, nullptr, SVC_PASSENGER | SVC_BICYCLE | SVC_BUS);
237  dev.openTag(SUMO_TAG_EDGE);
238  dev.writeAttr(SUMO_ATTR_ID, e->getID());
239  dev.writeAttr("traveltime", e->getTravelTime(&trip, 0.));
240  dev.writeAttr("effort", e->getEffort(&trip, 0.));
241  dev.closeTag();
242  }
243  }
244 
245  Network* getNetwork() const {
246  return myIntermodalNet;
247  }
248 
250  return myExternalEffort;
251  }
252 
253 private:
254  IntermodalRouter(Network* net, const int carWalkTransfer, double taxiWait, const std::string& routingAlgorithm,
255  const int routingMode, EffortCalculator* calc) :
256  SUMOAbstractRouter<E, _IntermodalTrip>("IntermodalRouterClone", true, nullptr, nullptr, false, false),
257  myAmClone(true), myInternalRouter(nullptr), myIntermodalNet(net),
258  myCarWalkTransfer(carWalkTransfer),
259  myTaxiWait(taxiWait),
260  myRoutingAlgorithm(routingAlgorithm), myRoutingMode(routingMode), myExternalEffort(calc) {
261  createNet();
262  }
263 
264  static inline double getCombined(const _IntermodalEdge* const edge, const _IntermodalTrip* const trip, double time) {
265  return edge->getTravelTime(trip, time) + trip->externalFactor * trip->calc->getEffort(edge->getNumericalID());
266  }
267 
268  inline void createNet() {
269  if (myIntermodalNet == nullptr) {
270  myIntermodalNet = new Network(E::getAllEdges(), false, myCarWalkTransfer);
271  myIntermodalNet->addCarEdges(E::getAllEdges(), myTaxiWait);
272  myCallback(*this);
273  }
274  if (myInternalRouter == nullptr) {
275  switch (myRoutingMode) {
276  case 0:
277  if (myRoutingAlgorithm == "astar") {
280  } else {
283  }
284  break;
285  case 1:
287  break;
288  case 2:
290  break;
291  case 3:
292  if (myExternalEffort != nullptr) {
293  std::vector<std::string> edgeLines;
294  for (const auto e : myIntermodalNet->getAllEdges()) {
295  edgeLines.push_back(e->getLine());
296  }
297  myExternalEffort->init(edgeLines);
298  }
300  break;
301  }
302  }
303  }
304 
305 private:
306  const bool myAmClone;
310  const int myCarWalkTransfer;
311  const double myTaxiWait;
312  const std::string myRoutingAlgorithm;
313  const int myRoutingMode;
315 
316 
317 private:
320 
321 };
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_BUS
vehicle is a bus
const double DEFAULT_PEDESTRIAN_SPEED
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SUMO_TAG_EDGE
begin/end of the description of an edge
@ SUMO_ATTR_LINE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
double gWeightsRandomFactor
Definition: StdDefs.cpp:29
const double INVALID_DOUBLE
Definition: StdDefs.h:62
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
Computes the shortest path through a network using the A* algorithm.
Definition: AStarRouter.h:76
Computes the shortest path through a network using the Dijkstra algorithm.
the effort calculator interface
virtual double getEffort(const int numericalID) const =0
virtual std::string output(const int edge) const =0
virtual void init(const std::vector< std::string > &edges)=0
the base edge type that is given to the internal router (SUMOAbstractRouter)
static double getTravelTimeStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
virtual double getTravelTime(const IntermodalTrip< E, N, V > *const, double) const
int getNumericalID() const
static double getEffortStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
virtual double getTravelTimeAggregated(const IntermodalTrip< E, N, V > *const trip, double time) const
static double getTravelTimeStaticRandomized(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
the intermodal network storing edges, connections and the mappings to the "real" edges
const EdgePair & getBothDirections(const E *e) const
Returns the pair of forward and backward edge.
const std::vector< _IntermodalEdge * > & getAllEdges()
_IntermodalEdge * getArrivalEdge(const E *e, const double pos) const
Returns the arriving intermodal edge.
_IntermodalEdge * getStopEdge(const std::string &stopId) const
Returns the associated stop edge.
void addCarEdges(const std::vector< E * > &edges, double taxiWait)
_IntermodalEdge * getCarEdge(const E *e) const
Returns the associated car edge.
const _IntermodalEdge * getDepartEdge(const E *e, const double pos) const
Returns the departing intermodal edge.
SUMOAbstractRouter< _IntermodalEdge, _IntermodalTrip > _InternalRouter
EffortCalculator * getExternalEffort() const
AStarRouter< _IntermodalEdge, _IntermodalTrip > _InternalAStar
IntermodalTrip< E, N, V > _IntermodalTrip
CreateNetCallback myCallback
static double getCombined(const _IntermodalEdge *const edge, const _IntermodalTrip *const trip, double time)
void(* CreateNetCallback)(IntermodalRouter< E, L, N, V > &)
IntermodalEdge< E, L, N, V > _IntermodalEdge
const int myCarWalkTransfer
Network * myIntermodalNet
virtual ~IntermodalRouter()
Destructor.
IntermodalNetwork< E, L, N, V > Network
IntermodalRouter(Network *net, const int carWalkTransfer, double taxiWait, const std::string &routingAlgorithm, const int routingMode, EffortCalculator *calc)
Network * getNetwork() const
IntermodalRouter(CreateNetCallback callback, const int carWalkTransfer, double taxiWait, const std::string &routingAlgorithm, const int routingMode=0, EffortCalculator *calc=nullptr)
Constructor.
bool compute(const E *, const E *, const _IntermodalTrip *const, SUMOTime, std::vector< const E * > &, bool)
Builds the route between the given edges using the minimum effort at the given time The definition of...
DijkstraRouter< _IntermodalEdge, _IntermodalTrip > _InternalDijkstra
IntermodalRouter & operator=(const IntermodalRouter &s)
Invalidated assignment operator.
const std::string myRoutingAlgorithm
bool compute(const E *from, const E *to, const double departPos, const double arrivalPos, const std::string stopID, const double speed, const V *const vehicle, const SVCPermissions modeSet, const SUMOTime msTime, std::vector< TripItem > &into, const double externalFactor=0.)
Builds the route between the given edges using the minimum effort at the given time The definition of...
const double myTaxiWait
void prohibit(const std::vector< E * > &toProhibit)
void writeWeights(OutputDevice &dev)
EffortCalculator *const myExternalEffort
SUMOAbstractRouter< E, _IntermodalTrip > * clone()
_InternalRouter * myInternalRouter
int getCarWalkTransfer() const
void writeNetwork(OutputDevice &dev)
the "vehicle" type that is given to the internal router (SUMOAbstractRouter)
const EffortCalculator *const calc
const double departPos
const double arrivalPos
const double externalFactor
const std::string & getID() const
Returns the id.
Definition: Named.h:73
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void updateViaCost(const E *const prev, const E *const e, const V *const v, double &time, double &effort, double &length) const
double getEffort(const E *const e, const V *const v, double t) const
virtual void prohibit(const std::vector< E * > &)
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
TripItem(const std::string &_line="")
std::vector< const E * > edges