Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

top_speed option: ignore live speed for speed based penalties #3460

Merged
merged 14 commits into from
Jan 11, 2022

Conversation

merkispavel
Copy link
Contributor

@merkispavel merkispavel commented Dec 15, 2021

Description

top_speed option does 2 things:

  • limits edge speed with the given value
  • penalizes edges with higher speed

This PR touches penalty logic of the top_speed. In the context of speed based penalties, these changes forces edge speed to be taken from "static" speed layers rather than dynamic ones(current, predictive)

Why

Live traffic speed is dynamic and can change quickly. For example, if you only want to use roads below 40kph, a high speed motorway may have big congestion with speeds at 20kph but it is possible that by the time the vehicle reaches the motorway, the traffic clears up and live speed returns back to normal 100kph
In my view, the same logic is applied to predicted speeds as well

Questions to reviewers

  • Does this change make sense to you?
  • Are changes consistent with original design of top_speed option(if there was any idea behind it)?

Next steps

If everybody is ok with this changes - I'll apply these changes to other places(other costings) and probably add some tests

@nilsnolde
Copy link
Member

nilsnolde commented Dec 15, 2021

hm, maybe I'm not thinking right about this, also not very familiar with time-dependent astar, but anyways: the changes make total sense to me in case of live traffic. we simply don't know what the speed will be by the time the car actually gets there. but for predicted speed we do know the right speed at the right time during traversal no? to me it seems that's cool to use for speed-based penalization, happy to hear your thoughts:)

average_historic_speed = tile->GetSpeed(edge, flow_mask_ & kStaticFlowMask);
}
float speed_penalty =
(average_historic_speed > top_speed_) ? (edge_speed - top_speed_) * 0.05f : 0.0f;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(average_historic_speed > top_speed_) ? (edge_speed - top_speed_) * 0.05f : 0.0f;
(average_historic_speed > top_speed_) ? (average_historic_speed - top_speed_) * 0.05f : 0.0f;

?
otherwise, if edge_speed < top_speed_ we can get negative speed penalty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, right. Thanks @genadz

@genadz
Copy link
Contributor

genadz commented Dec 16, 2021

hm, maybe I'm not thinking right about this, also not very familiar with time-dependent astar, but anyways: the changes make total sense to me in case of live traffic. we simply don't know what the speed will be by the time the car actually gets there. but for predicted speed we do know the right speed at the right time during traversal no? to me it seems that's cool to use for speed-based penalization, happy to hear your thoughts:)

valid note. it depends what is the goal of top_speed parameter. I see 2 situations:

  1. we want to penalize roads where actual speed will be higher than top_speed - in this case predicted speeds should be taken because we approximately know what speed will be on the edge;
  2. we want to penalize roads where actual speed may be higher than top_speed - here we should take some static data.

@nilsnolde
Copy link
Member

nilsnolde commented Dec 16, 2021

thanks. so basically option 1 is saying "we trust the speed data completely so please give me the (however accurate) speed at that time and edge".. for option 2 we'd assume (rightfully I guess) that the speeds are inaccurate bcs time will be off due to unexpected live events along the expansion etc and rather take the "safe" approach of the static average speed, constrained or free.

ha, that's more of a philosophical question than I expected 😅 since in the case where this applies we're not using the original edge_speed but the top_speed_ we really use it only to penalize, not for the base cost. still, I think I'd prefer actually option 1, because in cases where the edge_speed is lower than top_speed_ we also pretend to trust the dynamic speed values enough to take it as base cost. so to me that'd be more consistent no? but then raises actually the same conclusion for realtime speeds, ie the whole PR. anyways, just my thoughts, hoping for people with more experience to chime in. it's also not such a huge decision, so sorry for maybe overthinking this..

@kevinkreiser
Copy link
Member

the way i see it was more that it is a matter of the legal speed not the measured speed. if my top speed is 65mph and the speed limit is 55mph, but crazy people are driving 85mph I dont think i should be penalized and suggested to stay off that road. On the other hand if I'm conservative maybe I do want to avoid the crazy people so they don't run me over (an argument I often hear from my pappy).

