Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44d4903985 | |||
| 55e05b70ac | |||
| 210908dbe6 | |||
| 6b9006f6e7 | |||
| ca55521c87 | |||
| 67e99c9809 |
@@ -1,36 +0,0 @@
|
||||
@routing @maxspeed @car
|
||||
Feature: Car - Acceleration profiles
|
||||
|
||||
Background: Use specific speeds
|
||||
Given the profile "car"
|
||||
Given a grid size of 1000 meters
|
||||
|
||||
Scenario: Car - Use stoppage penalty at waypoints
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
And the query options
|
||||
| stoppage_penalty | 5,100 |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | b | ab,ab | 481.1s |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| b | a | ab,ab | 609.9s |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | a | ab,ab | 0s |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b |
|
||||
| a | 0 | 481.1 |
|
||||
| b | 609.9 | 0 |
|
||||
@@ -3,9 +3,102 @@ Feature: Testbot - Acceleration profiles
|
||||
|
||||
Background: Use specific speeds
|
||||
Given the profile "testbot"
|
||||
Given a grid size of 1000 meters
|
||||
|
||||
Scenario: Testbot - No stoppage penalties
|
||||
Given a grid size of 10 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time | distance |
|
||||
| a | b | ab,ab | 3.6s | 59.9m |
|
||||
| a | 1 | ab,ab | 0.6s | 10m |
|
||||
| a | 2 | ab,ab | 1.2s | 20m |
|
||||
| a | 3 | ab,ab | 1.8s | 30m |
|
||||
| a | 4 | ab,ab | 2.4s | 40m |
|
||||
| a | 5 | ab,ab | 3s | 50m |
|
||||
| 5 | b | ab,ab | 0.6s | 9.9m |
|
||||
| 4 | b | ab,ab | 1.2s | 19.9m |
|
||||
| 3 | b | ab,ab | 1.8s | 29.9m |
|
||||
| 2 | b | ab,ab | 2.4s | 39.9m |
|
||||
| 1 | b | ab,ab | 3s | 49.9m |
|
||||
| 1 | 2 | ab,ab | 0.6s | 10m |
|
||||
| 1 | 3 | ab,ab | 1.2s | 20m |
|
||||
| 1 | 4 | ab,ab | 1.8s | 30m |
|
||||
| 1 | 5 | ab,ab | 2.4s | 40m |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||
| a | 0 | 0.6 | 1.2 | 1.8 | 2.4 | 3 | 3.6 |
|
||||
| 1 | 0.8 | 0 | 0.6 | 1.2 | 1.8 | 2.4 | 3 |
|
||||
| 2 | 1.6 | 0.8 | 0 | 0.6 | 1.2 | 1.8 | 2.4 |
|
||||
| 3 | 2.4 | 1.6 | 0.8 | 0 | 0.6 | 1.2 | 1.8 |
|
||||
| 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 | 0.6 | 1.2 |
|
||||
| 5 | 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 | 0.6 |
|
||||
| b | 4.8 | 4 | 3.2 | 2.4 | 1.6 | 0.8 | 0 |
|
||||
|
||||
Scenario: Testbot - No stoppage points, tiny grid size
|
||||
Given a grid size of 1 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 6 7 8 9 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | b |
|
||||
| a | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 | 0.3 | 0.4 | 0.4 | 0.5 | 0.6 |
|
||||
| 1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 | 0.3 | 0.4 | 0.4 | 0.5 | 0.6 |
|
||||
| 2 | 0.1 | 0.1 | 0 | 0 | 0.1 | 0.2 | 0.2 | 0.3 | 0.3 | 0.4 | 0.5 |
|
||||
| 3 | 0.2 | 0.2 | 0 | 0 | 0.1 | 0.2 | 0.2 | 0.3 | 0.3 | 0.4 | 0.5 |
|
||||
| 4 | 0.3 | 0.3 | 0.2 | 0.1 | 0 | 0.1 | 0.1 | 0.2 | 0.2 | 0.3 | 0.4 |
|
||||
| 5 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 |
|
||||
| 6 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 | 0 | 0.1 | 0.1 | 0.2 | 0.3 |
|
||||
| 7 | 0.5 | 0.5 | 0.4 | 0.3 | 0.2 | 0.1 | 0.1 | 0 | 0 | 0.1 | 0.2 |
|
||||
| 8 | 0.6 | 0.6 | 0.5 | 0.4 | 0.3 | 0.2 | 0.2 | 0 | 0 | 0.1 | 0.2 |
|
||||
| 9 | 0.7 | 0.7 | 0.6 | 0.5 | 0.4 | 0.3 | 0.3 | 0.2 | 0.1 | 0 | 0.1 |
|
||||
| b | 0.8 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 | 0.4 | 0.3 | 0.2 | 0.1 | 0 |
|
||||
|
||||
Scenario: Testbot - No stoppage points, tiny grid size
|
||||
Given a grid size of 1 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 6 7 8 9 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
And the query options
|
||||
| stoppage_penalty | 1.85,15 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | b |
|
||||
| a | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 | 4.4 | 4.6 |
|
||||
| 1 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 | 4.4 |
|
||||
| 2 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 | 4.1 |
|
||||
| 3 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 | 3.8 |
|
||||
| 4 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 | 3.6 |
|
||||
| 5 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 | 3.2 |
|
||||
| 6 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 | 2.9 |
|
||||
| 7 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 | 2.5 |
|
||||
| 8 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 | 2 |
|
||||
| 9 | 4.4 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 | 1.4 |
|
||||
| b | 4.6 | 4.4 | 4.1 | 3.8 | 3.6 | 3.2 | 2.9 | 2.5 | 2 | 1.4 | 0 |
|
||||
|
||||
|
||||
Scenario: Testbot - Use stoppage penalty at waypoints
|
||||
Given a grid size of 10 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 b
|
||||
@@ -16,21 +109,60 @@ Feature: Testbot - Acceleration profiles
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
And the query options
|
||||
| stoppage_penalty | 5,100 |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | b | ab,ab | 412.3s |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| b | a | ab,ab | 505.9s |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | time |
|
||||
| a | a | ab,ab | 0s |
|
||||
| stoppage_penalty | 1.85,15 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | b |
|
||||
| a | 0 | 412.3 |
|
||||
| b | 505.9 | 0 |
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||
| a | 0 | 4.6 | 6.5 | 8 | 9.3 | 10.4 | 11.3 |
|
||||
| 1 | 4.6 | 0 | 4.6 | 6.5 | 8 | 9.3 | 10.3 |
|
||||
| 2 | 6.5 | 4.6 | 0 | 4.6 | 6.5 | 8 | 9.2 |
|
||||
| 3 | 8 | 6.5 | 4.6 | 0 | 4.6 | 6.5 | 8 |
|
||||
| 4 | 9.3 | 8 | 6.5 | 4.6 | 0 | 4.6 | 6.5 |
|
||||
| 5 | 10.4 | 9.3 | 8 | 6.5 | 4.6 | 0 | 4.6 |
|
||||
| b | 11.3 | 10.3 | 9.2 | 8 | 6.5 | 4.6 | 0 |
|
||||
|
||||
|
||||
Scenario: Long distance grid with no penalty
|
||||
Given a grid size of 1000 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||
| a | 0 | 59.9 | 119.9 | 179.9 | 239.9 | 299.9 | 359.9 |
|
||||
| 1 | 79.9 | 0 | 60 | 120 | 180 | 240 | 300 |
|
||||
| 2 | 159.9 | 80 | 0 | 60 | 120 | 180 | 240 |
|
||||
| 3 | 239.9 | 160 | 80 | 0 | 60 | 120 | 180 |
|
||||
| 4 | 319.9 | 240 | 160 | 80 | 0 | 60 | 120 |
|
||||
| 5 | 399.9 | 320 | 240 | 160 | 80 | 0 | 60 |
|
||||
| b | 479.9 | 400 | 320 | 240 | 160 | 80 | 0 |
|
||||
|
||||
Scenario: Long distance grid
|
||||
Given a grid size of 1000 meters
|
||||
Given the node map
|
||||
"""
|
||||
a 1 2 3 4 5 b
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | highway | maxspeed:forward | maxspeed:backward |
|
||||
| ab | trunk | 60 | 45 |
|
||||
|
||||
And the query options
|
||||
| stoppage_penalty | 1.85,15 |
|
||||
|
||||
When I request a travel time matrix I should get
|
||||
| | a | 1 | 2 | 3 | 4 | 5 | b |
|
||||
| a | 0 | 68.9 | 128.9 | 188.9 | 248.9 | 308.9 | 368.9 |
|
||||
| 1 | 86.6 | 0 | 69 | 129 | 189 | 249 | 309 |
|
||||
| 2 | 166.6 | 86.7 | 0 | 69 | 129 | 189 | 249 |
|
||||
| 3 | 246.6 | 166.7 | 86.7 | 0 | 69 | 129 | 189 |
|
||||
| 4 | 326.6 | 246.7 | 166.7 | 86.7 | 0 | 69 | 129 |
|
||||
| 5 | 406.6 | 326.7 | 246.7 | 166.7 | 86.7 | 0 | 69 |
|
||||
| b | 486.6 | 406.7 | 326.7 | 246.7 | 166.7 | 86.7 | 0 |
|
||||
@@ -123,8 +123,8 @@ struct BaseParameters
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace api
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
#endif // ROUTE_PARAMETERS_HPP
|
||||
|
||||
@@ -466,6 +466,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
return distance_and_phantoms;
|
||||
}
|
||||
|
||||
// TODO: remove stoppage penalty as its not needed here anymore
|
||||
PhantomNodeWithDistance MakePhantomNode(const util::Coordinate input_coordinate,
|
||||
const EdgeData &data,
|
||||
const double min_stoppage_penalty = 0,
|
||||
@@ -555,36 +556,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
point_on_segment,
|
||||
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
|
||||
EdgeDuration forward_stoppage_penalty = 0;
|
||||
EdgeDuration reverse_stoppage_penalty = 0;
|
||||
auto total_distance = penalty_range > 0 ? appx_distance(forward_geometry.begin(),
|
||||
std::prev(forward_geometry.end()))
|
||||
: 0.0;
|
||||
double forward_speed = 0;
|
||||
double reverse_speed = 0;
|
||||
auto total_distance = 0;
|
||||
auto penalty_range = max_stoppage_penalty - min_stoppage_penalty;
|
||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||
{
|
||||
@@ -593,11 +569,12 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
// Stoppage penalty based on speed
|
||||
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(
|
||||
forward_durations.begin(), forward_durations.end(), EdgeDuration{0});
|
||||
const auto speed = total_distance / (total_duration * 0.1);
|
||||
forward_stoppage_penalty =
|
||||
static_cast<EdgeDuration>((stoppage_penalty(speed) * 10) + .5);
|
||||
forward_speed = total_distance / (total_duration * 0.1);
|
||||
reverse_speed = forward_speed;
|
||||
}
|
||||
}
|
||||
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
|
||||
@@ -607,11 +584,14 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
// Stoppage penalty based on speed
|
||||
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(
|
||||
reverse_durations.begin(), reverse_durations.end(), EdgeDuration{0});
|
||||
const auto speed = total_distance / (total_duration * 0.1);
|
||||
reverse_stoppage_penalty =
|
||||
static_cast<EdgeDuration>((stoppage_penalty(speed) * 10) + .5);
|
||||
reverse_speed = total_distance / (total_duration * 0.1);
|
||||
if (forward_speed == 0)
|
||||
forward_speed = reverse_speed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,8 +623,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
reverse_duration,
|
||||
forward_duration_offset,
|
||||
reverse_duration_offset,
|
||||
forward_stoppage_penalty,
|
||||
reverse_stoppage_penalty,
|
||||
static_cast<float>((forward_speed + reverse_speed) / 2.0),
|
||||
is_forward_valid_source,
|
||||
is_forward_valid_target,
|
||||
is_reverse_valid_source,
|
||||
|
||||
@@ -182,12 +182,8 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||
duration = std::max(0, duration);
|
||||
}
|
||||
|
||||
// Add start and stop penalties
|
||||
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);
|
||||
// TODO: Add start and stop penalties to the duration to simulate accel/deceleration
|
||||
//
|
||||
|
||||
std::string summary;
|
||||
if (needs_summary)
|
||||
|
||||
@@ -64,7 +64,7 @@ struct Hint
|
||||
};
|
||||
|
||||
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),
|
||||
"ENCODED_HINT_SIZE does not match size of Hint");
|
||||
} // namespace engine
|
||||
|
||||
@@ -44,16 +44,16 @@ namespace engine
|
||||
struct PhantomNode
|
||||
{
|
||||
PhantomNode()
|
||||
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
||||
reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
|
||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
|
||||
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
||||
false},
|
||||
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_offset(0), reverse_distance_offset(0),
|
||||
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
||||
forward_duration_offset(0), reverse_duration_offset(0), forward_duration_penalty(0),
|
||||
reverse_duration_penalty(0), fwd_segment_position(0), is_valid_forward_source{false},
|
||||
is_valid_forward_target{false}, is_valid_reverse_source{false},
|
||||
is_valid_reverse_target{false}, bearing(0)
|
||||
forward_duration_offset(0), reverse_duration_offset(0), speed_approximation(0),
|
||||
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
||||
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
||||
|
||||
{
|
||||
}
|
||||
@@ -110,8 +110,9 @@ struct PhantomNode
|
||||
|
||||
bool IsValid(const unsigned number_of_nodes) const
|
||||
{
|
||||
return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
|
||||
(reverse_segment_id.id < number_of_nodes)) &&
|
||||
return location.IsValid() &&
|
||||
((forward_segment_id.id < number_of_nodes) ||
|
||||
(reverse_segment_id.id < number_of_nodes)) &&
|
||||
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
||||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
||||
@@ -168,8 +169,7 @@ struct PhantomNode
|
||||
EdgeDuration reverse_duration,
|
||||
EdgeDuration forward_duration_offset,
|
||||
EdgeDuration reverse_duration_offset,
|
||||
EdgeDuration forward_duration_penalty,
|
||||
EdgeDuration reverse_duration_penalty,
|
||||
EdgeDistance speed_approximation,
|
||||
bool is_valid_forward_source,
|
||||
bool is_valid_forward_target,
|
||||
bool is_valid_reverse_source,
|
||||
@@ -185,10 +185,9 @@ struct PhantomNode
|
||||
reverse_distance_offset{reverse_distance_offset}, forward_duration{forward_duration},
|
||||
reverse_duration{reverse_duration}, forward_duration_offset{forward_duration_offset},
|
||||
reverse_duration_offset{reverse_duration_offset},
|
||||
forward_duration_penalty{forward_duration_penalty},
|
||||
reverse_duration_penalty{reverse_duration_penalty},
|
||||
component{component.id, component.is_tiny}, location{location},
|
||||
input_location{input_location}, fwd_segment_position{other.fwd_segment_position},
|
||||
speed_approximation{speed_approximation}, component{component.id, component.is_tiny},
|
||||
location{location}, input_location{input_location},
|
||||
fwd_segment_position{other.fwd_segment_position},
|
||||
is_valid_forward_source{is_valid_forward_source},
|
||||
is_valid_forward_target{is_valid_forward_target},
|
||||
is_valid_reverse_source{is_valid_reverse_source},
|
||||
@@ -210,8 +209,7 @@ struct PhantomNode
|
||||
EdgeDuration reverse_duration;
|
||||
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 forward_duration_penalty;
|
||||
EdgeDuration reverse_duration_penalty;
|
||||
EdgeDistance speed_approximation; // m/s
|
||||
|
||||
ComponentID component;
|
||||
|
||||
@@ -227,7 +225,7 @@ struct PhantomNode
|
||||
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>;
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
||||
heap.Insert(phantom_node.forward_segment_id.id,
|
||||
-phantom_node.GetForwardWeightPlusOffset(),
|
||||
{phantom_node.forward_segment_id.id,
|
||||
-phantom_node.GetForwardDuration() + phantom_node.forward_duration_penalty,
|
||||
-phantom_node.GetForwardDuration(),
|
||||
-phantom_node.GetForwardDistance()});
|
||||
}
|
||||
if (phantom_node.IsValidReverseSource())
|
||||
@@ -94,7 +94,7 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||
-phantom_node.GetReverseWeightPlusOffset(),
|
||||
{phantom_node.reverse_segment_id.id,
|
||||
-phantom_node.GetReverseDuration() + phantom_node.reverse_duration_penalty,
|
||||
-phantom_node.GetReverseDuration(),
|
||||
-phantom_node.GetReverseDistance()});
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
||||
heap.Insert(phantom_node.forward_segment_id.id,
|
||||
phantom_node.GetForwardWeightPlusOffset(),
|
||||
{phantom_node.forward_segment_id.id,
|
||||
phantom_node.GetForwardDuration() + phantom_node.forward_duration_penalty,
|
||||
phantom_node.GetForwardDuration(),
|
||||
phantom_node.GetForwardDistance()});
|
||||
}
|
||||
if (phantom_node.IsValidReverseTarget())
|
||||
@@ -115,7 +115,7 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||
phantom_node.GetReverseWeightPlusOffset(),
|
||||
{phantom_node.reverse_segment_id.id,
|
||||
phantom_node.GetReverseDuration() + phantom_node.reverse_duration_penalty,
|
||||
phantom_node.GetReverseDuration(),
|
||||
phantom_node.GetReverseDistance()});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,8 +762,8 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
|
||||
return false;
|
||||
}
|
||||
|
||||
params->max_stoppage_penalty = min;
|
||||
params->min_stoppage_penalty = max;
|
||||
params->max_stoppage_penalty = max;
|
||||
params->min_stoppage_penalty = min;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace
|
||||
{
|
||||
namespace ph = boost::phoenix;
|
||||
namespace qi = boost::spirit::qi;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
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::api::BaseParameters::SnappingType> snapping_type;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace api
|
||||
} // namespace server
|
||||
} // namespace osrm
|
||||
|
||||
#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();
|
||||
constexpr EdgeDuration INVALID_MINIMUM_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 double MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED = 40; // metres/sec
|
||||
constexpr float MAXIMAL_ACCEL_DECEL_PENALIZABLE_SPEED_INVERSE = 40.f; // seconds/metre
|
||||
|
||||
// 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
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "osrm",
|
||||
"version": "5.21.0-customsnapping.2",
|
||||
"version": "5.21.0-customsnapping.6",
|
||||
"private": false,
|
||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||
"dependencies": {
|
||||
|
||||
@@ -86,8 +86,10 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
bool request_distance = params.annotations & api::TableParameters::AnnotationsType::Distance;
|
||||
bool request_duration = params.annotations & api::TableParameters::AnnotationsType::Duration;
|
||||
|
||||
constexpr bool always_calculate_distance = true;
|
||||
|
||||
auto result_tables_pair = algorithms.ManyToManySearch(
|
||||
snapped_phantoms, params.sources, params.destinations, request_distance);
|
||||
snapped_phantoms, params.sources, params.destinations, always_calculate_distance);
|
||||
|
||||
if ((request_duration && result_tables_pair.first.empty()) ||
|
||||
(request_distance && result_tables_pair.second.empty()))
|
||||
@@ -97,6 +99,57 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
|
||||
std::vector<api::TableAPI::TableCellRef> estimated_pairs;
|
||||
|
||||
// Adds some time to adjust for getting up to speed and slowing down to a stop
|
||||
// Returns a new `duration`
|
||||
auto adjust_for_startstop = [](const double &comfortable_acceleration,
|
||||
const EdgeDuration &duration,
|
||||
const EdgeDistance &distance) -> EdgeDuration {
|
||||
|
||||
// Assume linear acceleration from 0 to velocity
|
||||
// auto comfortable_acceleration = 1.85; // m/s^2
|
||||
|
||||
// Very short paths can end up with 0 duration. That'll lead to a divide
|
||||
// by zero, so instead, we'll assume the travel speed is 10m/s (36km/h).
|
||||
// Typically, the distance is also short, so we're quibbling at tiny numbers
|
||||
// here, but tiny numbers is what this adjustment lambda is all about,
|
||||
// so we do try to be reasonable.
|
||||
const auto average_speed =
|
||||
duration == 0 ? 10 : distance /
|
||||
(duration / 10.); // duration is in deciseconds, we need m/sec
|
||||
|
||||
// Using the equations of motion as a simple approximation, assuming constant acceleration
|
||||
// https://en.wikipedia.org/wiki/Equations_of_motion#Constant_translational_acceleration_in_a_straight_line
|
||||
const auto distance_to_full_speed =
|
||||
(average_speed * average_speed) / (2 * comfortable_acceleration);
|
||||
|
||||
/*
|
||||
std::cout << "Comfortable accel is " << comfortable_acceleration << std::endl;
|
||||
std::cout << "Average speed is " << average_speed << " duration is " << duration
|
||||
<< std::endl;
|
||||
std::cout << "Distance is " << distance << " distance to full speed is "
|
||||
<< distance_to_full_speed << std::endl;
|
||||
*/
|
||||
|
||||
if (distance_to_full_speed > distance / 2)
|
||||
{
|
||||
// std::cout << "Distance was too short, so only using half" << std::endl;
|
||||
const auto time_to_halfway = std::sqrt(distance / comfortable_acceleration);
|
||||
return (2 * time_to_halfway) * 10; // result is in deciseconds
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << "Distance was long, using cruising speed" << std::endl;
|
||||
const auto cruising_distance = distance - 2 * distance_to_full_speed;
|
||||
const auto cruising_time = cruising_distance / average_speed;
|
||||
const auto acceleration_time = average_speed / comfortable_acceleration;
|
||||
|
||||
// std::cout << "Cruising distance is " << cruising_distance << std::endl;
|
||||
// std::cout << "Cruising time is " << cruising_time << std::endl;
|
||||
// std::cout << "Acceleration time is " << acceleration_time << std::endl;
|
||||
return (cruising_time + 2 * acceleration_time) * 10; // result is in deciseconds
|
||||
}
|
||||
};
|
||||
|
||||
// Scan table for null results - if any exist, replace with distance estimates
|
||||
if (params.fallback_speed != INVALID_FALLBACK_SPEED || params.scale_factor != 1 ||
|
||||
(params.min_stoppage_penalty != INVALID_MINIMUM_STOPPAGE_PENALTY &&
|
||||
@@ -108,9 +161,21 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
{
|
||||
const auto &table_index = row * num_destinations + column;
|
||||
BOOST_ASSERT(table_index < result_tables_pair.first.size());
|
||||
// Zero out the diagonal
|
||||
if (result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && row == column)
|
||||
result_tables_pair.first[table_index] = 0;
|
||||
// apply an accel/deceleration penalty to the duration
|
||||
if (result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION && row != column)
|
||||
{
|
||||
/*
|
||||
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] =
|
||||
adjust_for_startstop(params.min_stoppage_penalty,
|
||||
result_tables_pair.first[table_index],
|
||||
result_tables_pair.second[table_index]);
|
||||
}
|
||||
// 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)
|
||||
@@ -160,6 +225,14 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
}
|
||||
}
|
||||
|
||||
// If distances weren't requested, delete them from the result so they don't
|
||||
// get rendered.
|
||||
if (!request_distance)
|
||||
{
|
||||
std::vector<EdgeDistance> empty;
|
||||
result_tables_pair.second.swap(empty);
|
||||
}
|
||||
|
||||
api::TableAPI table_api{facade, params};
|
||||
table_api.MakeResponse(result_tables_pair, snapped_phantoms, estimated_pairs, result);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user