rclcpp: Can't set initial parameters when allowing undeclared
Bug report
Required Info:
- Operating System:
- Ubunto Bionic
- Installation type:
- dashing sources
- Version or commit hash:
- master
Steps to reproduce issue
Setting to accept undeclared parameters and passing initial parameters:
std::vector<rclcpp::Parameter> initial_parameters =
{rclcpp::Parameter("my_string", std::string("str"))};
rclcpp::NodeOptions node_options;
node_options.allow_undeclared_parameters(true);
node_options.initial_parameters(initial_parameters);
auto node = std::make_shared<Node>("name", "ns", node_options);
node->get_parameter(param); // throws
Throws this:
12: terminate called after throwing an instance of 'rclcpp::ParameterTypeException'
12: what(): expected [string] got [not set]
On the other hand, setting the parameters after construction is happy:
rclcpp::NodeOptions node_options;
node_options.allow_undeclared_parameters(true);
auto node = std::make_shared<Node>("name", "ns", node_options);
node->set_parameters(initial_parameters);
node->get_parameter(param); // happy
Expected behavior
No throw on both cases
Actual behavior
Throw on first case
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 24 (24 by maintainers)
Commits related to this issue
- Add fault injection macros and unit tests to rcl_action (#730) * Add fault injection macros and unit tests to rcl_action Signed-off-by: Stephen Brawner <brawner@gmail.com> * Addressing feedbac... — committed to ApexAI/rclcpp by brawner 4 years ago
- Fix pause snapshot behavior and add regression test (#730) Signed-off-by: Emerson Knapp <eknapp@amazon.com> — committed to DensoADAS/rclcpp by emersonknapp 3 years ago
I cannot reproduce the issue in the original post,
get_parameterdoesn’t throw for me (my demo below).Either way, I’d recommend these as the “golden rules” for parameters in Dashing:
declare_parameter(s), and use it before using anyhas/get/setparameter methods.allow_undeclared_parametersandautomatically_declare_initial_parametersexcept in exceptional cases, you most likely should not be using them.I think the fundamental misunderstanding is that
NodeOptions::initial_parameteris not intended to seed the node with parameters, it is actually only for overriding parameter defaults (same goes for the YAML file). I think this is a reasonable thing to be confused about, given the name, so perhaps we should change it. Most places I refer to this as the “initial parameter values” rather than “initial parameters”.The
automatically_declare_initial_parametersis essentially a helper which uses those overrides to declare the parameters for you.That means when you, the user, set a value for a parameter (using
set_parameter(s)) it gets automatically declared (as if you haddeclare_parameter), but it is undeclared until you set it. If you only ever use initial parameter values and get, then the parameter will never be declared.I think you’re misunderstanding
allow_undeclared_parameters, it only avoids two things. First, throwing when you ‘get’ a parameter that has not been declared explicitly, and instead returns arclcpp::Parameterwith the type set toPARAMETER_NOT_SET(essentially like theNonetype in Python). Second, it also will avoid throwing when you useset_parameter(s)*, instead it implicitly declares the parameter and then sets it.It does not allow for parameters to be declared automatically just because they’re passed as initial parameters or in the YAML file.
This came up in the original review and I don’t think anything has changed since then. There are cases where both are enabled, one or the other is enabled, and when both are disabled that all make sense. I don’t think we should couple their behavior. If you want both behaviors, then enable them both.
I believe I’ve covered this topic quite thoroughly in the migration docs:
https://index.ros.org/doc/ros2/Releases/Release-Dashing-Diademata/#declaring-parameters
If you guys are still confused by it then we definitely need to update it, but I honestly don’t know how I could have made it clearer.
My example (it compiles and runs without error on master):