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

profiles api v2 #4072

Merged
merged 1 commit into from
Jul 18, 2017
Merged

profiles api v2 #4072

merged 1 commit into from
Jul 18, 2017

Conversation

emiltin
Copy link
Contributor

@emiltin emiltin commented May 22, 2017

improves the profile API and bumps the version from 1 to 2.

Tasklist

  • move properties into profile table
  • improve version handling to avoid calling api functions when loading file
  • avoid the need for get_restrictions() in profiles
  • avoid the need for get_name_suffix_list() in profiles
  • reconcile constants.max_turn_weight and contants.precisions
  • improve module interface so profiles can include each other easily
  • stop using globals, instead pass profile as an arg to way/etc functions
  • rename way_functions to process_way (some for node, segment, turn)
  • pass functions instead of strings to Handlers.run()
  • initialize raster sources in setup() instead of in a separate callback
  • rename Handlers to WayHandlers, to prepare for NodeHandlers, etc
  • reorder arguments to Handlers functions to match way function.
  • group fields in the profile table accessed from c++ under profile.properties
  • rename sources to raster in the api
  • update profile documentation
  • update relevant Wiki pages
  • review
  • adjust for comments

Requirements / Relations

This is a breaking change of the profile API.

@oxidase
Copy link
Contributor

oxidase commented May 22, 2017

@emiltin max_turn_weight is a read-only property that depends on TurnPenalty type and weight_precision. It is used to clip turn penalties in Lua to prevent overflows in conversions double to TurnPenalty. It can be set together with context.properties.weight_precision as

    if( weight_precision != sol::nullopt) {
      context.properties.weight_precision = weight_precision.value();
      context.properties.weight_multiplier = std::pow(10., context.properties.weight_precision);
      context.properties.max_turn_penalty = std::numeric_limits<TurnPenalty>::max() / weight_multiplier;
   }

@emiltin
Copy link
Contributor Author

emiltin commented May 23, 2017

ok. but is it really needed in the lua profiles then? can the capping be done on the c++ side?

@oxidase
Copy link
Contributor

oxidase commented May 23, 2017

it is needed in profiles as the maximal turn penalty that is used in transit routing restrictions. The turn restriction value can be clipped in c++ by removing assertions, but it should be made explicit with warnings

@emiltin
Copy link
Contributor Author

emiltin commented May 23, 2017

can the profile use a big constant as the max weight, and then let the c++ side cap it according to the current precision?

@oxidase
Copy link
Contributor

oxidase commented May 23, 2017

@emiltin yes, it is possible /cc @TheMarex

@emiltin emiltin force-pushed the refactor/profile_properties branch from fc018a9 to af92624 Compare May 23, 2017 11:03
@emiltin
Copy link
Contributor Author

emiltin commented May 23, 2017

all tests are green. profiles can now use constants.max_turn_weight if needed. it's defined as a constant with the value -1. this assumes that negative turn weights are not valid, is that true?

this PR is a breaking change changes the profile interface a bit.

@emiltin emiltin force-pushed the refactor/profile_properties branch 3 times, most recently from 10972c4 to f46ec93 Compare May 23, 2017 11:30
@emiltin
Copy link
Contributor Author

emiltin commented May 23, 2017

rebased

@emiltin
Copy link
Contributor Author

emiltin commented May 23, 2017

travis is failing with link errors:
/home/travis/build/Project-OSRM/osrm-backend/src/extractor/scripting_environment_lua.cpp:406: error: undefined reference to 'osrm::extractor::Sol2ScriptingEnvironment::MAX_TURN_WEIGHT'

it's compiling for me locally with gcc on linux. not sure why it's failing on travis?

Copy link
Contributor

@oxidase oxidase left a comment

Choose a reason for hiding this comment

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

undefined reference error can be related to different Release/Debug options in sol2:

struct S { static const int a = 1; };
int main() {  return S::a;  }

is ok, but &S::a would require a definition for S::a

@@ -46,6 +46,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
public:
static const constexpr int SUPPORTED_MIN_API_VERSION = 0;
static const constexpr int SUPPORTED_MAX_API_VERSION = 1;
static const constexpr int MAX_TURN_WEIGHT = -1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Negative turn restrictions are correct values #3683

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, then of course we cannot use -1 as a special value

@@ -598,6 +615,9 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
{
turn_function(turn);

if( turn.weight == MAX_TURN_WEIGHT )
turn.weight = context.properties.GetMaxTurnWeight();
Copy link
Contributor

Choose a reason for hiding this comment

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

It is better to set here std::min(turn.weight, context.properties.GetMaxTurnWeight()) to avoid MAX_TURN_WEIGHT and print later number of clamped values

Copy link
Contributor Author

@emiltin emiltin May 24, 2017

Choose a reason for hiding this comment

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

you mean unconditionally cap the value? ie:

turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());

what value should the profile use then to indicate max weight?

Copy link
Contributor

Choose a reason for hiding this comment

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

the only purpose of the turn penalty maximum weight is to prevent int32_t overflows on c++ side. If turn penalties are modified on c++ then side the maximum value is not needed in Lua, but number of modifications must be reported as a warning.

@emiltin
Copy link
Contributor Author

emiltin commented May 24, 2017

@oxidase adjusted according to your suggestions. let's see what travis thinks.

@oxidase
Copy link
Contributor

oxidase commented May 26, 2017

@emiltin i have pushed some commits directly to the branch to check changes on travis. The main change is in 62a0819 where max_turn_weight is moved to be a member of profiles properties. If it s not ok, you can kick out of the branch these commits.

Copy link
Member

@TheMarex TheMarex left a comment

Choose a reason for hiding this comment

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

General idea is fine, however this is a breaking change to the profile API. That means we need to bump the version and offer a fallback using the global properties.

@oxidase
Copy link
Contributor

oxidase commented May 26, 2017

@emiltin @TheMarex if the profile version is increased then 6e056e1 must be kicked out

@emiltin
Copy link
Contributor Author

emiltin commented May 26, 2017

thanks @oxidase for the commits.
@TheMarex yes, backward compatibility needs to be in place, that's not handled yet.

@emiltin
Copy link
Contributor Author

emiltin commented Jun 7, 2017

i think it's best to increase the api version to 2, and then incorporate other relevant changes to the api. it can then be merged at an appropriate osrm version change.

@emiltin emiltin changed the title profiles: move properties into profile table profiles api v2: move properties into profile table Jun 7, 2017
@emiltin
Copy link
Contributor Author

emiltin commented Jun 7, 2017

library files like handlers.lua are tied to a specific version of the api, for example because it accceses properties.weight_name.
this means that if you update osrm you also need to update the lua library. it also means that tests for older api version cannot use the library files, since the library files work with the latest api version.

@emiltin
Copy link
Contributor Author

emiltin commented Jun 7, 2017

for version 2 of the api we might want to improve the way versioning is handled: #4133

@emiltin emiltin force-pushed the refactor/profile_properties branch from 58a3ff5 to 6c8b7e4 Compare June 8, 2017 09:22
Copy link
Member

@TheMarex TheMarex left a comment

Choose a reason for hiding this comment

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

Looks good! The only missing pieces are documentation now:

  • docs/profile.md needs to be updated
  • CHANGELOG.md needs an entry for 5.10

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

is it correctly understood that the weight is just the inverse of the rate? and that setting output.weight in way_function is just a shorthand for setting both forward and backward rates?

should we change output.weigh to output.rate?

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

seems that weight = distance/rate. i'm trying to explain this in doc/profiles.md

Understanding speed, weight, rate and distance

When computing a route from A to B there can be different measure of what is the best route. Because speeds very on differnt types of roads, the shortest and the fastest route are typically different. But there are many other possible preferences. For example a user might prefer a bicycle route that follow parks or other green areas, even though both duration and distance are a bit longer.

To handle this, OSRM doesn't simply choose the ways with the highest speed. Intead it uses the concept of weight and rate. The rate is an abstract meassure that you can assign to to ways as you like to make some ways preferable to others. Routing will prefer ways with high rate.

The weight of a way is computed as distance / rate. The weight can be though of as the resistance or cost when passing a way. Routing will prefer ways with low weight.

You should set the speed to you best estimante of the actual speed that will be used on a particual way. This will result in the best estimated travel times.

If you want to prefer certain ways due to other factors than the speed, adjust the rate accordingly. If you adjust the speed, the time time estimation will be skewed.

If you set the same rate on all ways, the result will be shortest path routing.
If you set rate = speed on all ways, the result will be fastest path routing.
If you want to prioritize e.g. smaller street, increase the rate on these.

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

looking at how raster source data is used i'm wondering about this bit:

  local sourceData = sources:query(profile.raster_source, segment.source.lon, segment.source.lat)
  local invalid = sourceData.invalid_data()
  if sourceData.datum ~= invalid then
    -- use value in targetData.datum

