|
nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
|
#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 |
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:
| 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.
| 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.
| 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.
| using rclcpp::Service< S >::UniquePtr = ::rclcpp::ServiceHandle<S> |
rclcpp::Service<S>::UniquePtr — see SharedPtr.
|
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.
|
inline |
Default constructor — creates an unregistered service server. Use Node::create_service() to register one.
|
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.
|
inline |
The QoS the backend GRANTED this service's RESPONSE endpoint — the publisher that sends replies. Issue 1437; see get_request_subscription_actual_qos.
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.
|
inline |
Executor arena slot for the registration; SIZE_MAX until registered.
|
inline |
Check if the service was registered.
|
friend |