From 07f7344d5f8d94a743992a24e16b3b71aea32c05 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Thu, 7 Feb 2019 10:24:58 -0500 Subject: [PATCH] add stoppage penalties to table_params. use those to add penalties to table results. --- include/engine/api/table_parameters.hpp | 11 ++++- include/util/typedefs.hpp | 10 ++++- src/engine/plugins/table.cpp | 57 +++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 6 deletions(-) diff --git a/include/engine/api/table_parameters.hpp b/include/engine/api/table_parameters.hpp index fbbf6831e..725dc2136 100644 --- a/include/engine/api/table_parameters.hpp +++ b/include/engine/api/table_parameters.hpp @@ -60,6 +60,8 @@ struct TableParameters : public BaseParameters std::vector sources; std::vector destinations; double fallback_speed = INVALID_FALLBACK_SPEED; + double min_stoppage_penalty = INVALID_MINIMUM_STOPAGE_PENALTY; + double max_stoppage_penalty = INVALID_MAXIMUM_STOPAGE_PENALTY; enum class FallbackCoordinateType { @@ -108,11 +110,14 @@ struct TableParameters : public BaseParameters double fallback_speed_, FallbackCoordinateType fallback_coordinate_type_, double scale_factor_, + double min_stoppage_penalty_, + double max_stoppage_penalty_, Args... args_) : BaseParameters{std::forward(args_)...}, sources{std::move(sources_)}, destinations{std::move(destinations_)}, fallback_speed{fallback_speed_}, fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_}, - scale_factor{scale_factor_} + scale_factor{scale_factor_}, min_stoppage_penalty{min_stoppage_penalty_}, + max_stoppage_penalty{max_stoppage_penalty_} { } @@ -143,6 +148,10 @@ struct TableParameters : public BaseParameters if (scale_factor <= 0) return false; + if (min_stoppage_penalty <= 0 || max_stoppage_penalty <= 0 || + max_stoppage_penalty > min_stoppage_penalty) + return false; + return true; } }; diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index f29406d8b..28a7f7b26 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -48,7 +48,7 @@ struct osm_way_id struct duplicated_node { }; -} +} // namespace tag using OSMNodeID = osrm::Alias; static_assert(std::is_pod(), "OSMNodeID is not a valid alias"); using OSMWayID = osrm::Alias; @@ -117,7 +117,13 @@ static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits::max(); static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits::max(); static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits::max(); -static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits::max(); +static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits::max(); +static const EdgeDuration INVALID_MINIMUM_STOPAGE_PENALTY = + std::numeric_limits::max(); +static const EdgeDuration INVALID_MAXIMUM_STOPAGE_PENALTY = + std::numeric_limits::max(); +constexpr double MINIMAL_ACCEL_DECEL_PENALIZABLE_SPEED = 10; +constexpr double MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED = 40; // FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent // within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any diff --git a/src/engine/plugins/table.cpp b/src/engine/plugins/table.cpp index f78645c9d..3398bbd03 100644 --- a/src/engine/plugins/table.cpp +++ b/src/engine/plugins/table.cpp @@ -17,6 +17,31 @@ #include +namespace +{ + +// where does this speed lie with respect to the min/max penalizable speeds +inline double stoppage_penalty(double speed, double min_penalty, double penalty_range) +{ + // You're so slow already you don't get a penalty + if (speed < MINIMAL_ACCEL_DECEL_PENALIZABLE_SPEED) + return 0; + + // Find where it is on the scale + constexpr auto max = + MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED - MINIMAL_ACCEL_DECEL_PENALIZABLE_SPEED; + auto ratio = (speed - MINIMAL_ACCEL_DECEL_PENALIZABLE_SPEED) / max; + + // You're faster than the max so you get the max + if (ratio >= 1) + return min_penalty + penalty_range; + + // You're in between so you get a linear combination + return min_penalty + ratio * penalty_range; +} + +} // namespace + namespace osrm { namespace engine @@ -96,6 +121,7 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, } std::vector estimated_pairs; + const auto stoppage_penalty_range = params.max_stoppage_penalty - params.min_stoppage_penalty; // Scan table for null results - if any exist, replace with distance estimates if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1) @@ -106,6 +132,30 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, { const auto &table_index = row * num_destinations + column; BOOST_ASSERT(table_index < result_tables_pair.first.size()); + // Add decel/accel penalty to account for stoppage at the start/end of trip + if (stoppage_penalty_range >= 0 && + result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION) + { + const auto &source = + snapped_phantoms[params.sources.empty() ? row : params.sources[row]]; + const auto &destination = + snapped_phantoms[params.destinations.empty() ? column + : params.destinations[column]]; + + // TODO: if phantom node is actual node, will the distance/duration be 0? + + auto source_penalty = + stoppage_penalty(source.forward_distance / source.forward_duration, + params.min_stoppage_penalty, + stoppage_penalty_range); + auto dest_penalty = stoppage_penalty(destination.forward_distance / + destination.forward_duration, + params.min_stoppage_penalty, + stoppage_penalty_range); + + result_tables_pair.first[table_index] += source_penalty + dest_penalty; + } + // Estimate null results based on fallback_speed (if valid) and distance if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 && result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION) { @@ -132,6 +182,7 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, estimated_pairs.emplace_back(row, column); } + // Apply a scale factor to non-null result if requested if (params.scale_factor > 0 && params.scale_factor != 1 && result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && result_tables_pair.first[table_index] != 0) @@ -158,6 +209,6 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, return Status::Ok; } -} -} -} +} // namespace plugins +} // namespace engine +} // namespace osrm