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
rclcpp::Service< S > Class Template Reference

#include <service.hpp>

Public Types

using ConstSharedPtr = ::rclcpp::ServiceHandle< S >
 
using RequestType = typename S::Request
 
using ResponseType = typename S::Response
 
using SharedPtr = ::rclcpp::ServiceHandle< S >
 
using TypedServiceFn = void(*)(const RequestType &request, ResponseType &response)
 
using UniquePtr = ::rclcpp::ServiceHandle< S >
 rclcpp::Service<S>::UniquePtr — see SharedPtr.
 

Public Member Functions

::rclcpp::QoS get_request_subscription_actual_qos () const
 
::rclcpp::QoS get_response_publisher_actual_qos () const
 
const char * get_service_name () const
 
size_t handle_id () const
 Executor arena slot for the registration; SIZE_MAX until registered.
 
bool is_valid () const
 Check if the service was registered.
 
Service & operator= (Service &&other)
 
 Service ()
 
 Service (Service &&other)
 
 ~Service ()
 

Friends

class ::rclcpp::Node
 

Detailed Description

template<typename S>
class rclcpp::Service< S >

Dispatch service server for a ROS 2 service — the rclcpp model.

A handler is registered into the executor arena, which owns the RmwServiceServer and runs the handler during spin_once. The service type S must provide nested Request and Response types with TYPE_NAME, TYPE_HASH, SERIALIZED_SIZE_MAX, ffi_serialize(), and ffi_deserialize().

THIS OBJECT IS BOOKKEEPING — phase-456 W5. The server, the request buffer, the handler and its context are all the arena's; W3 made the arena's trampoline context the user's HANDLER rather than &out, so after registration nothing of the caller's is referenced and this object is freely movable.

What it does hold is what a REGISTRATION can be asked about and the arena cannot be asked for by an index alone: {initialized_, handle_id_, executor_, service_name_}. executor_ and handle_id_ are the pair that names the arena entry (issue 1437) — without the executor an index points into an arena this object cannot reach — and service_name_ is the phase-444 C++-side copy, because the runtime takes the name at create and drops it. Neither survives as state the arena refers back to; both are the caller's own record.

Measured (phase-456 W3), across examples/, tests/, book/ and packages/: a dispatch service has nothing invoked on it, at any site, out-ref or SharedPtr. It is a keep-alive — which is why Service<S>::SharedPtr is a two-word rclcpp::ServiceHandle<S> with no operator-> rather than a pointer to one of these.

Usage:

void add(const AddTwoInts::Request& req, AddTwoInts::Response& resp) {
resp.sum = req.a + req.b;
}
RCLCPP_TRY(node.create_service(srv, "/add_two_ints", &add));
// ... or, in ported shape:
auto handle = node.create_service<AddTwoInts>("/add_two_ints", &add);
Definition client.hpp:129
#define RCLCPP_TRY(expr)
Definition result.hpp:258

Member Typedef Documentation

◆ ConstSharedPtr

template<typename S >
using rclcpp::Service< S >::ConstSharedPtr = ::rclcpp::ServiceHandle<S>

rclcpp::Service<S>::ConstSharedPtr — see SharedPtr. The same handle: there is no mutable/const distinction to draw over a registration that exposes no operation on the entity.

◆ RequestType

template<typename S >
using rclcpp::Service< S >::RequestType = typename S::Request

◆ ResponseType

template<typename S >
using rclcpp::Service< S >::ResponseType = typename S::Response

◆ SharedPtr

template<typename S >
using rclcpp::Service< S >::SharedPtr = ::rclcpp::ServiceHandle<S>

rclcpp::Service<S>::SharedPtr — phase-456 W5.

rclcpp::Service<S>::SharedPtr member_; is how ported source declares a service member, so this alias must exist on every target — which std::shared_ptr does not.

IT IS NOT A POINTER TO A Service<S>. A registered service is the arena's; what this names is rclcpp::ServiceHandle<S> — two words, copyable, carrying only what a registration can perform, which the census says is nothing but "exist". See service_handle.hpp.

◆ TypedServiceFn

template<typename S >
using rclcpp::Service< S >::TypedServiceFn = void (*)(const RequestType& request, ResponseType& response)

Phase 189.M3.3.e — typed request-handler signature for the callback-style service (rclcpp dispatch model). The handler fills response from request; the executor sends the reply during spin.

phase-456 W3 deleted the TypedServiceFnWithCtx sibling. It was write-only state: the SFINAE guard on Node::create_service admits only a void(*)(const Request&, Response&), so no overload could ever set it, and the else if branch that read it in the trampoline was unreachable. A handler that wants context binds it at compile time instead — rclcpp::bind_service<Svc, C, &C::method> in component.hpp, where this is the context and no runtime pointer pair is needed.

◆ UniquePtr

template<typename S >
using rclcpp::Service< S >::UniquePtr = ::rclcpp::ServiceHandle<S>

rclcpp::Service<S>::UniquePtr — see SharedPtr.

Constructor & Destructor Documentation

◆ ~Service()

template<typename S >
rclcpp::Service< S >::~Service ( )
inline

Destructor — there is nothing to release.

The executor arena owns the server, the request buffer and the handler. This destructor deliberately does not release them: it clears this object's own bookkeeping, and the registration lives until its node is destroyed or a ServiceHandle releases it (srv_.reset(), issue 1667). Until phase-456 W5 the same destructor also freed a POLL server, behind an if (initialized_ && !callback_mode_); that half moved to rclcpp::PollService<S>, where the condition is unconditional.

◆ Service() [1/2]

template<typename S >
rclcpp::Service< S >::Service ( Service< S > &&  other)
inline

◆ Service() [2/2]

template<typename S >
rclcpp::Service< S >::Service ( )
inline

Default constructor — creates an unregistered service server. Use Node::create_service() to register one.

Member Function Documentation

◆ get_request_subscription_actual_qos()

template<typename S >
::rclcpp::QoS rclcpp::Service< S >::get_request_subscription_actual_qos ( ) const
inline

The QoS the backend GRANTED this service's REQUEST endpoint — the subscription that receives calls. Issue 1437.

rclcpp::Service::get_request_subscription_actual_qos. ONE create_service builds TWO endpoints that negotiate against DIFFERENT peers, so this and get_response_publisher_actual_qos are two answers and neither stands for the other: a reliable reply path over a best-effort request path is a working service that drops calls.

A policy the backend cannot report is an ABSENCE (ReliabilityPolicy::Unknown and friends), never the request echoed back — see Publisher::get_actual_qos.

phase-456 W5 — BOTH HALVES ANSWER, and the service comes out the other way from the subscription. PollSubscription::get_actual_qos had to be left off the dispatch half, because a dispatch Subscription<M> holds only sched_handle_id_ and reaching the arena would have meant inventing a signature that takes an executor (ledgered at cpp:Subscription::get_actual_qos). A dispatch service does NOT have that problem: issue 1437 already gave it executor_ beside handle_id_, and nros_cpp_service_server_get_actual_qos serves both roads — storage_ for the owner, (executor, handle_id) for the arena. So the upstream no-argument spelling is reachable here with no weakening, and no ledger row is owed.

◆ get_response_publisher_actual_qos()

template<typename S >
::rclcpp::QoS rclcpp::Service< S >::get_response_publisher_actual_qos ( ) const
inline

The QoS the backend GRANTED this service's RESPONSE endpoint — the publisher that sends replies. Issue 1437; see get_request_subscription_actual_qos.

◆ get_service_name()

template<typename S >
const char * rclcpp::Service< S >::get_service_name ( ) const
inline

Read back the service name this server was registered on — phase-444.

rclcpp's ServiceBase::get_service_name, and the server half of Client::get_service_name; see that method for why the name lives C++-side and why the accessor returns "" rather than NULL on an unregistered server.

phase-456 W5 split this class in two and the method answers on BOTH halves, unchanged — the same shape PollSubscription::get_publisher_count took under W2b. It reads service_name_, which each half keeps its own copy of, because the copy is made at create from the argument the caller passed and neither owner can recover it afterwards: the runtime takes the name and drops it, and there is no FFI that reads a name back out of the arena. A shared copy would have to live somewhere neither half owns.

◆ handle_id()

template<typename S >
size_t rclcpp::Service< S >::handle_id ( ) const
inline

Executor arena slot for the registration; SIZE_MAX until registered.

◆ is_valid()

template<typename S >
bool rclcpp::Service< S >::is_valid ( ) const
inline

Check if the service was registered.

◆ operator=()

template<typename S >
Service & rclcpp::Service< S >::operator= ( Service< S > &&  other)
inline

Friends And Related Symbol Documentation

◆ ::rclcpp::Node

template<typename S >
friend class ::rclcpp::Node
friend

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