66template<
class E,
class V>
81 const bool havePermissions =
false,
const bool haveRestrictions =
false,
double maxTrainLength = 5000) :
82 SUMOAbstractRouter<E, V>(
"RailwayRouter", unbuildIsWarning, effortOperation, ttOperation, havePermissions, haveRestrictions),
86 for (
const E*
const edge : edges) {
102 bool compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent =
false) {
105 WRITE_WARNINGF(
"Vehicle '%' with length % exceeds configured value of --railway.max-train-length %",
108 return _compute(from, to, vehicle, msTime, into, silent,
false);
113 std::vector<_RailEdge*> railEdges;
114 for (E* edge : toProhibit) {
115 railEdges.push_back(edge->getRailwayRoutingEdge());
137 bool _compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent,
bool avoidUnsafeBackTracking) {
139 std::vector<double> backLengths;
140 double backDist = vehicle->getLength() - from->getLength();
141 const E* start = from;
142 while (backDist > 0) {
144 if (prev ==
nullptr) {
148 backDist -= prev->getLength();
149 if (avoidUnsafeBackTracking && prev->getSuccessors().size() > 1) {
150 bool foundSwitch =
false;
151 for (
const E* succ : prev->getSuccessors()) {
152 if (succ != start && succ != prev->getBidiEdge()) {
161 backLengths.push_back(prev->getLength() + (backLengths.empty() ? from->getLength() : backLengths.back()));
165 std::vector<const _RailEdge*> intoTmp;
166 bool success =
myInternalRouter->
compute(start->getRailwayRoutingEdge(), to->getRailwayRoutingEdge(), vehicle, msTime, intoTmp, silent);
167#ifdef RailwayRouter_DEBUG_ROUTES
168 std::cout <<
"RailRouter veh=" << vehicle->getID() <<
" from=" << from->getID() <<
" to=" << to->getID() <<
" t=" <<
time2string(msTime)
169 <<
" safe=" << avoidUnsafeBackTracking <<
" success=" << success <<
" into=" <<
toString(into) <<
"\n";
172 const size_t intoSize = into.size();
173 const int backIndex = (int)backLengths.size() - 1;
174 for (
const _RailEdge* railEdge : intoTmp) {
176 const double length = backIndex >= 0 ? backLengths[backIndex] : vehicle->getLength();
177 railEdge->insertOriginalEdges(length, into);
179#ifdef RailwayRouter_DEBUG_ROUTES
180 std::cout <<
"RailRouter: internal result=" <<
toString(intoTmp) <<
"\n";
181 std::cout <<
"RailRouter: expanded result=" <<
toString(into) <<
"\n";
183 if (backLengths.size() > 0) {
185 into.erase(into.begin() + intoSize, into.begin() + intoSize + backLengths.size());
186#ifdef RailwayRouter_DEBUG_ROUTES
187 std::cout <<
"RailRouter: backLengths=" <<
toString(backLengths) <<
" intoSize=" << intoSize <<
" final result=" <<
toString(into) <<
"\n";
189 if (*(into.begin() + intoSize) != from) {
190 if (!avoidUnsafeBackTracking) {
193 into.erase(into.begin() + intoSize, into.end());
194 return _compute(from, to, vehicle, msTime, into, silent,
true);
196 WRITE_WARNING(
"Railway routing failure due to turn-around on short edge '" + from->getID()
197 +
"' for vehicle '" + vehicle->getID() +
"' time=" +
time2string(msTime) +
".");
211 FXMutexLock locker(myLock);
230 std::vector<const E*> repl;
232 assert(repl.size() > 0);
236 for (
const E* e : repl) {
237 result += (*myStaticOperation)(e, veh, time + result);
238 seenDist += e->getLength();
240 const double lengthOnLastEdge =
MAX2(0.0, veh->getLength() - seenDist);
253 const E* result =
nullptr;
255 for (
const E* cand : edge->getPredecessors()) {
256 if (!cand->isInternal() && cand->getBidiEdge() != edge) {
258 if (result ==
nullptr) {
284 mutable FXMutex myLock;
299template<
class E,
class V>
301template<
class E,
class V>
303template<
class E,
class V>
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Computes the shortest path through a network using the Dijkstra algorithm.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
the edge type representing backward edges
void insertOriginalEdges(double length, std::vector< const E * > &into) const
const E * getOriginal() const
Returns the original edge.
SUMOAbstractRouter< _RailEdge, V > _InternalRouter
static const E * getStraightPredecessor(const E *edge)
static double myReversalPenaltyFactor
RailwayRouter< E, V > *const myOriginal
RailwayRouter(RailwayRouter *other)
DijkstraRouter< _RailEdge, V > _InternalDijkstra
std::vector< _RailEdge * > myInitialEdges
a RailEdge for every existing edge, filled on construction (but not in clones)
RailwayRouter & operator=(const RailwayRouter &s)
Invalidated assignment operator.
std::vector< _RailEdge * > myRailEdges
complete rail network filled on demand (but not in clones)
const bool mySilent
whether to suppress warning/error if no route was found
bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
RailwayRouter(const std::vector< E * > &edges, bool unbuildIsWarning, typename SUMOAbstractRouter< E, V >::Operation effortOperation, typename SUMOAbstractRouter< E, V >::Operation ttOperation=nullptr, bool silent=false, const bool havePermissions=false, const bool haveRestrictions=false, double maxTrainLength=5000)
Constructor.
_InternalRouter * myInternalRouter
static SUMOAbstractRouter< E, V >::Operation myStaticOperation
The object's operation to perform. (hack)
const double myMaxTrainLength
bool _compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent, bool avoidUnsafeBackTracking)
void ensureInternalRouter()
const std::vector< _RailEdge * > & getRailEdges()
RailEdge< E, V > _RailEdge
static double myReversalPenalty
static double getTravelTimeStatic(const RailEdge< E, V > *const edge, const V *const veh, double time)
SUMOAbstractRouter< E, V > * clone()
virtual ~RailwayRouter()
Destructor.
void prohibit(const std::vector< E * > &toProhibit)
MsgHandler *const myErrorMsgHandler
the handler for routing errors
const bool myHavePermissions
whether edge permissions need to be considered
virtual void prohibit(const std::vector< E * > &toProhibit)
const bool myHaveRestrictions
whether edge restrictions need to be considered
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...