-
Notifications
You must be signed in to change notification settings - Fork 483
Description
Feature request
This is less of an explicit request, and more a question about how we should interact with user-defined parameter callbacks.
Feature description
If a user registers a callback with rclcpp::Node::add_on_set_parameters_callback(), should the callback be triggered for any qos_overrides* parameters that are internally created by the node (since #1465)?
For example, it is somewhat common to see user callbacks that look like this:
auto result = rcl_interfaces::msg::SetParametersResult();
result.successful = true;
for (auto parameter : parameters) {
if (parameter.get_name().compare("user_defined_param") == 0) {
// do something with the value here ...
} else {
string_result << "The parameter " << parameter.get_name() << " is not reconfigurable.\n";
result.successful = false;
}
}Since #1465, user code doing something like the code above will fail (the node terminates the process) if QoS overrides are enabled, because the parameter validation callback is not aware of the qos_overrides parameters declared by the nodes implementation.
Possible fixes:
- Document this pitfall well and provide an example of handling the new "qos_overrides" parameters like:
auto result = rcl_interfaces::msg::SetParametersResult();
result.successful = true;
for (auto parameter : parameters) {
if (parameter.get_name().compare("user_defined_param") == 0) {
// do something with the value here ...
+ else if (parameter.name.rfind("qos_overrides", 0) == 0) {
+ // Ignore changes to QoS override parameters here.
+ // Optionally, we could validate QoS values here, but we also have a more convenient mechanism for that when enabling QoS overrides
} else {
string_result << "The parameter " << parameter.get_name() << " is not reconfigurable.\n";
result.successful = false;
}
}- Document that rejecting unknown parameters is an anti-pattern
Just because one user callback doesn't know how to deal with a parameter doesn't mean that it should reject it. It's possible that another registered callback is expecting said parameter. If one callback rejects a change, then it may prevent other callbacks from getting a chance to handle the change. We would then recommend that the original example above be changed to look like:
auto result = rcl_interfaces::msg::SetParametersResult();
result.successful = true;
for (auto parameter : parameters) {
if (parameter.get_name().compare("user_defined_param") == 0) {
// do something with the value here ...
+ }
- } else {
- string_result << "The parameter " << parameter.get_name() << " is not reconfigurable.\n";
- result.successful = false;
- }
}- Change the rclcpp implementation to avoid calling user-defined callbacks for
qos_overridesparameters
This would make all existing code work as-is, but it is a little odd thatqos_overridesparameters are not passed to user callbacks when other default node params, likeuse_sim_timeare.
Implementation considerations
Whatever we choose, it would be good to resolve this prior to the Galactic release so there is a clear path forward for users porting to Galactic.