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
141 #ifdef DEBUG_STOPPINGPLACE
144 <<
" newDest=" << newDestination
149 std::map<MSStoppingPlace*, ConstMSEdgeVector> newRoutes;
150 std::map<MSStoppingPlace*, ConstMSEdgeVector> stopApproaches;
153 for (
auto param : weights) {
154 maxValues[param.first] = 0.;
162 if (onTheWay !=
nullptr) {
164 if (newDestination) {
165 newRoute.push_back(veh.
getEdge());
167 bool valid =
evaluateDestination(veh, brakeGap, newDestination, onTheWay,
getLastStepStoppingPlaceOccupancy(onTheWay), 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, addInput);
169 WRITE_WARNINGF(
TL(
"Stopping place '%' along the way cannot be used by vehicle '%' for unknown reason"), onTheWay->
getID(), veh.
getID());
172 newRoute = newRoutes[onTheWay];
176 int numAlternatives = 0;
177 std::vector<std::tuple<SUMOTime, MSStoppingPlace*, int>> blockedTimes;
180 if (destStoppingPlace !=
nullptr) {
185 const double stoppingPlaceFrustration =
getWeight(veh,
"frustration", 100);
186 const double stoppingPlaceKnowledge =
getWeight(veh,
"knowledge", 0);
188 for (
int i = 0; i < (int)stoppingPlaceCandidates.size(); ++i) {
194 const bool visible = stoppingPlaceCandidates[i].second || (stoppingPlaceCandidates[i].first == destStoppingPlace && destVisible);
196 if (!visible && (stoppingPlaceKnowledge == 0 || stoppingPlaceKnowledge <
RandHelper::rand(veh.
getRNG()))) {
202 if (blockedTime >= 0 &&
SIMSTEP - blockedTime < stoppingPlaceMemory) {
204 occupancy = capacity;
205 blockedTimes.push_back(std::make_tuple(blockedTime, stoppingPlaceCandidates[i].first, i));
206 #ifdef DEBUG_STOPPINGPLACE
208 std::cout <<
" altStoppingPlace=" << stoppingPlaceCandidates[i].first->getID() <<
" was blocked at " <<
time2string(blockedTime) <<
"\n";
214 if (
evaluateDestination(veh, brakeGap, newDestination, stoppingPlaceCandidates[i].first, occupancy, probs[i], router, stoppingPlaces, newRoutes, stopApproaches, maxValues, addInput)) {
217 }
else if (visible) {
225 if (numAlternatives == 0) {
227 std::sort(blockedTimes.begin(), blockedTimes.end(),
228 [](std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t2) {
229 if (std::get<0>(t1) < std::get<0>(t2)) {
232 if (std::get<0>(t1) == std::get<0>(t2)) {
233 if (std::get<1>(t1)->getID() < std::get<1>(t2)->getID()) {
236 if (std::get<1>(t1)->getID() == std::get<1>(t2)->getID()) {
237 return std::get<2>(t1) < std::get<2>(t2);
243 for (
auto item : blockedTimes) {
245 double prob = probs[std::get<2>(item)];
249 if (
evaluateDestination(veh, brakeGap, newDestination, sp, occupancy, prob, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, addInput)) {
250 #ifdef DEBUG_STOPPINGPLACE
252 std::cout <<
" altStoppingPlace=" << sp->
getID() <<
" targeting occupied stopping place based on blockTime " <<
STEPS2TIME(std::get<0>(item)) <<
" among " << blockedTimes.size() <<
" alternatives\n";
260 if (numAlternatives == 0) {
262 std::vector<std::pair<SUMOTime, MSStoppingPlace*>> candidates;
264 if (stoppingPlaceCandidate.first == destStoppingPlace) {
272 candidates.push_back(std::make_pair(dummy, stoppingPlaceCandidate.first));
274 std::sort(candidates.begin(), candidates.end(),
275 [](std::tuple<SUMOTime, MSStoppingPlace*>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*>
const & t2) {
276 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());
279 for (
auto item : candidates) {
280 if (
evaluateDestination(veh, brakeGap, newDestination, item.second, 0, 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, addInput)) {
281 #ifdef DEBUG_STOPPINGPLACE
283 std::cout <<
" altStoppingPlace=" << item.second->getID() <<
" targeting occupied stopping place (based on pure randomness) among " << candidates.size() <<
" alternatives\n";
294 #ifdef DEBUG_STOPPINGPLACE
296 std::cout <<
" maxValues=" <<
joinToString(maxValues,
" ",
":") <<
"\n";
301 double minStoppingPlaceCost = 0.0;
303 for (StoppingPlaceMap_t::iterator it = stoppingPlaces.begin(); it != stoppingPlaces.end(); ++it) {
307 if (weights[
"probability"] > 0. && maxValues[
"probability"] > 0.) {
309 bool dominated =
false;
310 double endPos = it->first->getEndLanePosition();
312 assert(to1.size() > 0);
313 for (
auto altSp : stoppingPlaces) {
314 if (altSp.first == it->first) {
318 assert(to2.size() > 0);
319 if (to1.size() > to2.size()) {
320 if (std::equal(to2.begin(), to2.end(), to1.begin())) {
326 }
else if (to1 == to2 && endPos > altSp.first->getEndLanePosition()) {
336 stoppingPlaceValues[
"probability"] = 1.0 - prob / maxValues[
"probability"];
339 stoppingPlaceValues[
"probability"] = 1.0;
343 stoppingPlaceValues[
"probability"] = 0;
351 if (nearStoppingPlace ==
nullptr || stoppingPlaceCost < minStoppingPlaceCost) {
352 minStoppingPlaceCost = stoppingPlaceCost;
353 nearStoppingPlace = it->first;
354 newRoute = newRoutes[nearStoppingPlace];
356 #ifdef DEBUG_STOPPINGPLACE
358 std::cout <<
" altStoppingPlace=" << it->first->
getID() <<
" score=" << stoppingPlaceCost <<
" vals=" <<
joinToString(stoppingPlaceValues,
" ",
":") <<
"\n";
364 #ifdef DEBUG_STOPPINGPLACE
366 std::cout <<
SIMTIME <<
" veh=" << veh.getID() <<
" dest=" << destStoppingPlace->getID() <<
" sufficient space\n";
371 #ifdef DEBUG_STOPPINGPLACE
373 std::cout <<
" stoppingPlaceResult=" <<
Named::getIDSecure(nearStoppingPlace) <<
"\n";
377 return nearStoppingPlace;
384 std::map<MSStoppingPlace*, ConstMSEdgeVector>& newRoutes, std::map<MSStoppingPlace*, ConstMSEdgeVector>& stoppingPlaceApproaches,
403 if (edgesToStop.size() > 0) {
405 if (rerouteOrigin != veh.
getEdge()) {
406 edgesToStop.insert(edgesToStop.begin(), veh.
getEdge());
409 stoppingPlaceApproaches[alternative] = edgesToStop;
413 int nextDestinationIndex = route.
size() - 1;
414 if (!newDestination) {
415 std::vector<std::pair<int, double> > stopIndices = veh.
getStopIndices();
416 if (stopIndices.size() > 1) {
417 nextDestinationIndex = stopIndices[1].first;
418 nextDestination = route.
getEdges()[nextDestinationIndex];
419 nextPos = stopIndices[1].second;
422 router.
compute(stoppingPlaceEdge, targetPos, nextDestination, nextPos, &veh, now, edgesFromStop,
true);
424 if (edgesFromStop.size() > 0 || newDestination) {
425 stoppingPlaceValues[
"probability"] = prob;
426 if (stoppingPlaceValues[
"probability"] > maxValues[
"probability"]) {
427 maxValues[
"probability"] = stoppingPlaceValues[
"probability"];
430 stoppingPlaceValues[
"absfreespace"] = stoppingPlaceValues[
"capacity"] - occupancy;
432 stoppingPlaceValues[
"relfreespace"] = stoppingPlaceValues[
"absfreespace"] /
MAX2(1.0, stoppingPlaceValues[
"capacity"]);
442 routeToPark.
begin(), routeToPark.
end() - 1, includeInternalLengths);
444 if (stoppingPlaceValues[
"distanceto"] == std::numeric_limits<double>::max()) {
445 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' to stopping place '%' at time=%."),
451 const double distToEnd = stoppingPlaceValues[
"distanceto"] - toPos + endPos;
453 if (distToEnd < brakeGap) {
461 if (newDestination) {
462 stoppingPlaceValues[
"distancefrom"] = 0;
463 stoppingPlaceValues[
"timefrom"] = 0;
469 routeFromPark.
begin(), routeFromPark.
end() - 1, includeInternalLengths);
470 if (stoppingPlaceValues[
"distancefrom"] == std::numeric_limits<double>::max()) {
471 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' from stopping place '%' at time=%."),
476 newEdges.insert(newEdges.end(), edgesFromStop.begin() + 1, edgesFromStop.end());
477 newEdges.insert(newEdges.end(), route.
begin() + nextDestinationIndex + 1, route.
end());
481 if (!
evaluateCustomComponents(veh, brakeGap, newDestination, alternative, occupancy, prob, router, stoppingPlaceValues, stoppingPlaceApproaches[alternative], newEdges, maxValues, addInput)) {
486 stoppingPlaces[alternative] = stoppingPlaceValues;
487 newRoutes[alternative] = newEdges;
535 result[evalParam.first] =
getWeight(veh, evalParam.first +
".weight", evalParam.second);
537 result[
"probability"] =
getWeight(veh,
"probability.weight", 0.);
563 WRITE_MESSAGEF(
"Vehicle '%' does not supply vehicle parameter '%'. Using default of %\n", veh.
getID(), key,
toString(defaultWeight));
565 return defaultWeight;
571 for (
auto it = maxValues.begin(); it != maxValues.end(); ++it) {
572 if (stoppingPlaceValues[it->first] > it->second) {
573 it->second = stoppingPlaceValues[it->first];
582 for (StoppingPlaceParamMap_t::const_iterator sc = absValues.begin(); sc != absValues.end(); ++sc) {
583 double weight = weights.at(sc->first);
584 double val = sc->second;
585 if (norm.at(sc->first) && maxValues.at(sc->first) > 0.) {
586 val /= maxValues.at(sc->first);
588 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.
double getLength() const
return the length of the edge
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
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 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...
const ConstMSEdgeVector & getEdges() const
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
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.
MSStoppingPlace * reroute(std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &addInput, const MSEdgeVector &closedEdges={})
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
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 int getRNGIndex() const =0
virtual SumoRNG * getRNG() const =0
Returns the associated RNG for this object.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
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 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.
virtual MSParkingArea * getNextParkingArea()=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)
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter