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