rclcpp  master
C++ ROS Client Library API
node_impl.hpp
Go to the documentation of this file.
1 // Copyright 2014 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 #ifndef RCLCPP__NODE_IMPL_HPP_
16 #define RCLCPP__NODE_IMPL_HPP_
17 
18 #include <rmw/error_handling.h>
19 #include <rmw/rmw.h>
20 
21 #include <algorithm>
22 #include <cstdlib>
23 #include <iostream>
24 #include <limits>
25 #include <map>
26 #include <memory>
27 #include <sstream>
28 #include <stdexcept>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include "rcl/publisher.h"
34 #include "rcl/subscription.h"
35 
36 #include "rcl_interfaces/msg/intra_process_message.hpp"
37 
40 #include "rclcpp/parameter.hpp"
46 
47 #ifndef RCLCPP__NODE_HPP_
48 #include "node.hpp"
49 #endif
50 
51 namespace rclcpp
52 {
53 
54 template<typename MessageT, typename Alloc, typename PublisherT>
57  const std::string & topic_name, size_t qos_history_depth,
58  std::shared_ptr<Alloc> allocator)
59 {
60  if (!allocator) {
61  allocator = std::make_shared<Alloc>();
62  }
63  rmw_qos_profile_t qos = rmw_qos_profile_default;
64  qos.depth = qos_history_depth;
65  return this->create_publisher<MessageT, Alloc, PublisherT>(topic_name, qos, allocator);
66 }
67 
68 template<typename MessageT, typename Alloc, typename PublisherT>
71  const std::string & topic_name, const rmw_qos_profile_t & qos_profile,
72  std::shared_ptr<Alloc> allocator)
73 {
74  if (!allocator) {
75  allocator = std::make_shared<Alloc>();
76  }
77  return rclcpp::create_publisher<MessageT, Alloc, PublisherT>(
78  this->node_topics_.get(),
79  topic_name,
80  qos_profile,
81  use_intra_process_comms_,
82  allocator);
83 }
84 
85 template<
86  typename MessageT,
87  typename CallbackT,
88  typename Alloc,
89  typename SubscriptionT>
92  const std::string & topic_name,
93  CallbackT && callback,
94  const rmw_qos_profile_t & qos_profile,
95  rclcpp::callback_group::CallbackGroup::SharedPtr group,
96  bool ignore_local_publications,
99  msg_mem_strat,
100  std::shared_ptr<Alloc> allocator)
101 {
102  using CallbackMessageT = typename rclcpp::subscription_traits::has_message_type<CallbackT>::type;
103 
104  if (!allocator) {
105  allocator = std::make_shared<Alloc>();
106  }
107 
108  if (!msg_mem_strat) {
111  }
112 
113  return rclcpp::create_subscription<MessageT, CallbackT, Alloc, CallbackMessageT, SubscriptionT>(
114  this->node_topics_.get(),
115  topic_name,
116  std::forward<CallbackT>(callback),
117  qos_profile,
118  group,
119  ignore_local_publications,
120  use_intra_process_comms_,
121  msg_mem_strat,
122  allocator);
123 }
124 
125 template<
126  typename MessageT,
127  typename CallbackT,
128  typename Alloc,
129  typename SubscriptionT>
132  const std::string & topic_name,
133  CallbackT && callback,
134  size_t qos_history_depth,
135  rclcpp::callback_group::CallbackGroup::SharedPtr group,
136  bool ignore_local_publications,
139  msg_mem_strat,
140  std::shared_ptr<Alloc> allocator)
141 {
142  rmw_qos_profile_t qos = rmw_qos_profile_default;
143  qos.depth = qos_history_depth;
144  return this->create_subscription<MessageT>(
145  topic_name,
146  std::forward<CallbackT>(callback),
147  qos,
148  group,
149  ignore_local_publications,
150  msg_mem_strat,
151  allocator);
152 }
153 
154 template<typename DurationT, typename CallbackT>
158  CallbackT callback,
159  rclcpp::callback_group::CallbackGroup::SharedPtr group)
160 {
162  std::chrono::duration_cast<std::chrono::nanoseconds>(period),
163  std::move(callback),
164  this->node_base_->get_context());
165  node_timers_->add_timer(timer, group);
166  return timer;
167 }
168 
169 template<typename ServiceT>
172  const std::string & service_name,
173  const rmw_qos_profile_t & qos_profile,
174  rclcpp::callback_group::CallbackGroup::SharedPtr group)
175 {
177  options.qos = qos_profile;
178 
179  using rclcpp::Client;
180  using rclcpp::ClientBase;
181 
183  node_base_.get(),
184  node_graph_,
185  service_name,
186  options);
187 
188  auto cli_base_ptr = std::dynamic_pointer_cast<ClientBase>(cli);
189  node_services_->add_client(cli_base_ptr, group);
190  return cli;
191 }
192 
193 template<typename ServiceT, typename CallbackT>
196  const std::string & service_name,
197  CallbackT && callback,
198  const rmw_qos_profile_t & qos_profile,
199  rclcpp::callback_group::CallbackGroup::SharedPtr group)
200 {
201  return rclcpp::create_service<ServiceT, CallbackT>(
202  node_base_, node_services_,
203  service_name, std::forward<CallbackT>(callback), qos_profile, group);
204 }
205 
206 template<typename CallbackT>
207 void
209 {
210  this->node_parameters_->register_param_change_callback(std::forward<CallbackT>(callback));
211 }
212 
213 template<typename ParameterT>
214 void
216  const std::string & name,
217  const ParameterT & value)
218 {
219  rclcpp::Parameter parameter;
220  if (!this->get_parameter(name, parameter)) {
221  this->set_parameters({
222  rclcpp::Parameter(name, value),
223  });
224  }
225 }
226 
227 // this is a partially-specialized version of set_parameter_if_not_set above,
228 // where our concrete type for ParameterT is std::map, but the to-be-determined
229 // type is the value in the map.
230 template<typename MapValueT>
231 void
233  const std::string & name,
234  const std::map<std::string, MapValueT> & values)
235 {
237 
238  for (const auto & val : values) {
239  std::string param_name = name + "." + val.first;
240  rclcpp::Parameter parameter;
241  if (!this->get_parameter(param_name, parameter)) {
242  params.push_back(rclcpp::Parameter(param_name, val.second));
243  }
244  }
245 
246  this->set_parameters(params);
247 }
248 
249 template<typename ParameterT>
250 bool
251 Node::get_parameter(const std::string & name, ParameterT & value) const
252 {
253  rclcpp::Parameter parameter;
254  bool result = get_parameter(name, parameter);
255  if (result) {
256  value = parameter.get_value<ParameterT>();
257  }
258 
259  return result;
260 }
261 
262 // this is a partially-specialized version of get_parameter above,
263 // where our concrete type for ParameterT is std::map, but the to-be-determined
264 // type is the value in the map.
265 template<typename MapValueT>
266 bool
268  const std::string & name,
269  std::map<std::string, MapValueT> & values) const
270 {
271  bool retval = false;
272  std::vector<std::string> prefix{name};
273  std::string name_with_dot = name + ".";
274  rcl_interfaces::msg::ListParametersResult result = node_parameters_->list_parameters(prefix, 0);
275  for (const auto & param : result.names) {
276  values[param.substr(name_with_dot.length())] =
277  node_parameters_->get_parameter(param).get_value<MapValueT>();
278  retval = true;
279  }
280 
281  return retval;
282 }
283 
284 template<typename ParameterT>
285 bool
287  const std::string & name,
288  ParameterT & value,
289  const ParameterT & alternative_value) const
290 {
291  bool got_parameter = get_parameter(name, value);
292  if (!got_parameter) {
293  value = alternative_value;
294  }
295  return got_parameter;
296 }
297 
298 template<typename ParameterT>
299 void
301  const std::string & name,
302  ParameterT & value,
303  const ParameterT & alternative_value)
304 {
305  bool got_parameter = get_parameter(name, value);
306  if (!got_parameter) {
307  this->set_parameters({
308  rclcpp::Parameter(name, alternative_value),
309  });
310  value = alternative_value;
311  }
312 }
313 
314 } // namespace rclcpp
315 
316 #endif // RCLCPP__NODE_IMPL_HPP_
void register_param_change_callback(CallbackT &&callback)
Register the callback for parameter changes.
Definition: node_impl.hpp:208
Definition: client.hpp:52
Default allocation strategy for messages received by subscriptions.
Definition: message_memory_strategy.hpp:40
rclcpp::Client< ServiceT >::SharedPtr create_client(const std::string &service_name, const rmw_qos_profile_t &qos_profile=rmw_qos_profile_services_default, rclcpp::callback_group::CallbackGroup::SharedPtr group=nullptr)
Structure to store an arbitrary parameter with templated get/set methods.
Definition: parameter.hpp:32
Definition: timer.hpp:192
rclcpp::WallTimer< CallbackT >::SharedPtr create_wall_timer(std::chrono::duration< int64_t, DurationT > period, CallbackT callback, rclcpp::callback_group::CallbackGroup::SharedPtr group=nullptr)
Create a timer.
Definition: node_impl.hpp:156
Definition: allocator_common.hpp:24
Definition: service.hpp:88
Definition: client.hpp:119
void get_parameter_or_set(const std::string &name, ParameterT &value, const ParameterT &alternative_value)
Get the parameter value; if not set, set the "alternative value" and store it in the node...
Definition: node_impl.hpp:300
rmw_qos_profile_t qos
decltype(auto) get_value() const
Get value of parameter using rclcpp::ParameterType as template argument.
Definition: parameter.hpp:66
void set_parameters_if_not_set(const std::string &name, const std::map< std::string, MapValueT > &values)
Set a map of parameters with the same prefix.
Definition: node_impl.hpp:232
static SharedPtr create_default()
Default factory method.
Definition: message_memory_strategy.hpp:77
T push_back(T... args)
typename std::remove_cv< rclcpp::function_traits::function_traits< CallbackT >::template argument_type< 0 > >::type type
Definition: subscription_traits.hpp:61
std::vector< rcl_interfaces::msg::SetParametersResult > set_parameters(const std::vector< rclcpp::Parameter > &parameters)
rcl_client_options_t rcl_client_get_default_options(void)
T dynamic_pointer_cast(T... args)
T move(T... args)
T length(T... args)
void set_parameter_if_not_set(const std::string &name, const ParameterT &value)
Definition: node_impl.hpp:215
std::shared_ptr< PublisherT > create_publisher(const std::string &topic_name, size_t qos_history_depth, std::shared_ptr< Alloc > allocator=nullptr)
Create and return a Publisher.
Definition: node_impl.hpp:56
rclcpp::Parameter get_parameter(const std::string &name) const
std::vector< rclcpp::Parameter > get_parameters(const std::vector< std::string > &names) const
rclcpp::Service< ServiceT >::SharedPtr create_service(const std::string &service_name, CallbackT &&callback, const rmw_qos_profile_t &qos_profile=rmw_qos_profile_services_default, rclcpp::callback_group::CallbackGroup::SharedPtr group=nullptr)
Definition: node_impl.hpp:195
std::shared_ptr< SubscriptionT > create_subscription(const std::string &topic_name, CallbackT &&callback, const rmw_qos_profile_t &qos_profile=rmw_qos_profile_default, rclcpp::callback_group::CallbackGroup::SharedPtr group=nullptr, bool ignore_local_publications=false, typename rclcpp::message_memory_strategy::MessageMemoryStrategy< typename rclcpp::subscription_traits::has_message_type< CallbackT >::type, Alloc >::SharedPtr msg_mem_strat=nullptr, std::shared_ptr< Alloc > allocator=nullptr)
Create and return a Subscription.
Definition: node_impl.hpp:91
bool get_parameter_or(const std::string &name, ParameterT &value, const ParameterT &alternative_value) const
Get the parameter value, or the "alternative value" if not set, and assign it to "value".
Definition: node_impl.hpp:286