ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
parameter_service.cpp
1 // Copyright 2015 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "rclcpp/parameter_service.hpp"
16 
17 #include <algorithm>
18 #include <memory>
19 #include <stdexcept>
20 #include <string>
21 #include <vector>
22 
23 #include "rclcpp/logging.hpp"
24 
25 #include "./parameter_service_names.hpp"
26 
28 
29 ParameterService::ParameterService(
30  const std::shared_ptr<rclcpp::node_interfaces::NodeBaseInterface> node_base,
31  const std::shared_ptr<rclcpp::node_interfaces::NodeServicesInterface> node_services,
33  const rmw_qos_profile_t & qos_profile)
34 {
35  const std::string node_name = node_base->get_name();
36 
37  get_parameters_service_ = create_service<rcl_interfaces::srv::GetParameters>(
38  node_base, node_services,
39  node_name + "/" + parameter_service_names::get_parameters,
40  [node_params](
41  const std::shared_ptr<rmw_request_id_t>,
42  const std::shared_ptr<rcl_interfaces::srv::GetParameters::Request> request,
43  std::shared_ptr<rcl_interfaces::srv::GetParameters::Response> response)
44  {
45  try {
46  auto parameters = node_params->get_parameters(request->names);
47  for (const auto & param : parameters) {
48  response->values.push_back(param.get_value_message());
49  }
51  RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to get parameters: %s", ex.what());
52  }
53  },
54  qos_profile, nullptr);
55 
56  get_parameter_types_service_ = create_service<rcl_interfaces::srv::GetParameterTypes>(
57  node_base, node_services,
58  node_name + "/" + parameter_service_names::get_parameter_types,
59  [node_params](
60  const std::shared_ptr<rmw_request_id_t>,
61  const std::shared_ptr<rcl_interfaces::srv::GetParameterTypes::Request> request,
62  std::shared_ptr<rcl_interfaces::srv::GetParameterTypes::Response> response)
63  {
64  try {
65  auto types = node_params->get_parameter_types(request->names);
66  std::transform(
67  types.cbegin(), types.cend(),
68  std::back_inserter(response->types), [](const uint8_t & type) {
69  return static_cast<rclcpp::ParameterType>(type);
70  });
72  RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to get parameter types: %s", ex.what());
73  }
74  },
75  qos_profile, nullptr);
76 
77  set_parameters_service_ = create_service<rcl_interfaces::srv::SetParameters>(
78  node_base, node_services,
79  node_name + "/" + parameter_service_names::set_parameters,
80  [node_params](
81  const std::shared_ptr<rmw_request_id_t>,
82  const std::shared_ptr<rcl_interfaces::srv::SetParameters::Request> request,
83  std::shared_ptr<rcl_interfaces::srv::SetParameters::Response> response)
84  {
85  // Set parameters one-by-one, since there's no way to return a partial result if
86  // set_parameters() fails.
87  auto result = rcl_interfaces::msg::SetParametersResult();
88  for (auto & p : request->parameters) {
89  try {
90  result = node_params->set_parameters_atomically(
93  RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to set parameter: %s", ex.what());
94  result.successful = false;
95  result.reason = ex.what();
96  } catch (const std::runtime_error & ex) {
97  RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to set parameter: %s", ex.what());
98  result.successful = false;
99  result.reason = ex.what();
100  }
101  response->results.push_back(result);
102  }
103  },
104  qos_profile, nullptr);
105 
106  set_parameters_atomically_service_ = create_service<rcl_interfaces::srv::SetParametersAtomically>(
107  node_base, node_services,
108  node_name + "/" + parameter_service_names::set_parameters_atomically,
109  [node_params](
110  const std::shared_ptr<rmw_request_id_t>,
111  const std::shared_ptr<rcl_interfaces::srv::SetParametersAtomically::Request> request,
112  std::shared_ptr<rcl_interfaces::srv::SetParametersAtomically::Response> response)
113  {
114  try {
115  std::vector<rclcpp::Parameter> pvariants;
116  std::transform(
117  request->parameters.cbegin(), request->parameters.cend(),
118  std::back_inserter(pvariants),
119  [](const rcl_interfaces::msg::Parameter & p) {
120  return rclcpp::Parameter::from_parameter_msg(p);
121  });
122  auto result = node_params->set_parameters_atomically(pvariants);
123  response->result = result;
125  RCLCPP_WARN(
126  rclcpp::get_logger("rclcpp"), "Failed to set parameters atomically: %s", ex.what());
127  response->result.successful = false;
128  response->result.reason = "One or more parameters were not declared before setting";
129  } catch (const std::runtime_error & ex) {
130  RCLCPP_WARN(
131  rclcpp::get_logger("rclcpp"), "Failed to set parameters atomically: %s", ex.what());
132  response->result.successful = false;
133  response->result.reason = ex.what();
134  }
135  },
136  qos_profile, nullptr);
137 
138  describe_parameters_service_ = create_service<rcl_interfaces::srv::DescribeParameters>(
139  node_base, node_services,
140  node_name + "/" + parameter_service_names::describe_parameters,
141  [node_params](
142  const std::shared_ptr<rmw_request_id_t>,
143  const std::shared_ptr<rcl_interfaces::srv::DescribeParameters::Request> request,
144  std::shared_ptr<rcl_interfaces::srv::DescribeParameters::Response> response)
145  {
146  try {
147  auto descriptors = node_params->describe_parameters(request->names);
148  response->descriptors = descriptors;
150  RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to describe parameters: %s", ex.what());
151  }
152  },
153  qos_profile, nullptr);
154 
155  list_parameters_service_ = create_service<rcl_interfaces::srv::ListParameters>(
156  node_base, node_services,
157  node_name + "/" + parameter_service_names::list_parameters,
158  [node_params](
159  const std::shared_ptr<rmw_request_id_t>,
160  const std::shared_ptr<rcl_interfaces::srv::ListParameters::Request> request,
161  std::shared_ptr<rcl_interfaces::srv::ListParameters::Response> response)
162  {
163  auto result = node_params->list_parameters(request->prefixes, request->depth);
164  response->result = result;
165  },
166  qos_profile, nullptr);
167 }
static RCLCPP_PUBLIC Parameter from_parameter_msg(const rcl_interfaces::msg::Parameter &parameter)
Convert a parameter message in a Parameter class object.
Definition: parameter.cpp:145
Thrown if parameter is not declared, e.g. either set or get was called without first declaring.
Definition: exceptions.hpp:285
Pure virtual interface class for the NodeParameters part of the Node API.
virtual RCLCPP_PUBLIC std::vector< rclcpp::Parameter > get_parameters(const std::vector< std::string > &names) const =0
Get descriptions of parameters given their names.
virtual RCLCPP_PUBLIC rcl_interfaces::msg::SetParametersResult set_parameters_atomically(const std::vector< rclcpp::Parameter > &parameters)=0
Set one or more parameters, all at once.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:27