@nilsnolde
Copy link
Member

nilsnolde commented Dec 16, 2021

but doesn't the same thought also apply to using "measured" (live/historical) speed in general? using it as base cost has the same implications no?

@kevinkreiser
Copy link
Member

i guess my point is that setting top speed should cap the travel speed to that, so measured speed will be capped when used as a base cost. my understanding was that when a user says my top speed is X, they are telling us I cannot drive faster than X, even if the measure speed is X + 20, i will be driving X.

@nilsnolde
Copy link
Member

aaah now I got it, yes.. makes sense, sorry for the noise!

@merkispavel
Copy link
Contributor Author

the way i see it was more that it is a matter of the legal speed not the measured speed
agreed, this is how I think about it as well

if my top speed is 65mph and the speed limit is 55mph, but crazy people are driving 85mph I dont think i should be penalized and suggested to stay off that road.

makes total sense. Any historic speed source(predicted even predicted one with N mins buckets) should smooth such extreme values(like 85mph on a road with 55mph speed limit)

@merkispavel
Copy link
Contributor Author

Looking at your thoughts, I would suggest to move one speed layer at a time. Let's disable live speeds(i.e current) source for top_speed feature and see how it goes
I'll update the PR soon

@merkispavel merkispavel changed the title top_speed option: don't use dynamic speed layers for speed based penalties top_speed option: ignore live speed for speed based penalties Dec 20, 2021
@merkispavel
Copy link
Contributor Author

I update the PR, folks. It's ready for review

