SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PedestrianRouter.h
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Pedestrian Router build a special network and (delegegates to a SUMOAbstractRouter)
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 #ifndef PedestrianRouter_h
21 #define PedestrianRouter_h
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <vector>
35 #include <algorithm>
36 #include <assert.h>
37 #include <utils/common/SysUtils.h>
39 #include <utils/common/SUMOTime.h>
40 #include <utils/common/ToString.h>
41 #include <utils/common/Named.h>
45 
46 #define TL_RED_PENALTY 20
47 
48 //#define PedestrianRouter_DEBUG_NETWORK
49 //#define PedestrianRouter_DEBUG_ROUTES
50 //#define PedestrianRouter_DEBUG_EFFORTS
51 
52 template <class E, class L>
53 inline const L* getSidewalk(const E* edge) {
54  if (edge == 0) {
55  return 0;
56  }
57  const std::vector<L*>& lanes = edge->getLanes();
58  for (typename std::vector<L*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) {
59  if ((*it)->allowsVehicleClass(SVC_PEDESTRIAN)) {
60  return *it;
61  }
62  }
63  return 0;
64 }
65 
66 // ===========================================================================
67 // class definitions
68 // ===========================================================================
69 
71 template<class E, class N>
73 
74  PedestrianTrip(const E* _from, const E* _to, SUMOReal _departPos, SUMOReal _arrivalPos, SUMOReal _speed, SUMOReal _departTime, const N* _node) :
75  from(_from),
76  to(_to),
77  node(_node),
78  departPos(_departPos < 0 ? _from->getLength() + _departPos : _departPos),
79  arrivalPos(_arrivalPos < 0 ? _to->getLength() + _arrivalPos : _arrivalPos),
80  speed(_speed),
81  departTime(_departTime)
82  {}
83 
84  // exists just for debugging purposes
85  std::string getID() const {
86  return from->getID() + ":" + to->getID() + ":" + toString(departTime);
87  }
88 
89  const E* from;
90  const E* to;
91  const N* node; // indicates whether only routing across this node shall be performed
94  const SUMOReal speed;
96 private:
99 };
100 
101 
103 template<class E, class L, class N>
104 class PedestrianEdge : public Named {
105  typedef std::pair<PedestrianEdge*, PedestrianEdge*> EdgePair;
106  /* brief build the pedestrian network (once)
107  * @param noE The number of edges in the dictionary of E
108  */
109 
110 public:
111  static size_t dictSize() {
112  return myEdgeDict.size();
113  }
114 
115  static void cleanup() {
116  myFromToLookup.clear();
117  myBidiLookup.clear();
118  myEdgeDict.clear();
119  }
120 
121  static void initPedestrianNetwork(size_t noE) {
122  if (myEdgeDict.size() > 0) {
123  return;
124  }
125 #ifdef PedestrianRouter_DEBUG_NETWORK
126  std::cout << "initPedestrianNetwork\n";
127 #endif
128  // build the Pedestrian edges
129  unsigned int numericalID = 0;
130  for (size_t i = 0; i < noE; i++) {
131  E* edge = E::dictionary(i);
132  const L* lane = getSidewalk<E, L>(edge);
133  if (edge->isInternal() || lane == 0) {
134  continue;
135  } else if (edge->isWalkingArea()) {
136  // only a single edge
137  myEdgeDict.push_back(PedestrianEdge(numericalID++, edge, lane, true));
138  } else { // regular edge or crossing
139  // forward and backward edges
140  myEdgeDict.push_back(PedestrianEdge(numericalID++, edge, lane, true));
141  myEdgeDict.push_back(PedestrianEdge(numericalID++, edge, lane, false));
142  // depart and arrival edges for (the router can decide the initial direction to take and the direction to arrive from)
143  myEdgeDict.push_back(PedestrianEdge(numericalID++, edge, lane, true, true));
144  myEdgeDict.push_back(PedestrianEdge(numericalID++, edge, lane, false, true));
145  }
146 
147  }
148  // build the lookup tables after myEdgeDict is complete
149  numericalID = 0;
150  for (size_t i = 0; i < noE; i++) {
151  E* edge = E::dictionary(i);
152  const L* lane = getSidewalk<E, L>(edge);
153  if (edge->isInternal() || lane == 0) {
154  continue;
155  } else if (edge->isWalkingArea()) {
156  // only a single edge and no connector edges
157  myBidiLookup[edge] = std::make_pair(&myEdgeDict[numericalID], &myEdgeDict[numericalID]);
158  myFromToLookup[edge] = std::make_pair(&myEdgeDict[numericalID], &myEdgeDict[numericalID]);
159  numericalID += 1;
160  } else { // regular edge or crossing
161  myBidiLookup[edge] = std::make_pair(&myEdgeDict[numericalID], &myEdgeDict[numericalID + 1]);
162  myFromToLookup[edge] = std::make_pair(&myEdgeDict[numericalID + 2], &myEdgeDict[numericalID + 3]);
163  numericalID += 4;
164  }
165  }
166 
167  // build the connections
168  for (size_t i = 0; i < noE; i++) {
169  E* edge = E::dictionary(i);
170  const L* lane = getSidewalk<E, L>(edge);
171  if (edge->isInternal() || lane == 0) {
172  continue;
173  }
174  // find all incoming and outgoing lanes for the sidewalk and
175  // connect the corresponding PedestrianEdges
176  const L* sidewalk = getSidewalk<E, L>(edge);
177  const EdgePair& pair = getBothDirections(edge);
178 
179 #ifdef PedestrianRouter_DEBUG_NETWORK
180  std::cout << " building connections from " << sidewalk->getID() << "\n";
181 #endif
182  std::vector<const L*> outgoing = sidewalk->getOutgoingLanes();
183  for (typename std::vector<const L*>::iterator it = outgoing.begin(); it != outgoing.end(); ++it) {
184  const L* target = *it;
185  const E* targetEdge = &(target->getEdge());
186 #ifdef PedestrianRouter_DEBUG_NETWORK
187  std::cout << " lane=" << getSidewalk<E, L>(targetEdge)->getID() << (target == getSidewalk<E, L>(targetEdge) ? "(used)" : "") << "\n";
188 #endif
189  if (target == getSidewalk<E, L>(targetEdge)) {
190  const EdgePair& targetPair = getBothDirections(targetEdge);
191  pair.first->myFollowingEdges.push_back(targetPair.first);
192  targetPair.second->myFollowingEdges.push_back(pair.second);
193 #ifdef PedestrianRouter_DEBUG_NETWORK
194  std::cout << " " << pair.first->getID() << " -> " << targetPair.first->getID() << "\n";
195  std::cout << " " << targetPair.second->getID() << " -> " << pair.second->getID() << "\n";
196 #endif
197  }
198  }
199  if (edge->isWalkingArea()) {
200  continue;
201  }
202  // build connections from depart connector
203  PedestrianEdge* startConnector = getDepartEdge(edge);
204  startConnector->myFollowingEdges.push_back(pair.first);
205  startConnector->myFollowingEdges.push_back(pair.second);
206  // build connections to arrival connector
207  PedestrianEdge* endConnector = getArrivalEdge(edge);
208  pair.first->myFollowingEdges.push_back(endConnector);
209  pair.second->myFollowingEdges.push_back(endConnector);
210 #ifdef PedestrianRouter_DEBUG_NETWORK
211  std::cout << " " << startConnector->getID() << " -> " << pair.first->getID() << "\n";
212  std::cout << " " << startConnector->getID() << " -> " << pair.second->getID() << "\n";
213  std::cout << " " << pair.first->getID() << " -> " << endConnector->getID() << "\n";
214  std::cout << " " << pair.second->getID() << " -> " << endConnector->getID() << "\n";
215 #endif
216  }
217  }
218 
219  bool includeInRoute(bool allEdges) const {
220  return !myAmConnector && (allEdges || (!myEdge->isCrossing() && !myEdge->isWalkingArea()));
221  }
222 
223  const E* getEdge() const {
224  return myEdge;
225  }
226 
228  static const EdgePair& getBothDirections(const E* e) {
229  typename std::map<const E*, EdgePair>::const_iterator it = myBidiLookup.find(e);
230  if (it == myBidiLookup.end()) {
231  assert(false);
232  throw ProcessError("Edge '" + e->getID() + "' not found in pedestrian network '");
233  }
234  return (*it).second;
235  }
236 
238  static PedestrianEdge* getDepartEdge(const E* e) {
239  typename std::map<const E*, EdgePair>::const_iterator it = myFromToLookup.find(e);
240  if (it == myFromToLookup.end()) {
241  assert(false);
242  throw ProcessError("Edge '" + e->getID() + "' not found in pedestrian network '");
243  }
244  return (*it).second.first;
245  }
246 
248  static PedestrianEdge* getArrivalEdge(const E* e) {
249  typename std::map<const E*, EdgePair>::const_iterator it = myFromToLookup.find(e);
250  if (it == myFromToLookup.end()) {
251  assert(false);
252  throw ProcessError("Edge '" + e->getID() + "' not found in pedestrian network '");
253  }
254  return (*it).second.second;
255  }
256 
259 
260  unsigned int getNumericalID() const {
261  return myNumericalID;
262  }
263 
265  static const PedestrianEdge* dictionary(size_t index) {
266  assert(index < myEdgeDict.size());
267  return &myEdgeDict[index];
268  }
269 
270  unsigned int getNumSuccessors() const {
271  return (unsigned int)myFollowingEdges.size();
272  }
273 
274  PedestrianEdge* getSuccessor(unsigned int i) const {
275  return myFollowingEdges[i];
276  }
277 
278  bool prohibits(const PedestrianTrip<E, N>* const trip) const {
279  if (trip->node == 0) {
280  // network only includes PedestrianEdges
281  return false;
282  } else {
283  // limit routing to the surroundings of the specified node
284  return (myEdge->getFromJunction() != trip->node
285  && myEdge->getToJunction() != trip->node);
286  }
287  }
288 
290 
291  /*@brief the function called by RouterTT_direct
292  * (distance is used as effort, effort is assumed to be independent of time
293  */
294  static SUMOReal getEffort(const PedestrianEdge* const edge, const PedestrianTrip<E, N>* const trip, SUMOReal time) {
295  if (edge->myAmConnector) {
296  return 0;
297  }
298  SUMOReal length = edge->myEdge->getLength();
299  if (edge->myEdge == trip->from) {
300  if (edge->myForward) {
301  length -= trip->departPos;
302  } else {
303  length = trip->departPos;
304  }
305  }
306  if (edge->myEdge == trip->to) {
307  if (edge->myForward) {
308  length = trip->arrivalPos;
309  } else {
310  length -= trip->arrivalPos;
311  }
312  }
313  // ensure that 'normal' edges always have a higher weight than connector edges
314  length = MAX2(length, POSITION_EPS);
315  SUMOReal tlsDelay = 0;
316  // @note pedestrian traffic lights should never have LINKSTATE_TL_REDYELLOW
317  if (edge->myEdge->isCrossing() && edge->myLane->getIncomingLinkState() == LINKSTATE_TL_RED) {
318  // red traffic lights occurring later in the route may be green by the time we arive
319  tlsDelay += MAX2(SUMOReal(0), TL_RED_PENALTY - (time - trip->departTime));
320 
321  }
322 #ifdef PedestrianRouter_DEBUG_EFFORTS
323  std::cout << " effort for " << getID() << " at " << time << ": " << length / trip->speed + tlsDelay << " l=" << length << " s=" << trip->speed << " tlsDelay=" << tlsDelay << "\n";
324 #endif
325  return length / trip->speed + tlsDelay;
326  }
327 
328 private:
329  PedestrianEdge(unsigned int numericalID, const E* edge, const L* lane, bool forward, bool connector = false) :
330  Named(edge->getID() + (edge->isWalkingArea() ? "" :
331  ((forward ? "_fwd" : "_bwd") + std::string(connector ? "_connector" : "")))),
332  myNumericalID(numericalID),
333  myEdge(edge),
334  myLane(lane),
335  myForward(forward),
336  myAmConnector(connector) { }
337 
339  unsigned int myNumericalID;
340 
342  const E* myEdge;
343 
345  const L* myLane;
346 
348  bool myForward;
349 
352 
354  std::vector<PedestrianEdge*> myFollowingEdges;
355 
357  static std::vector<PedestrianEdge> myEdgeDict;
358 
360  static std::map<const E*, EdgePair> myBidiLookup;
361 
363  static std::map<const E*, EdgePair> myFromToLookup;
364 
365 };
366 
367 
372 template<class E, class L, class N, class INTERNALROUTER>
373 class PedestrianRouter : public SUMOAbstractRouter<E, PedestrianTrip<E, N> > {
374 public:
375 
378 
381  SUMOAbstractRouter<E, _PedestrianTrip>(0, "PedestrianRouter") {
384  }
385 
387  virtual ~PedestrianRouter() {
388  delete myInternalRouter;
389  }
390 
393  }
394 
397  void compute(const E* from, const E* to, SUMOReal departPos, SUMOReal arrivalPos, SUMOReal speed,
398  SUMOTime msTime, const N* onlyNode, std::vector<const E*>& into, bool allEdges = false) {
399  //startQuery();
400  _PedestrianTrip trip(from, to, departPos, arrivalPos, speed, msTime, onlyNode);
401  std::vector<const _PedestrianEdge*> intoPed;
403  _PedestrianEdge::getArrivalEdge(to), &trip, msTime, intoPed);
404  for (size_t i = 0; i < intoPed.size(); ++i) {
405  if (intoPed[i]->includeInRoute(allEdges)) {
406  into.push_back(intoPed[i]->getEdge());
407  }
408  }
409 #ifdef PedestrianRouter_DEBUG_ROUTES
410  std::cout << TIME2STEPS(msTime) << " trip from " << from->getID() << " to " << to->getID()
411  << " departPos=" << departPos
412  << " arrivalPos=" << arrivalPos
413  << " onlyNode=" << (onlyNode == 0 ? "NULL" : onlyNode->getID())
414  << " edges=" << toString(intoPed)
415  << " resultEdges=" << toString(into)
416  << "\n";
417 #endif
418  //endQuery();
419  }
420 
423  void compute(const E*, const E*, const _PedestrianTrip* const,
424  SUMOTime, std::vector<const E*>&) {
425  throw ProcessError("Do not use this method");
426  }
427 
428  SUMOReal recomputeCosts(const std::vector<const E*>&, const _PedestrianTrip* const, SUMOTime) const {
429  throw ProcessError("Do not use this method");
430  }
431 
432  void prohibit(const std::vector<E*>& toProhibit) {
433  std::vector<_PedestrianEdge*> toProhibitPE;
434  for (typename std::vector<E*>::const_iterator it = toProhibit.begin(); it != toProhibit.end(); ++it) {
435  toProhibitPE.push_back(_PedestrianEdge::getBothDirections(*it).first);
436  toProhibitPE.push_back(_PedestrianEdge::getBothDirections(*it).second);
437  }
438  myInternalRouter->prohibit(toProhibitPE);
439  }
440 
441 private:
442  INTERNALROUTER* myInternalRouter;
443 
444 
445 private:
448 
449 private:
450 
451 };
452 
453 // common specializations
454 template<class E, class L, class N>
456  DijkstraRouterTT<PedestrianEdge<E, L, N>, PedestrianTrip<E, N>, prohibited_withRestrictions<PedestrianEdge<E, L, N>, PedestrianTrip<E, N> > > > { };
457 
458 
459 // ===========================================================================
460 // static member definitions (PedestrianEdge)
461 // ===========================================================================
462 
463 template<class E, class L, class N>
464 std::vector<PedestrianEdge<E, L, N> > PedestrianEdge<E, L, N>::myEdgeDict;
465 
466 template<class E, class L, class N>
467 std::map<const E*, typename PedestrianEdge<E, L, N>::EdgePair> PedestrianEdge<E, L, N>::myBidiLookup;
468 
469 template<class E, class L, class N>
470 std::map<const E*, typename PedestrianEdge<E, L, N>::EdgePair> PedestrianEdge<E, L, N>::myFromToLookup;
471 
472 #endif
473 
474 
475 /****************************************************************************/
476 
PedestrianRouter()
Constructor.
is a pedestrian
const L * getSidewalk(const E *edge)
INTERNALROUTER * myInternalRouter
static const EdgePair & getBothDirections(const E *e)
Returns the pair of forward and backward edge.
PedestrianTrip(const E *_from, const E *_to, SUMOReal _departPos, SUMOReal _arrivalPos, SUMOReal _speed, SUMOReal _departTime, const N *_node)
const SUMOReal departPos
void compute(const E *, const E *, const _PedestrianTrip *const, SUMOTime, std::vector< const E * > &)
Builds the route between the given edges using the minimum effort at the given time The definition of...
static PedestrianEdge * getDepartEdge(const E *e)
Returns the departing Pedestrian edge.
bool includeInRoute(bool allEdges) const
std::string getID() const
the &quot;vehicle&quot; type that is given to the internal router (SUMOAbstractRouter)
T MAX2(T a, T b)
Definition: StdDefs.h:74
std::pair< PedestrianEdge *, PedestrianEdge * > EdgePair
std::vector< PedestrianEdge * > myFollowingEdges
List of edges that may be approached from this edge.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
static std::vector< PedestrianEdge > myEdgeDict
the edge dictionary
bool myForward
the direction of this edge
static PedestrianEdge * getArrivalEdge(const E *e)
Returns the arriving Pedestrian edge.
PedestrianTrip & operator=(const PedestrianTrip &)
Invalidated assignment operator.
static void cleanup()
const E * myEdge
the original edge
const std::string & getID() const
Returns the id.
Definition: Named.h:60
void compute(const E *from, const E *to, SUMOReal departPos, SUMOReal arrivalPos, SUMOReal speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
unsigned int getNumSuccessors() const
const E * getEdge() const
bool myAmConnector
the direction of this edge
const SUMOReal departTime
#define TL_RED_PENALTY
bool prohibits(const PedestrianTrip< E, N > *const trip) const
#define POSITION_EPS
Definition: config.h:189
PedestrianTrip< E, N > _PedestrianTrip
const SUMOReal arrivalPos
const L * myLane
the original edge
PedestrianEdge< E, L, N > _PedestrianEdge
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
Base class for objects which have an id.
Definition: Named.h:45
unsigned int getNumericalID() const
void prohibit(const std::vector< E * > &toProhibit)
static const PedestrianEdge * dictionary(size_t index)
Returns the PedstrianEdge with the given numericalID.
PedestrianEdge * getSuccessor(unsigned int i) const
PedestrianEdge(unsigned int numericalID, const E *edge, const L *lane, bool forward, bool connector=false)
The link has red light (must brake)
static size_t dictSize()
int SUMOTime
Definition: SUMOTime.h:43
static std::map< const E *, EdgePair > myBidiLookup
retrieve the forward and backward edge for the given input edge E
#define SUMOReal
Definition: config.h:218
the edge type that is given to the internal router (SUMOAbstractRouter)
PedestrianRouter & operator=(const PedestrianRouter &s)
Invalidated assignment operator.
const SUMOReal speed
virtual SUMOAbstractRouter< E, PedestrianTrip< E, N > > * clone() const
static SUMOReal getEffort(const PedestrianEdge *const edge, const PedestrianTrip< E, N > *const trip, SUMOReal time)
unsigned int myNumericalID
the index in myEdgeDict
SUMOReal recomputeCosts(const std::vector< const E * > &, const _PedestrianTrip *const, SUMOTime) const
virtual ~PedestrianRouter()
Destructor.
static void initPedestrianNetwork(size_t noE)
static std::map< const E *, EdgePair > myFromToLookup
retrieve the depart and arrival edge for the given input edge E