Skip to content

Exception when declaring parameters after callback is set #769

Description

@Karsten1987

I am struggling with how to declare parameters for my diagnostic_updater. Specifically, I have the following setup: I am spawning the URG laser driver, which is a node and has a diagnostics updater instance as a class member variable. That diagnostics updater takes a node (or better node interfaces) in its constructor. The diagnostics updater has a parameter period which is meant to be updated dynamically. The URG node itself has multiple laser specific parameters declared as well.

Within code, this kind of looks like this:

Urg::Urg()
: rclcpp::Node("urg_laser_node")
{
  // Get parameters so we can change these later.
  this->declare_parameter<std::string>("ip_address", ip_address_);
  this->declare_parameter<int>("ip_port", ip_port_);
  this->declare_parameter<std::string>("laser_frame_id", laser_frame_id_);
  ...

  this->set_on_parameters_set_callback(std::bind(&UrgNode::param_change_callback, this, std::placeholders::_1));

  // the diagnostics_updater declares another parameter and results in an exception.
  diagnostic_updater_ = std::make_unique<diagnostic_updater::Updater>(
    this->get_node_base_interface(),
    this->get_node_topics_interface(),
    this->get_node_logging_interface(),
    this->get_node_parameters_interface());
  diagnostic_updater_->add("Hardware Status", this, &UrgNode::populateDiagnosticsStatus);
 
  // Having the parameter callback set at the very end, prevents the exception
  // this->set_on_parameters_set_callback(std::bind(&UrgNode::param_change_callback, this, std::placeholders::_1));
}

I am noticing two problems with this:

1.) When having set_on_parameters_set_callback called before initializing the diagnostics updater instance, I am unable to declare any parameter within the diagnostics instance as the assigned callback for the URG node is not aware of the diagnostics parameter and I get an exception:

libc++abi.dylib: terminating with uncaught exception of type rclcpp::exceptions::InvalidParameterValueException: parameter 'urg_node.diagnostics_updater_period' could not be set: The parameter urg_node.diagnostics_updater_period is not part of the reconfigurable parameters.

So I had to make sure that the parameter callback is set at last and no new parameters were declared after that.

2.) When modifying the URG callback in a way to catch a change of parameter for the diagnostics updater (i.e. the parameter "period"), I need public API on the diagnostics updater in order to set/get the current period on it. Plus, every other node which uses diagnostics, e.g. cartographer has to write the same logic in their code.

After thinking about this for a while, I'd like to have the parameter period being solely declared within the diagnostics updater and ideally have a callback for that parameter which is handled within the diagnostics updater itself.
I remember we talked about having multiple callbacks for parameters, especially with cases like use_sim_time. Is that possible with the current dashing API? If not, do you have any suggestions on how to handle that case?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingmore-information-neededFurther information is required

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions