15 #ifndef NAV2_UTIL__SERVICE_CLIENT_HPP_
16 #define NAV2_UTIL__SERVICE_CLIENT_HPP_
20 #include "rclcpp/rclcpp.hpp"
29 template<
class ServiceT>
39 const std::string & service_name,
40 const rclcpp::Node::SharedPtr & provided_node)
41 : service_name_(service_name), node_(provided_node)
43 callback_group_ = node_->create_callback_group(
44 rclcpp::CallbackGroupType::MutuallyExclusive,
46 callback_group_executor_.add_callback_group(callback_group_, node_->get_node_base_interface());
47 client_ = node_->create_client<ServiceT>(
49 rclcpp::ServicesQoS().get_rmw_qos_profile(),
53 using RequestType =
typename ServiceT::Request;
54 using ResponseType =
typename ServiceT::Response;
62 typename ResponseType::SharedPtr
invoke(
63 typename RequestType::SharedPtr & request,
64 const std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1))
66 while (!client_->wait_for_service(std::chrono::seconds(1))) {
68 throw std::runtime_error(
69 service_name_ +
" service client: interrupted while waiting for service");
72 node_->get_logger(),
"%s service client: waiting for service to appear...",
73 service_name_.c_str());
77 node_->get_logger(),
"%s service client: send async request",
78 service_name_.c_str());
79 auto future_result = client_->async_send_request(request);
81 if (callback_group_executor_.spin_until_future_complete(future_result, timeout) !=
82 rclcpp::FutureReturnCode::SUCCESS)
85 client_->remove_pending_request(future_result);
86 throw std::runtime_error(service_name_ +
" service client: async_send_request failed");
89 return future_result.get();
99 typename RequestType::SharedPtr & request,
100 typename ResponseType::SharedPtr & response)
102 while (!client_->wait_for_service(std::chrono::seconds(1))) {
104 throw std::runtime_error(
105 service_name_ +
" service client: interrupted while waiting for service");
108 node_->get_logger(),
"%s service client: waiting for service to appear...",
109 service_name_.c_str());
113 node_->get_logger(),
"%s service client: send async request",
114 service_name_.c_str());
115 auto future_result = client_->async_send_request(request);
117 if (callback_group_executor_.spin_until_future_complete(future_result) !=
118 rclcpp::FutureReturnCode::SUCCESS)
121 client_->remove_pending_request(future_result);
125 response = future_result.get();
126 return response.get();
134 bool wait_for_service(
const std::chrono::nanoseconds timeout = std::chrono::nanoseconds::max())
136 return client_->wait_for_service(timeout);
145 return service_name_;
149 std::string service_name_;
150 rclcpp::Node::SharedPtr node_;
151 rclcpp::CallbackGroup::SharedPtr callback_group_;
152 rclcpp::executors::SingleThreadedExecutor callback_group_executor_;
153 typename rclcpp::Client<ServiceT>::SharedPtr client_;
A simple wrapper on ROS2 services for invoke() and block-style calling.
bool wait_for_service(const std::chrono::nanoseconds timeout=std::chrono::nanoseconds::max())
Block until a service is available or timeout.
bool invoke(typename RequestType::SharedPtr &request, typename ResponseType::SharedPtr &response)
Invoke the service and block until completed.
ServiceClient(const std::string &service_name, const rclcpp::Node::SharedPtr &provided_node)
A constructor.
std::string getServiceName()
Gets the service name.
ResponseType::SharedPtr invoke(typename RequestType::SharedPtr &request, const std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
Invoke the service and block until completed or timed out.