|
nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
|
Namespaces | |
| namespace | detail |
Classes | |
| class | Client |
| class | ClientGoalHandle |
| struct | GoalUUID |
| struct | SendGoalOptions |
| class | Server |
| class | ServerGoalHandle |
Enumerations | |
| enum class | CancelResponse : int8_t { REJECT = 1 , ACCEPT = 2 } |
| enum class | CancelReturnCode : int8_t { Ok = 0 , Rejected = 1 , UnknownGoal = 2 , GoalTerminated = 3 } |
| enum class | GoalResponse : int8_t { REJECT = 1 , ACCEPT_AND_EXECUTE = 2 , ACCEPT_AND_DEFER = 3 } |
| enum class | GoalStatus : int8_t { Unknown = 0 , Accepted = 1 , Executing = 2 , Canceling = 3 , Succeeded = 4 , Canceled = 5 , Aborted = 6 } |
| enum class | ResultCode : int8_t { UNKNOWN = 0 , SUCCEEDED = 4 , CANCELED = 5 , ABORTED = 6 } |
Functions | |
| template<typename T = void, typename... Args> | |
| void | async_cancel_all_goals (Args &&...) |
| REFUSED without std::promise — issue 2027. | |
| template<typename T = void, typename... Args> | |
| void | async_cancel_goal (Args &&...) |
| REFUSED without std::promise — issue 2027. | |
| template<typename T = void, typename... Args> | |
| void | async_cancel_goals_before (Args &&...) |
| REFUSED without std::promise — issue 2027. | |
| template<typename T = void, typename... Args> | |
| void | async_get_result (Args &&...) |
| template<typename T = void> | |
| ::rclcpp::Future< GoalAccept > | async_send_goal (const GoalType &, const SendGoalOptions &=SendGoalOptions()) |
| REFUSED on a freestanding build — issue 2015. | |
| ::rclcpp::Result | cancel_goal (const ::rclcpp_action::GoalUUID &goal_id) |
| cancel_goal taking a GoalUUID value (phase-417 W4.b). | |
| ::rclcpp::Result | cancel_goal (const uint8_t goal_id[16]) |
| Client () | |
| Client (Client &&other) | |
| ::rclcpp::Stream< FeedbackType > & | feedback_stream () |
| ::rclcpp::Result | get_result_async (const ::rclcpp_action::GoalUUID &goal_id) |
| get_result_async taking a GoalUUID value (phase-417 W4.b). | |
| ::rclcpp::Result | get_result_async (const uint8_t goal_id[16]) |
| ::rclcpp::Future< ResultType > | get_result_future (const ::rclcpp_action::GoalUUID &goal_id) |
| get_result_future taking a GoalUUID value (phase-417 W4.b). | |
| ::rclcpp::Future< ResultType > | get_result_future (const uint8_t goal_id[16]) |
| template<size_t Cap> | |
| ::rclcpp::Future< ResultType, Cap > | get_result_future_sized (const uint8_t goal_id[16]) |
| template<typename A> | |
| class rclcpp_action::Client | GOAL (issue 2011) |
| bool | is_valid () const |
| Check if the action client is initialized and valid. | |
| Client & | operator= (Client &&other) |
| void | poll () |
| ::rclcpp::Result | send_goal_async (const GoalType &goal, ::rclcpp_action::GoalUUID &goal_id) |
| ::rclcpp::Result | send_goal_async (const GoalType &goal, uint8_t goal_id[16]) |
| ::rclcpp::Result | set_callbacks (const SendGoalOptions &options) |
| constexpr int32_t | to_ffi (CancelResponse r) |
| constexpr int32_t | to_ffi (GoalResponse r) |
| ::rclcpp::Result | try_recv_cancel_response (::rclcpp_action::CancelReturnCode &out) |
| ::rclcpp::Result | try_recv_feedback (FeedbackType &feedback) |
| template<size_t Cap> | |
| ::rclcpp::Result | try_recv_feedback_sized (FeedbackType &feedback) |
| ~Client () | |
Variables | |
| static const size_t | ACTION_NAME_MAX = 256 |
| static const size_t | CANCEL_STASH_CAP = 4 |
| struct rclcpp_action::SendGoalOptions | GOAL |
| static const size_t | MAX_CANCEL_INFOS = 16 |
|
strong |
Per-goal cancel decision returned from the user's cancel callback.
Issue 0796 — this is NOT the action_msgs/srv/CancelGoal RPC status; that is CancelReturnCode below. The two carry different meanings on overlapping FFI values (reject and Ok are both 0 there), so never cast between them. C names them apart too (rclc_cancel_response_t vs rclc_cancel_return_code_t), and Rust now does (nros_core::CancelResponse vs nros_core::CancelReturnCode).
Upstream's enum, value for value: rclcpp_action::CancelResponse is int8_t with REJECT = 1, ACCEPT = 2, and so is this one (0-based and CamelCase until issue 1637). The FFI is 0-based (RCLC_CANCEL_REJECT = 0): convert with rclcpp_action::to_ffi(CancelResponse), never with a static_cast<int32_t>.
| Enumerator | |
|---|---|
| REJECT | |
| ACCEPT | |
|
strong |
action_msgs/srv/CancelGoal RPC return code — the WHOLE-REQUEST outcome (issue 0796).
Written by a polling-tier server into send_cancel_reply, and read by a client from ActionClient::try_recv_cancel_response. Distinct from the per-goal CancelResponse above; these four discriminants are the wire contract, fixed by action_msgs.
| Enumerator | |
|---|---|
| Ok | |
| Rejected | |
| UnknownGoal | |
| GoalTerminated | |
|
strong |
Goal acceptance response returned from the user's goal callback.
Upstream's enum, value for value: rclcpp_action::GoalResponse is int8_t with REJECT = 1, ACCEPT_AND_EXECUTE = 2, ACCEPT_AND_DEFER = 3, and so is this one, enumerator for enumerator, so a ported switch or a stored integer means the same thing on both. (Until issue 1637 these were 0-based and CamelCase: Reject = 0, AcceptAndExecute = 1, ...)
The FFI below is 0-based (RCLC_GOAL_REJECT = 0 in rclc/detail/nros_generated.h), because a zero-initialised decision slot must mean reject. That integer is not this enum: convert with rclcpp_action::to_ffi(GoalResponse), NEVER with a static_cast<int32_t> — the cast yields upstream's value, and the FFI reads REJECT (1) as accept-and-execute.
| Enumerator | |
|---|---|
| REJECT | |
| ACCEPT_AND_EXECUTE | |
| ACCEPT_AND_DEFER | |
|
strong |
|
strong |
rclcpp_action::ResultCode — issue 2015, upstream's client-side terminal code, value for value: int8_t, the action_msgs/msg/GoalStatus numbers of the three terminal states (and UNKNOWN). The same numbers as GoalStatus, so a status from the goal-id-keyed callbacks converts with a cast.
| Enumerator | |
|---|---|
| UNKNOWN | |
| SUCCEEDED | |
| CANCELED | |
| ABORTED | |
| void rclcpp_action::async_cancel_all_goals | ( | Args && | ... | ) |
REFUSED without std::promise — issue 2027.
| void rclcpp_action::async_cancel_goal | ( | Args && | ... | ) |
REFUSED without std::promise — issue 2027.
| void rclcpp_action::async_cancel_goals_before | ( | Args && | ... | ) |
REFUSED without std::promise — issue 2027.
| void rclcpp_action::async_get_result | ( | Args && | ... | ) |
REFUSED without std::promise — issue 2027: a freestanding build, or a hosted libstdc++ built without threads (the arm-none-eabi and RTOS toolchains declare std::promise and never define it). The goal-id-keyed forms are get_result_future and cancel_goal + try_recv_cancel_response.
| ::rclcpp::Future< GoalAccept > rclcpp_action::async_send_goal | ( | const GoalType & | , |
| const SendGoalOptions & | = SendGoalOptions() ) |
REFUSED on a freestanding build — issue 2015.
| ::rclcpp::Result rclcpp_action::cancel_goal | ( | const ::rclcpp_action::GoalUUID & | goal_id | ) |
cancel_goal taking a GoalUUID value (phase-417 W4.b).
| ::rclcpp::Result rclcpp_action::cancel_goal | ( | const uint8_t | goal_id[16] | ) |
Cancel a goal (non-blocking) — issue 0796.
Sends the action_msgs/srv/CancelGoal request and returns; read the RPC outcome with try_recv_cancel_response() once the executor has spun. Mirrors C's rclc_action_cancel_goal and Rust's ActionClient::cancel_goal — rclcpp_action's async_cancel_goal returns a future, which RFC-0021 has no runtime to await.
Until this existed, a C++ application written against the CALLBACK tier could start a goal and had no way to stop it: cancel was only on the L1 PollingActionClient::send_cancel_request.
| goal_id | 16-byte goal UUID from send_goal() / send_goal_async(). |
| rclcpp_action::Client | ( | ) |
Default constructor — creates an uninitialized action client. Use Node::create_action_client() to initialize.
| rclcpp_action::Client | ( | Client && | other | ) |
| const::rclcpp::Stream< FeedbackType > & rclcpp_action::feedback_stream | ( | ) |
Get a reference to the action client's feedback stream.
The stream yields FeedbackType values across all currently-active goals for this client — feedback is not goal-scoped at this layer. It holds the LATEST feedback per client (issue 2011: it used to be one slot for every action client in the process); an unread one is overwritten. Callers that need per-goal separation should use the callback API (set_callbacks(SendGoalOptions{ .feedback = … })), which delivers (goal_id, bytes, len, ctx) via an executor-driven trampoline.
Usage (blocking):
Usage (non-blocking):
| ::rclcpp::Result rclcpp_action::get_result_async | ( | const ::rclcpp_action::GoalUUID & | goal_id | ) |
get_result_async taking a GoalUUID value (phase-417 W4.b).
| ::rclcpp::Result rclcpp_action::get_result_async | ( | const uint8_t | goal_id[16] | ) |
Request the result for a goal asynchronously (non-blocking).
Returns immediately after sending the get_result request. The result arrives via the result callback during poll().
| goal_id | 16-byte goal UUID from send_goal_async(). |
| ::rclcpp::Future< ResultType > rclcpp_action::get_result_future | ( | const ::rclcpp_action::GoalUUID & | goal_id | ) |
get_result_future taking a GoalUUID value (phase-417 W4.b).
| ::rclcpp::Future< ResultType > rclcpp_action::get_result_future | ( | const uint8_t | goal_id[16] | ) |
Request a goal result and return a Future for the result.
Sends the get_result request asynchronously and returns a Future that resolves when the result arrives. Poll the future (or call wait()) to retrieve the deserialized result.
Usage:
Keyed by goal_id (issue 2011): the future receives that goal's result and no other, whichever client or future polls first. A result for a goal no future waits on – including one whose future was cancelled or destroyed first – is dropped (the client's result callback still sees it). Several futures for one goal each receive its result, one reply apiece.
| goal_id | 16-byte goal UUID from send_goal() or GoalAccept. |
| ::rclcpp::Future< ResultType, Cap > rclcpp_action::get_result_future_sized | ( | const uint8_t | goal_id[16] | ) |
get_result_future with the RESULT buffer sized by the caller.
A Future<T> holds its receive buffer as a member, so the capacity is a class template argument: this returns Future<ResultType, Cap> (issue 0964).
| class rclcpp_action::Client rclcpp_action::GOAL | ( | issue | 2011 | ) |
| bool rclcpp_action::is_valid | ( | ) | const |
Check if the action client is initialized and valid.
| void rclcpp_action::poll | ( | ) |
Poll for pending async replies (non-blocking).
Checks for goal acceptance, feedback, and result replies. Invokes the corresponding callbacks registered via set_callbacks(). Call this in the spin loop after spin_once().
| ::rclcpp::Result rclcpp_action::send_goal_async | ( | const GoalType & | goal, |
| ::rclcpp_action::GoalUUID & | goal_id ) |
send_goal_async writing the generated id into a GoalUUID value (phase-417 W4.b).
| ::rclcpp::Result rclcpp_action::send_goal_async | ( | const GoalType & | goal, |
| uint8_t | goal_id[16] ) |
Send a goal asynchronously (non-blocking).
Returns immediately after sending the goal request. The goal UUID is filled on success. Responses arrive via callbacks registered with the executor (see SendGoalOptions and Node::create_action_client).
| goal | Goal to send. |
| goal_id | Output 16-byte goal UUID (filled on success). |
| ::rclcpp::Result rclcpp_action::set_callbacks | ( | const SendGoalOptions & | options | ) |
Register async callbacks for goal response, feedback, and result.
Binds the callbacks to the CLIENT, not to one goal: rclcpp passes a SendGoalOptions to each async_send_goal, while here they are installed once and serve every goal this client sends (RFC-0041: callbacks bind to the entity). The pointers are read when a reply is DISPATCHED, so install them before the spin that delivers the reply — before or after send_goal_async both work.
| options | Callback pointers and context. |
|
constexpr |
The FFI discriminant of a cancel decision — RCLC_CANCEL_REJECT (0), RCLC_CANCEL_ACCEPT (1). Anything but ACCEPT maps to reject.
|
constexpr |
The FFI discriminant of a goal decision — RCLC_GOAL_REJECT (0), RCLC_GOAL_ACCEPT_AND_EXECUTE (1), RCLC_GOAL_ACCEPT_AND_DEFER (2). This is the value a raw component callback (create_action_server_raw) returns. Anything outside upstream's three values maps to reject, the FFI's own answer for "nobody decided".
| ::rclcpp::Result rclcpp_action::try_recv_cancel_response | ( | ::rclcpp_action::CancelReturnCode & | out | ) |
Try to read the reply to a cancel_goal() (non-blocking).
Issue 2034 — the executor's spin takes every cancel reply (which frees its request's slot) and keeps the ones no async_cancel_* future or callback claimed, oldest first; this reads those, then a reply nothing has taken yet. At most CANCEL_STASH_CAP are kept: a reply nobody reads past that evicts the oldest.
| out | Receives the RPC return code on success. |
| ::rclcpp::Result rclcpp_action::try_recv_feedback | ( | FeedbackType & | feedback | ) |
Try to receive feedback (non-blocking).
| feedback | Output feedback struct (filled on success). |
| ::rclcpp::Result rclcpp_action::try_recv_feedback_sized | ( | FeedbackType & | feedback | ) |
try_recv_feedback with the receive buffer sized by the CALLER. See Subscription::try_recv_sized (issue 0964).
| rclcpp_action::~Client | ( | ) |
Destructor — RELEASES the arena entry (issue 1496).
The ActionClientCore with its three service clients and its feedback subscription lives in an ActionClientRawArenaEntry in the executor arena, whose callback context is storage_. nros_cpp_action_client_destroy (which needs no extra argument: CppActionClient keeps its own executor pointer and entry index) drops that entry in place — the entities are destroyed, so no late reply can read this storage — frees its callback slot and returns its arena bytes for reuse, so a create/destroy loop does not exhaust the executor.
Issue 2011 – a future still pending on this client becomes invalid (valid() false) instead of pointing at freed storage.
|
static |
Bound on the action name an action entity remembers for get_action_name() — phase-417 W4.b.
ONE spelling for all four action classes. PollingActionServer and PollingActionClient each defined their own ACTION_NAME_MAX = 256 and the two callback tiers had neither, which is how the accessor came to exist on half the C++ action surface (ledger rows c:action_{client,server}_get_action_name, "four surfaces, one accessor"). Sized to match rclcpp::SUBSCRIPTION_TOPIC_NAME_MAX and the C surface's MAX_ACTION_NAME_LEN, so a name that fits one entity fits all of them and a truncation is not a per-class surprise.
|
static |
Issue 2034 — how many cancel return codes a client keeps for try_recv_cancel_response once the executor's spin has taken their replies and no async_cancel_* future or callback claimed them. The number of cancels one client can have in flight (MAX_CONCURRENT_GOALS); a further unread reply evicts the OLDEST kept one.
| struct rclcpp_action::SendGoalOptions rclcpp_action::GOAL |
|
static |
Issue 2027 — how many goals_canceling entries a cancel response passed to an async_cancel_* future carries; a reply listing more keeps its first this many. Four times the goals a server holds at once (MAX_CONCURRENT_GOALS).