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

Adds max_linear_tolerance parameter: linear tolerance as a range #182

Merged
merged 8 commits into from Oct 18, 2021

Conversation

francocipollone
Copy link
Collaborator

Part of #130

Summary

This PR enables setting a range of linear tolerances to be used.

  • A new parameter is accepted to be used when calling the load(std::map<std::string, std::string> params) method: "max_linear_tolerance"
    • When max_linear_tolerance is passed, the builder will create a range of valid linear tolerances: [linear_tolerance, max_linear_tolerance]. Afterwards, the builder will try building the RoadGeometry scaling from the minimum value of linear tolerance to the maximum, doing increments of 10% of the previous linear tolerance.
  • The ToleranceSelectionPolicy was deprecated, as this is implicitly enabled when the optional parameter max_linear_tolerance is passed.
  • The old logic of automatic tolerance selection also increased the angular_tolerance in each iteration. In this PR that behavior is changed the angular_tolerance remains the same. Given that in general, the angular_tolerance isn't an issue when loading maps. If we still want to increase the angular_tolerance in each iteration I think that accepting a max_angular_tolerance parameter would be the way to go.

Comments for the reviewers

Reviewing the PR commit by commit is recommended.

/// When this parameters is passed, the linear tolerance the builder will use
/// is defined within the range [linear_tolerance, max_linear_tolerance].
/// The builder is expected to iteratively try higher linear tolerances as building process
/// fails.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of "as building process fails", let's use "until it either finds a value that works, or reaches this maximum value, at which point it will abort with a failure."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. Done.

