15 #include "rclcpp/client.hpp"
26 #include "rclcpp/exceptions.hpp"
27 #include "rclcpp/node_interfaces/node_base_interface.hpp"
28 #include "rclcpp/node_interfaces/node_graph_interface.hpp"
29 #include "rclcpp/utilities.hpp"
30 #include "rclcpp/logging.hpp"
34 using rclcpp::exceptions::throw_from_rcl_error;
36 ClientBase::ClientBase(
38 rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph)
39 : node_graph_(node_graph),
40 node_handle_(node_base->get_shared_rcl_node_handle()),
41 context_(node_base->get_context()),
44 std::weak_ptr<rcl_node_t> weak_node_handle(node_handle_);
48 new_rcl_client, [weak_node_handle](
rcl_client_t * client)
50 auto handle = weak_node_handle.lock();
54 rclcpp::get_node_logger(handle.get()).get_child(
"rclcpp"),
55 "Error in destruction of rcl client handle: %s", rcl_get_error_string().str);
61 "Error in destruction of rcl client handle: "
62 "the Node Handle was destructed too early. You will leak memory");
68 ClientBase::~ClientBase()
72 client_handle_.reset();
85 rclcpp::exceptions::throw_from_rcl_error(ret);
96 std::shared_ptr<rcl_client_t>
99 return client_handle_;
102 std::shared_ptr<const rcl_client_t>
105 return client_handle_;
113 this->get_rcl_node_handle(),
117 const rcl_node_t * node_handle = this->get_rcl_node_handle();
124 throw_from_rcl_error(ret,
"rcl_service_server_is_available failed");
130 ClientBase::wait_for_service_nanoseconds(std::chrono::nanoseconds timeout)
132 auto start = std::chrono::steady_clock::now();
134 auto node_ptr = node_graph_.lock();
142 if (timeout == std::chrono::nanoseconds(0)) {
146 auto event = node_ptr->get_graph_event();
149 std::chrono::nanoseconds time_to_wait =
150 timeout > std::chrono::nanoseconds(0) ?
151 timeout - (std::chrono::steady_clock::now() - start) :
152 std::chrono::nanoseconds::max();
153 if (time_to_wait < std::chrono::nanoseconds(0)) {
156 time_to_wait = std::chrono::nanoseconds(0);
169 node_ptr->wait_for_graph_change(
170 event, std::min(time_to_wait, std::chrono::nanoseconds(
RCL_MS_TO_NS(100))));
173 event->check_and_clear();
178 if (timeout > std::chrono::nanoseconds(0)) {
179 time_to_wait = timeout - (std::chrono::steady_clock::now() - start);
182 }
while (time_to_wait > std::chrono::nanoseconds(0));
187 ClientBase::get_rcl_node_handle()
189 return node_handle_.get();
193 ClientBase::get_rcl_node_handle()
const
195 return node_handle_.get();
201 return in_use_by_wait_set_.exchange(in_use_state);
207 const rmw_qos_profile_t * qos =
211 std::string(
"failed to get client's request publisher qos settings: ") +
212 rcl_get_error_string().str;
214 throw std::runtime_error(msg);
220 return request_publisher_qos;
226 const rmw_qos_profile_t * qos =
230 std::string(
"failed to get client's response subscription qos settings: ") +
231 rcl_get_error_string().str;
233 throw std::runtime_error(msg);
239 return response_subscription_qos;
246 client_handle_.get(),
251 using rclcpp::exceptions::throw_from_rcl_error;
252 throw_from_rcl_error(ret,
"failed to set the on new response callback for client");
RCLCPP_PUBLIC bool exchange_in_use_by_wait_set_state(bool in_use_state)
Exchange the "in use by wait set" state for this client.
RCLCPP_PUBLIC rclcpp::QoS get_request_publisher_actual_qos() const
Get the actual request publsher QoS settings, after the defaults have been determined.
RCLCPP_PUBLIC std::shared_ptr< rcl_client_t > get_client_handle()
Return the rcl_client_t client handle in a std::shared_ptr.
void set_on_new_response_callback(std::function< void(size_t)> callback)
Set a callback to be called when each new response is received.
RCLCPP_PUBLIC bool take_type_erased_response(void *response_out, rmw_request_id_t &request_header_out)
Take the next response for this client as a type erased pointer.
RCLCPP_PUBLIC const char * get_service_name() const
Return the name of the service.
void clear_on_new_response_callback()
Unset the callback registered for new responses, if any.
RCLCPP_PUBLIC rclcpp::QoS get_response_subscription_actual_qos() const
Get the actual response subscription QoS settings, after the defaults have been determined.
RCLCPP_PUBLIC bool service_is_ready() const
Return if the service is ready.
Encapsulation of Quality of Service settings.
Thrown when a method is trying to use a node, but it is invalid.
Pure virtual interface class for the NodeBase part of the Node API.
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_client_request_publisher_get_actual_qos(const rcl_client_t *client)
Get the actual qos settings of the client's request publisher.
RCL_PUBLIC RCL_WARN_UNUSED const char * rcl_client_get_service_name(const rcl_client_t *client)
Get the name of the service that this client will request a response from.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_client_fini(rcl_client_t *client, rcl_node_t *node)
Finalize a rcl_client_t.
RCL_PUBLIC RCL_WARN_UNUSED rcl_client_t rcl_get_zero_initialized_client(void)
Return a rcl_client_t struct with members set to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_take_response(const rcl_client_t *client, rmw_request_id_t *request_header, void *ros_response)
backwards compatibility function that takes a rmw_request_id_t only
struct rcl_client_s rcl_client_t
Structure which encapsulates a ROS Client.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_client_set_on_new_response_callback(const rcl_client_t *client, rcl_event_callback_t callback, const void *user_data)
Set the on new response callback function for the client.
RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * rcl_client_response_subscription_get_actual_qos(const rcl_client_t *client)
Get the actual qos settings of the client's response subscription.
RCL_PUBLIC RCL_WARN_UNUSED bool rcl_context_is_valid(const rcl_context_t *context)
Return true if the given context is currently valid, otherwise false.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_service_server_is_available(const rcl_node_t *node, const rcl_client_t *client, bool *is_available)
Check if a service server is available for the given service client.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_node_logger(const rcl_node_t *node)
Return a named logger using an rcl_node_t.
RCLCPP_PUBLIC bool ok(rclcpp::Context::SharedPtr context=nullptr)
Check rclcpp's status.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Structure which encapsulates a ROS Client.
Structure which encapsulates a ROS Node.
rcl_context_t * context
Context associated with this node.
static QoSInitialization from_rmw(const rmw_qos_profile_t &rmw_qos)
Create a QoSInitialization from an existing rmw_qos_profile_t, using its history and depth.
#define RCL_MS_TO_NS
Convenience macro to convert milliseconds to nanoseconds.
#define RCL_RET_CLIENT_TAKE_FAILED
Failed to take a response from the client return code.
#define RCL_RET_OK
Success return code.
#define RCL_RET_NODE_INVALID
Invalid rcl_node_t given return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.