nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Friends | List of all members
nros::Client< S > Class Template Reference

#include <client.hpp>

Public Types

using RequestType = typename S::Request
 
using ResponseType = typename S::Response
 
using TypedResponseFn = void(*)(const ResponseType &response)
 
using TypedResponseFnWithCtx = void(*)(const ResponseType &response, void *ctx)
 

Public Member Functions

Result async_send_request (const RequestType &req)
 
Result call (const RequestType &req, ResponseType &resp, uint32_t timeout_ms=5000)
 
Result call_polling (const RequestType &req, ResponseType &resp, uint32_t timeout_ms=100)
 
template<size_t RespCap>
Result call_polling_sized (const RequestType &req, ResponseType &resp, uint32_t timeout_ms=100)
 
template<size_t RespCap>
Result call_sized (const RequestType &req, ResponseType &resp, uint32_t timeout_ms=5000)
 call with the REPLY buffer sized by the caller (issue 0964).
 
 Client ()
 
 Client (Client &&other)
 
size_t handle_id () const
 
bool is_valid () const
 Check if the client is initialized and valid.
 
Clientoperator= (Client &&other)
 
Future< ResponseTypesend_request (const RequestType &req)
 
template<size_t RespCap>
Future< ResponseType, RespCap > send_request_sized (const RequestType &req)
 
int server_available () const
 
Expected< bool > service_is_ready () const
 
Result wait_for_service (uint32_t timeout_ms=5000)
 
 ~Client ()
 

Friends

class Node
 

Detailed Description

template<typename S>
class nros::Client< S >

Typed service client for a ROS 2 service.

Mirrors rclcpp::Client<S>. The service type S must provide nested Request and Response types with TYPE_NAME, TYPE_HASH, SERIALIZED_SIZE_MAX, ffi_serialize(), and ffi_deserialize().

Usage (async – preferred):

NROS_TRY(node.create_client(client, "/add_two_ints"));
auto fut = client.send_request(req);
NROS_TRY(fut.wait(executor.handle(), 5000, resp));
Definition client.hpp:55
typename S::Response ResponseType
Definition client.hpp:58
Future< ResponseType > send_request(const RequestType &req)
Definition client.hpp:75
#define NROS_TRY(expr)
Definition result.hpp:128

Member Typedef Documentation

◆ RequestType

template<typename S >
using nros::Client< S >::RequestType = typename S::Request

◆ ResponseType

template<typename S >
using nros::Client< S >::ResponseType = typename S::Response

◆ TypedResponseFn

template<typename S >
using nros::Client< S >::TypedResponseFn = void (*)(const ResponseType& response)

Phase 189.M3.3.f — typed response-handler signatures for the callback-style client (rclcpp async dispatch). The handler runs during spin_once when a reply arrives for a request sent via async_send_request.

◆ TypedResponseFnWithCtx

template<typename S >
using nros::Client< S >::TypedResponseFnWithCtx = void (*)(const ResponseType& response, void* ctx)

Constructor & Destructor Documentation

◆ ~Client()

template<typename S >
nros::Client< S >::~Client ( )
inline

Destructor – releases service client resources.

Future-style clients own an RmwServiceClient in storage_; callback-style clients (M3.3.f) are owned by the executor arena, so the dtor must NOT touch storage_ for them.

◆ Client() [1/2]

template<typename S >
nros::Client< S >::Client ( Client< S > &&  other)
inline

◆ Client() [2/2]

template<typename S >
nros::Client< S >::Client ( )
inline

Default constructor – creates an uninitialized service client. Use Node::create_client() to initialize.

Member Function Documentation

◆ async_send_request()

template<typename S >
Result nros::Client< S >::async_send_request ( const RequestType req)
inline

Phase 189.M3.3.f — callback-style async send. Only valid on a callback-style client (created via the create_client(out, name, callback, ...) overload); the reply is delivered to the registered response handler during spin_once (no Future). Returns immediately after sending.

◆ call()

template<typename S >
Result nros::Client< S >::call ( const RequestType req,
ResponseType resp,
uint32_t  timeout_ms = 5000 
)
inline

Send a request and block until a reply is received.