wouldn't it be easier if you could just do:

  local sourceDatum = sources:query(profile.raster_source, segment.source.lon, segment.source.lat)
  if sourceDatum ~= nil then
    -- use value in sourceDatum

and maybe we should rename source to something like raster_data? sources seems like a very generic word.

@TheMarex
Copy link
Member

is it correctly understood that the weight is just the inverse of the rate? and that setting output.weight in way_function is just a shorthand for setting both forward and backward rates?

weight is like the duration value: It is fixed for the whole way. rate on the other hand is like the speed values, it depends on the geometric length on the way. The formula is weight = length / rate (like duration = length / speed).

looking at how raster source data is used i'm wondering about this bit:

I think this is due to the fact that the C++ code will return an integer always. Probably needs a shim in the bindings to make this return nil in lua-land.

and maybe we should rename source to something like raster_data? sources seems like a very generic word.

Hrm yeah what about raster?

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

makes sense. however i'm confused by your statement that rate depends on the geometric length on the way. isn't it the other way around: weight depends on the length of the way, while rate does not?

.

@TheMarex
Copy link
Member

@emiltin yes, I meant you need the geometric length to convert rate to the actual value used by OSRM.

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

alright. if you set the weight, are the rates then ignored?

@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

why is there no forward_weight and backward_weight?

@emiltin emiltin force-pushed the refactor/profile_properties branch from 2611c38 to b27d45f Compare July 13, 2017 09:29
@emiltin
Copy link
Contributor Author

emiltin commented Jul 13, 2017

updated docs/profiles.md. might need a few adjustments regarding weight and rate.
also squashed and rebased.

@TheMarex
Copy link
Member

@emiltin just because we don't have forward_duration and backward_duration. I don't see a problem with adding it, it was just done for consistency I think. If you are up for it, that should be a simple change to ExtractionWay and ExtractorCallbacks::ProcessWay to change it to directional versions.

@emiltin emiltin force-pushed the refactor/profile_properties branch from 40fa316 to 13a1769 Compare July 17, 2017 11:34
@emiltin
Copy link
Contributor Author

emiltin commented Jul 17, 2017

updated changelog and rebased on master.

Copy link
Member

@TheMarex TheMarex left a comment

Choose a reason for hiding this comment

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

Thanks @emiltin for putting in the hard work there. This looks much better both on the code front, as well as on the documentation front. I'm excited to ship this with 5.10.

docs/profiles.md Outdated

As you scroll down the file you'll see local variables, and then local functions, and finally...
You can also set the weight og a way to a fixed value, In this case it's not calculated based on the length or rate, and the rate is ignored.
Copy link
Member

Choose a reason for hiding this comment

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

typo the weight of a way to a fixed value

docs/profiles.md Outdated

Towards the top of the file, a profile (such as [car.lua](../profiles/car.lua)) will typically define various configurations as global variables. A lot of these are look-up hashes of one sort or another.
The weight of a way normally computed as length / rate. The weight can be though of as the resistance or cost when passing the way. Routing will prefer ways with low weight.
Copy link
Member

Choose a reason for hiding this comment

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

typo can be thought of

@emiltin emiltin force-pushed the refactor/profile_properties branch from 13a1769 to 3dd01cc Compare July 18, 2017 06:27
@emiltin
Copy link
Contributor Author

emiltin commented Jul 18, 2017

i ran the changelog through a spell checker (US english) and corrected a number of errors.

@emiltin
Copy link
Contributor Author

emiltin commented Jul 18, 2017

should this wiki page https://github.com/Project-OSRM/osrm-backend/blob/master/docs/profiles.md be updated, or replaced with a reference to the file in the repo?

@TheMarex
Copy link
Member

@emiltin I think a link to the repo-docs would be best.

@emiltin
Copy link
Contributor Author

emiltin commented Jul 18, 2017

ah, the main wiki page already uses a link to the repo file.

@TheMarex TheMarex merged commit e413b25 into master Jul 18, 2017
@MoKob MoKob deleted the refactor/profile_properties branch August 4, 2017 09:17
lliehu added a commit to lliehu/cbf-routing-profiles that referenced this pull request Jun 24, 2023
Routing on proposed ways was blacklisted only for car profile.
This adds the same blacklisting also for foot and bike profiles.

It looks like this behavior was added in
Project-OSRM/osrm-backend#4258 and then
accidentally reverted when pull request with title "profiles api v2"
at Project-OSRM/osrm-backend#4072 was merged.
This commit restores the original change for bike and foot profiles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants