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"});
52 const MSEdgeVector& closedEdges,
const int insertStopIndex,
const bool keepCurrentStop) {
65 bool destVisible =
false;
68 if (destStoppingPlace ==
nullptr) {
74 for (
auto stoppingPlace : stoppingPlaceCandidates) {
75 if (stoppingPlace.first == destStoppingPlace && stoppingPlace.second) {
84 const int stopAnywhere = (int)
getWeight(veh,
"anywhere", -1);
96#ifdef DEBUG_STOPPINGPLACE
104 double bestDist = std::numeric_limits<double>::max();
108 if (&item.first->getLane().getEdge() == veh.
getEdge()
110 const double distToStart = item.first->getBeginLanePosition() - veh.
getPositionOnLane();
111 const double distToEnd = item.first->getEndLanePosition() - veh.
getPositionOnLane();
112 if (distToEnd > brakeGap) {
114 if (distToStart < bestDist) {
115 bestDist = distToStart;
116 onTheWay = item.first;
124#ifdef DEBUG_STOPPINGPLACE
143#ifdef DEBUG_STOPPINGPLACE
146 <<
" newDest=" << newDestination
151 std::map<MSStoppingPlace*, ConstMSEdgeVector> newRoutes;
152 std::map<MSStoppingPlace*, ConstMSEdgeVector> stopApproaches;
155 for (
auto param : weights) {
156 maxValues[param.first] = 0.;
164 if (onTheWay !=
nullptr) {
166 if (newDestination) {
167 newRoute.push_back(veh.
getEdge());
169 bool valid =
evaluateDestination(veh, brakeGap, newDestination, onTheWay,
getLastStepStoppingPlaceOccupancy(onTheWay), 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop);
171 WRITE_WARNINGF(
TL(
"Stopping place '%' along the way cannot be used by vehicle '%' for unknown reason"), onTheWay->
getID(), veh.
getID());
174 newRoute = newRoutes[onTheWay];
178 int numAlternatives = 0;
179 std::vector<std::tuple<SUMOTime, MSStoppingPlace*, int>> blockedTimes;
182 if (destStoppingPlace !=
nullptr) {
187 const double stoppingPlaceFrustration =
getWeight(veh,
"frustration", 100);
188 const double stoppingPlaceKnowledge =
getWeight(veh,
"knowledge", 0);
190 for (
int i = 0; i < (int)stoppingPlaceCandidates.size(); ++i) {
196 const bool visible = stoppingPlaceCandidates[i].second || (stoppingPlaceCandidates[i].first == destStoppingPlace && destVisible);
198 if (!visible && (stoppingPlaceKnowledge == 0 || stoppingPlaceKnowledge <
RandHelper::rand(veh.
getRNG()))) {
204 if (blockedTime >= 0 &&
SIMSTEP - blockedTime < stoppingPlaceMemory) {
206 occupancy = capacity;
207 blockedTimes.push_back(std::make_tuple(blockedTime, stoppingPlaceCandidates[i].first, i));
208#ifdef DEBUG_STOPPINGPLACE
210 std::cout <<
" altStoppingPlace=" << stoppingPlaceCandidates[i].first->getID() <<
" was blocked at " <<
time2string(blockedTime) <<
"\n";
216 if (
evaluateDestination(veh, brakeGap, newDestination, stoppingPlaceCandidates[i].first, occupancy, probs[i], router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
219 }
else if (visible) {
227 if (numAlternatives == 0) {
229 std::sort(blockedTimes.begin(), blockedTimes.end(),
230 [](std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*, int>
const & t2) {
231 if (std::get<0>(t1) < std::get<0>(t2)) {
234 if (std::get<0>(t1) == std::get<0>(t2)) {
235 if (std::get<1>(t1)->getID() < std::get<1>(t2)->getID()) {
238 if (std::get<1>(t1)->getID() == std::get<1>(t2)->getID()) {
239 return std::get<2>(t1) < std::get<2>(t2);
245 for (
auto item : blockedTimes) {
247 double prob = probs[std::get<2>(item)];
251 if (
evaluateDestination(veh, brakeGap, newDestination, sp, occupancy, prob, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
252#ifdef DEBUG_STOPPINGPLACE
254 std::cout <<
" altStoppingPlace=" << sp->
getID() <<
" targeting occupied stopping place based on blockTime " <<
STEPS2TIME(std::get<0>(item)) <<
" among " << blockedTimes.size() <<
" alternatives\n";
262 if (numAlternatives == 0) {
264 std::vector<std::pair<SUMOTime, MSStoppingPlace*>> candidates;
266 if (stoppingPlaceCandidate.first == destStoppingPlace) {
274 candidates.push_back(std::make_pair(dummy, stoppingPlaceCandidate.first));
276 std::sort(candidates.begin(), candidates.end(),
277 [](std::tuple<SUMOTime, MSStoppingPlace*>
const & t1, std::tuple<SUMOTime, MSStoppingPlace*>
const & t2) {
278 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());
281 for (
auto item : candidates) {
282 if (
evaluateDestination(veh, brakeGap, newDestination, item.second, 0, 1, router, stoppingPlaces, newRoutes, stopApproaches, maxValues, scores, insertStopIndex, keepCurrentStop)) {
283#ifdef DEBUG_STOPPINGPLACE
285 std::cout <<
" altStoppingPlace=" << item.second->getID() <<
" targeting occupied stopping place (based on pure randomness) among " << candidates.size() <<
" alternatives\n";
296#ifdef DEBUG_STOPPINGPLACE
298 std::cout <<
" maxValues=" <<
joinToString(maxValues,
" ",
":") <<
"\n";
303 double minStoppingPlaceCost = 0.0;
305 for (StoppingPlaceMap_t::iterator it = stoppingPlaces.begin(); it != stoppingPlaces.end(); ++it) {
309 if (weights[
"probability"] > 0. && maxValues[
"probability"] > 0.) {
311 bool dominated =
false;
312 double endPos = it->first->getEndLanePosition();
314 assert(to1.size() > 0);
315 for (
auto altSp : stoppingPlaces) {
316 if (altSp.first == it->first) {
320 assert(to2.size() > 0);
321 if (to1.size() > to2.size()) {
322 if (std::equal(to2.begin(), to2.end(), to1.begin())) {
328 }
else if (to1 == to2 && endPos > altSp.first->getEndLanePosition()) {
338 stoppingPlaceValues[
"probability"] = 1.0 - prob / maxValues[
"probability"];
341 stoppingPlaceValues[
"probability"] = 1.0;
345 stoppingPlaceValues[
"probability"] = 0;
353 if (nearStoppingPlace ==
nullptr || stoppingPlaceCost < minStoppingPlaceCost) {
354 minStoppingPlaceCost = stoppingPlaceCost;
355 nearStoppingPlace = it->first;
356 newRoute = newRoutes[nearStoppingPlace];
358#ifdef DEBUG_STOPPINGPLACE
360 std::cout <<
" altStoppingPlace=" << it->first->
getID() <<
" score=" << stoppingPlaceCost <<
" vals=" <<
joinToString(stoppingPlaceValues,
" ",
":") <<
"\n";
365 if (nearStoppingPlace !=
nullptr) {
366 for (
auto component : stoppingPlaces[nearStoppingPlace]) {
367 scores[component.first] = component.second;
372#ifdef DEBUG_STOPPINGPLACE
374 std::cout <<
SIMTIME <<
" veh=" << veh.getID() <<
" dest=" << destStoppingPlace->getID() <<
" sufficient space\n";
379#ifdef DEBUG_STOPPINGPLACE
381 std::cout <<
" stoppingPlaceResult=" <<
Named::getIDSecure(nearStoppingPlace) <<
"\n";
384 return nearStoppingPlace;
391 std::map<MSStoppingPlace*, ConstMSEdgeVector>& newRoutes, std::map<MSStoppingPlace*, ConstMSEdgeVector>& stoppingPlaceApproaches,
410 if (insertStopIndex > 0) {
414 if (it != rerouteOriginIt) {
415 edgesUpstream.push_back(*it);
419 const MSEdge* rerouteOrigin = *rerouteOriginIt;
420 router.
compute(rerouteOrigin, posOnLane, stoppingPlaceEdge, targetPos, &veh, now, edgesToStop,
true);
421 if (edgesToStop.size() > 0) {
423 if (insertStopIndex == 0 && rerouteOrigin != veh.
getEdge()) {
424 edgesToStop.insert(edgesToStop.begin(), veh.
getEdge());
427 std::reverse(edgesUpstream.begin(), edgesUpstream.end());
428 for (
auto edge : edgesUpstream) {
429 edgesToStop.insert(edgesToStop.begin(), edge);
432 stoppingPlaceApproaches[alternative] = edgesToStop;
436 int nextDestinationIndex = route.
size() - 1;
437 if (!newDestination) {
438 std::vector<std::pair<int, double> > stopIndices = veh.
getStopIndices();
439 int nextDestStopIndex = 1 + insertStopIndex;
440 if (!keepCurrentStop) {
443 if ((
int)stopIndices.size() > nextDestStopIndex) {
444 nextDestinationIndex = stopIndices[nextDestStopIndex].first;
445 nextDestination = route.
getEdges()[nextDestinationIndex];
446 nextPos = stopIndices[nextDestStopIndex].second;
448 router.
compute(stoppingPlaceEdge, targetPos, nextDestination, nextPos, &veh, now, edgesFromStop,
true);
450 if (edgesFromStop.size() > 0 || newDestination) {
451 stoppingPlaceValues[
"probability"] = prob;
452 if (stoppingPlaceValues[
"probability"] > maxValues[
"probability"]) {
453 maxValues[
"probability"] = stoppingPlaceValues[
"probability"];
456 stoppingPlaceValues[
"absfreespace"] = stoppingPlaceValues[
"capacity"] - occupancy;
458 stoppingPlaceValues[
"relfreespace"] = stoppingPlaceValues[
"absfreespace"] /
MAX2(1.0, stoppingPlaceValues[
"capacity"]);
467 stoppingPlaceValues[
"distanceto"] = routeToPark.getDistanceBetween(veh.
getPositionOnLane(), toPos,
468 routeToPark.begin(), routeToPark.end() - 1, includeInternalLengths);
470 if (stoppingPlaceValues[
"distanceto"] == std::numeric_limits<double>::max()) {
471 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' to stopping place '%' at time=%."),
477 const double distToEnd = stoppingPlaceValues[
"distanceto"] - toPos + endPos;
479 if (distToEnd < brakeGap) {
487 if (newDestination) {
488 stoppingPlaceValues[
"distancefrom"] = 0;
489 stoppingPlaceValues[
"timefrom"] = 0;
495 routeFromPark.begin(), routeFromPark.end() - 1, includeInternalLengths);
496 if (stoppingPlaceValues[
"distancefrom"] == std::numeric_limits<double>::max()) {
497 WRITE_WARNINGF(
TL(
"Invalid distance computation for vehicle '%' from stopping place '%' at time=%."),
502 newEdges.insert(newEdges.end(), edgesFromStop.begin() + 1, edgesFromStop.end());
503 newEdges.insert(newEdges.end(), route.
begin() + nextDestinationIndex + 1, route.
end());
507 if (!
evaluateCustomComponents(veh, brakeGap, newDestination, alternative, occupancy, prob, router, stoppingPlaceValues, stoppingPlaceApproaches[alternative], newEdges, maxValues, addInput)) {
512 stoppingPlaces[alternative] = stoppingPlaceValues;
513 newRoutes[alternative] = newEdges;
561 result[evalParam.first] =
getWeight(veh, evalParam.first +
".weight", evalParam.second);
563 result[
"probability"] =
getWeight(veh,
"probability.weight", 0.);
589 WRITE_MESSAGEF(
"Vehicle '%' does not supply vehicle parameter '%'. Using default of %\n", veh.
getID(), key,
toString(defaultWeight));
591 return defaultWeight;
597 for (
auto it = maxValues.begin(); it != maxValues.end(); ++it) {
598 if (stoppingPlaceValues[it->first] > it->second) {
599 it->second = stoppingPlaceValues[it->first];
608 for (StoppingPlaceParamMap_t::const_iterator sc = absValues.begin(); sc != absValues.end(); ++sc) {
609 double weight = weights.at(sc->first);
610 double val = sc->second;
611 if (norm.at(sc->first) && maxValues.at(sc->first) > 0.) {
612 val /= maxValues.at(sc->first);
614 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)
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
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...
MSStoppingPlace * reroute(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...
const MSRouteIterator determineRerouteOrigin(SUMOVehicle &veh, int insertStopIndex)
Determine the rerouting origin edge (not necessarily the current edge of the vehicle!...
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
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.
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 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 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