change phantom node to store an appx speed regardless of direction. use this speed to estimate an accel/decel penalty and scale the penalty based on the distance traveled up to a cutoff. only used in the table plugin at the moment. TODO still lives in the guidance assemble_leg area
This commit is contained in:
parent
67e99c9809
commit
ca55521c87
@ -123,8 +123,8 @@ struct BaseParameters
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif // ROUTE_PARAMETERS_HPP
|
#endif // ROUTE_PARAMETERS_HPP
|
||||||
|
@ -466,6 +466,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
return distance_and_phantoms;
|
return distance_and_phantoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove stoppage penalty as its not needed here anymore
|
||||||
PhantomNodeWithDistance MakePhantomNode(const util::Coordinate input_coordinate,
|
PhantomNodeWithDistance MakePhantomNode(const util::Coordinate input_coordinate,
|
||||||
const EdgeData &data,
|
const EdgeData &data,
|
||||||
const double min_stoppage_penalty = 0,
|
const double min_stoppage_penalty = 0,
|
||||||
@ -555,36 +556,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
point_on_segment,
|
point_on_segment,
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
||||||
|
|
||||||
// where does this speed lie with respect to the min/max penalizable speeds
|
|
||||||
auto penalty_range = min_stoppage_penalty != INVALID_MINIMUM_STOPPAGE_PENALTY &&
|
|
||||||
max_stoppage_penalty != INVALID_MAXIMUM_STOPPAGE_PENALTY
|
|
||||||
? max_stoppage_penalty - min_stoppage_penalty
|
|
||||||
: 0;
|
|
||||||
auto stoppage_penalty =
|
|
||||||
[penalty_range, min_stoppage_penalty, max_stoppage_penalty](double speed) -> double {
|
|
||||||
// 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 max_stoppage_penalty;
|
|
||||||
|
|
||||||
// You're in between so you get a linear combination
|
|
||||||
return min_stoppage_penalty + ratio * penalty_range;
|
|
||||||
};
|
|
||||||
|
|
||||||
// We may end up adding a stoppage penalty
|
// We may end up adding a stoppage penalty
|
||||||
EdgeDuration forward_stoppage_penalty = 0;
|
double forward_speed = 0;
|
||||||
EdgeDuration reverse_stoppage_penalty = 0;
|
double reverse_speed = 0;
|
||||||
auto total_distance = penalty_range > 0 ? appx_distance(forward_geometry.begin(),
|
auto total_distance = 0;
|
||||||
std::prev(forward_geometry.end()))
|
auto penalty_range = max_stoppage_penalty - min_stoppage_penalty;
|
||||||
: 0.0;
|
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
{
|
{
|
||||||
@ -593,11 +569,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
// Stoppage penalty based on speed
|
// Stoppage penalty based on speed
|
||||||
if (data.forward_segment_id.enabled && penalty_range > 0)
|
if (data.forward_segment_id.enabled && penalty_range > 0)
|
||||||
{
|
{
|
||||||
|
total_distance =
|
||||||
|
appx_distance(forward_geometry.begin(), std::prev(forward_geometry.end()));
|
||||||
const auto total_duration = std::accumulate(
|
const auto total_duration = std::accumulate(
|
||||||
forward_durations.begin(), forward_durations.end(), EdgeDuration{0});
|
forward_durations.begin(), forward_durations.end(), EdgeDuration{0});
|
||||||
const auto speed = total_distance / (total_duration * 0.1);
|
forward_speed = total_distance / (total_duration * 0.1);
|
||||||
forward_stoppage_penalty =
|
reverse_speed = forward_speed;
|
||||||
static_cast<EdgeDuration>((stoppage_penalty(speed) * 10) + .5);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
@ -607,11 +584,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
// Stoppage penalty based on speed
|
// Stoppage penalty based on speed
|
||||||
if (data.reverse_segment_id.enabled && penalty_range > 0)
|
if (data.reverse_segment_id.enabled && penalty_range > 0)
|
||||||
{
|
{
|
||||||
|
if (total_distance == 0)
|
||||||
|
total_distance =
|
||||||
|
appx_distance(forward_geometry.begin(), std::prev(forward_geometry.end()));
|
||||||
const auto total_duration = std::accumulate(
|
const auto total_duration = std::accumulate(
|
||||||
reverse_durations.begin(), reverse_durations.end(), EdgeDuration{0});
|
reverse_durations.begin(), reverse_durations.end(), EdgeDuration{0});
|
||||||
const auto speed = total_distance / (total_duration * 0.1);
|
reverse_speed = total_distance / (total_duration * 0.1);
|
||||||
reverse_stoppage_penalty =
|
if (forward_speed == 0)
|
||||||
static_cast<EdgeDuration>((stoppage_penalty(speed) * 10) + .5);
|
forward_speed = reverse_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,8 +623,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
reverse_duration,
|
reverse_duration,
|
||||||
forward_duration_offset,
|
forward_duration_offset,
|
||||||
reverse_duration_offset,
|
reverse_duration_offset,
|
||||||
forward_stoppage_penalty,
|
static_cast<float>((forward_speed + reverse_speed) / 2.0),
|
||||||
reverse_stoppage_penalty,
|
|
||||||
is_forward_valid_source,
|
is_forward_valid_source,
|
||||||
is_forward_valid_target,
|
is_forward_valid_target,
|
||||||
is_reverse_valid_source,
|
is_reverse_valid_source,
|
||||||
|
@ -182,12 +182,8 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
duration = std::max(0, duration);
|
duration = std::max(0, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add start and stop penalties
|
// TODO: Add start and stop penalties to the duration to simulate accel/deceleration
|
||||||
if (distance > 0)
|
//
|
||||||
duration +=
|
|
||||||
(target_traversed_in_reverse
|
|
||||||
? source_node.reverse_duration_penalty + target_node.reverse_duration_penalty
|
|
||||||
: source_node.forward_duration_penalty + target_node.forward_duration_penalty);
|
|
||||||
|
|
||||||
std::string summary;
|
std::string summary;
|
||||||
if (needs_summary)
|
if (needs_summary)
|
||||||
|
@ -64,7 +64,7 @@ struct Hint
|
|||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(Hint) == sizeof(PhantomNode) + 4, "Hint is bigger than expected");
|
static_assert(sizeof(Hint) == sizeof(PhantomNode) + 4, "Hint is bigger than expected");
|
||||||
constexpr std::size_t ENCODED_HINT_SIZE = 124;
|
constexpr std::size_t ENCODED_HINT_SIZE = 120;
|
||||||
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
|
static_assert(ENCODED_HINT_SIZE / 4 * 3 >= sizeof(Hint),
|
||||||
"ENCODED_HINT_SIZE does not match size of Hint");
|
"ENCODED_HINT_SIZE does not match size of Hint");
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -44,16 +44,16 @@ namespace engine
|
|||||||
struct PhantomNode
|
struct PhantomNode
|
||||||
{
|
{
|
||||||
PhantomNode()
|
PhantomNode()
|
||||||
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
||||||
reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
|
false},
|
||||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
|
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
|
||||||
|
forward_weight_offset(0), reverse_weight_offset(0),
|
||||||
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
||||||
forward_distance_offset(0), reverse_distance_offset(0),
|
forward_distance_offset(0), reverse_distance_offset(0),
|
||||||
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
||||||
forward_duration_offset(0), reverse_duration_offset(0), forward_duration_penalty(0),
|
forward_duration_offset(0), reverse_duration_offset(0), speed_approximation(0),
|
||||||
reverse_duration_penalty(0), fwd_segment_position(0), is_valid_forward_source{false},
|
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
||||||
is_valid_forward_target{false}, is_valid_reverse_source{false},
|
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
||||||
is_valid_reverse_target{false}, bearing(0)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -110,8 +110,9 @@ struct PhantomNode
|
|||||||
|
|
||||||
bool IsValid(const unsigned number_of_nodes) const
|
bool IsValid(const unsigned number_of_nodes) const
|
||||||
{
|
{
|
||||||
return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
|
return location.IsValid() &&
|
||||||
(reverse_segment_id.id < number_of_nodes)) &&
|
((forward_segment_id.id < number_of_nodes) ||
|
||||||
|
(reverse_segment_id.id < number_of_nodes)) &&
|
||||||
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
||||||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||||
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
||||||
@ -168,8 +169,7 @@ struct PhantomNode
|
|||||||
EdgeDuration reverse_duration,
|
EdgeDuration reverse_duration,
|
||||||
EdgeDuration forward_duration_offset,
|
EdgeDuration forward_duration_offset,
|
||||||
EdgeDuration reverse_duration_offset,
|
EdgeDuration reverse_duration_offset,
|
||||||
EdgeDuration forward_duration_penalty,
|
EdgeDistance speed_approximation,
|
||||||
EdgeDuration reverse_duration_penalty,
|
|
||||||
bool is_valid_forward_source,
|
bool is_valid_forward_source,
|
||||||
bool is_valid_forward_target,
|
bool is_valid_forward_target,
|
||||||
bool is_valid_reverse_source,
|
bool is_valid_reverse_source,
|
||||||
@ -185,10 +185,9 @@ struct PhantomNode
|
|||||||
reverse_distance_offset{reverse_distance_offset}, forward_duration{forward_duration},
|
reverse_distance_offset{reverse_distance_offset}, forward_duration{forward_duration},
|
||||||
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
|
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
|
||||||
reverse_duration_offset{reverse_duration_offset},
|
reverse_duration_offset{reverse_duration_offset},
|
||||||
forward_duration_penalty{forward_duration_penalty},
|
speed_approximation{speed_approximation}, component{component.id, component.is_tiny},
|
||||||
reverse_duration_penalty{reverse_duration_penalty},
|
location{location}, input_location{input_location},
|
||||||
component{component.id, component.is_tiny}, location{location},
|
fwd_segment_position{other.fwd_segment_position},
|
||||||
input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
|
|
||||||
is_valid_forward_source{is_valid_forward_source},
|
is_valid_forward_source{is_valid_forward_source},
|
||||||
is_valid_forward_target{is_valid_forward_target},
|
is_valid_forward_target{is_valid_forward_target},
|
||||||
is_valid_reverse_source{is_valid_reverse_source},
|
is_valid_reverse_source{is_valid_reverse_source},
|
||||||
@ -210,8 +209,7 @@ struct PhantomNode
|
|||||||
EdgeDuration reverse_duration;
|
EdgeDuration reverse_duration;
|
||||||
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
|
||||||
EdgeDuration forward_duration_penalty;
|
EdgeDistance speed_approximation; // m/s
|
||||||
EdgeDuration reverse_duration_penalty;
|
|
||||||
|
|
||||||
ComponentID component;
|
ComponentID component;
|
||||||
|
|
||||||
@ -227,7 +225,7 @@ struct PhantomNode
|
|||||||
unsigned short bearing : 12;
|
unsigned short bearing : 12;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(PhantomNode) == 88, "PhantomNode has more padding then expected");
|
static_assert(sizeof(PhantomNode) == 84, "PhantomNode has more padding then expected");
|
||||||
|
|
||||||
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
{phantom_node.forward_segment_id.id,
|
{phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardDuration() + phantom_node.forward_duration_penalty,
|
-phantom_node.GetForwardDuration(),
|
||||||
-phantom_node.GetForwardDistance()});
|
-phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseSource())
|
||||||
@ -94,7 +94,7 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
{phantom_node.reverse_segment_id.id,
|
{phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseDuration() + phantom_node.reverse_duration_penalty,
|
-phantom_node.GetReverseDuration(),
|
||||||
-phantom_node.GetReverseDistance()});
|
-phantom_node.GetReverseDistance()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
phantom_node.GetForwardWeightPlusOffset(),
|
phantom_node.GetForwardWeightPlusOffset(),
|
||||||
{phantom_node.forward_segment_id.id,
|
{phantom_node.forward_segment_id.id,
|
||||||
phantom_node.GetForwardDuration() + phantom_node.forward_duration_penalty,
|
phantom_node.GetForwardDuration(),
|
||||||
phantom_node.GetForwardDistance()});
|
phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseTarget())
|
if (phantom_node.IsValidReverseTarget())
|
||||||
@ -115,7 +115,7 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
phantom_node.GetReverseWeightPlusOffset(),
|
phantom_node.GetReverseWeightPlusOffset(),
|
||||||
{phantom_node.reverse_segment_id.id,
|
{phantom_node.reverse_segment_id.id,
|
||||||
phantom_node.GetReverseDuration() + phantom_node.reverse_duration_penalty,
|
phantom_node.GetReverseDuration(),
|
||||||
phantom_node.GetReverseDistance()});
|
phantom_node.GetReverseDistance()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace
|
|||||||
{
|
{
|
||||||
namespace ph = boost::phoenix;
|
namespace ph = boost::phoenix;
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_policies<T>
|
template <typename T, char... Fmt> struct no_trailing_dot_policy : qi::real_policies<T>
|
||||||
{
|
{
|
||||||
@ -222,8 +222,8 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
|||||||
qi::symbols<char, engine::Approach> approach_type;
|
qi::symbols<char, engine::Approach> approach_type;
|
||||||
qi::symbols<char, engine::api::BaseParameters::SnappingType> snapping_type;
|
qi::symbols<char, engine::api::BaseParameters::SnappingType> snapping_type;
|
||||||
};
|
};
|
||||||
}
|
} // namespace api
|
||||||
}
|
} // namespace server
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -119,8 +119,7 @@ static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistan
|
|||||||
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<EdgeDistance>::max();
|
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<EdgeDistance>::max();
|
||||||
constexpr EdgeDuration INVALID_MINIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
constexpr EdgeDuration INVALID_MINIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
||||||
constexpr EdgeDuration INVALID_MAXIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
constexpr EdgeDuration INVALID_MAXIMUM_STOPPAGE_PENALTY = std::numeric_limits<EdgeDuration>::max();
|
||||||
constexpr double MINIMAL_ACCEL_DECEL_PENALIZABLE_SPEED = 10; // metres/second
|
constexpr float MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED_INVERSE = 40.f; // seconds/metre
|
||||||
constexpr double MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED = 40; // metres/sec
|
|
||||||
|
|
||||||
// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent
|
// 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
|
// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any
|
||||||
|
@ -97,6 +97,22 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
|
|
||||||
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
||||||
|
|
||||||
|
auto penalize = [¶ms](float speed, EdgeDuration duration) -> EdgeDuration {
|
||||||
|
// this is the penalty before adjusting for the length of the route
|
||||||
|
auto speed_ratio = speed * MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED_INVERSE;
|
||||||
|
auto penalty = speed_ratio * (params.max_stoppage_penalty - params.min_stoppage_penalty) +
|
||||||
|
params.min_stoppage_penalty;
|
||||||
|
// how much distance would we cover if we took half of it at this speed
|
||||||
|
// scale the penalty based on this distance, if its small we dont get much
|
||||||
|
// of the penalty, buf if its large we get up to the whole penalty
|
||||||
|
// .05 is to scale the duration to second and cut it in half
|
||||||
|
// .005 is like / 200m, so the estimated distance as a ratio of 200m
|
||||||
|
// so you get the full penalty if your route is 200m or more
|
||||||
|
auto distance_ratio = (speed * duration * .05) * 0.008;
|
||||||
|
return static_cast<EdgeDuration>(
|
||||||
|
(distance_ratio < 1.f ? distance_ratio * penalty : penalty) * 10.);
|
||||||
|
};
|
||||||
|
|
||||||
// Scan table for null results - if any exist, replace with distance estimates
|
// Scan table for null results - if any exist, replace with distance estimates
|
||||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1 ||
|
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1 ||
|
||||||
(params.min_stoppage_penalty != INVALID_MINIMUM_STOPPAGE_PENALTY &&
|
(params.min_stoppage_penalty != INVALID_MINIMUM_STOPPAGE_PENALTY &&
|
||||||
@ -108,9 +124,20 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
{
|
{
|
||||||
const auto &table_index = row * num_destinations + column;
|
const auto &table_index = row * num_destinations + column;
|
||||||
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||||
// Zero out the diagonal
|
// apply an accel/deceleration penalty to the duration
|
||||||
if (result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && row == column)
|
if (result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && row != column)
|
||||||
result_tables_pair.first[table_index] = 0;
|
{
|
||||||
|
const auto &source =
|
||||||
|
snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
|
||||||
|
const auto &destination =
|
||||||
|
snapped_phantoms[params.destinations.empty() ? column
|
||||||
|
: params.destinations[column]];
|
||||||
|
result_tables_pair.first[table_index] +=
|
||||||
|
penalize(source.speed_approximation,
|
||||||
|
result_tables_pair.first[table_index]) +
|
||||||
|
penalize(destination.speed_approximation,
|
||||||
|
result_tables_pair.first[table_index]);
|
||||||
|
}
|
||||||
// Estimate null results based on fallback_speed (if valid) and distance
|
// Estimate null results based on fallback_speed (if valid) and distance
|
||||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
|
if (params.fallback_speed != INVALID_FALLBACK_SPEED && params.fallback_speed > 0 &&
|
||||||
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
|
||||||
|
Loading…
Reference in New Issue
Block a user