Flammel
Flammel

Reputation: 41

Set Ros2 Parameter from another Node

I have two nodes in c++ that use the same parameter. If I want to reconfigure the node1 parameter_x via the rqt, it would be great if the parameter_x of the node2 is also changed automatically. Is there a possibility for this?

i have try in node1:

auto node = rclcpp::Node::make_shared("node2");
node->set_parameter(rclcpp::Parameter("parameter_x", 50));

Upvotes: 1

Views: 2766

Answers (3)

Christian Rauch
Christian Rauch

Reputation: 94

The classes rclcpp::SyncParametersClient and rclcpp::AsyncParametersClient wrap the low-level parameter services. Have a look at the set_and_get_parameters and set_and_get_parameters_async examples from the demos repo for how to use the API.

Both classes (SyncParametersClient uses the AsyncParametersClient) take at least a node (std::shared_ptr<NodeT> node) and a node name (std::string remote_node_name). Hereby, node is the ROS node from where you want to set the parameters, i.e. the parameter client, and remote_node_name is the name of the node whose parameters you want to set, i.e. the parameter server.

Upvotes: 0

Muhammad Luqman
Muhammad Luqman

Reputation: 96

It cannot be done using set_parameters inside of nodes but instead using a Service call . Two service calls are availble

  • SetParameters allows setting parameters one at a time

  • SetParametersAtomically sets multiple parameters at once, atomically. This means that if setting one parameter fails, none of the parameters are changed.

  • I have produced a video about it as well -> link

Upvotes: 0

Flammel
Flammel

Reputation: 41

i have found the solution:

auto parameter = rcl_interfaces::msg::Parameter();
auto request = std::make_shared<rcl_interfaces::srv::SetParametersAtomically::Request>();

client = this->create_client<rcl_interfaces::srv::SetParametersAtomically>(serviceName); // E.g.: serviceName = "/turtlesim/set_parameters_atomically"

parameter.name = parameter_name;  // E.g.: parameter_name = "background_b"
parameter.value.type = 1          //  bool = 1,    int = 2,        float = 3,     string = 4
parameter.value.bool_value = true // .bool_value, .integer_value, .double_value, .string_value

request->parameters.push_back(parameter);

while (!client->wait_for_service(1s)) {
    if (!rclcpp::ok()) {
    RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
    return;
    }
    RCLCPP_INFO_STREAM(this->get_logger(), "service " << serviceName <<" not available, waiting again..."); 
}
auto result = client->async_send_request(request);

Upvotes: 1

Related Questions