Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/router/FlippedEdge.h
169678 views
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 FlippedEdge.h
15
/// @author Ruediger Ebendt
16
/// @date 01.12.2023
17
///
18
// Extension of ReversedEdge, which is a wrapper around a ROEdge
19
// or an MSEdge used for backward search. In contrast to reversed
20
// edges, flipped edges have flipped nodes instead of standard nodes.
21
// Introduced for the arc flag router.
22
/****************************************************************************/
23
#pragma once
24
#include <config.h>
25
#include <utils/common/SUMOVehicleClass.h>
26
#ifdef HAVE_FOX
27
#include <utils/foxtools/MsgHandlerSynchronized.h>
28
#endif
29
#include "ReversedEdge.h"
30
31
32
// ===========================================================================
33
// class declarations
34
// ===========================================================================
35
template<class E, class N, class V>
36
class FlippedNode;
37
38
// ===========================================================================
39
// class definitions
40
// ===========================================================================
41
/// @brief The edge type representing backward edges with flipped nodes
42
template<class E, class N, class V>
43
class FlippedEdge : public ReversedEdge<E, V> {
44
public:
45
46
typedef std::vector<std::pair<const FlippedEdge<E, N, V>*, const FlippedEdge<E, N, V>*> > ConstFlippedEdgePairVector;
47
48
/** @brief Constructor
49
* @param[in] originalEdge The original (forward) edge
50
*/
51
FlippedEdge(const E* originalEdge) :
52
ReversedEdge<E, V>(originalEdge),
53
myFromJunction(originalEdge->getToJunction()->getFlippedRoutingNode()),
54
myToJunction(originalEdge->getFromJunction()->getFlippedRoutingNode())
55
{}
56
57
/// @brief Destructor
58
~FlippedEdge() {}
59
60
/// @brief Initialize the flipped edge
61
void init();
62
63
/// @brief Returns the from-junction
64
const FlippedNode<E, N, V>* getFromJunction() const {
65
return myFromJunction;
66
}
67
68
/// @brief Returns the to-junction
69
const FlippedNode<E, N, V>* getToJunction() const {
70
return myToJunction;
71
}
72
73
/** @brief Returns the time for travelling on the given edge with the given vehicle at the given time
74
* @param[in] edge The edge
75
* @param[in] veh The vehicle
76
* @param[in] time The time
77
* @return The time for travelling on the given edge with the given vehicle at the given time
78
*/
79
static double getTravelTimeStatic(const FlippedEdge<E, N, V>* const edge, const V* const veh, double time) {
80
return edge->getOriginalEdge()->getTravelTime(veh, time);
81
}
82
83
/** @brief Returns the randomized time for travelling on the given edge with the given vehicle at the given time
84
* @param[in] edge The edge
85
* @param[in] veh The vehicle
86
* @param[in] time The time
87
* @return The randomized time for travelling on the given edge with the given vehicle at the given time
88
*/
89
static double getTravelTimeStaticRandomized(const FlippedEdge<E, N, V>* const edge, const V* const veh, double time) {
90
return edge->getOriginalEdge()->getTravelTimeStaticRandomized(edge->getOriginalEdge(), veh, time);
91
}
92
93
/** @brief Returns the via successors
94
* @param[in] vClass The vehicle class
95
* @param[in] ignoreTransientPermissions Unused parameter
96
* @return The via successors
97
*/
98
const ConstFlippedEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
99
UNUSED_PARAMETER(ignoreTransientPermissions); // @todo this should be changed (somewhat hidden by #14756)
100
if (vClass == SVC_IGNORING || this->getOriginalEdge()->isTazConnector()) { // || !MSNet::getInstance()->hasPermissions()) {
101
return myViaSuccessors;
102
}
103
#ifdef HAVE_FOX
104
FXMutexLock lock(mySuccessorMutex);
105
#endif
106
auto i = myClassesViaSuccessorMap.find(vClass);
107
if (i != myClassesViaSuccessorMap.end()) {
108
// can use cached value
109
return i->second;
110
}
111
// instantiate vector
112
ConstFlippedEdgePairVector& result = myClassesViaSuccessorMap[vClass];
113
// this vClass is requested for the first time. rebuild all successors
114
for (const auto& viaPair : myViaSuccessors) {
115
if (viaPair.first->getOriginalEdge()->isTazConnector()
116
|| viaPair.first->getOriginalEdge()->isConnectedTo(*(this->getOriginalEdge()), vClass)) {
117
result.push_back(viaPair);
118
}
119
}
120
return result;
121
}
122
123
/** @brief Returns the bidirectional edge
124
* @return The bidirectional edge
125
*/
126
const FlippedEdge<E, N, V>* getBidiEdge() const {
127
return this->getOriginalEdge()->getBidiEdge()->getFlippedRoutingEdge();
128
}
129
130
/** @brief Returns the distance to another flipped edge
131
* param[in] other The other flipped edge
132
* param[in] doBoundaryEstimate The boolean flag indicating whether the distance is estimated using both boundaries or not
133
* @return The distance to another flipped edge
134
*/
135
double getDistanceTo(const FlippedEdge<E, N, V>* other, const bool doBoundaryEstimate = false) const {
136
return this->getOriginalEdge()->getDistanceTo(other->getOriginalEdge(), doBoundaryEstimate);
137
}
138
139
/** @brief Returns the minimum travel time
140
* @param[in] veh The vehicle
141
* @return The minimum travel time
142
*/
143
double getMinimumTravelTime(const V* const veh) const {
144
return this->getOriginalEdge()->getMinimumTravelTime(veh);
145
}
146
147
/** @brief Returns the time penalty
148
* @return The time penalty
149
*/
150
double getTimePenalty() const {
151
return this->getOriginalEdge()->getTimePenalty();
152
}
153
154
/** @brief Returns a boolean flag indicating whether this edge has loaded travel times or not
155
* @return true iff this edge has loaded travel times
156
*/
157
bool hasLoadedTravelTimes() const {
158
return this->getOriginalEdge()->hasLoadedTravelTimes();
159
}
160
161
/** @brief Returns the speed allowed on this edge
162
* @return The speed allowed on this edge
163
*/
164
double getSpeedLimit() const {
165
return this->getOriginalEdge()->getSpeedLimit();
166
}
167
168
/** @brief Returns a lower bound on shape.length() / myLength
169
* @note The bound is sufficient for the astar air-distance heuristic
170
* @return A lower bound on shape.length() / myLength
171
*/
172
double getLengthGeometryFactor() const {
173
return this->getOriginalEdge()->getLengthGeometryFactor();
174
}
175
176
/** @brief Returns the edge priority (road class)
177
* @return The edge priority (road class)
178
*/
179
int getPriority() const {
180
return this->getOriginalEdge()->getPriority();
181
}
182
183
protected:
184
/// @brief The junctions for this edge
185
FlippedNode<E, N, V>* myFromJunction;
186
FlippedNode<E, N, V>* myToJunction;
187
188
private:
189
/// @brief The successors available for a given vClass
190
mutable std::map<SUMOVehicleClass, ConstFlippedEdgePairVector> myClassesViaSuccessorMap;
191
mutable ConstFlippedEdgePairVector myViaSuccessors;
192
193
#ifdef HAVE_FOX
194
/// @brief Mutex for accessing successor edges
195
mutable FXMutex mySuccessorMutex;
196
#endif
197
};
198
199
// ===========================================================================
200
// method definitions
201
// ===========================================================================
202
203
template<class E, class N, class V>
204
void FlippedEdge<E, N, V>::init() {
205
if (!this->getOriginalEdge()->isInternal()) {
206
for (const auto& viaPair : this->getOriginalEdge()->getViaSuccessors()) {
207
const FlippedEdge<E, N, V>* revSource = viaPair.first->getFlippedRoutingEdge();
208
const E* via = viaPair.second;
209
const FlippedEdge<E, N, V>* preVia = nullptr;
210
while (via != nullptr && via->isInternal()) {
211
via->getFlippedRoutingEdge()->myViaSuccessors.push_back(std::make_pair(this, preVia));
212
preVia = via->getFlippedRoutingEdge();
213
via = via->getViaSuccessors().front().second;
214
}
215
revSource->myViaSuccessors.push_back(std::make_pair(this, preVia));
216
}
217
}
218
}
219
220