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
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:
use_sim_timeshould still workIf a node uses parameters and knows all parameters it can use at compile time
If a node uses parameters but does not know all parameters it can use at compile time
costmap_2d::ObstacleLayerdoes not know all of the parameter names until afterobservation_sourcesis 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
Deleting/undeclaring a parameter
Registering callback for unexpected parameters.
Does setting a parameter define/create/declare it?
If No:
if yes:
Behavior:
Assuming node author does not declare parameters or change how unexpected parameters are handled
set_parameter()call succeedsset_parameter()call fails since first call declared a parameter with a given typeset_parameter()failsset_parameter()succeedsset_parameter()failsset_parameter()succeeds