66template<
class E,
class V>
82 bool havePermissions =
false,
const bool haveRestrictions =
false,
double maxTrainLength = 5000,
83 double reversalPenalty = 60) :
84 SUMOAbstractRouter<E, V>(
"RailwayRouter", unbuildIsWarning, effortOperation, ttOperation, havePermissions, haveRestrictions),
90 for (
const E*
const edge : edges) {
106 bool compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent =
false) {
109 WRITE_WARNINGF(
"Vehicle '%' with length % exceeds configured value of --railway.max-train-length %",
112 return _compute(from, to, vehicle, msTime, into, silent,
false);
118 for (
auto item : toProhibit) {
119 _toProhibit[item.first->getRailwayRoutingEdge()] = item.second;
123#ifdef RailwayRouter_DEBUG_ROUTES
124 std::cout <<
"RailRouter numProhibitions=" << toProhibit.size() <<
"\n";
129 double recomputeCosts(
const std::vector<const E*>& edges,
const V*
const v,
SUMOTime msTime,
double* lengthp =
nullptr)
const {
131 const E* prev =
nullptr;
134 for (
const E*
const e : edges) {
135 if (prev !=
nullptr && e->getBidiEdge() == prev) {
136 if (e->getLength() > v->getLength()) {
139 const double savingsFactor = 1 - v->getLength() / e->getLength();
140 double effortCorrection = 0;
141 double lengthCorrection = 0.;
142 effortCorrection += this->
getEffort(prev, v, timeCorrection);
143 this->
updateViaCost(prev, e, v, timeCorrection, effortCorrection, lengthCorrection);
144 effort -= savingsFactor * effortCorrection;
145 if (lengthp !=
nullptr) {
146 *lengthp -= savingsFactor * lengthCorrection;
178 bool _compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent,
bool avoidUnsafeBackTracking) {
181 std::vector<double> backLengths;
182 double backDist =
myReversalPenalty >= 0 ? vehicle->getLength() - from->getLength() : 0;
183 const E* start = from;
184 while (backDist > 0) {
186 if (prev ==
nullptr) {
187#ifdef RailwayRouter_DEBUG_ROUTES
188 std::cout <<
" Could not determine back edge for vehicle '" << vehicle->getID() <<
"' when routing from edge '" << from->getID() <<
"' at time=" <<
time2string(msTime) <<
"\n";
193 backDist -= prev->getLength();
194 if (avoidUnsafeBackTracking && prev->getSuccessors().size() > 1) {
195 bool foundSwitch =
false;
196 for (
const E* succ : prev->getSuccessors()) {
197 if (succ != start && succ != prev->getBidiEdge()) {
206 backLengths.push_back(prev->getLength() + (backLengths.empty()
207 ?
MIN2(vehicle->getLength(), from->getLength())
208 : backLengths.back()));
212 std::vector<const _RailEdge*> intoTmp;
216 bool success =
myInternalRouter->compute(start->getRailwayRoutingEdge(), to->getRailwayRoutingEdge(), vehicle, msTime, intoTmp, silent);
218#ifdef RailwayRouter_DEBUG_ROUTES
219 std::cout <<
"RailRouter veh=" << vehicle->getID() <<
" from=" << from->getID() <<
" to=" << to->getID() <<
" t=" <<
time2string(msTime)
220 <<
" safe=" << avoidUnsafeBackTracking <<
" success=" << success <<
" into=" <<
toString(into) <<
"\n";
223 const size_t intoSize = into.size();
224 int backIndex = (int)backLengths.size();
225 for (
const _RailEdge* railEdge : intoTmp) {
226 if (railEdge->getOriginal() !=
nullptr) {
230 const double length = backIndex >= 0 ? backLengths[backIndex] : vehicle->getLength();
231 railEdge->insertOriginalEdges(length, into);
233#ifdef RailwayRouter_DEBUG_ROUTES
234 std::cout <<
"RailRouter: internal result=" <<
toString(intoTmp) <<
"\n";
235 std::cout <<
"RailRouter: expanded result=" <<
toString(into) <<
"\n";
236 std::cout <<
"RailRouter: backLengths=" <<
toString(backLengths) <<
" bls=" << backLengths.size() <<
" intoSize=" << intoSize <<
" final result=" <<
toString(into) <<
"\n";
238 if (backLengths.size() > 0) {
240 into.erase(into.begin() + intoSize, into.begin() + intoSize + backLengths.size());
241 if (*(into.begin() + intoSize) != from) {
242 if (!avoidUnsafeBackTracking) {
245 into.erase(into.begin() + intoSize, into.end());
247 success =
_compute(from, to, vehicle, msTime, into, silent,
true);
250 WRITE_WARNING(
"Railway routing failure due to turn-around on short edge '" + from->getID()
251 +
"' for vehicle '" + vehicle->getID() +
"' time=" +
time2string(msTime) +
".");
257 for (
const E* e : into) {
258 if (this->
myProhibited.find(e) != this->myProhibited.end()) {
275 FXMutexLock locker(
myLock);
294 std::vector<const E*> repl;
296 assert(repl.size() > 0);
300 for (
const E* e : repl) {
301 result += (*myStaticOperation)(e, veh, time + result);
302 seenDist += e->getLength();
304 const double lengthOnLastEdge =
MAX2(0.0, veh->getLength() - seenDist);
319 const E* result =
nullptr;
320#ifdef RailwayRouter_DEBUG_ROUTES
321 std::cout <<
" getStraightPredecessor edge=" << edge->getID() <<
" prevRouteSize=" << prevRoute.size() <<
" backIndex=" << backIndex <<
"\n";
323 if ((
int)prevRoute.size() > backIndex) {
324 return prevRoute[(int)prevRoute.size() - 1 - backIndex];
326 for (
const E* cand : edge->getPredecessors()) {
327 if (!cand->isInternal() && cand->getBidiEdge() != edge) {
329 if (result ==
nullptr) {
373template<
class E,
class V>
375template<
class E,
class V>
377template<
class E,
class V>
template FXMutex GLObjectValuePassConnector< double >::myLock
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
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 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)
void prohibit(const Prohibitions &toProhibit)
void setBulkMode(const bool mode)
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
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...
_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 const E * getStraightPredecessor(const E *edge, std::vector< const E * > &prevRoute, int backIndex)
static double getTravelTimeStatic(const RailEdge< E, V > *const edge, const V *const veh, double time)
SUMOAbstractRouter< E, V > * clone()
std::map< const E *, RouterProhibition > Prohibitions
const E * myLastFrom
track previous edge for correct bulk routing
virtual ~RailwayRouter()
Destructor.
RailwayRouter(const std::vector< E * > &edges, bool unbuildIsWarning, typename SUMOAbstractRouter< E, V >::Operation effortOperation, typename SUMOAbstractRouter< E, V >::Operation ttOperation=nullptr, bool silent=false, bool havePermissions=false, const bool haveRestrictions=false, double maxTrainLength=5000, double reversalPenalty=60)
Constructor.
const bool myHavePermissions
whether edge permissions need to be considered
std::map< const _RailEdge *, RouterProhibition > Prohibitions
double(* Operation)(const E *const, const V *const, double)
Type of the function that is used to retrieve the edge effort.
void updateViaCost(const E *const prev, const E *const e, const V *const v, double &time, double &effort, double &length) const
double getEffort(const E *const e, const V *const v, double t) const
SUMOAbstractRouter(const std::string &type, bool unbuildIsWarning, Operation operation, Operation ttOperation, const bool havePermissions, const bool haveRestrictions)
Constructor.
Prohibitions myProhibited
The list of explicitly prohibited edges and estimated end time of prohibition.
const bool myHaveRestrictions
whether edge restrictions need to be considered
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
MsgHandler * myErrorMsgHandler
the handler for routing errors