ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

ROS2: Set Remote Parameter - Results in Exception

asked 2020-02-13 17:42:03 -0500

Kevlar gravatar image

Version: ROS2 Eloquent

Platform: Linux 5.0.0-37-generic #40~18.04.1-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux

I am trying to set a parameter for Node #1 from Node #2. If I understand correctly, I need to first create a SynParametersClient on Node #2:

mHelmParameters = std::make_shared<rclcpp::SyncParametersClient>(this, "Helm");

When I attempt to set the parameter:

mHelmParameters->set_parameters({ rclcpp::Parameter(parameterName, parameterValue) });

I get the following:

terminate called after throwing an instance of 'std::runtime_error'

what():  Node has already been added to an executor.

When the set_parameters() call is made, it is in the same thread/call chain from the receipt of a subscribed message. The general intent is when Node 2 receives a particular message I want to set a parameter on Node 1.

I found this thread: https://answers.ros.org/question/3038... However, it results in a "you don't need the Client to set your own parameters." All well and good, but that doesn't help, since I'm trying to set a remote parameter.

From what I can discern from other threads and documentation, it doesn't seem feasible to do this from within the context of a 'spin' call (which, if I also understand correctly, is making the callback for the 'message received' method). Therefore, I would need to break out of the 'spin' call periodically, see that I have a parameter to set, set it, then get back to 'spinning'. If I'm incorrect in this analysis, how do I get around the thrown exception?

Thanks!

edit retag flag offensive close merge delete

Comments

I have a similar issue on Foxy. Specifically, I'm trying to use colcon test to spin up a "node under test" that has parameters and a temporary node defined in a gtest executable. Both the node under test and gtest executable are started with a test launch file. The temporary node needs to access/modify the parameters of the node under test. I get the same exception when my temporary node tries to call has, get, and set.

dustingooding gravatar image dustingooding  ( 2021-01-26 11:12:51 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-04-09 12:19:47 -0500

clyde gravatar image

You can use AsyncParametersClient to do this. Here's an example setting a bool parameter on a remote node:

  void set_bool_param(std::string param, bool value)
  {
    if (!param_client_) {
      param_client_ = std::make_shared<rclcpp::AsyncParametersClient>(this, "remote_node");
    }

    if (param_client_->service_is_ready()) {
      RCLCPP_INFO_STREAM(get_logger(), "set " << param << " to " << value);
      param_client_->set_parameters({rclcpp::Parameter(param, value)},
        [this](std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>> future)
        {
          future.wait();
          auto results = future.get();
          if (results.size() != 1) {
            RCLCPP_ERROR_STREAM(get_logger(), "expected 1 result, got " << results.size());
          } else {
            if (results[0].successful) {
              RCLCPP_INFO(get_logger(), "success");
            } else {
              RCLCPP_ERROR(get_logger(), "failure");
            }
          }
        });
    } else {
      RCLCPP_ERROR(get_logger(), "remote parameter server is not ready");
    }
  }
edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2020-02-13 17:42:03 -0500

Seen: 580 times

Last updated: Apr 09 '21