34#define DEBUGCOND (veh.isSelected())
40 myParamPrefix(paramPrefix), myCheckValidity(checkValidity) {
41 myEvalParams = { {
"probability", 0.}, {
"capacity", 0.}, {
"timefrom", 0.}, {
"timeto", 0.}, {
"distancefrom", 0.}, {
"distanceto", 1.}, {
"absfreespace", 0.}, {
"relfreespace", 0.}, };
42 myInvertParams = { {
"probability",
false}, {
"capacity",
true }, {
"timefrom",
false }, {
"timeto",
false }, {
"distancefrom",
false }, {
"distanceto",
false }, {
"absfreespace",
true }, {
"relfreespace",
true } };
43 for (
auto param : addEvalParams) {
45 myInvertParams[param.first] = (addInvertParams.count(param.first) > 0) ? addInvertParams[param.first] :
false;
48 myNormParams.insert({param.first, param.first !=
"probability"});
54 const MSEdgeVector& closedEdges,
const int insertStopIndex,
const bool keepCurrentStop) {
66 bool destVisible =
false;
67 if (destStoppingPlace !=
nullptr) {
70 for (
auto stoppingPlace : stoppingPlaceCandidates) {
71 if (stoppingPlace.first == destStoppingPlace && stoppingPlace.second) {
80 const int stopAnywhere = (int)
getWeight(veh,
"anywhere", -1);
81 const bool ignoreDest =
getWeight(veh,
"ignoreDest", destStoppingPlace !=
nullptr ? 0 : 1) != 0;
93#ifdef DEBUG_STOPPINGPLACE
100 double bestDist = std::numeric_limits<double>::max();
104 if (&item.first->getLane().getEdge() == veh.
getEdge()
106 const double distToStart = item.first->getBeginLanePosition() - veh.
getPositionOnLane();
107 const double distToEnd = item.first->getEndLanePosition() - veh.
getPositionOnLane();
108 if (distToEnd > brakeGap) {
110 if (distToStart < bestDist) {
111 bestDist = distToStart;
112 onTheWay = item.first;
120#ifdef DEBUG_STOPPINGPLACE
127 if (!ignoreDest && !destVisible && onTheWay ==
nullptr) {
139#ifdef DEBUG_STOPPINGPLACE
142 <<
" newDest=" << newDestination
147 std::map<MSStoppingPlace*, ConstMSEdgeVector> newRoutes;
148 std::map<MSStoppingPlace*, ConstMSEdgeVector> stopApproaches;
151 for (
auto param : weights) {
152 maxValues[param.first] = 0.;
160 if (onTheWay !=
nullptr) {
162 if (newDestination) {
163 newRoute.push_back(veh.
getEdge());
165 bool valid =
evaluateDestination(veh, brakeGap, newDestination, onTheWay,
getLastStepStoppingPlaceOccupancy(onTheWay), 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop);
167 WRITE_WARNINGF(
TL(
"Stopping place '%' along the way cannot be used by vehicle '%' for unknown reason"), onTheWay->
getID(), veh.
getID());
170 newRoute = newRoutes[onTheWay];
174 int numAlternatives = 0;
175 std::vector<std::tuple<SUMOTime, MSStoppingPlace*, int>> blockedTimes;
178 if (destStoppingPlace !=
nullptr) {
183 const double stoppingPlaceFrustration =
getWeight(veh,
"frustration", 100);
184 const double stoppingPlaceKnowledge =
getWeight(veh,
"knowledge", 0);
186 for (
int i = 0; i < (int)stoppingPlaceCandidates.size(); ++i) {
192 const bool visible = stoppingPlaceCandidates[i].second || (stoppingPlaceCandidates[i].first == destStoppingPlace && destVisible);
194 if (!visible && (stoppingPlaceKnowledge == 0 || stoppingPlaceKnowledge <
RandHelper::rand(veh.
getRNG()))) {
200 if (blockedTime >= 0 &&
SIMSTEP - blockedTime < stoppingPlaceMemory) {
202 occupancy = capacity;
203 blockedTimes.push_back(std::make_tuple(blockedTime, stoppingPlaceCandidates[i].first, i));
204#ifdef DEBUG_STOPPINGPLACE
206 std::cout <<
" altStoppingPlace=" << stoppingPlaceCandidates[i].first->getID() <<
" was blocked at " <<
time2string(blockedTime) <<
"\n";
212 if (
evaluateDestination(veh, brakeGap, newDestination, stoppingPlaceCandidates[i].first, occupancy, probs[i], router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
215 }
else if (visible) {
223 if (numAlternatives == 0) {
225 std::sort(blockedTimes.begin(), blockedTimes.end(),
226 [](std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t2) {
227 if (std::get<0>(t1) < std::get<0>(t2)) {
230 if (std::get<0>(t1) == std::get<0>(t2)) {
231 if (std::get<1>(t1)->getID() < std::get<1>(t2)->getID()) {
234 if (std::get<1>(t1)->getID() == std::get<1>(t2)->getID()) {
235 return std::get<2>(t1) < std::get<2>(t2);
241 for (
auto item : blockedTimes) {
243 double prob = probs[std::get<2>(item)];
247 if (
evaluateDestination(veh, brakeGap, newDestination, sp, occupancy, prob, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
248#ifdef DEBUG_STOPPINGPLACE
250 std::cout <<
" altStoppingPlace=" << sp->
getID() <<
" targeting occupied stopping place based on blockTime " <<
STEPS2TIME(std::get<0>(item)) <<
" among " << blockedTimes.size() <<
" alternatives\n";
258 if (numAlternatives == 0) {
260 std::vector<std::pair<SUMOTime, MSStoppingPlace*>> candidates;
262 if (stoppingPlaceCandidate.first == destStoppingPlace) {
270 candidates.push_back(std::make_pair(dummy, stoppingPlaceCandidate.first));
272 std::sort(candidates.begin(), candidates.end(),
273 [](std::tuple<SUMOTime, MSStoppingPlace*>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*>
const & t2) {
274 return std::get<0>(t1) < std::get<0>(t2) || (std::get<0>(t1) == std::get<0>(t2) && std::get<1>(t1)->getID() < std::get<1>(t2)->getID());
277 for (
auto item : candidates) {
278 if (
evaluateDestination(veh, brakeGap, newDestination, item.second, 0, 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
279#ifdef DEBUG_STOPPINGPLACE
281 std::cout <<
" altStoppingPlace=" << item.second->getID() <<
" targeting occupied stopping place (based on pure randomness) among " << candidates.size() <<
" alternatives\n";
292#ifdef DEBUG_STOPPINGPLACE
294 std::cout <<
" maxValues=" <<
joinToString(maxValues,
" ",
":") <<
"\n";
299 double minStoppingPlaceCost = 0.0;
301 for (StoppingPlaceMap_t::iterator it = stoppingPlaces.begin(); it != stoppingPlaces.end(); ++it) {
305 if (weights[
"probability"] > 0. && maxValues[
"probability"] > 0.) {
307 bool dominated =
false;
308 double endPos = it->first->getEndLanePosition();
310 assert(to1.size() > 0);
311 for (
auto altSp : stoppingPlaces) {
312 if (altSp.first == it->first) {
316 assert(to2.size() > 0);
317 if (to1.size() > to2.size()) {
318 if (std::equal(to2.begin(), to2.end(), to1.begin())) {
324 }
else if (to1 == to2 && endPos > altSp.first->getEndLanePosition()) {
334 stoppingPlaceValues[
"probability"] = 1.0 - prob / maxValues[
"probability"];
337 stoppingPlaceValues[
"probability"] = 1.0;
341 stoppingPlaceValues[
"probability"] = 0;
349 if (nearStoppingPlace ==
nullptr || stoppingPlaceCost < minStoppingPlaceCost) {
350 minStoppingPlaceCost = stoppingPlaceCost;
351 nearStoppingPlace = it->first;
352 newRoute = newRoutes[nearStoppingPlace];
354#ifdef DEBUG_STOPPINGPLACE
356 std::cout <<
" altStoppingPlace=" << it->first->
getID() <<
" score=" << stoppingPlaceCost <<
" vals=" <<
joinToString(stoppingPlaceValues,
" ",
":") <<
"\n";
361 if (nearStoppingPlace !=
nullptr) {
362 for (
auto component : stoppingPlaces[nearStoppingPlace]) {
363 scores[component.first] = component.second;
368#ifdef DEBUG_STOPPINGPLACE
370 std::cout <<
SIMTIME <<
" veh=" << veh.getID() <<
" dest=" << destStoppingPlace->getID() <<
" sufficient space\n";
375#ifdef DEBUG_STOPPINGPLACE
377 std::cout <<
" stoppingPlaceResult=" <<
Named::getIDSecure(nearStoppingPlace) <<
"\n";
380 return nearStoppingPlace;
387 std::map<MSStoppingPlace*, ConstMSEdgeVector>& newRoutes, std::map<MSStoppingPlace*, ConstMSEdgeVector>& stoppingPlaceApproaches,
406 if (insertStopIndex > 0) {
410 if (it != rerouteOriginIt) {
411 edgesUpstream.push_back(*it);
415 const MSEdge* rerouteOrigin = *rerouteOriginIt;
416 router.
compute(rerouteOrigin, posOnLane, stoppingPlaceEdge, targetPos, &veh, now, edgesToStop,
true);
417 if (edgesToStop.size() > 0) {
419 if (insertStopIndex == 0 && rerouteOrigin != veh.
getEdge()) {
420 edgesToStop.insert(edgesToStop.begin(), veh.
getEdge());
423 std::reverse(edgesUpstream.begin(), edgesUpstream.end());
424 for (
auto edge : edgesUpstream) {
425 edgesToStop.insert(edgesToStop.begin(), edge);
428 stoppingPlaceApproaches[alternative] = edgesToStop;
432 int nextDestinationIndex = route.
size() - 1;
433 if (!newDestination) {
434 std::vector<std::pair<int, double> > stopIndices = veh.
getStopIndices();
435 int nextDestStopIndex = 1 + insertStopIndex;
436 if (!keepCurrentStop) {
439 if ((
int)stopIndices.size() > nextDestStopIndex) {
440 nextDestinationIndex = stopIndices[nextDestStopIndex].first;
441 nextDestination = route.
getEdges()[nextDestinationIndex];
442 nextPos = stopIndices[nextDestStopIndex].second;
444 router.
compute(stoppingPlaceEdge, targetPos, nextDestination, nextPos, &veh, now, edgesFromStop,
true);
446 if (edgesFromStop.size() > 0 || newDestination) {
447 stoppingPlaceValues[
"probability"] = prob;
448 if (stoppingPlaceValues[
"probability"] > maxValues[
"probability"]) {
449 maxValues[
"probability"] = stoppingPlaceValues[
"probability"];
452 stoppingPlaceValues[
"absfreespace"] = stoppingPlaceValues[
"capacity"] - occupancy;
454 stoppingPlaceValues[
"relfreespace"] = stoppingPlaceValues[
"absfreespace"] /
MAX2(1.0, stoppingPlaceValues[
"capacity"]);
463 stoppingPlaceValues[
"distanceto"] = routeToPark.getDistanceBetween(veh.
getPositionOnLane(), toPos,
464 routeToPark.begin(), routeToPark.end() - 1, includeInternalLengths);
466 if (stoppingPlaceValues[
"distanceto"] == std::numeric_limits<double>::max()) {
467 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' to stopping place '%' at time=%."),
473 const double distToEnd = stoppingPlaceValues[
"distanceto"] - toPos + endPos;
475 if (distToEnd < brakeGap) {
482 const double correctionFirstEdge = veh.
getPositionOnLane() / edgesToStop.front()->getVehicleMaxSpeed(&veh);
484 stoppingPlaceValues[
"timeto"] = router.
recomputeCosts(edgesToStop, &veh,
SIMSTEP) - correctionLastEdge - correctionFirstEdge;
486 if (newDestination) {
487 stoppingPlaceValues[
"distancefrom"] = 0;
488 stoppingPlaceValues[
"timefrom"] = 0;
494 routeFromPark.begin(), routeFromPark.end() - 1, includeInternalLengths);
495 if (stoppingPlaceValues[
"distancefrom"] == std::numeric_limits<double>::max()) {
496 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' from stopping place '%' at time=%."),
501 newEdges.insert(newEdges.end(), edgesFromStop.begin() + 1, edgesFromStop.end());
502 newEdges.insert(newEdges.end(), route.
begin() + nextDestinationIndex + 1, route.
end());
506 if (!
evaluateCustomComponents(veh, brakeGap, newDestination, alternative, occupancy, prob, router, stoppingPlaceValues, stoppingPlaceApproaches[alternative], newEdges, maxValues, addInput)) {
511 stoppingPlaces[alternative] = stoppingPlaceValues;
512 newRoutes[alternative] = newEdges;
560 result[evalParam.first] =
getWeight(veh, evalParam.first +
".weight", evalParam.second);
562 result[
"probability"] =
getWeight(veh,
"probability.weight", 0.);
588 WRITE_MESSAGEF(
"Vehicle '%' does not supply vehicle parameter '%'. Using default of %\n", veh.
getID(), key,
toString(defaultWeight));
590 return defaultWeight;
596 for (
auto it = maxValues.begin(); it != maxValues.end(); ++it) {
597 if (stoppingPlaceValues[it->first] > it->second) {
598 it->second = stoppingPlaceValues[it->first];
607 for (StoppingPlaceParamMap_t::const_iterator sc = absValues.begin(); sc != absValues.end(); ++sc) {
608 double weight = weights.at(sc->first);
609 double val = sc->second;
610 if (norm.at(sc->first) && maxValues.at(sc->first) > 0.) {
611 val /= maxValues.at(sc->first);
613 cost += (invert.at(sc->first)) ? weight * (1. - val) : weight * val;
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
ConstMSEdgeVector::const_iterator MSRouteIterator
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A road/street connecting two junctions.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
double getLength() const
Returns the lane's length.
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
MSEdge & getEdge() const
Returns the lane's edge.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSVehicleRouter & getRouterTT(int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
bool hasInternalLinks() const
return whether the network contains internal links
int size() const
Returns the number of edges to pass.
const ConstMSEdgeVector & getEdges() const
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
const MSEdge * getLastEdge() const
returns the destination edge
const RGBColor & getColor() const
Returns the color.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
double getDistanceBetween(double fromPos, double toPos, const MSLane *fromLane, const MSLane *toLane, int routePosition=0) const
Compute the distance between 2 given edges on this route, optionally including the length of internal...
A lane area vehicles can halt at.
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
virtual double getLastFreePos(const SUMOVehicle &forVehicle, double brakePos=0) const
Returns the last free position on this stop.
virtual bool useStoppingPlace(MSStoppingPlace *stoppingPlace)
Whether the stopping place should be included in the search (can be used to add an additional filter)
virtual void rememberBlockedStoppingPlace(SUMOVehicle &veh, const MSStoppingPlace *stoppingPlace, bool blocked)=0
store the blocked stopping place in the vehicle
virtual SUMOTime sawBlockedStoppingPlace(SUMOVehicle &veh, MSStoppingPlace *place, bool local)=0
ask the vehicle when it has seen the stopping place
StoppingPlaceParamSwitchMap_t myNormParams
std::map< std::string, bool > StoppingPlaceParamSwitchMap_t
std::map< std::string, double > StoppingPlaceParamMap_t
static void updateMaxValues(StoppingPlaceParamMap_t &stoppingPlaceValues, StoppingPlaceParamMap_t &maxValues)
keep track of the maximum values of each component
virtual SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouter(SUMOVehicle &veh, const MSEdgeVector &prohibited={})
Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
std::map< MSStoppingPlace *, StoppingPlaceParamMap_t, ComparatorIdLess > StoppingPlaceMap_t
virtual int getNumberStoppingPlaceReroutes(SUMOVehicle &veh)=0
ask how many times already the vehicle has been rerouted to another stopping place
virtual double getStoppingPlaceCapacity(MSStoppingPlace *stoppingPlace)=0
Return the number of places the StoppingPlace provides.
static double getTargetValue(const StoppingPlaceParamMap_t &absValues, const StoppingPlaceParamMap_t &maxValues, const StoppingPlaceParamMap_t &weights, const StoppingPlaceParamSwitchMap_t &norm, const StoppingPlaceParamSwitchMap_t &invert)
compute the scalar target function value by means of a linear combination of all components/weights a...
const MSRouteIterator determineRerouteOrigin(SUMOVehicle &veh, int insertStopIndex)
Determine the rerouting origin edge (not necessarily the current edge of the vehicle!...
virtual double getStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace)=0
Return the number of occupied places of the StoppingPlace.
const std::string myParamPrefix
double getWeight(SUMOVehicle &veh, const std::string param, const double defaultWeight, const bool warn=false)
read the value of a stopping place search param, e.g. a component weight factor
virtual StoppingPlaceParamMap_t collectWeights(SUMOVehicle &veh)
read target function weights for this vehicle
StoppingPlaceParamMap_t myEvalParams
MSStoppingPlace * rerouteStoppingPlace(MSStoppingPlace *destStoppingPlace, const std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &scores, const MSEdgeVector &closedEdges={}, const int insertStopIndex=0, const bool keepCurrentStop=true)
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
StoppingPlaceParamSwitchMap_t myInvertParams
virtual void rememberStoppingPlaceScore(SUMOVehicle &veh, MSStoppingPlace *place, const std::string &score)=0
store the stopping place score in the vehicle
virtual void resetStoppingPlaceScores(SUMOVehicle &veh)=0
forget all stopping place score for this vehicle
virtual void setNumberStoppingPlaceReroutes(SUMOVehicle &veh, int value)=0
update the number of reroutes for the vehicle
virtual bool validComponentValues(StoppingPlaceParamMap_t &stoppingPlaceValues)
Whether the stopping place should be discarded due to its results from the component evaluation (allo...
virtual bool evaluateCustomComponents(SUMOVehicle &veh, double brakeGap, bool newDestination, MSStoppingPlace *alternative, double occupancy, double prob, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, StoppingPlaceParamMap_t &stoppingPlaceValues, ConstMSEdgeVector &newRoute, ConstMSEdgeVector &stoppingPlaceApproach, StoppingPlaceParamMap_t &maxValues, StoppingPlaceParamMap_t &addInput)
Compute some custom target function components.
std::pair< MSStoppingPlace *, bool > StoppingPlaceVisible
virtual double getLastStepStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace)=0
Return the number of occupied places of the StoppingPlace from the previous time step.
virtual bool evaluateDestination(SUMOVehicle &veh, double brakeGap, bool newDestination, MSStoppingPlace *alternative, double occupancy, double prob, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, StoppingPlaceMap_t &stoppingPlaces, std::map< MSStoppingPlace *, ConstMSEdgeVector > &newRoutes, std::map< MSStoppingPlace *, ConstMSEdgeVector > &stoppingPlaceApproaches, StoppingPlaceParamMap_t &maxValues, StoppingPlaceParamMap_t &addInput, const int insertStopIndex=0, const bool keepCurrentStop=true)
compute the target function for a single alternative
MSStoppingPlaceRerouter()=delete
Constructor.
const SUMOVTypeParameter & getParameter() const
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
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
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual int getRNGIndex() const =0
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual SumoRNG * getRNG() const =0
Returns the associated RNG for this object.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
virtual const std::list< MSStop > & getStops() const =0
virtual double getArrivalPos() const =0
Returns this vehicle's desired arrivalPos for its current route (may change on reroute)
virtual double getBrakeGap(bool delayed=false) const =0
get distance for coming to a stop (used for rerouting checks)
virtual std::vector< std::pair< int, double > > getStopIndices() const =0
return list of route indices and stop positions for the remaining stops
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual const MSRoute & getRoute() const =0
Returns the current route.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter