33#define DEBUGCOND (veh.isSelected())
38 myStoppingType(stoppingType), myParamPrefix(paramPrefix), myCheckValidity(checkValidity), myConsiderDestVisibility(checkVisibility) {
39 myEvalParams = { {
"probability", 0.}, {
"capacity", 0.}, {
"timefrom", 0.}, {
"timeto", 0.}, {
"distancefrom", 0.}, {
"distanceto", 1.}, {
"absfreespace", 0.}, {
"relfreespace", 0.}, };
40 myInvertParams = { {
"probability",
false}, {
"capacity",
true }, {
"timefrom",
false }, {
"timeto",
false }, {
"distancefrom",
false }, {
"distanceto",
false }, {
"absfreespace",
true }, {
"relfreespace",
true } };
41 for (
auto param : addEvalParams) {
43 myInvertParams[param.first] = (addInvertParams.count(param.first) > 0) ? addInvertParams[param.first] :
false;
46 myNormParams.insert({param.first, param.first !=
"probability"});
64 bool destVisible =
false;
67 if (destStoppingPlace ==
nullptr) {
73 for (
auto stoppingPlace : stoppingPlaceCandidates) {
74 if (stoppingPlace.first == destStoppingPlace && stoppingPlace.second) {
83 const int stopAnywhere = (int)
getWeight(veh,
"anywhere", -1);
95#ifdef DEBUG_STOPPINGPLACE
103 double bestDist = std::numeric_limits<double>::max();
107 if (&item.first->getLane().getEdge() == veh.
getEdge()
109 const double distToStart = item.first->getBeginLanePosition() - veh.
getPositionOnLane();
110 const double distToEnd = item.first->getEndLanePosition() - veh.
getPositionOnLane();
111 if (distToEnd > brakeGap) {
113 if (distToStart < bestDist) {
114 bestDist = distToStart;
115 onTheWay = item.first;
123#ifdef DEBUG_STOPPINGPLACE
142#ifdef DEBUG_STOPPINGPLACE
145 <<
" newDest=" << newDestination
150 std::map<MSStoppingPlace*, ConstMSEdgeVector> newRoutes;
151 std::map<MSStoppingPlace*, ConstMSEdgeVector> stopApproaches;
154 for (
auto param : weights) {
155 maxValues[param.first] = 0.;
163 if (onTheWay !=
nullptr) {
165 if (newDestination) {
166 newRoute.push_back(veh.
getEdge());
168 bool valid =
evaluateDestination(veh, brakeGap, newDestination, onTheWay,
getLastStepStoppingPlaceOccupancy(onTheWay), 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores);
170 WRITE_WARNINGF(
TL(
"Stopping place '%' along the way cannot be used by vehicle '%' for unknown reason"), onTheWay->
getID(), veh.
getID());
173 newRoute = newRoutes[onTheWay];
177 int numAlternatives = 0;
178 std::vector<std::tuple<SUMOTime, MSStoppingPlace*, int>> blockedTimes;
181 if (destStoppingPlace !=
nullptr) {
186 const double stoppingPlaceFrustration =
getWeight(veh,
"frustration", 100);
187 const double stoppingPlaceKnowledge =
getWeight(veh,
"knowledge", 0);
189 for (
int i = 0; i < (int)stoppingPlaceCandidates.size(); ++i) {
195 const bool visible = stoppingPlaceCandidates[i].second || (stoppingPlaceCandidates[i].first == destStoppingPlace && destVisible);
197 if (!visible && (stoppingPlaceKnowledge == 0 || stoppingPlaceKnowledge <
RandHelper::rand(veh.
getRNG()))) {
203 if (blockedTime >= 0 &&
SIMSTEP - blockedTime < stoppingPlaceMemory) {
205 occupancy = capacity;
206 blockedTimes.push_back(std::make_tuple(blockedTime, stoppingPlaceCandidates[i].first, i));
207#ifdef DEBUG_STOPPINGPLACE
209 std::cout <<
" altStoppingPlace=" << stoppingPlaceCandidates[i].first->getID() <<
" was blocked at " <<
time2string(blockedTime) <<
"\n";
215 if (
evaluateDestination(veh, brakeGap, newDestination, stoppingPlaceCandidates[i].first, occupancy, probs[i], router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores)) {
218 }
else if (visible) {
226 if (numAlternatives == 0) {
228 std::sort(blockedTimes.begin(), blockedTimes.end(),
229 [](std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t2) {
230 if (std::get<0>(t1) < std::get<0>(t2)) {
233 if (std::get<0>(t1) == std::get<0>(t2)) {
234 if (std::get<1>(t1)->getID() < std::get<1>(t2)->getID()) {
237 if (std::get<1>(t1)->getID() == std::get<1>(t2)->getID()) {
238 return std::get<2>(t1) < std::get<2>(t2);
244 for (
auto item : blockedTimes) {
246 double prob = probs[std::get<2>(item)];
250 if (
evaluateDestination(veh, brakeGap, newDestination, sp, occupancy, prob, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores)) {
251#ifdef DEBUG_STOPPINGPLACE
253 std::cout <<
" altStoppingPlace=" << sp->
getID() <<
" targeting occupied stopping place based on blockTime " <<
STEPS2TIME(std::get<0>(item)) <<
" among " << blockedTimes.size() <<
" alternatives\n";
261 if (numAlternatives == 0) {
263 std::vector<std::pair<SUMOTime, MSStoppingPlace*>> candidates;
265 if (stoppingPlaceCandidate.first == destStoppingPlace) {
273 candidates.push_back(std::make_pair(dummy, stoppingPlaceCandidate.first));
275 std::sort(candidates.begin(), candidates.end(),
276 [](std::tuple<SUMOTime, MSStoppingPlace*>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*>
const & t2) {
277 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());
280 for (
auto item : candidates) {
281 if (
evaluateDestination(veh, brakeGap, newDestination, item.second, 0, 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores)) {
282#ifdef DEBUG_STOPPINGPLACE
284 std::cout <<
" altStoppingPlace=" << item.second->getID() <<
" targeting occupied stopping place (based on pure randomness) among " << candidates.size() <<
" alternatives\n";
295#ifdef DEBUG_STOPPINGPLACE
297 std::cout <<
" maxValues=" <<
joinToString(maxValues,
" ",
":") <<
"\n";
302 double minStoppingPlaceCost = 0.0;
304 for (StoppingPlaceMap_t::iterator it = stoppingPlaces.begin(); it != stoppingPlaces.end(); ++it) {
308 if (weights[
"probability"] > 0. && maxValues[
"probability"] > 0.) {
310 bool dominated =
false;
311 double endPos = it->first->getEndLanePosition();
313 assert(to1.size() > 0);
314 for (
auto altSp : stoppingPlaces) {
315 if (altSp.first == it->first) {
319 assert(to2.size() > 0);
320 if (to1.size() > to2.size()) {
321 if (std::equal(to2.begin(), to2.end(), to1.begin())) {
327 }
else if (to1 == to2 && endPos > altSp.first->getEndLanePosition()) {
337 stoppingPlaceValues[
"probability"] = 1.0 - prob / maxValues[
"probability"];
340 stoppingPlaceValues[
"probability"] = 1.0;
344 stoppingPlaceValues[
"probability"] = 0;
352 if (nearStoppingPlace ==
nullptr || stoppingPlaceCost < minStoppingPlaceCost) {
353 minStoppingPlaceCost = stoppingPlaceCost;
354 nearStoppingPlace = it->first;
355 newRoute = newRoutes[nearStoppingPlace];
357#ifdef DEBUG_STOPPINGPLACE
359 std::cout <<
" altStoppingPlace=" << it->first->
getID() <<
" score=" << stoppingPlaceCost <<
" vals=" <<
joinToString(stoppingPlaceValues,
" ",
":") <<
"\n";
364 if (nearStoppingPlace !=
nullptr) {
365 for (
auto component : stoppingPlaces[nearStoppingPlace]) {
366 scores[component.first] = component.second;
371#ifdef DEBUG_STOPPINGPLACE
373 std::cout <<
SIMTIME <<
" veh=" << veh.getID() <<
" dest=" << destStoppingPlace->getID() <<
" sufficient space\n";
378#ifdef DEBUG_STOPPINGPLACE
380 std::cout <<
" stoppingPlaceResult=" <<
Named::getIDSecure(nearStoppingPlace) <<
"\n";
383 return nearStoppingPlace;
390 std::map<MSStoppingPlace*, ConstMSEdgeVector>& newRoutes, std::map<MSStoppingPlace*, ConstMSEdgeVector>& stoppingPlaceApproaches,
409 if (edgesToStop.size() > 0) {
411 if (rerouteOrigin != veh.
getEdge()) {
412 edgesToStop.insert(edgesToStop.begin(), veh.
getEdge());
415 stoppingPlaceApproaches[alternative] = edgesToStop;
419 int nextDestinationIndex = route.
size() - 1;
420 if (!newDestination) {
421 std::vector<std::pair<int, double> > stopIndices = veh.
getStopIndices();
422 if (stopIndices.size() > 1) {
423 nextDestinationIndex = stopIndices[1].first;
424 nextDestination = route.
getEdges()[nextDestinationIndex];
425 nextPos = stopIndices[1].second;
428 router.
compute(stoppingPlaceEdge, targetPos, nextDestination, nextPos, &veh, now, edgesFromStop,
true);
430 if (edgesFromStop.size() > 0 || newDestination) {
431 stoppingPlaceValues[
"probability"] = prob;
432 if (stoppingPlaceValues[
"probability"] > maxValues[
"probability"]) {
433 maxValues[
"probability"] = stoppingPlaceValues[
"probability"];
436 stoppingPlaceValues[
"absfreespace"] = stoppingPlaceValues[
"capacity"] - occupancy;
438 stoppingPlaceValues[
"relfreespace"] = stoppingPlaceValues[
"absfreespace"] /
MAX2(1.0, stoppingPlaceValues[
"capacity"]);
447 stoppingPlaceValues[
"distanceto"] = routeToPark.getDistanceBetween(veh.
getPositionOnLane(), toPos,
448 routeToPark.begin(), routeToPark.end() - 1, includeInternalLengths);
450 if (stoppingPlaceValues[
"distanceto"] == std::numeric_limits<double>::max()) {
451 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' to stopping place '%' at time=%."),
457 const double distToEnd = stoppingPlaceValues[
"distanceto"] - toPos + endPos;
459 if (distToEnd < brakeGap) {
467 if (newDestination) {
468 stoppingPlaceValues[
"distancefrom"] = 0;
469 stoppingPlaceValues[
"timefrom"] = 0;
475 routeFromPark.begin(), routeFromPark.end() - 1, includeInternalLengths);
476 if (stoppingPlaceValues[
"distancefrom"] == std::numeric_limits<double>::max()) {
477 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' from stopping place '%' at time=%."),
482 newEdges.insert(newEdges.end(), edgesFromStop.begin() + 1, edgesFromStop.end());
483 newEdges.insert(newEdges.end(), route.
begin() + nextDestinationIndex + 1, route.
end());
487 if (!
evaluateCustomComponents(veh, brakeGap, newDestination, alternative, occupancy, prob, router, stoppingPlaceValues, stoppingPlaceApproaches[alternative], newEdges, maxValues, addInput)) {
492 stoppingPlaces[alternative] = stoppingPlaceValues;
493 newRoutes[alternative] = newEdges;
541 result[evalParam.first] =
getWeight(veh, evalParam.first +
".weight", evalParam.second);
543 result[
"probability"] =
getWeight(veh,
"probability.weight", 0.);
569 WRITE_MESSAGEF(
"Vehicle '%' does not supply vehicle parameter '%'. Using default of %\n", veh.
getID(), key,
toString(defaultWeight));
571 return defaultWeight;
577 for (
auto it = maxValues.begin(); it != maxValues.end(); ++it) {
578 if (stoppingPlaceValues[it->first] > it->second) {
579 it->second = stoppingPlaceValues[it->first];
588 for (StoppingPlaceParamMap_t::const_iterator sc = absValues.begin(); sc != absValues.end(); ++sc) {
589 double weight = weights.at(sc->first);
590 double val = sc->second;
591 if (norm.at(sc->first) && maxValues.at(sc->first) > 0.) {
592 val /= maxValues.at(sc->first);
594 cost += (invert.at(sc->first)) ? weight * (1. - val) : weight * val;
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_PARKING_AREA
A parking area.
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.
MSEdge & getEdge() const
Returns the lane's edge.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSVehicleRouter & getRouterTT(const 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.
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
MSStoppingPlace * reroute(std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &scores, const MSEdgeVector &closedEdges={})
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
std::map< std::string, double > StoppingPlaceParamMap_t
const bool myConsiderDestVisibility
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 SumoXMLTag myStoppingType
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
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)
compute the target function for a single alternative
StoppingPlaceParamMap_t myEvalParams
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.
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 ConstMSEdgeVector::const_iterator getRerouteOrigin() const =0
Returns the starting point for reroutes (usually the current edge)
virtual MSParkingArea * getNextParkingArea()=0
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 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