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_action::Server< A > Class Template Reference

#include <server.hpp>

Public Types

using FeedbackType = typename A::Feedback
 
using GoalType = typename A::Goal
 
using ResultType = typename A::Result
 
using TypedAcceptedFn = void(*)(const uint8_t uuid[16])
 User-facing typed accepted-goal callback signature (issue 0796).
 
using TypedAcceptedFnWithCtx = void(*)(const uint8_t uuid[16], void *ctx)
 User-facing typed accepted-goal callback signature with user context.
 
using TypedCancelFn = ::rclcpp_action::CancelResponse(*)(const uint8_t uuid[16])
 User-facing typed cancel callback signature.
 
using TypedCancelFnWithCtx = ::rclcpp_action::CancelResponse(*)(const uint8_t uuid[16], void *ctx)
 User-facing typed cancel callback signature with user context (Phase 84.G9).
 
using TypedGoalFn = ::rclcpp_action::GoalResponse(*)(const uint8_t uuid[16], const GoalType &goal)
 User-facing typed goal callback signature.
 
using TypedGoalFnWithCtx = ::rclcpp_action::GoalResponse(*)(const uint8_t uuid[16], const GoalType &goal, void *ctx)
 User-facing typed goal callback signature with user context (Phase 84.G9).
 
using TypedVisitorFn = void(*)(const uint8_t uuid[16], ::rclcpp_action::GoalStatus status)
 User-facing visitor signature for for_each_active_goal.
 

Public Member Functions

::rclcpp::Result abort (const ::rclcpp_action::GoalUUID &goal_id, const ResultType &result)
 abort taking a GoalUUID value.
 
::rclcpp::Result abort (const uint8_t goal_id[16], const ResultType &result)
 
::rclcpp::Result canceled (const ::rclcpp_action::GoalUUID &goal_id, const ResultType &result)
 canceled taking a GoalUUID value.
 
::rclcpp::Result canceled (const uint8_t goal_id[16], const ResultType &result)
 
::rclcpp::Result complete_goal (const ::rclcpp_action::GoalUUID &goal_id, ::rclcpp_action::GoalStatus status, const ResultType &result)
 complete_goal taking a GoalUUID value (phase-417 W4.b).
 
::rclcpp::Result complete_goal (const ::rclcpp_action::GoalUUID &goal_id, const ResultType &result)
 complete_goal taking a GoalUUID value (phase-417 W4.b).
 
::rclcpp::Result complete_goal (const uint8_t goal_id[16], ::rclcpp_action::GoalStatus status, const ResultType &result)
 
::rclcpp::Result complete_goal (const uint8_t goal_id[16], const ResultType &result)
 
template<typename F >
::rclcpp::Result for_each_active_goal (F f)
 
const char * get_action_name () const
 
bool goal_exists (const ::rclcpp_action::GoalUUID &goal_id) const
 goal_exists taking a GoalUUID value.
 
bool goal_exists (const uint8_t goal_id[16]) const
 
bool is_valid () const
 Check if the action server is initialized and valid.
 
Server & operator= (Server &&other)
 
::rclcpp::Result publish_feedback (const ::rclcpp_action::GoalUUID &goal_id, const FeedbackType &feedback)
 publish_feedback taking a GoalUUID value (phase-417 W4.b).
 
::rclcpp::Result publish_feedback (const uint8_t goal_id[16], const FeedbackType &feedback)
 
 Server ()
 
 Server (Server &&other)
 
template<typename F >
::rclcpp::Result set_accepted_callback (F f)
 
::rclcpp::Result set_accepted_callback_with_ctx (TypedAcceptedFnWithCtx f, void *ctx)
 
template<typename F >
::rclcpp::Result set_cancel_callback (F f)
 
::rclcpp::Result set_cancel_callback_with_ctx (TypedCancelFnWithCtx f, void *ctx)
 
template<typename F >
::rclcpp::Result set_goal_callback (F f)
 
::rclcpp::Result set_goal_callback_with_ctx (TypedGoalFnWithCtx f, void *ctx)
 
::rclcpp::Result succeed (const ::rclcpp_action::GoalUUID &goal_id, const ResultType &result)
 succeed taking a GoalUUID value.
 
::rclcpp::Result succeed (const uint8_t goal_id[16], const ResultType &result)
 
 ~Server ()
 

Friends

class ::rclcpp::Node
 

Detailed Description

template<typename A>
class rclcpp_action::Server< A >

Typed action server for a ROS 2 action.

Mirrors upstream's rclcpp_action::Server<A> with a callback-based API. The action type A must provide nested Goal, Result, and Feedback types with TYPE_NAME, TYPE_HASH, SERIALIZED_SIZE_MAX, ffi_serialize(), and ffi_deserialize().

Usage:

using Fib = example_interfaces::action::Fibonacci;
RCLCPP_TRY(node.create_action_server(srv, "/fibonacci"));
srv.set_goal_callback(
[](const uint8_t[16], const Fib::Goal& g) {
if (g.order > 46) return rclcpp_action::GoalResponse::REJECT;
});
Definition client.hpp:95
#define RCLCPP_TRY(expr)
Definition result.hpp:258

Callbacks must be stateless (empty-capture lambdas or plain function pointers). This is a freestanding C++14 library without std::function, so per-instance closure storage is not available.

What upstream's Server<A> has and this one does not (ADOPT-BOUNDED):

Member Typedef Documentation

◆ FeedbackType

template<typename A >
using rclcpp_action::Server< A >::FeedbackType = typename A::Feedback

◆ GoalType

template<typename A >
using rclcpp_action::Server< A >::GoalType = typename A::Goal

◆ ResultType

template<typename A >
using rclcpp_action::Server< A >::ResultType = typename A::Result

◆ TypedAcceptedFn

template<typename A >
using rclcpp_action::Server< A >::TypedAcceptedFn = void (*)(const uint8_t uuid[16])

User-facing typed accepted-goal callback signature (issue 0796).

◆ TypedAcceptedFnWithCtx

template<typename A >
using rclcpp_action::Server< A >::TypedAcceptedFnWithCtx = void (*)(const uint8_t uuid[16], void* ctx)

User-facing typed accepted-goal callback signature with user context.

◆ TypedCancelFn

template<typename A >
using rclcpp_action::Server< A >::TypedCancelFn = ::rclcpp_action::CancelResponse (*)(const uint8_t uuid[16])

User-facing typed cancel callback signature.

◆ TypedCancelFnWithCtx

template<typename A >
using rclcpp_action::Server< A >::TypedCancelFnWithCtx = ::rclcpp_action::CancelResponse (*)(const uint8_t uuid[16], void* ctx)

User-facing typed cancel callback signature with user context (Phase 84.G9).

◆ TypedGoalFn

User-facing typed goal callback signature.

◆ TypedGoalFnWithCtx

template<typename A >
using rclcpp_action::Server< A >::TypedGoalFnWithCtx = ::rclcpp_action::GoalResponse (*)(const uint8_t uuid[16], const GoalType& goal, void* ctx)

User-facing typed goal callback signature with user context (Phase 84.G9).

◆ TypedVisitorFn

template<typename A >
using rclcpp_action::Server< A >::TypedVisitorFn = void (*)(const uint8_t uuid[16], ::rclcpp_action::GoalStatus status)

User-facing visitor signature for for_each_active_goal.

Constructor & Destructor Documentation

◆ ~Server()

template<typename A >
rclcpp_action::Server< A >::~Server ( )
inline

Destructor — RELEASES the arena entry (issue 1496).

The action's five RMW entities (three service servers, the feedback and status publishers), its goal table and its result slab live in an ActionServerRawArenaEntry in the executor arena, and the entry's callback context is storage_. nros_cpp_action_server_detach drops that entry in place — the entities are destroyed, so the action leaves the graph and no late send_goal can dispatch into this storage — frees its callback slot, and returns its arena bytes to the executor's free list for the next registration that fits. A program that creates and destroys servers in a loop therefore does not exhaust NROS_EXECUTOR_MAX_CBS or the arena. (nros_cpp_action_server_destroy after it is a drop_in_place over Copy fields and runs no destructor itself; the release is the detach call's.)

◆ Server() [1/2]

template<typename A >
rclcpp_action::Server< A >::Server ( Server< A > &&  other)
inline

◆ Server() [2/2]

template<typename A >
rclcpp_action::Server< A >::Server ( )
inline

Default constructor — creates an uninitialized action server. Use Node::create_action_server() to initialize.

Member Function Documentation

◆ abort() [1/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::abort ( const ::rclcpp_action::GoalUUID &  goal_id,
const ResultType &  result 
)
inline

abort taking a GoalUUID value.

◆ abort() [2/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::abort ( const uint8_t  goal_id[16],
const ResultType &  result 
)
inline

Terminate goal_id as ABORTED. See succeed.

Upstream's is goal_handle->abort(std::shared_ptr<Result>); this is on the server, keyed by goal id, result by const reference — no goal handle.

◆ canceled() [1/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::canceled ( const ::rclcpp_action::GoalUUID &  goal_id,
const ResultType &  result 
)
inline

canceled taking a GoalUUID value.

◆ canceled() [2/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::canceled ( const uint8_t  goal_id[16],
const ResultType &  result 
)
inline

Terminate goal_id as CANCELED. See succeed.

Spelled canceled — rclcpp_action's and C's spelling — not cancel. Rust used to disagree here and was renamed to match in the same work item.

Upstream's is goal_handle->canceled(std::shared_ptr<Result>); this is on the server, keyed by goal id, result by const reference — no goal handle.

◆ complete_goal() [1/4]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::complete_goal ( const ::rclcpp_action::GoalUUID &  goal_id,
::rclcpp_action::GoalStatus  status,
const ResultType &  result 
)
inline

complete_goal taking a GoalUUID value (phase-417 W4.b).

◆ complete_goal() [2/4]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::complete_goal ( const ::rclcpp_action::GoalUUID &  goal_id,
const ResultType &  result 
)
inline

complete_goal taking a GoalUUID value (phase-417 W4.b).

◆ complete_goal() [3/4]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::complete_goal ( const uint8_t  goal_id[16],
::rclcpp_action::GoalStatus  status,
const ResultType &  result 
)
inline

Terminate a goal with a result and the status it terminated in.

Issue 0796 — status used to be hardcoded Succeeded inside the shim, so a server that aborted a goal reported success to the client. The parameter order matches PollingActionServer::complete_goal and the C API's rclc_polling_action_server_complete_goal_raw, so the three surfaces agree; Succeeded is defaulted because it is the common case and because that keeps existing two-argument calls compiling.

rclcpp_action has no complete_goal: a goal ends through its ServerGoalHandle (succeed / abort / canceled). Here the terminal status is an argument and the goal is named by its id, because there is no goal handle; succeed / abort / canceled below are forwarders onto this.

◆ complete_goal() [4/4]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::complete_goal ( const uint8_t  goal_id[16],
const ResultType &  result 
)
inline

Terminate a goal as SUCCEEDED. Equivalent to complete_goal(goal_id, GoalStatus::Succeeded, result).

◆ for_each_active_goal()

template<typename A >
template<typename F >
::rclcpp::Result rclcpp_action::Server< A >::for_each_active_goal ( F  f)
inline

Iterate over every currently live goal and invoke f(uuid, status).

F must be a stateless callable convertible to void (*)(const uint8_t uuid[16], GoalStatus status). The arena never stores the original goal CDR payload, so only identity + status are forwarded — if you need the goal bytes, stash them in a {uuid → state} table from inside set_goal_callback. F must be a stateless callable convertible to void(*)(const uint8_t[16], GoalStatus). phase-456 W3b — the visitor rides the void* ctx this FFI already has, carried by value through rclcpp::detail::fn_to_context, instead of a TypedVisitorFn user_visitor_fn_ member set on entry and cleared on exit. That member was the only piece of per-instance state on this class that was nullptr everywhere except inside one function body, and the move constructor and move assignment each copied it — bookkeeping for a value known to be null at every point a move can observe it.

The lifetime argument is stronger here than the one W3 made for a service handler: this FFI call is SYNCHRONOUS, so the context does not outlive the full-expression that built it. Nothing of the caller's is referenced after the call returns, which is also why the visitor needs no clearing step — there is nowhere for it to be left behind.

◆ get_action_name()

template<typename A >
const char * rclcpp_action::Server< A >::get_action_name ( ) const
inline

Read back the action name this server was created on — phase-417 W4.b.

The callback tier's half of "four surfaces, one accessor" (ledger row c:action_server_get_action_name): PollingActionServer and PollingActionClient have had get_action_name() all along, C now has rcl_action_server_get_action_name, and this tier — the one a ported rclcpp_action program uses — had a char action_name_[256] field populated at construction and read by nothing.

The field is back, and it is now READ. The earlier removal was right about dead state and the note it left ("if an accessor is wanted, it belongs on an FFI getter over the name the runtime already owns") does not apply: the runtime does NOT own it here. CppActionServer keeps a raw arena handle and nros_cpp_action_server_create takes _action_name and drops it, so there is nothing FFI-side to hand back. Subscription::get_topic_name pays the same 256 bytes for the same reason, and a borrowed const char* was rejected — create_action_server takes a const char* that a hosted caller may well have obtained from a temporary.

Returns "" (never NULL) on an uninitialised server, matching Subscription::get_topic_name and the two polling tiers.

◆ goal_exists() [1/2]

template<typename A >
bool rclcpp_action::Server< A >::goal_exists ( const ::rclcpp_action::GoalUUID &  goal_id) const
inline

goal_exists taking a GoalUUID value.

◆ goal_exists() [2/2]

template<typename A >
bool rclcpp_action::Server< A >::goal_exists ( const uint8_t  goal_id[16]) const
inline

Is goal_id a goal this server still knows about? — phase-417 W4.b.

rcl's rcl_action_server_goal_exists, and C's rclc_action_server_goal_exists. TRUE while the goal is ACTIVE and while its completed result is still retained for a later get_result, which is rcl's own window. A predicate rather than a Result, because the ported idiom is a guard.

◆ is_valid()

template<typename A >
bool rclcpp_action::Server< A >::is_valid ( ) const
inline

Check if the action server is initialized and valid.

◆ operator=()

template<typename A >
Server & rclcpp_action::Server< A >::operator= ( Server< A > &&  other)
inline

◆ publish_feedback() [1/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::publish_feedback ( const ::rclcpp_action::GoalUUID &  goal_id,
const FeedbackType &  feedback 
)
inline

publish_feedback taking a GoalUUID value (phase-417 W4.b).

◆ publish_feedback() [2/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::publish_feedback ( const uint8_t  goal_id[16],
const FeedbackType &  feedback 
)
inline

Publish feedback for an active goal.

Upstream spells it goal_handle->publish_feedback(std::shared_ptr<Feedback>). There is no goal handle here: the call is on the SERVER, keyed by goal id, and takes the feedback by const reference (no shared_ptr, no allocator).

Parameters
goal_id16-byte goal UUID from the goal callback.
feedbackFeedback to publish.
Returns
Result indicating success or failure.

◆ set_accepted_callback()

template<typename A >
template<typename F >
::rclcpp::Result rclcpp_action::Server< A >::set_accepted_callback ( F  f)
inline

Register a callback invoked once per ACCEPTED goal (issue 0796).

Fires after the accept reply has reached the client, for GoalResponse::ACCEPT_AND_EXECUTE and GoalResponse::ACCEPT_AND_DEFER alike. This is where a deferred goal starts executing: the goal callback answers accept/reject and must return promptly, so it is the wrong place to begin work.

Upstream's handle_accepted receives an owning std::shared_ptr<ServerGoalHandle>; this callback receives the 16-byte goal id instead, and the goal is driven through this server (publish_feedback, succeed, ...) because goals live in the server's static arena.

Mirrors C's rclc_accepted_callback_t (passed at rclc_action_server_init_with_callbacks) and Rust's third argument to create_action_server_with_callbacks(goal, cancel, accepted). Without it a C++ user who returned ACCEPT_AND_DEFER was never told the goal had been accepted.

F must be a stateless callable convertible to TypedAcceptedFn.

◆ set_accepted_callback_with_ctx()

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::set_accepted_callback_with_ctx ( TypedAcceptedFnWithCtx  f,
void *  ctx 
)
inline

Register an accepted-goal callback with a user context pointer.

Mirrors set_goal_callback_with_ctx. Mutually exclusive with set_accepted_callback().

◆ set_cancel_callback()

template<typename A >
template<typename F >
::rclcpp::Result rclcpp_action::Server< A >::set_cancel_callback ( F  f)
inline

Register a cancel callback.

F must be a stateless callable convertible to TypedCancelFn.

◆ set_cancel_callback_with_ctx()

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::set_cancel_callback_with_ctx ( TypedCancelFnWithCtx  f,
void *  ctx 
)
inline

Register a cancel callback with a user context pointer.

Mirrors set_goal_callback_with_ctx — the bare function pointer receives a void* alongside each UUID so stateful cancel policies don't need captured lambdas or global state. Mutually exclusive with set_cancel_callback().

◆ set_goal_callback()

template<typename A >
template<typename F >
::rclcpp::Result rclcpp_action::Server< A >::set_goal_callback ( F  f)
inline

Register a typed goal callback.

F must be a stateless callable that decays to TypedGoalFn (empty-capture lambda or plain function pointer). F must be a stateless callable convertible to TypedGoalFn (empty-capture lambda or plain function pointer).

◆ set_goal_callback_with_ctx()

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::set_goal_callback_with_ctx ( TypedGoalFnWithCtx  f,
void *  ctx 
)
inline

Register a typed goal callback with a user context pointer.

The bare function pointer is stored alongside a void* that is forwarded to every invocation — lets callers reach stateful objects without capturing lambdas or file-scope globals. Overrides and is overridden by set_goal_callback() (the two modes are mutually exclusive).

◆ succeed() [1/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::succeed ( const ::rclcpp_action::GoalUUID &  goal_id,
const ResultType &  result 
)
inline

succeed taking a GoalUUID value.

◆ succeed() [2/2]

template<typename A >
::rclcpp::Result rclcpp_action::Server< A >::succeed ( const uint8_t  goal_id[16],
const ResultType &  result 
)
inline

Terminate goal_id as SUCCEEDED — phase-417 W4.b.

C has rclc_action_succeed / _abort / _canceled, Rust has ActionServerHandle::succeed / abort / canceled, and every rclcpp_action server ends with goal_handle->succeed(result). C++ had only complete_goal, so the terminal line of a ported server was one nobody could keep. These three are FORWARDERS onto complete_goal: the goal state machine stays Rust-side (RFC-0019), and no state is added here.

complete_goal remains the general form for a status computed at runtime.

Upstream's is goal_handle->succeed(std::shared_ptr<Result>). Ours is on the server, keyed by goal id, result by const reference: there is no goal handle and no shared_ptr (goals live in the server's static arena).

Friends And Related Symbol Documentation

◆ ::rclcpp::Node

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

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