Skip to content

Expected vs Unexpected parameters Node::create_param() #475

Closed
@sloretz

Description

@sloretz

Feature request

Allow node author to define expected parameters and what happens when an unexpected parameter is set.

Feature description

This issue is a first step towards larger features like parameter constraints (allowed types, read-only parameters, allowed ranges, etc...). These will be ticketed separately.

If a node does not use parameters:

  • Universal parameters like use_sim_time should still work
  • Reject attempts to set parameters to give feedback to run-time user

If a node uses parameters and knows all parameters it can use at compile time

  • Initial values might be needed if parameter is required and run-time user doesn't set it
  • Run-time user may set a new value for a known parameter provided it is a legal value
    • Future work: parameter constraints
    • For now: If a type changes then handle the update the same as an unexpected parameter

If a node uses parameters but does not know all parameters it can use at compile time

  • Initial values needed for known parameters that don't get set by a user
  • Node author needs ability to accept/reject parameters that are not known at compile time
    • Example: costmap_2d::ObstacleLayer does not know all of the parameter names until after observation_sources is set.

Implementation considerations

Some parameters functionality will move to rcl (ros2/rcl#194). This ticket assumes the client library (rclcpp, rclpy, etc) will be responsible for parameter storage including default values and having knowledge of expected versus unexpected parameters.

Lifecycle considerations

If a node author wants custom logic for unexpected parameters then that logic must be set up before a parameter can be set by a run-time user. This includes defining expected parameters. Parameters cannot be set until a node is added to an executor, and that can't happen until a node is constructed. Therefore, a node author may define parameters and set up unexpected parameter handling in their constructor.

Creating a parameter
/// Create a parameter with an optional initial value
/*
 * \param[in] initial_value the name and initial value of the parameter
 * \raise an exception if an error occurs
 */
void
NodeParameters::create_parameter(const ParameterVariant & initial_value);

void
NodePamameters::create_parameter(const std::string & name)
{
  /* TODO it does not appear possible to create a ParameterVariant with a name but no type */
}

// Convenience call
template <typename T>
void
NodePamameters::create_parameter(const std::string & name, T value)
{
  ParameterVariant param(name, value);
  return create_parameter(param);
}
Deleting/undeclaring a parameter
/// Undeclare parameter with a given name
/* Deleted parameters are treated as unexpected the next time a user tries to set them
 * \param[in] name the name of the parameter to declare
 * \raise an exception if an error occurs
 */
void
NodeParameters::delete_parameter(const std::string & name);
Registering callback for unexpected parameters.
// Set callback to be called when when an unexpected parameter is set
// This callback controls whether the parameter change is accepted or rejected
// \sa register_param_change_callback() for a callback called on all parameter changes
void
NodeParameters::register_unexpected_param_change_callback(ParametersCallbackFunction callback);
Does setting a parameter define/create/declare it?

If No:

  • Pros
    • Default behavior of setting an undeclared parameter is the same for both node authors and run-time users (deny set by default)
    • Node author typo in parameter name raises an exception instead of silently proceeding with the wrong name
  • Cons
    • Forces a node author to declare parameters or change the unexpected parameter handling

if yes:

  • Pros
    • Opt-in to declaring parameters, otherwise current API stays the same
  • Cons
    • Typos by node author are harder to catch
    • Default behavior of setting an unexpected parameter is different if you're a node author vs node user
    • In a future with parameter constraints, what are the default constraints when setting a parameter?

Behavior:
Assuming node author does not declare parameters or change how unexpected parameters are handled

  • Node author calls set_parameter() on the same name twice, but with different types
    • If no:
      • Both calls fail because the parameter is unexpected
    • If yes:
      • First set_parameter() call succeeds
      • Second set_parameter() call fails since first call declared a parameter with a given type
  • Run-time user tries to set parameter never declared by node author
    • If no or yes: Run-time parameter is rejected as an unexpected parameter
  • Node author calls set_parameter(), run-time user later tries to set parameter with same type
    • if no:
      • Node author set_parameter() fails
      • run time set parameter fails because the parameter is undeclared
    • if yes:
      • Node author's call to set_parameter() succeeds
      • run time set parameter succeeds
  • Node author calls set_parameter(), run-time user later tries to set parameter with different type
    • if no:
      • Node author set_parameter() fails
      • run time set parameter fails because the parameter is undeclared
    • if yes:
      • Node author's call to set_parameter() succeeds
      • run time set parameter fails because it tried to change the type

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions