Class GenericClient

Nested Relationships

Nested Types

Inheritance Relationships

Base Type

Class Documentation

class GenericClient : public rclcpp::ClientBase

Public Types

using Request = void*
using Response = void*
using SharedResponse = std::shared_ptr<void>
using Promise = std::promise<SharedResponse>
using SharedPromise = std::shared_ptr<Promise>
using Future = std::future<SharedResponse>
using SharedFuture = std::shared_future<SharedResponse>

Public Functions

GenericClient(rclcpp::node_interfaces::NodeBaseInterface *node_base, rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph, const std::string &service_name, const std::string &service_type, rcl_client_options_t &client_options)
virtual SharedResponse create_response() override
virtual std::shared_ptr<rmw_request_id_t> create_request_header() override
virtual void handle_response(std::shared_ptr<rmw_request_id_t> request_header, std::shared_ptr<void> response) override
FutureAndRequestId async_send_request(const Request request)

Send a request to the service server.

This method returns a FutureAndRequestId instance that can be passed to Executor::spin_until_future_complete() to wait until it has been completed.

If the future never completes, e.g. the call to Executor::spin_until_future_complete() times out, GenericClient::remove_pending_request() must be called to clean the client internal state. Not doing so will make the Client instance to use more memory each time a response is not received from the service server.

auto future = client->async_send_request(my_request);
if (
  rclcpp::FutureReturnCode::TIMEOUT ==
  executor->spin_until_future_complete(future, timeout))
{
  client->remove_pending_request(future);
  // handle timeout
} else {
  handle_response(future.get());
}
Parameters:

request[in] request to be send.

Returns:

a FutureAndRequestId instance.

template<typename AllocatorT = std::allocator<int64_t>>
inline size_t prune_requests_older_than(std::chrono::time_point<std::chrono::system_clock> time_point, std::vector<int64_t, AllocatorT> *pruned_requests = nullptr)

Clean all pending requests older than a time_point.

Parameters:
  • time_point[in] Requests that were sent before this point are going to be removed.

  • pruned_requests[inout] Removed requests id will be pushed to the vector if a pointer is provided.

Returns:

number of pending requests that were removed.

size_t prune_pending_requests()
bool remove_pending_request(int64_t request_id)
inline bool take_response(Response response_out, rmw_request_id_t &request_header_out)

Take the next response for this client.

Parameters:
  • response_out[out] The reference to a Service Response into which the middleware will copy the response being taken.

  • request_header_out[out] The request header to be filled by the middleware when taking, and which can be used to associate the response to a specific request.

Throws:

rclcpp::exceptions::RCLError – based exceptions if the underlying rcl function fail.

Returns:

true if the response was taken, otherwise false.

Protected Types

using CallbackInfoVariant = std::variant<std::promise<SharedResponse>>

Protected Functions

int64_t async_send_request_impl(const Request request, CallbackInfoVariant value)
std::optional<CallbackInfoVariant> get_and_erase_pending_request(int64_t request_number)

Protected Attributes

std::map<int64_t, std::pair<std::chrono::time_point<std::chrono::system_clock>, CallbackInfoVariant>> pending_requests_
std::mutex pending_requests_mutex_
struct FutureAndRequestId : public rclcpp::detail::FutureAndRequestId<Future>

A convenient GenericClient::Future and request id pair.

Public members:

  • future: a std::future<void *>.

  • request_id: the request id associated with the future.

All the other methods are equivalent to the ones std::future provides.

Public Functions

inline SharedFuture share() noexcept

See std::future::share().

FutureAndRequestId(FutureAndRequestId &&other) noexcept = default

Move constructor.

FutureAndRequestId(const FutureAndRequestId &other) = delete

Deleted copy constructor, each instance is a unique owner of the future.

FutureAndRequestId &operator=(FutureAndRequestId &&other) noexcept = default

Move assignment.

FutureAndRequestId &operator=(const FutureAndRequestId &other) = delete

Deleted copy assignment, each instance is a unique owner of the future.

~FutureAndRequestId() = default

Destructor.