MALIDRIVE_VALIDATE(
rg_config_.tolerances.max_linear_tolerance.value() >= rg_config_.tolerances.linear_tolerance,
maliput::common::assertion_error,
std::string("max_linear_tolerance should be greater or equal than linear_tolerance.\n linear_tolerance: ") +
Copy link
Collaborator

Choose a reason for hiding this comment

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

"greater or equal than" should be "greater than or equal to".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

rg_config_.tolerances.max_linear_tolerance.value() >= rg_config_.tolerances.linear_tolerance,
maliput::common::assertion_error,
std::string("max_linear_tolerance should be greater or equal than linear_tolerance.\n linear_tolerance: ") +
std::to_string(rg_config_.tolerances.linear_tolerance) + std::string("\nmax_linear_tolerance: ") +
Copy link
Collaborator

Choose a reason for hiding this comment

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

"\nmax_linear_tolerance

For consistency, should add a space after "\n".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

std::array<double, constants::kMaxToleranceSelectionRounds + 1> angular_tolerances{};
std::array<double, constants::kMaxToleranceSelectionRounds + 1> scale_lengths{};

// As a max linear tolerance is provided, the tolerance range logic is enabled.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"As a" should be "Because a".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@@ -130,6 +109,31 @@ struct RoadGeometryConfiguration {
/// @param road_geometry_configuration A string-string map containing the configuration for the builder.
static RoadGeometryConfiguration FromMap(const std::map<std::string, std::string>& road_geometry_configuration);

/// Holds linear and angular tolerance to be used by the builder.
/// A range could be selected for linear tolerance, allowing the builder to try
/// different values of linear tolerance within that range when the builder process fails.
Copy link
Collaborator

Choose a reason for hiding this comment

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

values of linear tolerance

should be:

values of linear tolerances

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's replace "when the builder process fails" with "searching for a value that works".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

/// A range could be selected for linear tolerance, allowing the builder to try
/// different values of linear tolerance within that range when the builder process fails.
struct BuildTolerance {
/// Set linear and angular tolerance.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"Set" should be "Sets" per Google style guide.

(Ditto below.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@@ -10,6 +10,9 @@ namespace constants {
static constexpr double kLinearTolerance{5e-2}; // [m]
static constexpr double kAngularTolerance{1e-2}; // [rad]
static constexpr double kScaleLength{1.}; // [m]
/// Step used to increase the tolerance by the Builder.
static constexpr double kIncreasingToleranceStep{1.1};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a multiplier? The word "Step" without a qualifier makes me think it is an absolute step size (meter units). Maybe we can use "Multiplier"?

static constexpr double kToleranceStepMultiplier{1.1};

I took away "Increasing" since that can be inferred based on multiplier > 1.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fully agree. Done.

@@ -25,6 +25,12 @@ namespace loader {
/// - Default: ""
/// - @b linear_tolerance : RoadGeometry's linear tolerance.
/// - Default: @e "5e-2" (#malidrive::constants::kLinearTolerance)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This got me thinking: given max_linear_tolerance, is there ever a reason to specify a minimum linear tolerance? If the builder is able to find a linear tolerance that is smaller than the specified minimum, is there a reason not to use it?

If smaller linear tolerances are always better, could we allow users to only specify the max linear tolerance, and have the loader start searching from a very small value that is epsilon above zero?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My concern about starting with a minimum epsilon value (an epsilon to be defined) is the time that it could take in achieving the right tolerance. However, if the user is willing to accept that time then it could be useful.

I wouldn't remove the linear_tolerance variable given that it would be a hint for the builder when it is known that a certain map won't support tolerances less than that linear_tolerance.

So at the end the user could do:

  • set only linear_tolerance: Builder will only try with this linear tolerance
  • set only max_linear_tolerance: Builder will start the iteration process from a small value(epsilon TBD)
  • set both linear_tolerance and max_linear_tolerance: Builder will iterate from the minimum to the maximum value of the range delimited by linear_tolerance and max_linear_tolerance

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sound good. Let's just document the fact that it might take a lot of time if the user only specifies a max tolerance, but the benefit is potentially lower tolerance.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

While implementing this new behavior I found that there was one verification that was being done at a parser level that wasn't taken into account during this tolerance selection mechanism: #183 (Edited: Mentioned in the issue: Actually it was taken into account however it was causing unnecessary extra time when iterating the tolerances)

So I pushed #185 and after this is merged and I will push the here-discussed implementation about the linear_tolerance and max_linear_tolerance flags.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So at the end the user could do:
set only linear_tolerance: Builder will only try with this linear tolerance
set only max_linear_tolerance: Builder will start the iteration process from a small value(epsilon TBD)
set both linear_tolerance and max_linear_tolerance: Builder will iterate from the minimum to the maximum value of the range delimited by linear_tolerance and max_linear_tolerance

I've addressed this at:

I also added some tests:

RoadGeometryConfiguration::ToleranceSelectionPolicy::kAutomaticSelection;
// By default the RoadGeometryBuilderBaseTest::SetUp() is using GetRoadGeometryConfigurationFor() to get the
// RoadGeometryConfigurations which already define a max_linear_tolerance.
// However a new max linear tolerance is defined just to the purpose of the test.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"to the purpose" should be "for the purpose".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. Done.

/// - Default: By default it isn't set. When `max_linear_tolerance` isn't also set then @e "5e-2"
/// (#malidrive::constants::kLinearTolerance) is used.
/// - @b max_linear_tolerance : A maximum allowed linear tolerance.
/// When this parameters is passed, the linear tolerance the builder will use
Copy link
Collaborator

Choose a reason for hiding this comment

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

"this parameters" should be "this parameter".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. Done.

/// `road_geometry_configuration.scale_length` are negative.
/// `manager` or `factory` are nullptr.
/// @throws maliput::common::assertion_error When `road_geometry_configuration.tolerances.max_linear_tolerance` is
/// less than `road_geometry_configuration.tolerances.linear_tolerance`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

The comma should be a period.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

/// `manager` or `factory` are nullptr.
/// @throws maliput::common::assertion_error When `road_geometry_configuration.tolerances.max_linear_tolerance` is
/// less than `road_geometry_configuration.tolerances.linear_tolerance`,
/// @throws maliput::common::assertion_error When `manager` are nullptr.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"are" should be "is".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Collaborator

@liangfok liangfok left a comment

Choose a reason for hiding this comment

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

LGTM

@francocipollone francocipollone merged commit 7d07074 into main Oct 18, 2021
@francocipollone francocipollone deleted the francocipollone/add_tolerance_range branch October 18, 2021 22:38
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

2 participants