Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
RORouteDef.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2002-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/****************************************************************************/
20// Base class for a vehicle's route definition
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <iterator>
26#include <algorithm>
29#include <utils/common/Named.h>
35#include "ROEdge.h"
36#include "RORoute.h"
39#include "RORouteDef.h"
40#include "ROVehicle.h"
41
42// ===========================================================================
43// static members
44// ===========================================================================
45bool RORouteDef::myUsingJTRR(false);
47
48// ===========================================================================
49// method definitions
50// ===========================================================================
51RORouteDef::RORouteDef(const std::string& id, const int lastUsed,
52 const bool tryRepair, const bool mayBeDisconnected) :
53 Named(StringUtils::convertUmlaute(id)),
54 myPrecomputed(nullptr), myLastUsed(lastUsed), myTryRepair(tryRepair),
55 myMayBeDisconnected(mayBeDisconnected),
56 myDiscardSilent(false) {
57}
58
59
61 for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
62 if (myRouteRefs.count(*i) == 0) {
63 delete *i;
64 }
65 }
66}
67
68
69void
73
74
75void
77 std::copy(alt->myAlternatives.begin(), alt->myAlternatives.end(),
78 back_inserter(myAlternatives));
79 std::copy(alt->myAlternatives.begin(), alt->myAlternatives.end(),
80 std::inserter(myRouteRefs, myRouteRefs.end()));
81}
82
83
86 SUMOTime begin, const ROVehicle& veh) const {
87 if (myPrecomputed == nullptr) {
88 preComputeCurrentRoute(router, begin, veh);
89 }
90 return myPrecomputed;
91}
92
93
94void
96 for (int i = 0; i < (int)myAlternatives.size();) {
97 if (i != myLastUsed || mySkipNewRoutes) {
98 if (myAlternatives[i]->isPermitted(veh, errorHandler)) {
99 i++;
100 } else {
101 myAlternatives.erase(myAlternatives.begin() + i);
102 if (myLastUsed > i) {
103 myLastUsed--;
104 }
105 }
106 } else {
107 i++;
108 }
109 }
110}
111
112
113void
115 SUMOTime begin, const ROVehicle& veh) const {
116 myNewRoute = false;
118 const bool ignoreErrors = oc.getBool("ignore-errors");
119 assert(myAlternatives[0]->getEdgeVector().size() > 0);
121 if (myAlternatives[0]->getFirst()->prohibits(&veh) && (!oc.getBool("repair.from")
122 // do not try to reassign starting edge for trip input
123 || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
124 mh->inform("Vehicle '" + veh.getID() + "' is not allowed to depart on edge '" +
125 myAlternatives[0]->getFirst()->getID() + "'.");
126 return;
127 } else if (myAlternatives[0]->getLast()->prohibits(&veh) && (!oc.getBool("repair.to")
128 // do not try to reassign destination edge for trip input
129 || myMayBeDisconnected || myAlternatives[0]->getEdgeVector().size() < 2)) {
130 // this check is not strictly necessary unless myTryRepair is set.
131 // However, the error message is more helpful than "no connection found"
132 mh->inform("Vehicle '" + veh.getID() + "' is not allowed to arrive on edge '" +
133 myAlternatives[0]->getLast()->getID() + "'.");
134 return;
135 }
136 const bool skipTripRouting = (oc.exists("write-trips") && oc.getBool("write-trips")
138 if ((myTryRepair && !skipTripRouting) || myUsingJTRR) {
139 ConstROEdgeVector newEdges;
140 if (repairCurrentRoute(router, begin, veh, myAlternatives[0]->getEdgeVector(), newEdges)) {
141 if (myAlternatives[0]->getEdgeVector() != newEdges) {
142 if (!myMayBeDisconnected) {
143 WRITE_WARNINGF(TL("Repaired route of vehicle '%'."), veh.getID());
144 }
145 myNewRoute = true;
146 RGBColor* col = myAlternatives[0]->getColor() != nullptr ? new RGBColor(*myAlternatives[0]->getColor()) : nullptr;
147 myPrecomputed = new RORoute(myID, 0, myAlternatives[0]->getProbability(), newEdges, col, myAlternatives[0]->getStops());
148 } else {
150 }
151 }
152 return;
153 }
155 || OptionsCont::getOptions().getBool("remove-loops"))
156 && (skipTripRouting || myAlternatives[myLastUsed]->isValid(veh, ignoreErrors))) {
158 } else {
159 // build a new route to test whether it is better
161 ConstROEdgeVector edges;
162 if (repairCurrentRoute(router, begin, veh, oldEdges, edges, true)) {
163 if (edges.front()->isTazConnector()) {
164 edges.erase(edges.begin());
165 }
166 if (edges.back()->isTazConnector()) {
167 edges.pop_back();
168 }
169 // check whether the same route was already used
170 int existing = -1;
171 for (int i = 0; i < (int)myAlternatives.size(); i++) {
172 if (edges == myAlternatives[i]->getEdgeVector()) {
173 existing = i;
174 break;
175 }
176 }
177 if (existing >= 0) {
178 myPrecomputed = myAlternatives[existing];
179 } else {
180 RGBColor* col = myAlternatives[0]->getColor() != nullptr ? new RGBColor(*myAlternatives[0]->getColor()) : nullptr;
181 myPrecomputed = new RORoute(myID, 0, 1, edges, col, myAlternatives[0]->getStops());
182 myNewRoute = true;
183 }
184 }
185 }
186}
187
188
189bool
191 SUMOTime begin, const ROVehicle& veh,
192 ConstROEdgeVector oldEdges, ConstROEdgeVector& newEdges,
193 bool isTrip) const {
194 MsgHandler* mh = (OptionsCont::getOptions().getBool("ignore-errors") ?
196 const int initialSize = (int)oldEdges.size();
197 if (initialSize == 1) {
198 if (myUsingJTRR) {
200 bool ok = router.compute(oldEdges.front(), nullptr, &veh, begin, newEdges);
201 myDiscardSilent = ok && newEdges.size() == 0;
202 } else {
203 newEdges = oldEdges;
204 }
205 } else {
206 if (oldEdges.front()->prohibits(&veh)) {
207 // option repair.from is in effect
208 const std::string& frontID = oldEdges.front()->getID();
209 for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
210 if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
211 i = oldEdges.erase(i);
212 } else {
213 WRITE_MESSAGE("Changing invalid starting edge '" + frontID
214 + "' to '" + (*i)->getID() + "' for vehicle '" + veh.getID() + "'.");
215 break;
216 }
217 }
218 }
219 if (oldEdges.size() == 0) {
220 mh->inform("Could not find new starting edge for vehicle '" + veh.getID() + "'.");
221 return false;
222 }
223 if (oldEdges.back()->prohibits(&veh)) {
224 // option repair.to is in effect
225 const std::string& backID = oldEdges.back()->getID();
226 // oldEdges cannot get empty here, otherwise we would have left the stage when checking "from"
227 while (oldEdges.back()->prohibits(&veh) || oldEdges.back()->isInternal()) {
228 oldEdges.pop_back();
229 }
230 WRITE_MESSAGE("Changing invalid destination edge '" + backID
231 + "' to edge '" + oldEdges.back()->getID() + "' for vehicle '" + veh.getID() + "'.");
232 }
233 ConstROEdgeVector mandatory = veh.getMandatoryEdges(oldEdges.front(), oldEdges.back());
234 std::set<ConstROEdgeVector::const_iterator> jumpStarts;
235 veh.collectJumps(mandatory, jumpStarts);
236 assert(mandatory.size() >= 2);
237 // removed prohibited
238 for (ConstROEdgeVector::iterator i = oldEdges.begin(); i != oldEdges.end();) {
239 if ((*i)->prohibits(&veh) || (*i)->isInternal()) {
240 // no need to check the mandatories here, this was done before
241 WRITE_MESSAGEF(TL("Removing invalid edge '%' from route for vehicle '%'."), (*i)->getID(), veh.getID());
242 i = oldEdges.erase(i);
243 } else {
244 ++i;
245 }
246 }
247 // reconnect remaining edges
248 if (mandatory.size() > oldEdges.size() && initialSize > 2) {
249 WRITE_MESSAGEF(TL("There are stop edges which were not part of the original route for vehicle '%'."), veh.getID());
250 }
251 const ConstROEdgeVector& targets = mandatory.size() > oldEdges.size() ? mandatory : oldEdges;
252 newEdges.push_back(targets.front());
253 ConstROEdgeVector::iterator nextMandatory = mandatory.begin() + 1;
254 int lastMandatory = 0;
255 for (ConstROEdgeVector::const_iterator i = targets.begin() + 1;
256 i != targets.end() && nextMandatory != mandatory.end(); ++i) {
257 const ROEdge* prev = *(i - 1);
258 const ROEdge* cur = *i;
259 if (prev->isConnectedTo(*cur, veh.getVClass()) && (!isRailway(veh.getVClass()) || prev->getBidiEdge() != cur)) {
260 newEdges.push_back(cur);
261 } else {
262 if (initialSize > 2) {
263 // only inform if the input is (probably) not a trip
264 WRITE_MESSAGEF(TL("Edge '%' not connected to edge '%' for vehicle '%'."), (*(i - 1))->getID(), (*i)->getID(), veh.getID());
265 }
266 const ROEdge* last = newEdges.back();
267 newEdges.pop_back();
268 if (last->isTazConnector() && newEdges.size() > 1) {
269 // assume this was a viaTaz
270 last = newEdges.back();
271 newEdges.pop_back();
272 }
273 if (veh.hasJumps() && jumpStarts.count(nextMandatory - 1) != 0) {
274 while (*i != *nextMandatory) {
275 ++i;
276 }
277 newEdges.push_back(last);
278 newEdges.push_back(*i);
279 //std::cout << " skipJump mIndex=" << (nextMandatory - 1 - mandatory.begin()) << " last=" << last->getID() << " next=" << (*i)->getID() << " newEdges=" << toString(newEdges) << "\n";
280 } else {
281
282 int numEdgesBefore = (int)newEdges.size();
283 // router.setHint(targets.begin(), i, &veh, begin);
284 if (!router.compute(last, *i, &veh, begin, newEdges)) {
285 // backtrack: try to route from last mandatory edge to next mandatory edge
286 // XXX add option for backtracking in smaller increments
287 // (i.e. previous edge to edge after *i)
288 // we would then need to decide whether we have found a good
289 // tradeoff between faithfulness to the input data and detour-length
290 if (lastMandatory >= (int)newEdges.size() || last == newEdges[lastMandatory] || !backTrack(router, i, lastMandatory, nextMandatory, newEdges, veh, begin)) {
291 mh->inform("Mandatory edge '" + (*i)->getID() + "' not reachable by vehicle '" + veh.getID() + "'.");
292 return false;
293 }
294 } else if (!myMayBeDisconnected && !isTrip && last != (*i)) {
295 double airDist = last->getToJunction()->getPosition().distanceTo(
296 (*i)->getFromJunction()->getPosition());
297 double repairDist = 0;
298 for (auto it2 = (newEdges.begin() + numEdgesBefore + 1); it2 != newEdges.end() && it2 != newEdges.end() - 1; it2++) {
299 repairDist += (*it2)->getLength();
300 }
301 const double detourFactor = repairDist / MAX2(airDist, 1.0);
302 const double detour = MAX2(0.0, repairDist - airDist);
303 const double maxDetourFactor = OptionsCont::getOptions().getFloat("repair.max-detour-factor");
304 if (detourFactor > maxDetourFactor) {
305 WRITE_MESSAGEF(" Backtracking to avoid detour of %m for gap of %m)", detour, airDist);
306 backTrack(router, i, lastMandatory, nextMandatory, newEdges, veh, begin);
307 } else if (detourFactor > 1.1) {
308 WRITE_MESSAGEF(" Taking detour of %m to avoid gap of %m)", detour, airDist);
309 }
310 }
311 }
312 }
313 if (*i == *nextMandatory) {
314 nextMandatory++;
315 lastMandatory = (int)newEdges.size() - 1;
316 }
317 }
318 }
319 return true;
320}
321
322
323bool
325 ConstROEdgeVector::const_iterator& i, int lastMandatory, ConstROEdgeVector::iterator nextMandatory,
326 ConstROEdgeVector& newEdges, const ROVehicle& veh, SUMOTime begin) {
327 ConstROEdgeVector edges;
328 bool ok = router.compute(newEdges[lastMandatory], *nextMandatory, &veh, begin, edges);
329 if (!ok) {
330 return false;
331 }
332
333 while (*i != *nextMandatory) {
334 ++i;
335 }
336 newEdges.erase(newEdges.begin() + lastMandatory + 1, newEdges.end());
337 std::copy(edges.begin() + 1, edges.end(), back_inserter(newEdges));
338 return true;
339}
340
341
342void
344 const ROVehicle* const veh, RORoute* current, SUMOTime begin,
345 MsgHandler* errorHandler) {
346 if (myTryRepair || myUsingJTRR) {
347 if (myNewRoute) {
348 delete myAlternatives[0];
349 myAlternatives[0] = current;
350 }
351 if (!router.isValid(current->getEdgeVector(), veh)) {
352 throw ProcessError("Route '" + getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
353 }
354 double costs = router.recomputeCosts(current->getEdgeVector(), veh, begin);
355 if (veh->hasJumps()) {
356 // @todo: jumpTime should be applied in recomputeCost to ensure the
357 // correctness of time-dependent traveltimes
358 costs += STEPS2TIME(veh->getJumpTime());
359 }
360 current->setCosts(costs);
361 return;
362 }
363 // add the route when it's new
364 if (myAlternatives.back()->getProbability() < 0 || !myAlternatives.back()->isPermitted(veh, errorHandler)) {
365 if (myAlternatives.back()->getProbability() >= 0 && errorHandler == MsgHandler::getErrorInstance()) {
366 throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
367 }
368 delete myAlternatives.back();
369 myAlternatives.pop_back();
370 }
371 if (myNewRoute) {
372 myAlternatives.push_back(current);
373 }
374 // recompute the costs and (when a new route was added) scale the probabilities
375 const double scale = double(myAlternatives.size() - 1) / double(myAlternatives.size());
376 for (RORoute* const alt : myAlternatives) {
377 if (!router.isValid(alt->getEdgeVector(), veh)) {
378 throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
379 }
380 // recompute the costs for all routes
381 const double newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
382 assert(myAlternatives.size() != 0);
383 if (myNewRoute) {
384 if (alt == current) {
385 // set initial probability and costs
386 alt->setProbability(1. / (double) myAlternatives.size());
387 alt->setCosts(newCosts);
388 } else {
389 // rescale probs for all others
390 alt->setProbability(alt->getProbability() * scale);
391 }
392 }
394 }
395 assert(myAlternatives.size() != 0);
397 const bool keepRoute = RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().keepRoute();
398 if (!RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().keepAllRoutes() && !keepRoute) {
399 // remove with probability of 0 (not mentioned in Gawron)
400 for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end();) {
401 if ((*i)->getProbability() == 0) {
402 delete *i;
403 i = myAlternatives.erase(i);
404 } else {
405 i++;
406 }
407 }
408 }
409 int maxNumber = RouteCostCalculator<RORoute, ROEdge, ROVehicle>::getCalculator().getMaxRouteNumber();
410 if ((int)myAlternatives.size() > maxNumber) {
411 const RORoute* last = myAlternatives[myLastUsed];
412 // only keep the routes with highest probability
413 sort(myAlternatives.begin(), myAlternatives.end(), [](const RORoute * const a, const RORoute * const b) {
414 return a->getProbability() > b->getProbability();
415 });
416 if (keepRoute) {
417 for (int i = 0; i < (int)myAlternatives.size(); i++) {
418 if (myAlternatives[i] == last) {
419 myLastUsed = i;
420 break;
421 }
422 }
423 if (myLastUsed >= maxNumber) {
425 myLastUsed = maxNumber - 1;
426 }
427 }
428 for (std::vector<RORoute*>::iterator i = myAlternatives.begin() + maxNumber; i != myAlternatives.end(); i++) {
429 delete *i;
430 }
431 myAlternatives.erase(myAlternatives.begin() + maxNumber, myAlternatives.end());
432 }
433 // rescale probabilities
434 double newSum = 0.;
435 for (const RORoute* const alt : myAlternatives) {
436 newSum += alt->getProbability();
437 }
438 assert(newSum > 0);
439 // @note newSum may be larger than 1 for numerical reasons
440 for (RORoute* const alt : myAlternatives) {
441 alt->setProbability(alt->getProbability() / newSum);
442 }
443
444 // find the route to use
445 if (!keepRoute) {
446 double chosen = RandHelper::rand();
447 myLastUsed = 0;
448 for (const RORoute* const alt : myAlternatives) {
449 chosen -= alt->getProbability();
450 if (chosen <= 0) {
451 return;
452 }
453 myLastUsed++;
454 }
455 }
456}
457
458const ROEdge*
460 return myAlternatives.back()->getFirst();
461}
462
463
464const ROEdge*
466 return myAlternatives.back()->getLast();
467}
468
469
472 bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const {
473 if (asAlternatives) {
475 for (int i = 0; i != (int)myAlternatives.size(); i++) {
476 myAlternatives[i]->writeXMLDefinition(dev, veh, true, true, withExitTimes, withLength);
477 }
478 dev.closeTag();
479 return dev;
480 } else {
481 return myAlternatives[myLastUsed]->writeXMLDefinition(dev, veh, withCost, false, withExitTimes, withLength);
482 }
483}
484
485
487RORouteDef::copy(const std::string& id, const SUMOTime stopOffset) const {
489 for (const RORoute* const route : myAlternatives) {
490 RGBColor* col = route->getColor() != nullptr ? new RGBColor(*route->getColor()) : nullptr;
491 RORoute* newRoute = new RORoute(id, route->getCosts(), route->getProbability(), route->getEdgeVector(), col, route->getStops());
492 newRoute->addStopOffset(stopOffset);
493 result->addLoadedAlternative(newRoute);
494 }
495 return result;
496}
497
498
499double
501 double sum = 0.;
502 for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) {
503 sum += (*i)->getProbability();
504 }
505 return sum;
506}
507
508
509/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:289
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define TL(string)
Definition MsgHandler.h:304
std::vector< const ROEdge * > ConstROEdgeVector
Definition ROEdge.h:57
#define STEPS2TIME(x)
Definition SUMOTime.h:55
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
@ SUMO_ATTR_LAST
T MAX2(T a, T b)
Definition StdDefs.h:86
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.
Definition Named.h:54
std::string myID
The name of the object.
Definition Named.h:125
const std::string & getID() const
Returns the id.
Definition Named.h:74
A storage for options typed value containers)
Definition OptionsCont.h:89
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 & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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
Definition Position.h:263
A basic edge for routing applications.
Definition ROEdge.h:73
const ROEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition ROEdge.h:556
const RONode * getToJunction() const
Definition ROEdge.h:543
bool isTazConnector() const
Definition ROEdge.h:174
bool isConnectedTo(const ROEdge &e, const SUMOVehicleClass vClass, bool ignoreTransientPermissions=false) const
returns the information whether this edge is directly connected to the given
Definition ROEdge.cpp:462
const Position & getPosition() const
Returns the position of the node.
Definition RONode.h:67
SUMOVehicleClass getVClass() const
Definition RORoutable.h:117
const std::string & getID() const
Returns the id of the routable.
Definition RORoutable.h:95
Base class for a vehicle's route definition.
Definition RORouteDef.h:53
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)
RORoute * myPrecomputed
precomputed route for out-of-order computation
Definition RORouteDef.h:164
void addLoadedAlternative(RORoute *alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA.
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.
std::vector< RORoute * > myAlternatives
The alternatives.
Definition RORouteDef.h:170
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const
Saves the built route / route alternatives.
RORoute * buildCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Triggers building of the complete route (via preComputeCurrentRoute) or returns precomputed route.
const bool myMayBeDisconnected
Definition RORouteDef.h:179
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
virtual ~RORouteDef()
Destructor.
bool myDiscardSilent
Whether this route should be silently discarded.
Definition RORouteDef.h:182
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)
static bool myUsingJTRR
Definition RORouteDef.h:184
bool myNewRoute
Information whether a new route was generated.
Definition RORouteDef.h:176
const bool myTryRepair
Definition RORouteDef.h:178
int myLastUsed
Index of the route used within the last step.
Definition RORouteDef.h:167
std::set< RORoute * > myRouteRefs
Routes which are deleted someplace else.
Definition RORouteDef.h:173
static bool mySkipNewRoutes
Definition RORouteDef.h:185
const ROEdge * getDestination() const
void addAlternative(SUMOAbstractRouter< ROEdge, ROVehicle > &router, const ROVehicle *const, RORoute *current, SUMOTime begin, MsgHandler *errorHandler)
Adds an alternative to the list of routes.
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
static bool backTrack(SUMOAbstractRouter< ROEdge, ROVehicle > &router, ConstROEdgeVector::const_iterator &i, int lastMandatory, ConstROEdgeVector::iterator nextMandatory, ConstROEdgeVector &newEdges, const ROVehicle &veh, SUMOTime begin)
backtrack to last mandatory edge and route to next mandatory
A complete router's route.
Definition RORoute.h:52
void addStopOffset(const SUMOTime offset)
Adapts the until time of all stops by the given offset.
Definition RORoute.h:196
const ConstROEdgeVector & getEdgeVector() const
Returns the list of edges this route consists of.
Definition RORoute.h:152
void setCosts(double costs)
Sets the costs of the route.
Definition RORoute.cpp:64
A vehicle as used by router.
Definition ROVehicle.h:50
void collectJumps(const ConstROEdgeVector &mandatory, std::set< ConstROEdgeVector::const_iterator > &jumpStarts) const
collect mandatory-edge iterators that define jumps in the route
SUMOTime getJumpTime() const
Definition ROVehicle.h:129
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
Definition ROVehicle.h:92
ConstROEdgeVector getMandatoryEdges(const ROEdge *requiredStart, const ROEdge *requiredEnd) const
compute mandatory edges
bool hasJumps() const
Definition ROVehicle.h:125
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()
bool isValid(const std::vector< const E * > &edges, const V *const v) 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...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
Some static methods for string processing.
Definition StringUtils.h:40
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
Definition json.hpp:21884