// better to use layers with smoothed/constant speeds
if (top_speed_ != kMaxAssumedSpeed && (flow_sources & kCurrentFlowMask)) {
average_edge_speed =
tile->GetSpeed(edge, flow_mask_ & kNotCurrentFlowMask, time_info.second_of_week);
Copy link
Member

@kevinkreiser kevinkreiser Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this should be:

Suggested change
tile->GetSpeed(edge, flow_mask_ & kNotCurrentFlowMask, time_info.second_of_week);
tile->GetSpeed(edge, flow_mask_ & (~kCurrentFlowMask), time_info.second_of_week);

its less confusing that way imho

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll drop this alias

@@ -629,6 +629,7 @@ constexpr uint8_t kFreeFlowMask = 1;
constexpr uint8_t kConstrainedFlowMask = 2;
constexpr uint8_t kPredictedFlowMask = 4;
constexpr uint8_t kCurrentFlowMask = 8;
constexpr uint8_t kNotCurrentFlowMask = kFreeFlowMask | kConstrainedFlowMask | kPredictedFlowMask;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont th ink we need this we can just use bitwise operators directly right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind. I didn't measure but I hope it won't impact performance

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bitwise negation of a constant? if the compiler doesnt optimize that then ill be a monkeys uncle!

Copy link
Contributor Author

@merkispavel merkispavel Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, damn, indeed.. I forgot that they are constants(constexpr-s). The complier definitely handles such things 👍 Thanks for the hint, @kevinkreiser

kevinkreiser
kevinkreiser previously approved these changes Dec 21, 2021
Copy link
Member

@kevinkreiser kevinkreiser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks fine to me, i suggested a small change to use negation to flip the current flow bit rather than having another constant.

The compiler is expected to handle any constant operations so there's no need to bring new variables
@kevinkreiser
Copy link
Member

Shouldn't we do other motorized costings like truck etc?

@merkispavel
Copy link
Contributor Author

Shouldn't we do other motorized costings like truck etc?

My bad. Originally I grepped only autocost.cc file for top_speed_ usages.
Now all costings(truck, motor*, etc) have these change. Nice catch @kevinkreiser 🙏

@mandeepsandhu
Copy link
Contributor

Some of the closure penalty tests are failing. I remember we penalized closed roads by costing it as a very low-speed road. Looks like that penalty is no longer applied?

@@ -172,9 +172,6 @@ TEST_P(ClosurePenalty, AvoidClosure) {
.str();

std::vector<std::string> expected_path = {"QT", "TU", "RU", "OR", "LO", "IL", "FI", "CF"};
if (costing == "motor_scooter") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mandeepsandhu I've seen a comment about this change in your PR #2964 (comment)
I guess this is insignificant(as you noted)

@merkispavel
Copy link
Contributor Author

Tests are finally fixed. All tests pass and the PR ready for the final review.
FYI I added on more commit to extract speed penalty calculation and avoid its duplication across costings. Let me know if this is redundant: it's a standalone commit so it's easy to revert

Copy link
Contributor

@mandeepsandhu mandeepsandhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@merkispavel
Copy link
Contributor Author

Going to merge it, folks. Feel free to leave comments/review if there's something that needs to be fixed/reverted/etc

@merkispavel merkispavel merged commit b5ce7c4 into master Jan 11, 2022
@merkispavel merkispavel deleted the drop-current-flow-avoidance branch January 11, 2022 09:44
@nilsnolde
Copy link
Member

no worries, was waiting for tests passing before approving. good with me, thanks!

@kevinkreiser
Copy link
Member

yep you covered my comments so i was good thanks

kevinkreiser pushed a commit that referenced this pull request Jan 12, 2022
* Not use live/predicted speeds for speed penalties

* Drop only live speeds from top_speed penalties

* Apply top speed changes for TaxiCost

* remove unnecessary dynamicflowmask anymore

* Test that live speed is disabled to top_speed option

* Update CHANGELOG.md

* Drop newly added flow constant, use bitwise negation inplace

The compiler is expected to handle any constant operations so there's no need to bring new variables

* Apply top_speed changes to other costings

* Fix closure test: use common expected route for motorscooter

* Refactor: extract speed based penalty calculation
kevinkreiser added a commit that referenced this pull request Jan 14, 2022
* sequester outputs of location correlation in pbf

* missed a spot

* refactor costing protos

* lint and docs

* fix changelog

* top_speed option: ignore live speed for speed based penalties (#3460)

* Not use live/predicted speeds for speed penalties

* Drop only live speeds from top_speed penalties

* Apply top speed changes for TaxiCost

* remove unnecessary dynamicflowmask anymore

* Test that live speed is disabled to top_speed option

* Update CHANGELOG.md

* Drop newly added flow constant, use bitwise negation inplace

The compiler is expected to handle any constant operations so there's no need to bring new variables

* Apply top_speed changes to other costings

* Fix closure test: use common expected route for motorscooter

* Refactor: extract speed based penalty calculation

* allow the caller to ask for only certain parts of the top level protobuf api

* Include roads under construction into the graph (#3455)

* Use roads under construction

 * updated lua code to include roads under construction;
 * added a new config option to include or exclude roads
   under construction from valhalla graph;
 * exclude roads under construction from routing;
 * exclude roads under construction from shortcuts building.

* Added tests for roads under construction

* Update changelog

* Update taginfo.json

* Add 'hov' costing to test constructions

* Put 'construction' use above the transit uses

* Turn off access for roads under construction

* Remove needless 's' from the option 'include_constructions'

* Turn off access for construction in lua;

 - exclude construction from density calculation;
 - do not use construction as an intersecting edge;

* Exclude roads under construction from stopimpact calculation

* Fix isochrone test

* Update changelog

* allow the caller to ask for only certain parts of the top level protobuf api

* if you want pbf and you are sending json as input we need to parse the format string

* changelog merge again

* changelog merge again

* have the main parsing function do the request clearing in one place rather than duplicating

* when not specified default to minimal pbf return for pbf formats. update tests to prove it

* kick ci

* fix mac build

* changelog formatting

* changelog formatting

Co-authored-by: Pavel Merkis <pavel.merkis@mapbox.com>
Co-authored-by: Henadzi Klimuk <genadz.klimuk@mapbox.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants