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

Refactor mapmatching configuration to use a struct #2485

Merged
merged 2 commits into from
Aug 24, 2020

Conversation

genadz
Copy link
Contributor

@genadz genadz commented Jul 22, 2020

Add configuration struct for mapmatching. It can be initialized with default values or with boost::property_tree (if some parameters are missing -> use default values, don't throw any exception).

Tasklist

  • Add tests
  • Add #fixes with the issue number that this PR addresses
  • Generally use squash merge to rebase and clean comments before merging
  • Update the changelog

@genadz genadz force-pushed the mm-static-config branch 2 times, most recently from bb29886 to 7f1335f Compare July 22, 2020 09:52
}

void Config::CandidateSearch::Read(const boost::property_tree::ptree& params) {
ReadParamOptional(search_radius, params, "default.search_radius");
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'm not sure about this: should we treat parameters from json as optional or required ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this it should be optional, with a sensible default configuration. My understanding though is that this is different from the current behavior, but should be fine because we are relaxing (vs strengthening) an API constraint (i.e., what was previously optional is now required).


namespace {

boost::property_tree::ptree json_to_pt(const std::string& json) {
Copy link
Contributor

Choose a reason for hiding this comment

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

ACK! We have 12 places where this function is copied. We should add it to a header somewhere and not have 13 places.

See also: #2481 (comment)

/cc @purew

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch! will fix

void Read(const boost::property_tree::ptree& params);
};

struct Emission {
Copy link
Contributor

Choose a reason for hiding this comment

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

This struct specifically characterizes a likelihood function, so I'd call it EmissionLikelihood. Same for TransitionLikelihood.

Copy link
Contributor

Choose a reason for hiding this comment

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

It should probably be TransitionCost, etc. since that's existing terminology used in meili.


struct CandidateSearch {
// default search radius (meters) for measurements; it's used to determine maximum search radius
float search_radius = 50.f;
Copy link
Contributor

Choose a reason for hiding this comment

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

For these variables that have SI units, we should add a units suffix, like search_radius_meters.

#include "meili/config.h"
#include "midgard/logging.h"

#define CHECK_POSITIVE_PARAM(value, name) \
Copy link
Contributor

@mookerji mookerji Jul 25, 2020

Choose a reason for hiding this comment

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

Macro is a great idea, but I think we can generalize this. My thoughts:

  • Add a macro.h header ... somewhere. I'm not sure what folder to put this in. Move this macro definition to that header so it can be used elsewhere.
  • Generalize CHECK_POSITIVE_PARAM to a more general conditional check, like a CHECK_THROWS(<condition>, <message>) macro. You could probably define something like:
#define CHECK_THROWS(condition, exc_info)  \
  do {                                                                                           \
    if (!(condition)) {                                                                    \
      throw std::invalid_argument(exc_info);                             \
    }                                                                                              \
  } while (0)

I probably butchered the syntax here, but you get the idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done. the main idea here was to avoid copying an exception message


// define options that can be dynamically reassigned with user request
struct Customizable {
bool turn_penalty_factor = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make more sense for each struct here to have a is_customizable=true|false flag?

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 thought about it. We can't have one flag for the whole struct because the struct may have customizable and non-customizable fields the same time. I think, the best solution here to remove flags from Customizable struct and put to others that have customizable params (looks like below you suggested the same).

interpolation_distance = false;
}

void Config::Customizable::Read(const boost::property_tree::ptree& params) {
Copy link
Contributor

Choose a reason for hiding this comment

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

See comment below about possibly moving the flag into each struct. This property of each configuration should be colocated with each value its describing.

@@ -492,21 +492,21 @@ struct path_t {
namespace valhalla {
namespace meili {

MapMatcher::MapMatcher(const boost::property_tree::ptree& config,
MapMatcher::MapMatcher(const Config& config,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think the API compatibility should be an issue, I've also cc'd some downstream users of the mapmatching library in case they have opinions.

@@ -293,8 +293,8 @@ void thor_worker_t::parse_measurements(const Api& request) {

// we require locations
try {
auto default_accuracy = matcher->config().get<float>("gps_accuracy");
auto default_radius = matcher->config().get<float>("search_radius");
auto default_accuracy = matcher->config().emission.gps_accuracy;
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's get rid of these auto's when we see them. I think in this case, it makes the code to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed for some cases considering readability.

Copy link
Contributor

@mookerji mookerji left a comment

Choose a reason for hiding this comment

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

This is looking really good! Made some suggestions and eager to hear what you think.

Copy link
Member

@SiarheiFedartsou SiarheiFedartsou left a comment

Choose a reason for hiding this comment

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

Significantly improves readability. LGTM.

test/utils.h Outdated Show resolved Hide resolved
@mookerji
Copy link
Contributor

This is looking really good, @genadz ! I'm out, but hopefully @kevinkreiser can help you get this merged.

 * Read config parameters from boost::property_tree::ptree

 * Add unittest for mapmatching config

 * Move some common functions from test files to shared header
@genadz genadz requested review from SiarheiFedartsou and removed request for yuzheyan August 21, 2020 15:01
@kevinkreiser kevinkreiser dismissed mookerji’s stale review August 21, 2020 18:35

all questions were addressed

@kevinkreiser kevinkreiser merged commit 81f7f2b into valhalla:master Aug 24, 2020
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

4 participants