52 const bool tryRepair,
const bool mayBeDisconnected) :
54 myPrecomputed(nullptr), myLastUsed(lastUsed), myTryRepair(tryRepair),
55 myMayBeDisconnected(mayBeDisconnected),
56 myDiscardSilent(false) {
67std::shared_ptr<RORoute>
97 const bool ignoreErrors = oc.
getBool(
"ignore-errors");
104 mh->
inform(
"Vehicle '" + veh.
getID() +
"' is not allowed to depart on edge '" +
107 }
else if (
myAlternatives[0]->getLast()->prohibits(&veh, hasRestrictions) && (!oc.
getBool(
"repair.to")
112 mh->
inform(
"Vehicle '" + veh.
getID() +
"' is not allowed to arrive on edge '" +
116 const bool skipTripRouting = (oc.
exists(
"write-trips") && oc.
getBool(
"write-trips")
144 if (edges.front()->isTazConnector()) {
145 edges.erase(edges.begin());
147 if (edges.back()->isTazConnector()) {
178 const int initialSize = (int)oldEdges.size();
186 if (initialSize == 1) {
189 bool ok = router.
compute(oldEdges.front(),
nullptr, &veh, begin, newEdges);
195 if (oldEdges.front()->prohibits(&veh, hasRestrictions)) {
197 const std::string& frontID = oldEdges.front()->getID();
198 for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
199 if ((*i)->prohibits(&veh, hasRestrictions) || (*i)->isInternal()) {
200 i = oldEdges.erase(i);
203 +
"' to '" + (*i)->getID() +
"' for vehicle '" + veh.
getID() +
"'.");
208 if (oldEdges.size() == 0) {
209 mh->
inform(
"Could not find new starting edge for vehicle '" + veh.
getID() +
"'.");
212 if (oldEdges.back()->prohibits(&veh, hasRestrictions)) {
214 const std::string& backID = oldEdges.back()->getID();
216 while (oldEdges.back()->prohibits(&veh, hasRestrictions) || oldEdges.back()->isInternal()) {
220 +
"' to edge '" + oldEdges.back()->getID() +
"' for vehicle '" + veh.
getID() +
"'.");
222 std::vector<ROVehicle::Mandatory> mandatory = veh.
getMandatoryEdges(oldEdges.front(), oldEdges.back());
223 assert(mandatory.size() >= 2);
225 for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
226 if ((*i)->prohibits(&veh, hasRestrictions) || (*i)->isInternal()) {
228 WRITE_MESSAGEF(
TL(
"Removing invalid edge '%' from route for vehicle '%'."), (*i)->getID(), veh.
getID());
229 i = oldEdges.erase(i);
235 if (mandatory.size() > oldEdges.size() && initialSize > 2) {
236 WRITE_MESSAGEF(
TL(
"There are stop edges which were not part of the original route for vehicle '%'."), veh.
getID());
239 bool checkPositions =
false;
240 if (mandatory.size() >= oldEdges.size()) {
241 for (
auto m : mandatory) {
242 targets.push_back(m.edge);
243 checkPositions |= m.pos >= 0;
248 newEdges.push_back(targets.front());
249 auto nextMandatory = mandatory.begin() + 1;
250 int lastMandatory = 0;
251 for (ConstROEdgeVector::const_iterator i = targets.begin() + 1;
252 i != targets.end() && nextMandatory != mandatory.end(); ++i) {
253 const ROEdge* prev = *(i - 1);
256 newEdges.push_back(cur);
258 if (initialSize > 2) {
262 const ROEdge* last = newEdges.back();
266 last = newEdges.back();
269 if (veh.
hasJumps() && (nextMandatory - 1)->isJump) {
270 while (*i != nextMandatory->edge) {
273 newEdges.push_back(last);
274 newEdges.push_back(*i);
277 if (veh.
getID() ==
"10.T0.1-13-P-j26-1.2.H.0") {
278 std::cout <<
" beforeRepair newEdges=" <<
toString(newEdges) <<
" last=" << last->
getID() <<
"\n";
281 int numEdgesBefore = (int)newEdges.size();
283 if (
myTryRepair && lastMandatory < (
int)newEdges.size() && last != newEdges[lastMandatory]) {
288 && mandatory[i - targets.begin() - 1].pos >= 0
289 && mandatory[i - targets.begin()].pos >= 0) {
291 last, mandatory[i - targets.begin() - 1].pos,
292 *i, mandatory[i - targets.begin()].pos,
293 &veh, begin, newEdges);
295 ok = router.
compute(last, *i, &veh, begin, newEdges);
304 if (lastMandatory >= (
int)newEdges.size() || last == newEdges[lastMandatory] || !
backTrack(router, i, lastMandatory, nextMandatory->edge, newEdges, veh, begin)) {
305 mh->
inform(
"Mandatory edge '" + (*i)->getID() +
"' not reachable by vehicle '" + veh.
getID() +
"'.");
310 (*i)->getFromJunction()->getPosition());
311 double repairDist = 0;
312 for (
auto it2 = (newEdges.begin() + numEdgesBefore + 1); it2 != newEdges.end() && it2 != newEdges.end() - 1; it2++) {
313 repairDist += (*it2)->getLength();
315 const double detourFactor = repairDist /
MAX2(airDist, 1.0);
316 const double detour =
MAX2(0.0, repairDist - airDist);
318 if (detourFactor > maxDetourFactor) {
319 WRITE_MESSAGEF(
" Backtracking to avoid detour of %m for gap of %m)", detour, airDist);
320 backTrack(router, i, lastMandatory, nextMandatory->edge, newEdges, veh, begin);
321 }
else if (detourFactor > 1.1) {
322 WRITE_MESSAGEF(
" Taking detour of %m to avoid gap of %m)", detour, airDist);
325 if (veh.
getID() ==
"10.T0.1-13-P-j26-1.2.H.0") {
326 std::cout <<
" at=" << numEdgesBefore <<
" before=" << numEdgesBefore <<
" after=" << newEdges.size() <<
" new=" <<
toString(newEdges) <<
"\n";
330 if (*i == nextMandatory->edge) {
332 lastMandatory = (int)newEdges.size() - 1;
337 auto it = newEdges.begin();
340 it = std::find(it, newEdges.end(), e);
341 if (it == newEdges.end()) {
342 mh->
inform(
"Stop edge '" + e->
getID() +
"' is inconsistent with via edges for vehicle '" + veh.
getID() +
"'.");
354 ConstROEdgeVector::const_iterator& i,
int lastMandatory,
const ROEdge* nextMandatory,
357 bool ok = router.
compute(newEdges[lastMandatory], nextMandatory, &veh, begin, edges,
true);
362 while (*i != nextMandatory) {
365 newEdges.erase(newEdges.begin() + lastMandatory + 1, newEdges.end());
366 std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
371std::shared_ptr<RORoute>
375 std::shared_ptr<RORoute> replaced =
nullptr;
384 double costs = router.
recomputeCosts(current->getEdgeVector(), veh, begin);
390 current->setCosts(costs);
396 throw ProcessError(
"Route '" + current->getID() +
"' (vehicle '" + veh->
getID() +
"') is not valid.");
407 throw ProcessError(
"Route '" + current->getID() +
"' (vehicle '" + veh->
getID() +
"') is not valid.");
410 const double newCosts = router.
recomputeCosts(alt->getEdgeVector(), veh, begin);
413 if (alt == current) {
416 alt->setCosts(newCosts);
419 alt->setProbability(alt->getProbability() * scale);
430 if ((*i)->getProbability() == 0) {
442 return a->getProbability() > b->getProbability();
461 newSum += alt->getProbability();
466 alt->setProbability(alt->getProbability() / newSum);
474 chosen -= alt->getProbability();
499 bool asAlternatives,
bool withExitTimes,
bool withCost,
bool withLength)
const {
500 if (asAlternatives) {
503 myAlternatives[i]->writeXMLDefinition(dev, veh,
true,
true, withExitTimes, withLength);
516 for (
const std::shared_ptr<const RORoute> route :
myAlternatives) {
517 RGBColor* col = route->getColor() !=
nullptr ?
new RGBColor(*route->getColor()) :
nullptr;
518 std::shared_ptr<RORoute> newRoute = std::make_shared<RORoute>(
id, route->getCosts(), route->getProbability(), route->getEdgeVector(), col, route->getStops());
519 newRoute->addStopOffset(stopOffset);
530 sum += r->getProbability();
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_MESSAGE(msg)
std::vector< const ROEdge * > ConstROEdgeVector
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Base class for objects which have an id.
std::string myID
The name of the object.
const std::string & getID() const
Returns the id.
A storage for options typed value containers)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
A basic edge for routing applications.
const ROEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
const RONode * getToJunction() const
bool isTazConnector() const
bool isConnectedTo(const ROEdge &e, const SUMOVehicleClass vClass, bool ignoreTransientPermissions=false) const
returns the information whether this edge is directly connected to the given
The router's network representation.
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
void updateLaneProhibitions(SUMOTime begin)
bool hasProhibitions() const
bool hasParamRestrictions() const
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
const Prohibitions & getProhibitions() const
const Position & getPosition() const
Returns the position of the node.
SUMOVehicleClass getVClass() const
const std::string & getID() const
Returns the id of the routable.
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Base class for a vehicle's route definition.
const ROEdge * getOrigin() const
bool repairCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh, ConstROEdgeVector oldEdges, ConstROEdgeVector &newEdges, bool isTrip=false) const
Builds the complete route (or chooses her from the list of alternatives, when existing)
static bool backTrack(SUMOAbstractRouter< ROEdge, ROVehicle > &router, ConstROEdgeVector::const_iterator &i, int lastMandatory, const ROEdge *nextMandatory, ConstROEdgeVector &newEdges, const ROVehicle &veh, SUMOTime begin)
backtrack to last mandatory edge and route to next mandatory
std::shared_ptr< RORoute > myPrecomputed
precomputed route for out-of-order computation
std::shared_ptr< RORoute > addAlternative(SUMOAbstractRouter< ROEdge, ROVehicle > &router, const ROVehicle *const, std::shared_ptr< RORoute > current, SUMOTime begin, MsgHandler *errorHandler)
Adds an alternative to the list of routes and returns the route that was replaced or nullptr.
RORouteDef(const std::string &id, const int lastUsed, const bool tryRepair, const bool mayBeDisconnected)
Constructor.
double getOverallProb() const
Returns the sum of the probablities of the contained routes.
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const
Saves the built route / route alternatives.
const bool myMayBeDisconnected
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
bool myDiscardSilent
Whether this route should be silently discarded.
std::shared_ptr< RORoute > buildCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Triggers building of the complete route (via preComputeCurrentRoute) or returns precomputed route.
std::vector< std::shared_ptr< RORoute > > myAlternatives
The alternatives.
void preComputeCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Builds the complete route (or chooses her from the list of alternatives, when existing)
bool myNewRoute
Information whether a new route was generated.
void addLoadedAlternative(std::shared_ptr< RORoute > alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA.
int myLastUsed
Index of the route used within the last step.
static bool mySkipNewRoutes
const ROEdge * getDestination() const
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
void validateAlternatives(const ROVehicle *veh, MsgHandler *errorHandler)
removes invalid alternatives and raise an error or warning
A vehicle as used by router.
SUMOTime getJumpTime() const
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
std::vector< Mandatory > getMandatoryEdges(const ROEdge *requiredStart, const ROEdge *requiredEnd) const
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Abstract base class providing static factory method.
static RouteCostCalculator< R, E, V > & getCalculator()
void setMsgHandler(MsgHandler *const errorMsgHandler)
bool hasProhibitions() const
virtual void prohibit(const Prohibitions &toProhibit)
virtual bool supportsProhibitions() const
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...
bool isValid(const std::vector< const E * > &edges, const V *const v, double t) const
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
std::vector< std::string > via
List of the via-edges the vehicle must visit.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
Some static methods for string processing.
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects