-
Notifications
You must be signed in to change notification settings - Fork 481
Add ParameterDescriptor override from yaml #909
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
base: rolling
Are you sure you want to change the base?
Add ParameterDescriptor override from yaml #909
Conversation
fbde81f to
532f273
Compare
|
@hidmic can you please take a look at these pr's? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass, though most comments that apply to ros2/rcl#533 (review) will likely apply to this patch.
Also, rclpy must be updated as well (but hold on until we've settled on these PRs first).
| /// A map of fully qualified node names to a list of parameters | ||
| using ParameterMap = std::unordered_map<std::string, std::vector<Parameter>>; | ||
| using rcl_interfaces::msg::ParameterDescriptor; | ||
| using ParameterAndDescriptor = std::unordered_map<std::string, std::pair<Parameter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox std::pair is convenient but obscure when reading code (e.g. what is param.second.second??). Consider defining a struct instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be even easier to directly create the ParameterInfo struct here.
| const char * const c_param_name = c_param_descriptors_node->parameter_names[p]; | ||
| if (NULL == c_param_name) { | ||
| std::string message( | ||
| "At node " + std::to_string(n) + " parameter " + std::to_string(p) + " name is NULL"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox do we need an auxiliary variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message string? Probably not needed, this was left from the previous code, not my additions.
|
@hidmic Thanks for the first pass reviews! In regard to changes to |
|
@bpwilcox do you still plan on submitting changes? Or shall I close this patch? |
Yes, I believe I should have some more cycles to work on this in the near future. |
532f273 to
b8d89d3
Compare
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
minor cleanup and lint fix Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: bpwilcox <[email protected]> Signed-off-by: Brian Wilcox <[email protected]>
Signed-off-by: Brian Wilcox <[email protected]>
… unit test Signed-off-by: Brian Wilcox <[email protected]>
b8d89d3 to
070abdd
Compare
|
FYI this PR has been rebased to work with Galactic and it's ready for review, together with ros2/rcl#533 |
| ParameterMap | ||
| parameter_map_from_yaml_file(const std::string & yaml_filename); | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox nit: drop extra blank line
| // but did not get declared explcitily by this point. | ||
| if (automatically_declare_parameters_from_overrides) { | ||
| rcl_interfaces::msg::ParameterDescriptor descriptor; | ||
| descriptor.dynamic_typing = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox why the change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reverted this change, though I am still open to discussing the most appropriate behavior for dynamic_tuning field being set from a yaml file. For example, if you have a blackboard node and wanted to have a parameter become static typing, this change would overwrite. Before allowing yaml descriptor overrides, I'd agree it makes more sense to have parameters be dynamic typing when automatically declared, but now with this feature, I'm unsure if this should be the case.
| auto has_parameter_override = false; | ||
| auto has_descriptor_override = false; | ||
|
|
||
| if (overrides_it->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET) { | ||
| has_parameter_override = true; | ||
| } | ||
| if (overrides_it->second.descriptor.name != "") { | ||
| has_descriptor_override = true; | ||
| } | ||
|
|
||
| if (has_parameter_override && has_descriptor_override) { | ||
| initial_value = &overrides_it->second.value; | ||
| parameter_infos.at(name).descriptor = overrides_it->second.descriptor; | ||
| } else if (has_parameter_override) { | ||
| initial_value = &overrides_it->second.value; | ||
| } else if (has_descriptor_override) { | ||
| parameter_infos.at(name).descriptor = overrides_it->second.descriptor; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox isn't this equivalent to:
| auto has_parameter_override = false; | |
| auto has_descriptor_override = false; | |
| if (overrides_it->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET) { | |
| has_parameter_override = true; | |
| } | |
| if (overrides_it->second.descriptor.name != "") { | |
| has_descriptor_override = true; | |
| } | |
| if (has_parameter_override && has_descriptor_override) { | |
| initial_value = &overrides_it->second.value; | |
| parameter_infos.at(name).descriptor = overrides_it->second.descriptor; | |
| } else if (has_parameter_override) { | |
| initial_value = &overrides_it->second.value; | |
| } else if (has_descriptor_override) { | |
| parameter_infos.at(name).descriptor = overrides_it->second.descriptor; | |
| } | |
| if (overrides_it->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET) { | |
| initial_value = &overrides_it->second.value; | |
| } | |
| if (overrides_it->second.descriptor.name != "") { | |
| parameter_infos[name].descriptor = overrides_it->second.descriptor; | |
| } |
| } | ||
| // zero init parameter value | ||
| c_node_param_descriptors->parameter_descriptors = | ||
| static_cast<rcl_param_descriptor_t *>(alloc.allocate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox nit: using zero_allocate() would have the same net effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree but is there any benefit of changing?
| EXPECT_TRUE(params.count("bar")); | ||
| EXPECT_STREQ("Integer Range Descriptor", params.at("bar").descriptor.description.c_str()); | ||
| EXPECT_STREQ("Even numbers only", params.at("bar").descriptor.additional_constraints.c_str()); | ||
| EXPECT_EQ(-1234, params.at("bar").descriptor.integer_range[0].from_value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox can't we use min_value in place for the literal? Same in all other cases below.
|
|
||
| /// A description of the parameter | ||
| rcl_interfaces::msg::ParameterDescriptor descriptor; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bpwilcox meta: hmm, why not pushing this descriptor attribute into rclcpp::Parameter? Then we can use rclcpp::Parameter everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree that you could put the descriptor in the rclcpp::Parameter object, however that seems to be a more far-reaching change than this PR, especially since many user-code uses rclcpp::Parameter. I think it is a good candidate for a follow-up PR.
Signed-off-by: Brian <[email protected]>
29be629 to
ff1b8e5
Compare
|
@hidmic Could you take another pass through this review since latest changes? |
|
@bpwilcox yes! I'll take a look at these tomorrow morning first thing. Sorry for the insane delay, I've been too busy. |
) Signed-off-by: Simon Honigmann <[email protected]> Co-authored-by: Simon Honigmann <[email protected]>
This PR (built on top of required PR ros2/rcl#533) allows for parameter descriptions to be parsed from the yaml parameter file (proposed syntax described in above PR link) into the
parameter_overrideswhen declaring a parameter viadeclare_parameter. This enables users to describe the parameter constraints at run-time to fill aParameterDescriptor.msgfor parameter validation and documentation. As mentioned in #807 (comment), this feature may be particularly useful for a "parameter blackboard" or for dynamic parameter tuning.Matching modifications can be made to enable this feature for
rclpy.