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
14 changes: 7 additions & 7 deletions maliput_malidrive/include/maliput_malidrive/constants.h
Expand Up @@ -10,6 +10,13 @@ namespace constants {
static constexpr double kLinearTolerance{5e-2}; // [m]
static constexpr double kAngularTolerance{1e-2}; // [rad]
static constexpr double kScaleLength{1.}; // [m]
/// Base linear tolerance used as minimum value in the linear tolerance range
/// when tolerance selection mechanism is enabled and no linear_tolerance parameter
/// is passed to the builder.
static constexpr double kBaseLinearTolerance{1e-6}; // [m]
/// Multiplier used to increase the tolerance by the Builder.
static constexpr double kToleranceStepMultiplier{1.1};

/// Stricter tolerances.
static constexpr double kStrictLinearTolerance{1e-12}; // [m]
static constexpr double kStrictAngularTolerance{1e-12}; // [rad]
Expand All @@ -18,13 +25,6 @@ static constexpr double kStrictAngularTolerance{1e-12}; // [rad]
static constexpr double kSpeedTolerance{1e-4}; // [m/s]
static constexpr double kDefaultMinSpeedLimit{0.}; // [m/s]
static constexpr double kDefaultMaxSpeedLimit{40. / 3.6}; // [m/s] --> 40km/h
/// Number of trials the Builder will run with different tolerances.
/// Using default linear tolerance value it is expected that the builder tries with
/// tolerances in a range between 0.05 and 0.49. (#kLinearTolerance and #kLinearTolerance * #kIncreasingToleranceStep ^
/// #kMaxToleranceSelectionRounds )
static constexpr int kMaxToleranceSelectionRounds{24};
/// Step used to increase the tolerance by the Builder. See #kMaxToleranceSelectionRounds.
static constexpr double kIncreasingToleranceStep{1.1};

} // namespace constants
} // namespace malidrive
21 changes: 14 additions & 7 deletions maliput_malidrive/include/maliput_malidrive/loader/loader.h
Expand Up @@ -24,7 +24,20 @@ namespace loader {
/// - @b opendrive_file : Path to the XODR file to be loaded.
/// - Default: ""
/// - @b linear_tolerance : RoadGeometry's linear tolerance.
/// - Default: @e "5e-2" (#malidrive::constants::kLinearTolerance)
/// - 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 parameter 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 until it either finds
/// a value that works, or reaches this maximum value, at which point it will abort with a
/// failure.
/// When `linear_tolerance` isn't set, the minimum value of the range will be defined by
/// #malidrive::constants::kBaseLinearTolerance. It is recommended to define the minimum
/// value using the `linear_tolerance` parameter to hint the builder to a valid range,
/// otherwise this method could demand a considerable extra time while it tries out
/// relatively small linear tolerances.
/// - Default: By default it isn't set. The builder will try only `linear_tolerance`.
/// - @b angular_tolerance : RoadGeometry's angular tolerance.
/// - Default: @e "1e-3" (#malidrive::constants::kAngularTolerance)
/// - @b scale_length : RoadGeometry's scale length.
Expand All @@ -47,12 +60,6 @@ namespace loader {
/// - 1. @e "none"
/// - 2. @e "simplify"
/// - Default: @e "none"
/// - @b tolerance_selection_policy : Tolerance selection method used by the builder.
/// - Options:
/// - 1. "manual" : @e linear_tolerance will be used.
/// - 2. "automatic" : @e linear_tolerance is used as base and bigger tolerances are used when the base tolerance
/// make the builder to fail.
/// - Default: @e "automatic"
/// - @b standard_strictness_policy : Indicates how permissive builder should be with the XODR description.
/// - Options:
/// - 1. @e "strict" : Do not permit any errors.
Expand Down
166 changes: 100 additions & 66 deletions maliput_malidrive/src/maliput_malidrive/builder/road_geometry_builder.cc

Large diffs are not rendered by default.

Expand Up @@ -104,23 +104,21 @@ class RoadGeometryBuilder {
/// `manager` must not be nullptr. Ownership will be transferred to the
/// resulting RoadGeometry.
///
/// `factory` must not be nullptr. Used to create the road curve for the lanes.
///
/// Resulting maliput::api::RoadGeometry will have `linear_tolerance`,
/// `angular_tolerance` and `scale_length` properties set by the
/// Resulting maliput::api::RoadGeometry will have properties set by the
/// `road_geometry_configuration`.
///
/// Note: the `opendrive_file` parameter of `road_geometry_configuration` is
/// ignored because a manager is expected to emerge.
///
/// @throws maliput::common::assertion_error When
/// `road_geometry_configuration.linear_tolerance`,
/// `road_geometry_configuration.angular_tolerance` or
/// `road_geometry_configuration.tolerances.linear_tolerance`,
/// `road_geometry_configuration.tolerances.angular_tolerance` or
/// `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`.
/// @throws maliput::common::assertion_error When `manager` is nullptr.
RoadGeometryBuilder(std::unique_ptr<xodr::DBManager> manager,
const RoadGeometryConfiguration& road_geometry_configuration,
std::unique_ptr<RoadCurveFactoryBase> factory);
const RoadGeometryConfiguration& road_geometry_configuration);

/// Creates a maliput equivalent backend (malidrive::RoadGeometry).
///
Expand Down
Expand Up @@ -28,16 +28,6 @@ const std::map<RoadGeometryConfiguration::SimplificationPolicy, std::string> sim
{RoadGeometryConfiguration::SimplificationPolicy::kNone, "none"},
{RoadGeometryConfiguration::SimplificationPolicy::kSimplifyWithinToleranceAndKeepGeometryModel, "simplify"}};

// Holds the conversion from string(keys) to ToleranceSelectionPolicy(values);
const std::map<std::string, RoadGeometryConfiguration::ToleranceSelectionPolicy> str_to_tolerance_selection_policy{
{"manual", RoadGeometryConfiguration::ToleranceSelectionPolicy::kManualSelection},
{"automatic", RoadGeometryConfiguration::ToleranceSelectionPolicy::kAutomaticSelection}};

// Holds the conversion from ToleranceSelectionPolicy(keys) to string(values);
const std::map<RoadGeometryConfiguration::ToleranceSelectionPolicy, std::string> tolerance_selection_policy_to_str{
{RoadGeometryConfiguration::ToleranceSelectionPolicy::kManualSelection, "manual"},
{RoadGeometryConfiguration::ToleranceSelectionPolicy::kAutomaticSelection, "automatic"}};

// Holds the conversion from string(keys) to StandardStrictnessPolicy(values);
const std::map<std::string, RoadGeometryConfiguration::StandardStrictnessPolicy> str_to_standard_strictness_policy{
{"strict", RoadGeometryConfiguration::StandardStrictnessPolicy::kStrict},
Expand Down Expand Up @@ -101,12 +91,17 @@ RoadGeometryConfiguration RoadGeometryConfiguration::FromMap(

it = road_geometry_configuration.find(kStrLinearTolerance);
if (it != road_geometry_configuration.end()) {
rg_config.linear_tolerance = std::stod(it->second);
rg_config.tolerances.linear_tolerance = std::stod(it->second);
}

it = road_geometry_configuration.find(kStrMaxLinearTolerance);
if (it != road_geometry_configuration.end()) {
rg_config.tolerances.max_linear_tolerance = std::stod(it->second);
}

it = road_geometry_configuration.find(kStrAngularTolerance);
if (it != road_geometry_configuration.end()) {
rg_config.angular_tolerance = std::stod(it->second);
rg_config.tolerances.angular_tolerance = std::stod(it->second);
}

it = road_geometry_configuration.find(kStrScaleLength);
Expand All @@ -133,11 +128,6 @@ RoadGeometryConfiguration RoadGeometryConfiguration::FromMap(
rg_config.simplification_policy = FromStrToSimplificationPolicy(it->second);
}

it = road_geometry_configuration.find(kStrToleranceSelectionPolicy);
if (it != road_geometry_configuration.end()) {
rg_config.tolerance_selection_policy = FromStrToToleranceSelectionPolicy(it->second);
}

it = road_geometry_configuration.find(kStrStandardStrictnessPolicy);
if (it != road_geometry_configuration.end()) {
rg_config.standard_strictness_policy = FromStrToStandardStrictnessPolicy(it->second);
Expand All @@ -151,19 +141,22 @@ RoadGeometryConfiguration RoadGeometryConfiguration::FromMap(
}

std::map<std::string, std::string> RoadGeometryConfiguration::ToStringMap() const {
std::map<std::string, std::string> config_map{
{{kStrRoadGeometryId}, id.string()},
{{kStrOpendriveFile}, opendrive_file},
{{kStrLinearTolerance}, std::to_string(linear_tolerance)},
{{kStrAngularTolerance}, std::to_string(angular_tolerance)},
{{kStrScaleLength}, std::to_string(scale_length)},
{{kStrInertialToBackendFrameTranslation}, inertial_to_backend_frame_translation.to_str()},
{{kStrSimplificationPolicy}, FromSimplificationPolicyToStr(simplification_policy)},
{{kStrToleranceSelectionPolicy}, FromToleranceSelectionPolicyToStr(tolerance_selection_policy)},
{{kStrStandardStrictnessPolicy}, FromStandardStrictnessPolicyToStr(standard_strictness_policy)},
{{kStrOmitNonDrivableLanes}, omit_nondrivable_lanes ? "true" : "false"},
{{kStrBuildPolicy}, BuildPolicy::FromTypeToStr(build_policy.type)},
};
std::map<std::string, std::string> config_map{};
config_map.emplace(kStrRoadGeometryId, id.string());
config_map.emplace(kStrOpendriveFile, opendrive_file);
if (tolerances.linear_tolerance.has_value()) {
config_map.emplace(kStrLinearTolerance, std::to_string(tolerances.linear_tolerance.value()));
}
if (tolerances.max_linear_tolerance.has_value()) {
config_map.emplace(kStrMaxLinearTolerance, std::to_string(tolerances.max_linear_tolerance.value()));
}
config_map.emplace(kStrAngularTolerance, std::to_string(tolerances.angular_tolerance));
config_map.emplace(kStrScaleLength, std::to_string(scale_length));
config_map.emplace(kStrInertialToBackendFrameTranslation, inertial_to_backend_frame_translation.to_str());
config_map.emplace(kStrSimplificationPolicy, FromSimplificationPolicyToStr(simplification_policy));
config_map.emplace(kStrStandardStrictnessPolicy, FromStandardStrictnessPolicyToStr(standard_strictness_policy));
config_map.emplace(kStrOmitNonDrivableLanes, omit_nondrivable_lanes ? "true" : "false");
config_map.emplace(kStrBuildPolicy, BuildPolicy::FromTypeToStr(build_policy.type));
if (build_policy.num_threads.has_value()) {
config_map.emplace(kStrNumThreads, std::to_string(build_policy.num_threads.value()));
}
Expand Down Expand Up @@ -194,20 +187,6 @@ std::string RoadGeometryConfiguration::FromSimplificationPolicyToStr(
return simplification_policy_to_str.at(policy);
}

RoadGeometryConfiguration::ToleranceSelectionPolicy RoadGeometryConfiguration::FromStrToToleranceSelectionPolicy(
const std::string& policy) {
const auto it = str_to_tolerance_selection_policy.find(policy);
if (it == str_to_tolerance_selection_policy.end()) {
MALIDRIVE_THROW_MESSAGE("Unknown tolerance selection policy: " + policy);
}
return str_to_tolerance_selection_policy.at(policy);
}

std::string RoadGeometryConfiguration::FromToleranceSelectionPolicyToStr(
const RoadGeometryConfiguration::ToleranceSelectionPolicy& policy) {
return tolerance_selection_policy_to_str.at(policy);
}

RoadGeometryConfiguration::StandardStrictnessPolicy RoadGeometryConfiguration::FromStrToStandardStrictnessPolicy(
const std::string& policy) {
const char token = '|';
Expand Down Expand Up @@ -247,6 +226,23 @@ std::string RoadGeometryConfiguration::FromStandardStrictnessPolicyToStr(
}
}

RoadGeometryConfiguration::BuildTolerance::BuildTolerance(double angular_tolerance_in)
: angular_tolerance(angular_tolerance_in) {
// Verification of values is made downstream at the RoadGeometryBuilder entity.
}

RoadGeometryConfiguration::BuildTolerance::BuildTolerance(double linear_tolerance_in, double angular_tolerance_in)
: linear_tolerance(linear_tolerance_in), angular_tolerance(angular_tolerance_in) {
// Verification of values is made downstream at the RoadGeometryBuilder entity.
}

RoadGeometryConfiguration::BuildTolerance::BuildTolerance(double min_linear_tolerance_in,
double max_linear_tolerance_in, double angular_tolerance_in)
: BuildTolerance(min_linear_tolerance_in, angular_tolerance_in) {
max_linear_tolerance = max_linear_tolerance_in;
// Verification of values is made downstream at the RoadGeometryBuilder entity.
}

RoadGeometryConfiguration::StandardStrictnessPolicy operator|(
const RoadGeometryConfiguration::StandardStrictnessPolicy& first,
const RoadGeometryConfiguration::StandardStrictnessPolicy& second) {
Expand Down
Expand Up @@ -46,13 +46,13 @@ struct RoadGeometryConfiguration {
static constexpr char const* kStrRoadGeometryId = "road_geometry_id";
static constexpr char const* kStrOpendriveFile = "opendrive_file";
static constexpr char const* kStrLinearTolerance = "linear_tolerance";
static constexpr char const* kStrMaxLinearTolerance = "max_linear_tolerance";
static constexpr char const* kStrAngularTolerance = "angular_tolerance";
static constexpr char const* kStrScaleLength = "scale_length";
static constexpr char const* kStrInertialToBackendFrameTranslation = "inertial_to_backend_frame_translation";
static constexpr char const* kStrBuildPolicy = "build_policy";
static constexpr char const* kStrNumThreads = "num_threads";
static constexpr char const* kStrSimplificationPolicy = "simplification_policy";
static constexpr char const* kStrToleranceSelectionPolicy = "tolerance_selection_policy";
static constexpr char const* kStrStandardStrictnessPolicy = "standard_strictness_policy";
static constexpr char const* kStrOmitNonDrivableLanes = "omit_nondrivable_lanes";
/// @}
Expand All @@ -75,12 +75,6 @@ struct RoadGeometryConfiguration {
kSimplifyWithinToleranceAndKeepGeometryModel, ///< Merge geometry pieces and keep the original geometry model.
};

/// How the tolerance and scale length should be computed.
enum class ToleranceSelectionPolicy {
kManualSelection, ///< Manual adjustment.
kAutomaticSelection, ///< Automatic selection.
};

/// Converts a string to a SimplificationPolicy.
///
/// @param policy String to be translated to a SimplificationPolicy. Valid strings match the enumerator's name except
Expand All @@ -96,21 +90,6 @@ struct RoadGeometryConfiguration {
/// @returns A string.
static std::string FromSimplificationPolicyToStr(const SimplificationPolicy& policy);

/// Converts a string to a ToleranceSelectionPolicy.
///
/// @param policy String to be translated to a ToleranceSelectionPolicy. Valid strings match the enumerator's name
/// except without the leading 'k' and is all lower case.
/// @returns A ToleranceSelectionPolicy value.
/// @throws maliput::common::assertion_error When `policy` isn't a valid ToleranceSelectionPolicy.
static ToleranceSelectionPolicy FromStrToToleranceSelectionPolicy(const std::string& policy);

/// Converts a ToleranceSelectionPolicy to a string.
///
/// @param policy ToleranceSelectionPolicy to be translated to a string. Enumerator's name matches the string except
/// without the leading 'k' and is all lower case.
/// @returns A string.
static std::string FromToleranceSelectionPolicyToStr(const ToleranceSelectionPolicy& policy);

/// Converts a string to a StandardStrictnessPolicy.
///
/// @param policy String to be translated to a StandardStrictnessPolicy. Valid strings match the enumerator's name
Expand All @@ -130,6 +109,34 @@ 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 tolerances within that range searching for a value that works.
struct BuildTolerance {
/// Sets angular tolerance.
/// @param angular_tolerance_in angular tolerance.
explicit BuildTolerance(double angular_tolerance_in);

/// Sets linear and angular tolerance.
/// @param linear_tolerance_in linear tolerance.
/// @param angular_tolerance_in angular tolerance.
explicit BuildTolerance(double linear_tolerance_in, double angular_tolerance_in);

/// Sets linear tolerance range and angular tolerance.
/// @param min_linear_tolerance_in minimum linear tolerance to be used.
/// @param max_linear_tolerance_in maximum linear tolerance to be used.
/// @param angular_tolerance_in angular tolerance.
explicit BuildTolerance(double min_linear_tolerance_in, double max_linear_tolerance_in,
double angular_tolerance_in);
/// Nominal linear_tolerance to be used in the RoadGeometry. Corresponds to the minimumm range of linear tolerances
/// when `max_linear_tolerance.has_value` is true.
std::optional<double> linear_tolerance{std::nullopt};
/// Maximum range of linear tolerances.
std::optional<double> max_linear_tolerance{std::nullopt};
/// Angular tolerance to be used in the RoadGeometry.
double angular_tolerance{constants::kAngularTolerance};
};

/// @returns A string-string map containing the RoadGeometry configuration.
std::map<std::string, std::string> ToStringMap() const;

Expand All @@ -138,13 +145,11 @@ struct RoadGeometryConfiguration {
/// @{
maliput::api::RoadGeometryId id{"maliput"};
std::string opendrive_file{""};
double linear_tolerance{constants::kLinearTolerance};
double angular_tolerance{constants::kAngularTolerance};
BuildTolerance tolerances{constants::kAngularTolerance};
double scale_length{constants::kScaleLength};
maliput::math::Vector3 inertial_to_backend_frame_translation{0., 0., 0.};
BuildPolicy build_policy{BuildPolicy::Type::kSequential};
SimplificationPolicy simplification_policy{SimplificationPolicy::kNone};
ToleranceSelectionPolicy tolerance_selection_policy{ToleranceSelectionPolicy::kAutomaticSelection};
StandardStrictnessPolicy standard_strictness_policy{StandardStrictnessPolicy::kPermissive};
// Note: this flag will change its default to false. It might lead to badly
// constructed RoadGeometries. Consider the following case:
Expand Down