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

add traffic to CostMatrix #4071

Merged
merged 26 commits into from
May 9, 2023
Merged

add traffic to CostMatrix #4071

merged 26 commits into from
May 9, 2023

Conversation

nilsnolde
Copy link
Member

@nilsnolde nilsnolde commented Apr 13, 2023

fixes #4038

Extending the work done in #3795, I added time awareness to the CostMatrix algo as well.

A few high-level things to mention:

  • currently we only support adding depart_at/current time spec, i.e. only on origin locations. I left a TODO for arrive_by which could be done (also for bidir A*), but not a priority for me at least and also quite a bit more work/complexity
  • the whole decision model in thor/matrix_action changed a bit. It still preserves the previous way we decided on the matrix algo, so nothing will change for Valhalla deployments which don't have any time info
  • unless prioritize_bidirectional: true is set (and of course plus a valid time on the sources/targets), we'll favor the more accurate (albeit much slower) TimeDistance matrix algo
  • to trigger a CostMatrix with time awareness:
    • add "prioritize_bidirectional": true in the root of the request
    • add at least one date_time string to an origin location or set the global date_time.type = 1/0

@nilsnolde
Copy link
Member Author

I'll leave it here for now. Next week I'll be on vacation, I'll comment more after. Feel free to have a glance of course:)

@nilsnolde nilsnolde changed the title Nn costmatrix add traffic add traffic to CostMatrix Apr 13, 2023
src/sif/recost.cc Outdated Show resolved Hide resolved
Comment on lines +1279 to +1281
// TODO: actually we should not ignore access restrictions: if the reverse path
// traversed a closed edge due to time restrictions, we could do a mini traversal
// to circumvent the closed edge(s)
Copy link
Member Author

Choose a reason for hiding this comment

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

it's not the nicest patch, but still nicer than navigating over an edge we know is closed

const float max_matrix_distance) {
const sif::travel_mode_t mode,
const float max_matrix_distance,
const bool has_time,
Copy link
Member Author

Choose a reason for hiding this comment

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

we tell it when there's a valid time. we compute it in matrix_action where we already check if any time is valid

};

Cost new_cost{0.f, 0.f};
const auto label_cb = [&new_cost](const EdgeLabel& label) { new_cost = label.cost(); };
Copy link
Member Author

@nilsnolde nilsnolde Apr 15, 2023

Choose a reason for hiding this comment

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

we only need to update the cost when recosting the path, no path necessary. once we want to tackle #3920, we can do it similar to bidir a*

Comment on lines +1005 to +1007
const auto edge_cb = [&edge_itr, &path_edges]() {
return (edge_itr == path_edges.end()) ? GraphId{} : (*edge_itr++);
};
Copy link
Member Author

Choose a reason for hiding this comment

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

same as bidir a*, only the label callback changes


// return true if any location had a time set
// also disable time if it doesn't make sense computationally
bool has_time(Api& request) {
Copy link
Member Author

Choose a reason for hiding this comment

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

changed it to check_matrix_time and moved it to matrix_common.h

bool has_time =
check_matrix_time(request,
options.prioritize_bidirectional() ? MatrixType::Cost : MatrixType::TimeDist);
if (has_time && !options.prioritize_bidirectional() && !force_costmatrix) {
Copy link
Member Author

Choose a reason for hiding this comment

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

do a timedistance matrix, no matter the costing model, if:

  • there's time
  • prioritize_bidirectional is false
  • the server doesn't have COST_MATRIX defined

Copy link
Member Author

@nilsnolde nilsnolde Apr 27, 2023

Choose a reason for hiding this comment

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

document & warn properly

options.prioritize_bidirectional() ? MatrixType::Cost : MatrixType::TimeDist);
if (has_time && !options.prioritize_bidirectional() && !force_costmatrix) {
return tyr::serializeMatrix(request, timedistancematrix(), distance_scale, MatrixType::TimeDist);
} else if (has_time && options.prioritize_bidirectional()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

otherwise, if there's a valid time AND prioritize_bidirectional is true, we do a CostMatrix

Comment on lines 95 to 98
} else if (matrix_type == MatrixType::Cost) {
return tyr::serializeMatrix(request, costmatrix(has_time), distance_scale, matrix_type);
} else {
return tyr::serializeMatrix(request, timedistancematrix(), distance_scale, matrix_type);
Copy link
Member Author

Choose a reason for hiding this comment

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

these two are the same as before

Comment on lines +34 to +35
check_matrix_time(request, MatrixType::Cost),
options.date_time_type() == Options::invariant);
Copy link
Member Author

Choose a reason for hiding this comment

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

also enable time awareness for /optimized

@@ -22,37 +22,6 @@ static bool IsTrivial(const uint64_t& edgeid,
}
return false;
}

// Will return a destination's date_time string
std::string GetDateTime(const std::string& origin_dt,
Copy link
Member Author

Choose a reason for hiding this comment

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

moved this to matrix_common.h as well so we can use it in both

@@ -2,7 +2,7 @@

#include "baldr/json.h"
#include "proto_conversions.h"
#include "thor/costmatrix.h"
#include "thor/matrix_common.h"
Copy link
Member Author

Choose a reason for hiding this comment

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

I moved most common things, which were actually previously defined in costmatrix.h to matrix_common.h as the import pattern was a bit weird otherwise (timedistance.h matrix would import costmatrix.h..)

Comment on lines +75 to +76
json->emplace("algorithm",
std::string(matrix_type == MatrixType::Cost ? "costmatrix" : "timedistancematrix"));
Copy link
Member Author

@nilsnolde nilsnolde Apr 15, 2023

Choose a reason for hiding this comment

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

add a algorithm field to the response to both osrm and valhalla formats

Comment on lines -30 to -33
constexpr float kMaxCost = 99999999.9999f;

// Time and Distance structure
struct TimeDistance {
Copy link
Member Author

Choose a reason for hiding this comment

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

moved these to matrix_common.h as well

@@ -15,15 +15,18 @@
#include <valhalla/sif/dynamiccost.h>
#include <valhalla/sif/edgelabel.h>
#include <valhalla/thor/astarheuristic.h>
#include <valhalla/thor/costmatrix.h>
Copy link
Member Author

Choose a reason for hiding this comment

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

this was strange 😄

…shortcuts in the algorithm, we'd need to hack the hierarchy limits
src/thor/matrix_action.cc Outdated Show resolved Hide resolved
@nilsnolde
Copy link
Member Author

Addressed the review comments from yesterday @kevinkreiser :

  • 9419e4b: re-arranged the decision model for which algo to use in matrix_action a little
  • ada29d7: Also added warnings if the config forces the algorithm but the request im-/explicitly suggested a different algorithm.
  • 49ff04b: minor things like leaving a todo & changing < to <= in one place

@nilsnolde
Copy link
Member Author

Anecdotally, one client was benchmarking the time results with the bidir A*. They computed a route for every 5 mins of the week (only with historical traffic) and it’s aligning perfectly, BUT the matrix is in ~60% of the cases off by one second (matrix reported exactly 1 sec longer than routing). Not sure if that’s the serializers or in the algos (though doesn’t look/feel like it’s the algos..). Not a show stopper IMO, but still worth noting.

@nilsnolde
Copy link
Member Author

There was a minor conflict in costmatrix.cc. After CI is done, this is good to merge from my side @kevinkreiser :)

@kevinkreiser
Copy link
Member

looks like setsources is missing the timeinfo arg

@nilsnolde
Copy link
Member Author

Yeah there were a few code merge conflicts and I shouldn't have tried solving those in the Github UI, it made a bit of a mess. That function was called twice, old & new way, so it threw.

I fixed it.

Comment on lines 794 to 795
source_edgelabel_.resize(source_count_);
source_edgestatus_.resize(source_count_);
Copy link
Member

Choose a reason for hiding this comment

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

arent these now redundant with Initialize?

@nilsnolde
Copy link
Member Author

no coverage report, due to the github outage I assume, but we already know it's slightly failing due to not being able to configure hierarchy limits in the config. win succeeded, even though showing as "Queued"

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.

time-dependent cost matrix
2 participants