Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 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 : /****************************************************************************/
14 : /// @file PedestrianEdge.h
15 : /// @author Jakob Erdmann
16 : /// @author Michael Behrisch
17 : /// @author Robert Hilbrich
18 : /// @date Mon, 03 March 2014
19 : ///
20 : // The pedestrian accessible edges for the Intermodal Router
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #define TL_RED_PENALTY 20
26 :
27 : //#define IntermodalRouter_DEBUG_EFFORTS
28 :
29 :
30 : // ===========================================================================
31 : // class definitions
32 : // ===========================================================================
33 : /// @brief the pedestrian edge type that is given to the internal router (SUMOAbstractRouter)
34 : template<class E, class L, class N, class V>
35 : class PedestrianEdge : public IntermodalEdge<E, L, N, V> {
36 : public:
37 1030347 : PedestrianEdge(int numericalID, const E* edge, const L* lane, bool forward, const double pos = -1.) :
38 : IntermodalEdge<E, L, N, V>(edge->getID() + (edge->isWalkingArea() ? "" : (forward ? "_fwd" : "_bwd")) + toString(pos), numericalID, edge, "!ped"),
39 1030347 : myLane(lane),
40 1030347 : myForward(forward),
41 979689 : myStartPos(pos >= 0 ? pos : (forward ? 0. : edge->getLength())),
42 2523819 : myIsOpposite(false) {
43 1030347 : if (!forward && (
44 : edge->getFunction() == SumoXMLEdgeFunc::NORMAL
45 229969 : || edge->getFunction() == SumoXMLEdgeFunc::INTERNAL)) {
46 226793 : const L* sidewalk = getSidewalk<E, L>(edge);
47 435869 : if (sidewalk != nullptr && sidewalk->getPermissions() != SVC_PEDESTRIAN) {
48 : // some non-pedestrian traffic is allowed
49 299663 : myIsOpposite = true;
50 : }
51 : }
52 1030347 : }
53 :
54 4353946 : bool includeInRoute(bool allEdges) const {
55 4353946 : return allEdges || (!this->getEdge()->isCrossing() && !this->getEdge()->isWalkingArea() && !this->getEdge()->isInternal());
56 : }
57 :
58 26367385 : bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
59 26367385 : if (trip->node == 0) {
60 : // network only includes IntermodalEdges
61 : return false;
62 : } else {
63 : // limit routing to the surroundings of the specified node
64 : return (this->getEdge()->getFromJunction() != trip->node
65 13314165 : && this->getEdge()->getToJunction() != trip->node);
66 : }
67 : }
68 :
69 23217268 : double getPartialLength(const IntermodalTrip<E, N, V>* const trip) const {
70 : double length = this->getLength();
71 23217268 : if (this->getEdge() == trip->from && !myForward && trip->departPos < myStartPos) {
72 283548 : length = trip->departPos - (myStartPos - this->getLength());
73 : }
74 23217268 : if (this->getEdge() == trip->to && myForward && trip->arrivalPos < myStartPos + this->getLength()) {
75 2113492 : length = trip->arrivalPos - myStartPos;
76 : }
77 23217268 : if (this->getEdge() == trip->from && myForward && trip->departPos > myStartPos) {
78 298464 : length -= (trip->departPos - myStartPos);
79 : }
80 23217268 : if (this->getEdge() == trip->to && !myForward && trip->arrivalPos > myStartPos - this->getLength()) {
81 784411 : length -= (trip->arrivalPos - (myStartPos - this->getLength()));
82 : }
83 : // ensure that 'normal' edges always have a higher weight than connector edges
84 : length = MAX2(length, NUMERICAL_EPS);
85 23217268 : return length;
86 : }
87 :
88 21795596 : double getTravelTime(const IntermodalTrip<E, N, V>* const trip, double time) const {
89 21795596 : const double length = getPartialLength(trip);
90 : double tlsDelay = 0;
91 : // @note pedestrian traffic lights should never have LINKSTATE_TL_REDYELLOW
92 21795596 : if (this->getEdge()->isCrossing()) {
93 4088343 : double timeToCrossing = (time - STEPS2TIME(trip->departTime));
94 4088343 : if (myLane->getIncomingLinkState() == LINKSTATE_TL_RED) {
95 : // red traffic lights occurring later in the route may be green by the time we arrive
96 4348264 : tlsDelay += MAX2(double(0), TL_RED_PENALTY - timeToCrossing);
97 1154763 : } else if (myLane->getIncomingLinkState() == LINKSTATE_TL_GREEN_MAJOR && timeToCrossing > TL_RED_PENALTY / 2) {
98 : // green traffic lights occurring later in the route may be red by the time we arrive
99 : tlsDelay += TL_RED_PENALTY;
100 : }
101 4565712 : tlsDelay += this->getEdge()->getTimePenalty();
102 : }
103 : #ifdef IntermodalRouter_DEBUG_EFFORTS
104 : std::cout << " effort for " << trip->getID() << " at " << time << " edge=" << this->getID() << " effort=" << length / trip->speed + tlsDelay << " l=" << length << " fullLength=" << this->getLength() << " s=" << trip->speed << " tlsDelay=" << tlsDelay << "\n";
105 : #endif
106 21795596 : return length / (trip->speed * (myIsOpposite ? gWeightsWalkOppositeFactor : 1)) + tlsDelay;
107 : }
108 :
109 214107 : double getStartPos() const {
110 214107 : return myStartPos;
111 : }
112 :
113 561424 : double getEndPos() const {
114 561424 : return myForward ? myStartPos + this->getLength() : myStartPos - this->getLength();
115 : }
116 :
117 : private:
118 : /// @brief the original edge
119 : const L* myLane;
120 :
121 : /// @brief the direction of this edge
122 : const bool myForward;
123 :
124 : /// @brief the starting position for split edges
125 : const double myStartPos;
126 :
127 : /// @brief whether this edge goes against the flow of traffic
128 : bool myIsOpposite;
129 :
130 : };
|