Spins the executor internally (like the runtime's Promise::wait). Never calls zpico_get — all I/O is driven by spin_once.

Parameters
reqRequest to send.
respOutput response struct (filled on success).
timeout_msMaximum wait time (default 5000ms).
Returns
Result indicating success, timeout, or failure.

◆ call_polling()

template<typename S >
Result nros::Client< S >::call_polling ( const RequestType req,
ResponseType resp,
uint32_t  timeout_ms = 100 
)
inline

Issue 0278 (Half B) — send a request and block up to timeout_ms for the reply WITHOUT spinning the executor, so this is safe to call from inside a subscription/timer callback (where call()/Future::wait would return Reentrant, issue 0290). It sends then sleep-polls the reply queue.

CONSTRAINT: usable from a callback only on a MULTI-THREADED backend (zenoh MT, cyclonedds), where the backend's own read task delivers the reply into the client's queue while this loop yields. On a single-threaded / polled backend the reply can only arrive via spin_once — which the callback is blocking — so it will TIME OUT; use call() from the main loop there. Keep timeout_ms SHORT (tens of ms): this blocks the executor's dispatch thread for its duration.

Parameters
reqRequest to send.
respOutput response struct (filled on success).
timeout_msMaximum wait (default 100ms).
Returns
success on a received reply; ErrorCode::Timeout on no reply in time; NotInitialized / Error otherwise.

◆ call_polling_sized()

template<typename S >
template<size_t RespCap>
Result nros::Client< S >::call_polling_sized ( const RequestType req,
ResponseType resp,
uint32_t  timeout_ms = 100 
)
inline

call_polling with the REPLY buffer sized by the caller (issue 0964). The request buffer stays on the estimate: it is transmit scratch, where an over-estimate only wastes stack.

◆ call_sized()

template<typename S >
template<size_t RespCap>
Result nros::Client< S >::call_sized ( const RequestType req,
ResponseType resp,
uint32_t  timeout_ms = 5000 
)
inline

call with the REPLY buffer sized by the caller (issue 0964).

◆ handle_id()

template<typename S >
size_t nros::Client< S >::handle_id ( ) const
inline

Executor handle for the callback-style client (Phase 189.M3.3.f); SIZE_MAX for future-style / uninitialized.

◆ is_valid()

template<typename S >
bool nros::Client< S >::is_valid ( ) const
inline

Check if the client is initialized and valid.

◆ operator=()

template<typename S >
Client & nros::Client< S >::operator= ( Client< S > &&  other)
inline

◆ send_request()

template<typename S >
Future< ResponseType > nros::Client< S >::send_request ( const RequestType req)
inline

Send a request and return a Future for the response (non-blocking).

Call wait() on the returned future to block until the response arrives, or poll with is_ready() / try_take().

Parameters
reqRequest to send.
Returns
Future that resolves to the response. Returns a consumed (empty) future on serialization or send failure.

◆ send_request_sized()

template<typename S >
template<size_t RespCap>
Future< ResponseType, RespCap > nros::Client< S >::send_request_sized ( const RequestType req)
inline

send_request with the REPLY buffer sized by the caller.

The receive buffer of a Future<T> is a member, so the capacity is a class template argument rather than a function one: this returns a Future<ResponseType, RespCap> (issue 0964). The request buffer is a transmit scratch buffer and is deliberately left on the estimate – over-sizing there only wastes stack.

Template Parameters
RespCapStack bytes the returned future holds for the reply.

◆ server_available()

template<typename S >
int nros::Client< S >::server_available ( ) const
inline
Deprecated:
Use service_is_ready().

phase-379 W6 — preserved exactly: 1 ready, 0 not yet, -1 cannot answer. It cannot distinguish a failed call from an unsupported backend, which is why it is replaced rather than kept.

◆ service_is_ready()

template<typename S >
Expected< bool > nros::Client< S >::service_is_ready ( ) const
inline

Phase 124.C.3 — graph-aware "is the matching server up?" probe.

Returns the count from the RMW backend's matched-server view:

  • 1 — at least one matching server is currently visible.
  • ok(false) — no matching server discovered yet.
  • error(Unsupported) — backend cannot answer (e.g. XRCE without participant enumeration); caller must fall back to a timed wait_for_service or assume reachability.
  • error(<code>) — the probe itself failed.

Never spins the executor — synchronous, safe to call from inside callbacks. Mirrors rclcpp::ClientBase::service_is_ready but with a tri-state result instead of collapsing "don't know" and "no" into the same false.

◆ wait_for_service()

template<typename S >
Result nros::Client< S >::wait_for_service ( uint32_t  timeout_ms = 5000)
inline

phase-338 W8 — block until a matching service server is discoverable.

Mirrors rclcpp::ClientBase::wait_for_service. Prefer this over hand-rolling a retry loop around the first call() / send_request(): it waits for the actual condition instead of guessing an attempt count, and it re-probes, so a server that starts AFTER the wait begins is still seen (a single liveliness query samples the router's current token list and terminates).

Spins the executor cooperatively while probing, so do NOT call it from inside a callback — use the non-blocking server_available() there.

Returns ok when the server is visible, Timeout when the budget elapses.

Friends And Related Symbol Documentation

◆ Node

template<typename S >
friend class Node
friend

The documentation for this class was generated from the following files: