From d42030e1d6854c305ddfa906026a22008edfd6db Mon Sep 17 00:00:00 2001 From: Jakob Erdmann Date: Wed, 24 Apr 2024 09:58:46 +0200 Subject: [PATCH] fix #13494 --- src/microsim/MSBaseVehicle.cpp | 6 +++ src/microsim/MSBaseVehicle.h | 5 +++ src/microsim/MSEdge.cpp | 41 ++++++++++++------- src/microsim/MSEdge.h | 13 ++++-- .../transportables/MSTransportable.cpp | 1 + src/netbuild/NBAlgorithms_Railway.cpp | 2 +- src/netbuild/NBAlgorithms_Railway.h | 2 +- src/netbuild/NBEdge.cpp | 2 +- src/netbuild/NBEdge.h | 7 ++-- src/netbuild/NBVehicle.h | 7 ++++ src/router/ROEdge.cpp | 2 +- src/router/ROEdge.h | 2 +- src/router/RORoutable.h | 6 +++ src/utils/router/CarEdge.h | 12 +++--- src/utils/router/DijkstraRouter.h | 3 +- src/utils/router/IntermodalEdge.h | 3 +- src/utils/router/IntermodalTrip.h | 7 ++++ src/utils/router/RailEdge.h | 3 +- src/utils/router/ReversedEdge.h | 3 +- src/utils/vehicle/SUMOTrafficObject.h | 7 ++++ 20 files changed, 99 insertions(+), 35 deletions(-) diff --git a/src/microsim/MSBaseVehicle.cpp b/src/microsim/MSBaseVehicle.cpp index 6c2b5d09e11..1fb99fb3172 100644 --- a/src/microsim/MSBaseVehicle.cpp +++ b/src/microsim/MSBaseVehicle.cpp @@ -191,6 +191,12 @@ MSBaseVehicle::replaceParameter(const SUMOVehicleParameter* newParameter) { myParameter = newParameter; } + +bool +MSBaseVehicle::ignoreTransientPermissions() const { + return (getRoutingMode() & libsumo::ROUTING_MODE_IGNORE_TRANSIENT_PERMISSIONS) != 0; +} + double MSBaseVehicle::getMaxSpeed() const { return MIN2(myType->getMaxSpeed(), myType->getDesiredMaxSpeed() * myChosenSpeedFactor); diff --git a/src/microsim/MSBaseVehicle.h b/src/microsim/MSBaseVehicle.h index af280529eeb..8355c1f07a4 100644 --- a/src/microsim/MSBaseVehicle.h +++ b/src/microsim/MSBaseVehicle.h @@ -159,6 +159,11 @@ class MSBaseVehicle : public SUMOVehicle { return myType->getParameter().vehicleClass; } + /** @brief Returns whether this object is ignoring transient permission + * changes (during routing) + */ + bool ignoreTransientPermissions() const; + /** @brief Returns the maximum speed (the minimum of desired and technical maximum speed) * @return The vehicle's maximum speed */ diff --git a/src/microsim/MSEdge.cpp b/src/microsim/MSEdge.cpp index bdd3ae4f438..dca23dfd6cc 100644 --- a/src/microsim/MSEdge.cpp +++ b/src/microsim/MSEdge.cpp @@ -74,6 +74,7 @@ MSEdge::MSEdge(const std::string& id, int numericalID, myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0), myLastFailedInsertionTime(-1), myFromJunction(nullptr), myToJunction(nullptr), + myHaveTransientPermissions(false), myOtherTazConnector(nullptr), myStreetName(streetName), myEdgeType(edgeType), @@ -317,6 +318,7 @@ MSEdge::rebuildAllowedLanes(const bool onInit) { // rebuild myMinimumPermissions and myCombinedPermissions myMinimumPermissions = SVCAll; myCombinedPermissions = 0; + bool lanesChangedPermission = false; for (MSLane* const lane : *myLanes) { // same dedicated lanes are ignored in meso to avoid capacity errors. // Here we have to make sure that vehicles which are set to depart on @@ -324,6 +326,14 @@ MSEdge::rebuildAllowedLanes(const bool onInit) { SVCPermissions allow = getMesoPermissions(lane->getPermissions(), SVC_PEDESTRIAN); myMinimumPermissions &= allow; myCombinedPermissions |= allow; + lanesChangedPermission |= lane->hadPermissionChanges(); + } + if (!onInit && !myHaveTransientPermissions && lanesChangedPermission) { + myHaveTransientPermissions = true; + // backup original structures when first needed + myOrigAllowed = myAllowed; + myOrigAllowedTargets = myAllowedTargets; + myOrigClassesViaSuccessorMap = myClassesViaSuccessorMap; } // rebuild myAllowed myAllowed.clear(); @@ -347,6 +357,12 @@ MSEdge::rebuildAllowedLanes(const bool onInit) { } else { rebuildAllowedTargets(false); for (MSEdge* pred : myPredecessors) { + if (myHaveTransientPermissions && !pred->myHaveTransientPermissions) { + pred->myOrigAllowed = pred->myAllowed; + pred->myOrigAllowedTargets = pred->myAllowedTargets; + pred->myOrigClassesViaSuccessorMap = pred->myClassesViaSuccessorMap; + pred->myHaveTransientPermissions = true; + } pred->rebuildAllowedTargets(false); } if (MSGlobals::gUseMesoSim) { @@ -455,9 +471,10 @@ MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const std::vector* -MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const { - AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination); - if (i != myAllowedTargets.end()) { +MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions) const { + const auto& targets = ignoreTransientPermissions && myHaveTransientPermissions ? myOrigAllowedTargets : myAllowedTargets; + AllowedLanesByTarget::const_iterator i = targets.find(&destination); + if (i != targets.end()) { for (const auto& allowed : i->second) { if ((allowed.first & vclass) == vclass) { return allowed.second.get(); @@ -1204,26 +1221,27 @@ MSEdge::getSuccessors(SUMOVehicleClass vClass) const { const MSConstEdgePairVector& -MSEdge::getViaSuccessors(SUMOVehicleClass vClass) const { +MSEdge::getViaSuccessors(SUMOVehicleClass vClass, bool ignoreTransientPermissions) const { if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) { return myViaSuccessors; } #ifdef HAVE_FOX ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1); #endif - auto i = myClassesViaSuccessorMap.find(vClass); - if (i != myClassesViaSuccessorMap.end()) { + auto& viaMap = ignoreTransientPermissions && myHaveTransientPermissions ? myOrigClassesViaSuccessorMap : myClassesViaSuccessorMap; + auto i = viaMap.find(vClass); + if (i != viaMap.end()) { // can use cached value return i->second; } // instantiate vector - MSConstEdgePairVector& result = myClassesViaSuccessorMap[vClass]; + MSConstEdgePairVector& result = viaMap[vClass]; // this vClass is requested for the first time. rebuild all successors for (const auto& viaPair : myViaSuccessors) { if (viaPair.first->isTazConnector()) { result.push_back(viaPair); } else { - const std::vector* allowed = allowedLanes(*viaPair.first, vClass); + const std::vector* allowed = allowedLanes(*viaPair.first, vClass, ignoreTransientPermissions); if (allowed != nullptr && allowed->size() > 0) { result.push_back(viaPair); } @@ -1556,12 +1574,7 @@ MSEdge::getDistanceAt(double pos) const { bool MSEdge::hasTransientPermissions() const { - for (const MSLane* lane : *myLanes) { - if (lane->hadPermissionChanges()) { - return true; - } - } - return false; + return myHaveTransientPermissions; } diff --git a/src/microsim/MSEdge.h b/src/microsim/MSEdge.h index 6fdad818a4c..f6acd03709a 100644 --- a/src/microsim/MSEdge.h +++ b/src/microsim/MSEdge.h @@ -40,7 +40,6 @@ #include #include #include -#include #include "MSNet.h" @@ -225,7 +224,7 @@ class MSEdge : public Named, public Parameterised { * @return The lanes that may be used to reach the given edge, nullptr if no such lanes exist */ const std::vector* allowedLanes(const MSEdge& destination, - SUMOVehicleClass vclass = SVC_IGNORING) const; + SUMOVehicleClass vclass = SVC_IGNORING, bool ignoreTransientPermissions = false) const; @@ -389,7 +388,7 @@ class MSEdge : public Named, public Parameterised { * @param[in] vClass The vClass for which to restrict the successors * @return The eligible following edges */ - const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const; + const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const; /** @brief Returns the number of edges this edge is connected to @@ -607,7 +606,7 @@ class MSEdge : public Named, public Parameterised { return false; } const SUMOVehicleClass svc = vehicle->getVClass(); - return ((vehicle->getRoutingMode() & libsumo::ROUTING_MODE_IGNORE_TRANSIENT_PERMISSIONS) + return (vehicle->ignoreTransientPermissions() ? (myOriginalCombinedPermissions & svc) != svc : (myCombinedPermissions & svc) != svc); } @@ -920,9 +919,11 @@ class MSEdge : public Named, public Parameterised { /// @brief Associative container from vehicle class to allowed-lanes. AllowedLanesCont myAllowed; + AllowedLanesCont myOrigAllowed; /// @brief From target edge to lanes allowed to be used to reach it AllowedLanesByTarget myAllowedTargets; + AllowedLanesByTarget myOrigAllowedTargets; /// @brief The intersection of lane permissions for this edge SVCPermissions myMinimumPermissions = SVCAll; @@ -933,6 +934,9 @@ class MSEdge : public Named, public Parameterised { SVCPermissions myOriginalMinimumPermissions = SVCAll; /// @brief The original union of lane permissions for this edge (before temporary modifications) SVCPermissions myOriginalCombinedPermissions; + + /// @brief whether transient permission changes were applied to this edge or a predecessor + bool myHaveTransientPermissions; /// @} /// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr @@ -999,6 +1003,7 @@ class MSEdge : public Named, public Parameterised { /// @brief The successors available for a given vClass mutable std::map myClassesViaSuccessorMap; + mutable std::map myOrigClassesViaSuccessorMap; /// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges Boundary myBoundary; diff --git a/src/microsim/transportables/MSTransportable.cpp b/src/microsim/transportables/MSTransportable.cpp index 9593b6aca9e..c3f5272aef5 100644 --- a/src/microsim/transportables/MSTransportable.cpp +++ b/src/microsim/transportables/MSTransportable.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/src/netbuild/NBAlgorithms_Railway.cpp b/src/netbuild/NBAlgorithms_Railway.cpp index 15cdc1cb37d..741d1a80412 100644 --- a/src/netbuild/NBAlgorithms_Railway.cpp +++ b/src/netbuild/NBAlgorithms_Railway.cpp @@ -84,7 +84,7 @@ NBRailwayTopologyAnalyzer::Track::getSuccessors(SUMOVehicleClass svc) const { const std::vector >& -NBRailwayTopologyAnalyzer::Track::getViaSuccessors(SUMOVehicleClass svc) const { +NBRailwayTopologyAnalyzer::Track::getViaSuccessors(SUMOVehicleClass svc, bool /*ignoreTransientPermissions*/) const { if ((minPermissions & svc) != 0) { return viaSuccessors; } else { diff --git a/src/netbuild/NBAlgorithms_Railway.h b/src/netbuild/NBAlgorithms_Railway.h index 66a08e599e1..d340d3e3e28 100644 --- a/src/netbuild/NBAlgorithms_Railway.h +++ b/src/netbuild/NBAlgorithms_Railway.h @@ -66,7 +66,7 @@ class NBRailwayTopologyAnalyzer { void addSuccessor(Track* track); const std::vector& getSuccessors(SUMOVehicleClass svc = SVC_IGNORING) const; - const std::vector >& getViaSuccessors(SUMOVehicleClass svc = SVC_IGNORING) const; + const std::vector >& getViaSuccessors(SUMOVehicleClass svc = SVC_IGNORING, bool ignoreTransientPermissions = false) const; const std::string& getID() const { return id; diff --git a/src/netbuild/NBEdge.cpp b/src/netbuild/NBEdge.cpp index 4c047ce5c7b..a4f61ddb5b0 100644 --- a/src/netbuild/NBEdge.cpp +++ b/src/netbuild/NBEdge.cpp @@ -4692,7 +4692,7 @@ NBEdge::getSuccessors(SUMOVehicleClass vClass) const { const ConstRouterEdgePairVector& -NBEdge::getViaSuccessors(SUMOVehicleClass vClass) const { +NBEdge::getViaSuccessors(SUMOVehicleClass vClass, bool /*ignoreTransientPermissions*/) const { // @todo cache successors instead of recomputing them every time myViaSuccessors.clear(); for (const Connection& con : myConnections) { diff --git a/src/netbuild/NBEdge.h b/src/netbuild/NBEdge.h index 0c6b03e7869..0919d18b9b4 100644 --- a/src/netbuild/NBEdge.h +++ b/src/netbuild/NBEdge.h @@ -67,7 +67,7 @@ class NBRouterEdge { virtual double getLength() const = 0; virtual const NBRouterEdge* getBidiEdge() const = 0; virtual int getNumericalID() const = 0; - virtual const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const = 0; + virtual const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const = 0; virtual bool isInternal() const { return false; } @@ -327,8 +327,9 @@ class NBEdge : public Named, public Parameterised, public NBRouterEdge { bool isInternal() const { return true; } - const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { + const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const { UNUSED_PARAMETER(vClass); + UNUSED_PARAMETER(ignoreTransientPermissions); return myViaSuccessors; } /// }@ @@ -1515,7 +1516,7 @@ class NBEdge : public Named, public Parameterised, public NBRouterEdge { /** @brief Returns the following edges for the given vClass */ - const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const; + const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const; //@} const std::string& getID() const { diff --git a/src/netbuild/NBVehicle.h b/src/netbuild/NBVehicle.h index 64c92745a03..4e8bcd62fc7 100644 --- a/src/netbuild/NBVehicle.h +++ b/src/netbuild/NBVehicle.h @@ -58,6 +58,13 @@ class NBVehicle { return myVClass; } + /** @brief Returns whether this object is ignoring transient permission + * changes (during routing) + */ + bool ignoreTransientPermissions() const { + return false; + }; + double getLength() const { return myLength; } diff --git a/src/router/ROEdge.cpp b/src/router/ROEdge.cpp index ebd3ebe2484..d4ddc46c25f 100644 --- a/src/router/ROEdge.cpp +++ b/src/router/ROEdge.cpp @@ -399,7 +399,7 @@ ROEdge::getSuccessors(SUMOVehicleClass vClass) const { const ROConstEdgePairVector& -ROEdge::getViaSuccessors(SUMOVehicleClass vClass) const { +ROEdge::getViaSuccessors(SUMOVehicleClass vClass, bool /*ignoreTransientPermissions*/) const { if (vClass == SVC_IGNORING || !RONet::getInstance()->hasPermissions() || isTazConnector()) { return myFollowingViaEdges; } diff --git a/src/router/ROEdge.h b/src/router/ROEdge.h index 116d7d30aac..7652deb6d19 100644 --- a/src/router/ROEdge.h +++ b/src/router/ROEdge.h @@ -350,7 +350,7 @@ class ROEdge : public Named, public Parameterised { * @param[in] vClass The vClass for which to restrict the successors * @return The eligible following edges */ - const ROConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const; + const ROConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const; /** @brief Returns the number of edges connected to this edge diff --git a/src/router/RORoutable.h b/src/router/RORoutable.h index 0edb6894355..2e929917649 100644 --- a/src/router/RORoutable.h +++ b/src/router/RORoutable.h @@ -110,6 +110,12 @@ class RORoutable { return getType() != 0 ? getType()->vehicleClass : SVC_IGNORING; } + /** @brief Returns whether this object is ignoring transient permission + * changes (during routing) + */ + bool ignoreTransientPermissions() const { + return false; + }; /// @brief Returns the vehicle's maximum speed inline double getMaxSpeed() const { diff --git a/src/utils/router/CarEdge.h b/src/utils/router/CarEdge.h index f7994408dbc..27f74752abf 100644 --- a/src/utils/router/CarEdge.h +++ b/src/utils/router/CarEdge.h @@ -67,15 +67,16 @@ class CarEdge : public IntermodalEdge { } } - virtual const std::vector >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { + virtual const std::vector >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const { if (vClass == SVC_IGNORING) { return this->myFollowingViaEdges; } #ifdef HAVE_FOX FXMutexLock locker(myLock); #endif - typename std::map > >::const_iterator i = myClassesViaSuccessorMap.find(vClass); - if (i != myClassesViaSuccessorMap.end()) { + auto& viaMap = ignoreTransientPermissions ? myOrigClassesViaSuccessorMap : myClassesViaSuccessorMap; + typename std::map > >::const_iterator i = viaMap.find(vClass); + if (i != viaMap.end()) { // can use cached value return i->second; } else { @@ -86,10 +87,10 @@ class CarEdge : public IntermodalEdge { } for (const std::pair& e : this->myFollowingViaEdges) { if (!e.first->includeInRoute(false) || e.first->getEdge() == this->getEdge() || classedCarFollowers.count(e.first->getEdge()) > 0) { - myClassesViaSuccessorMap[vClass].push_back(e); + viaMap[vClass].push_back(e); } } - return myClassesViaSuccessorMap[vClass]; + return viaMap[vClass]; } } @@ -144,6 +145,7 @@ class CarEdge : public IntermodalEdge { /// @brief The successors available for a given vClass mutable std::map > > myClassesViaSuccessorMap; + mutable std::map > > myOrigClassesViaSuccessorMap; #ifdef HAVE_FOX /// The mutex used to avoid concurrent updates of myClassesSuccessorMap diff --git a/src/utils/router/DijkstraRouter.h b/src/utils/router/DijkstraRouter.h index 6108f15dfe0..34310687690 100644 --- a/src/utils/router/DijkstraRouter.h +++ b/src/utils/router/DijkstraRouter.h @@ -124,6 +124,7 @@ class DijkstraRouter : public SUMOAbstractRouter { std::cout << "DEBUG: starting search for '" << Named::getIDSecure(vehicle) << "' time: " << STEPS2TIME(msTime) << "\n"; #endif const SUMOVehicleClass vClass = vehicle == nullptr ? SVC_IGNORING : vehicle->getVClass(); + const bool ignoreTransient = vehicle == nullptr ? false : vehicle->ignoreTransientPermissions(); std::tuple query = std::make_tuple(from, vehicle, msTime); if ((this->myBulkMode || (this->myAutoBulkMode && query == myLastQuery)) && !this->myAmClean) { #ifdef DijkstraRouter_DEBUG_BULKMODE @@ -203,7 +204,7 @@ class DijkstraRouter : public SUMOAbstractRouter { myExternalEffort->update(minEdge->getNumericalID(), minimumInfo->prev->edge->getNumericalID(), minEdge->getLength()); } // check all ways from the node with the minimal length - for (const std::pair& follower : minEdge->getViaSuccessors(vClass)) { + for (const std::pair& follower : minEdge->getViaSuccessors(vClass, ignoreTransient)) { auto& followerInfo = this->myEdgeInfos[follower.first->getNumericalID()]; // check whether it can be used if (followerInfo.prohibited || this->isProhibited(follower.first, vehicle)) { diff --git a/src/utils/router/IntermodalEdge.h b/src/utils/router/IntermodalEdge.h index 66e89aded31..882443bfb68 100644 --- a/src/utils/router/IntermodalEdge.h +++ b/src/utils/router/IntermodalEdge.h @@ -136,8 +136,9 @@ class IntermodalEdge : public Named { return myFollowingEdges; } - virtual const std::vector >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { + virtual const std::vector >& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const { UNUSED_PARAMETER(vClass); + UNUSED_PARAMETER(ignoreTransientPermissions); // the network is already tailored. No need to check for permissions here return myFollowingViaEdges; } diff --git a/src/utils/router/IntermodalTrip.h b/src/utils/router/IntermodalTrip.h index d1048e04af2..a3d99da2489 100644 --- a/src/utils/router/IntermodalTrip.h +++ b/src/utils/router/IntermodalTrip.h @@ -62,6 +62,13 @@ class IntermodalTrip { return vehicle != 0 ? vehicle->getVClass() : SVC_PEDESTRIAN; } + /** @brief Returns whether this object is ignoring transient permission + * changes (during routing) + */ + bool ignoreTransientPermissions() const { + return vehicle != 0 ? vehicle->ignoreTransientPermissions() : false; + }; + inline double getLength() const { // person length is arbitrary (only used in the context of rail-reversal validity return vehicle != 0 ? vehicle->getVehicleType().getLength() : 1; diff --git a/src/utils/router/RailEdge.h b/src/utils/router/RailEdge.h index acdfd8b885c..20fb3d70181 100644 --- a/src/utils/router/RailEdge.h +++ b/src/utils/router/RailEdge.h @@ -233,7 +233,8 @@ class RailEdge { return myOriginal != nullptr && myOriginal->restricts(vehicle); } - const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { + const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const { + UNUSED_PARAMETER(ignoreTransientPermissions); // @todo this should be changed (somewhat hidden by #14756) if (vClass == SVC_IGNORING || myOriginal == nullptr || myOriginal->isTazConnector()) { // || !MSNet::getInstance()->hasPermissions()) { return myViaSuccessors; } diff --git a/src/utils/router/ReversedEdge.h b/src/utils/router/ReversedEdge.h index 0a94ba052fc..ee7cfddc943 100644 --- a/src/utils/router/ReversedEdge.h +++ b/src/utils/router/ReversedEdge.h @@ -91,7 +91,8 @@ class ReversedEdge { return edge->myOriginal->getTravelTime(veh, time); } - const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const { + const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const { + UNUSED_PARAMETER(ignoreTransientPermissions); // @todo this should be changed (somewhat hidden by #14756) if (vClass == SVC_IGNORING || myOriginal->isTazConnector()) { // || !MSNet::getInstance()->hasPermissions()) { return myViaSuccessors; } diff --git a/src/utils/vehicle/SUMOTrafficObject.h b/src/utils/vehicle/SUMOTrafficObject.h index e6d15ea210b..00b5ccd9626 100644 --- a/src/utils/vehicle/SUMOTrafficObject.h +++ b/src/utils/vehicle/SUMOTrafficObject.h @@ -162,6 +162,13 @@ class SUMOTrafficObject : public Named { */ virtual SUMOVehicleClass getVClass() const = 0; + /** @brief Returns whether this object is ignoring transient permission + * changes (during routing) + */ + virtual bool ignoreTransientPermissions() const { + return false; + }; + virtual int getRoutingMode() const = 0; /** @brief Returns the object's maximum speed (minimum of technical and desired maximum speed)