nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
Namespaces | Classes | Typedefs | Enumerations | Functions | Variables
rclcpp Namespace Reference

Namespaces

namespace  detail
 

Classes

class  Client
 
class  ClientHandle
 
class  ClockQoS
 rclcpp::ClockQoS — KEEP_LAST(1), BEST_EFFORT, VOLATILE. ADOPT. More...
 
class  Executor
 
struct  FixedSequence
 
struct  FixedString
 
struct  format_of
 
class  Future
 
class  GuardCondition
 
struct  LeSpan
 
class  Node
 
class  NodeBuilder
 
struct  NodeHandle
 
class  NodeWithTimers
 
class  OnShutdownCallbackHandle
 
class  ParameterEventsQoS
 
class  ParametersQoS
 
class  PollClient
 
class  PollingActionClient
 
class  PollingActionServer
 
class  PollingSubscription
 
class  PollService
 
class  PollSubscription
 
class  PreShutdownCallbackHandle
 
class  Publisher
 
class  QoS
 
class  Rate
 
class  ResultOf
 
class  ResultOf< void >
 
class  RosoutQoS
 
class  SensorDataQoS
 rmw_qos_profile_sensor_data — KEEP_LAST(5), BEST_EFFORT, VOLATILE. ADOPT. More...
 
class  Service
 
class  ServicesQoS
 
class  ShutdownCallbackHandle
 
struct  Span
 
class  Stream
 
struct  StringView
 
class  Subscription
 
class  SystemDefaultsQoS
 
class  Timer
 
class  TimerHandle
 
class  TimerOps
 

Typedefs

using IntegrityStatus = ::nros_cpp_integrity_status_t
 
using Result = ResultOf< void >
 
using ShutdownCallback = void(*)(void *context)
 
using WallRate = Rate
 

Enumerations

enum class  DurabilityPolicy : int { Volatile = 0 , TransientLocal = 1 , SystemDefault = 2 , Unknown = 3 }
 Durability policy. Matches DDS DURABILITY_QOS_POLICY. More...
 
enum class  ErrorCode : int32_t {
  Ok = 0 , Error = -1 , Timeout = -2 , InvalidArgument = -3 ,
  NotFound = -4 , AlreadyExists = -5 , Full = -6 , NotInitialized = -7 ,
  BadSequence = -8 , ServiceFailed = -9 , PublishFailed = -10 , SubscriptionFailed = -11 ,
  NotAllowed = -12 , Rejected = -13 , TryAgain = -14 , Reentrant = -15 ,
  Unsupported = -16 , TransportError = -100
}
 
enum class  FutureReturnCode { SUCCESS , TIMEOUT , INTERRUPTED }
 
enum class  HistoryPolicy : int { KeepLast = 0 , KeepAll = 1 , SystemDefault = 2 , Unknown = 3 }
 History policy. Matches DDS HISTORY_QOS_POLICY. More...
 
enum class  LivelinessPolicy : int {
  SystemDefault = 0 , Automatic = 1 , ManualByTopic = 2 , ManualByNode = 3 ,
  Unknown = 4
}
 
enum class  ReliabilityPolicy : int { Reliable = 0 , BestEffort = 1 , SystemDefault = 2 , Unknown = 3 }
 
enum class  SerializationFormat : uint8_t { Cdr = 1 , Uorb = 2 }
 

Functions

void arm_monitors ()
 
Result create_node (::rclcpp::Node &out, const char *name, const char *ns)
 
Result create_node_on (::rclcpp::Node &out, void *executor_handle, const char *name, const char *ns)
 
template<typename NodeT , typename CallbackT >
inline ::rclcpp::TimerHandle create_timer (NodeT &&node, ::rclcpp::Clock *clock, ::rclcpp::Duration period, CallbackT &&callback)
 
void * global_handle ()
 
void init ()
 rclcpp::init() — the zero-argument form. ADOPT.
 
void init (int argc, char const *const *argv)
 
Result init_in (const char *locator, uint8_t domain_id, const char *session_name)
 
Result init_in (const char *locator, uint8_t domain_id, const char *session_name, const char *node_namespace)
 
Result init_in (const char *locator=nullptr, uint8_t domain_id=0)
 
Result init_in (int argc, char const *const *argv, const char *session_name=nullptr)
 
Result init_with_rmw (const char *rmw, const char *locator=nullptr, uint8_t domain_id=0, const char *session_name="node")
 
constexpr QoS KeepAll ()
 rclcpp::KeepAll(). Same ADOPT-BOUNDED note as KeepLast.
 
constexpr QoS KeepLast (::size_t depth)
 
constexpr SerializationFormat linked_format ()
 
constexpr const char * linked_format_name ()
 
ResultOf<::rclcpp::Node > make_node (const char *name, const char *ns=nullptr)
 
bool ok ()
 
Result on_shutdown (ShutdownCallback callback, void *context=nullptr, OnShutdownCallbackHandle *out=nullptr)
 
constexpr bool operator!= (const QoS &left, const QoS &right)
 
constexpr bool operator== (const QoS &left, const QoS &right)
 
Result pre_shutdown (ShutdownCallback callback, void *context=nullptr, PreShutdownCallbackHandle *out=nullptr)
 
const char * qos_policy_kind_to_cstr (uint32_t policy)
 
const char * rclc_qos_policy_kind_to_cstr (uint32_t policy)
 
bool remove_on_shutdown_callback (OnShutdownCallbackHandle handle)
 
bool remove_pre_shutdown_callback (PreShutdownCallbackHandle handle)
 
bool shutdown ()
 
Result shutdown_in ()
 
void spin (const Node::SharedPtr &node)
 
Result spin_in ()
 
Result spin_in (uint32_t duration_ms, int32_t poll_ms=10)
 
Result spin_once (int32_t timeout_ms=10)
 
void spin_some (const Node::SharedPtr &node)
 
template<typename Future >
FutureReturnCode spin_until_future_complete (const Node::SharedPtr &node, const Future &future, int32_t timeout_ms=-1)
 

Variables

constexpr uint8_t kDomainIdExplicitZero = 255
 
static constexpr size_t PUBLISHER_TOPIC_NAME_MAX = 256
 
static constexpr size_t SUBSCRIPTION_TOPIC_NAME_MAX = 256
 

Detailed Description

rclcpp::Node::declare_parameter<T>(name, default) — declare, then read back, returning the value in effect.

Re-declaring is not an error: a launch-seeded parameter is DECLARED before user code runs, and upstream's contract is that declare adopts the override. That adoption is now the store's own ALREADY_EXISTS answer followed by the read-back below, rather than a helper that copied a value between two stores. On any other failure the code default is returned.

rclcpp::Node is named by the friend declaration below and by the out-of-line Node::create_* bodies further down. rclcpp/node.hpp (included below, after the class, so a consumer pays only for the entities it uses) has the definition; a qualified friend needs the name to EXIST first, which an unqualified friend class Node; used to supply implicitly.

phase-427 W7 — declared in rclcpp::, which is where the definition lives.

Typedef Documentation

◆ IntegrityStatus

using rclcpp::IntegrityStatus = typedef ::nros_cpp_integrity_status_t

E2E message-integrity status of one received sample (issue 0073): the sequence gap since the previous in-order sample, duplicate, and crc_valid (1 ok, 0 mismatch, -1 no CRC on the wire). The C++ spelling of the FFI struct (RFC-0089, 2026-10-13: ours-only names take rclcpp::), a typedef rather than a mirror so the two can never drift.

◆ Result

The name every caller writes for the value-less case, and the name this header's macros expand to.

◆ ShutdownCallback

Signature of a shutdown callback: void callback(void* context).

rclcpp takes std::function<void()>, which is a heap allocation per registration and needs the STL. This is freestanding C++ with no allocator, so the callback is a plain function pointer plus an opaque context the callee casts back to its own state — the same shape every other callback in this API uses. Capture what you need in a struct and pass its address.

◆ WallRate

rclcpp::WallRate — the steady-clock rate. Identical to Rate here; see the "same clock" bullet in the envelope above.

Enumeration Type Documentation

◆ DurabilityPolicy

Durability policy. Matches DDS DURABILITY_QOS_POLICY.

Enumerator
Volatile 
TransientLocal 
SystemDefault 

Nobody stated a durability policy — the middleware chose.

Unknown 

The backend could not determine this policy. An ABSENCE.

◆ ErrorCode

Error codes returned by nros-cpp functions.

Values match the C nros_cpp_ret_t enum in <nros/nros_cpp_generated.h>. Issue #229 — value-identical to the C NROS_RET_* codes AND the NROS_CPP_RET_* FFI codes (one numbering across all three spaces), so Result(<any C-ABI return>) is correct by identity. The static_assert pin tables below and in parameter.hpp fail the build on re-divergence.

Enumerator
Ok 

Success.

Error 

Generic failure not covered by a more specific code.

Timeout 

Operation deadline elapsed before completion.

InvalidArgument 

Null pointer, empty topic name, or out-of-range value.

NotFound 

Entity not found (topic, parameter, service…).

AlreadyExists 

Already exists (duplicate declare/register).

Full 

Static pool exhausted (executor slots, subscription buffers, …).

NotInitialized 

rclcpp::init() was never called or the entity is in a default state. See is_valid() on entity classes.

BadSequence 

Operation invalid in the current state (bad call sequence).

ServiceFailed 

Service request/reply failed.

PublishFailed 

Publish failed.

SubscriptionFailed 

Subscription create/take failed.

NotAllowed 

Operation not allowed for this entity/backend.

Rejected 

Request was rejected — the peer considered it and declined. A goal rejected by an action server, or a QoS/ABI incompatibility. Distinct from Error, which means the request never got that far (issue 0868).

TryAgain 

Transient — no data ready yet (non-blocking take). Retry later.

Reentrant 

A blocking call was made from inside a callback.

Unsupported 

Operation not implemented by the active backend.

TransportError 

Underlying zenoh-pico / DDS transport rejected the operation.

◆ FutureReturnCode

Mirror of rclcpp::FutureReturnCode (issue 0339).

spin_until_future_complete used to return void, so a caller could not tell success from timeout and the standard idiom

Definition client.hpp:129
FutureReturnCode spin_until_future_complete(const Node::SharedPtr &node, const Future &future, int32_t timeout_ms=-1)
Definition rclcpp.hpp:886

could not be written against the shim at all.

Enumerator
SUCCESS 
TIMEOUT 

The deadline passed with the future still pending.

INTERRUPTED 

rclcpp::ok() went false (shutdown) before the future was ready.

◆ HistoryPolicy

History policy. Matches DDS HISTORY_QOS_POLICY.

Enumerator
KeepLast 
KeepAll 
SystemDefault 

Nobody stated a history policy — the middleware chose.

Unknown 

The backend could not determine this policy. An ABSENCE.

◆ LivelinessPolicy

Liveliness policy kind. Matches DDS LIVELINESS_QOS_POLICY.

SystemDefault is discriminant 0, the value rmw gives RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT; this enumerator was spelled LivelinessNone before phase-483. ManualByNode is ours-only — rmw deprecated it, so rclcpp's LivelinessPolicy does not list it.

Enumerator
SystemDefault 
Automatic 
ManualByTopic 
ManualByNode 
Unknown 

The backend could not determine this policy. An ABSENCE, reportable by get_actual_qos() and never a value to request.

◆ ReliabilityPolicy

Reliability policy. Matches DDS RELIABILITY_QOS_POLICY and rclcpp::ReliabilityPolicy.

enum class, as upstream's is (phase-483 W1). These were unscoped while they lived in nros::; in rclcpp:: an unscoped KeepLast enumerator would collide with upstream's rclcpp::KeepLast profile helper.

Enumerator
Reliable 
BestEffort 
SystemDefault 

Nobody stated a reliability policy — the middleware chose. Reportable by get_actual_qos(); not a value to request.

Unknown 

The backend could not determine this policy. An ABSENCE.

◆ SerializationFormat

The serialization formats this image can name.

RFC-0088 D2 — the discriminant is image-local. It is assigned per build from the formats declared in that image; the low values below are reserved for the in-tree formats for readability and nothing more. Never persist one, and never compare one against a value another image produced — the string (linked_format_name()) is the identity that crosses an image boundary.

Enumerator
Cdr 

OMG CDR as ROS 2 puts it on the wire, encapsulation header included.

Uorb 

PX4's in-memory struct, verbatim — no encoding step at all (RFC-0011).

Function Documentation

◆ arm_monitors()

void rclcpp::arm_monitors ( )
inline

phase-474 I2 – the application's start-up is over: arm the contract monitors of every executor that waits for this (CONFIG_NROS_MONITOR_ARM_ON_CALL). Call it where the application enters its running state, e.g. an INIT/RUN state machine's RUN transition.

Safe from any thread and from inside a callback (it bumps one atomic; each executor arms at its next spin). Before arming a verdict is counted (suppressed_before_arm) but not stored, logged or traced. Does nothing on an image whose monitors arm at the first spin, which is the default.

◆ create_node()

Result rclcpp::create_node ( ::rclcpp::Node &  out,
const char *  name,
const char *  ns = nullptr 
)
inline

Create a node (convenience — uses the global executor).

This is the primary way to create nodes after calling rclcpp::init().

Parameters
outReceives the initialized node.
nameNode name.
nsNode namespace; nullptr or "" = unset (inherit the executor's), "/" = the root. See rclcpp::Node::create (issue 1473).

◆ create_node_on()

Result rclcpp::create_node_on ( ::rclcpp::Node &  out,
void *  executor_handle,
const char *  name,
const char *  ns = nullptr 
)
inline

Phase 274.W2 — create a node on an explicit executor handle.

Used by per-tier setup functions (emitted by nros codegen entry --lang cpp for multi-tier workspaces) where each tier's setup runs on the tier's borrowed executor, not the global one. The executor handle is the void* passed to the tier's setup(void* executor) callback.

Parameters
outReceives the initialized node.
executor_handleExplicit executor handle (from a tier setup param).
nameNode name.
nsNode namespace; nullptr or "" = unset (inherit the executor's), "/" = the root (issue 1473).

◆ create_timer()

inline ::rclcpp::TimerHandle rclcpp::create_timer ( NodeT &&  node,
::rclcpp::Clock *  clock,
::rclcpp::Duration  period,
CallbackT &&  callback 
)

rclcpp::create_timer(node, clock, period, callback) — humble's only clock-taking timer verb. FREESTANDING since phase-476 W2.

ADOPT-BOUNDED: the clock is rclcpp::Clock* (what node->get_clock() returns), not rclcpp::Clock::SharedPtr; the period is truncated to whole MILLISECONDS; Humble's optional trailing group argument is not taken; and the result is a rclcpp::TimerHandle (rclcpp::TimerBase::SharedPtr names the same type).

◆ global_handle()

void * rclcpp::global_handle ( )
inline

Get the global executor handle for Future::wait().

Returns the raw storage pointer used by the global init()/spin_once() free functions. Use with Future::wait(rclcpp::global_handle(), ...).

Returns
Executor handle, or nullptr if not initialized.

DEFINED in <rclcpp/node.hpp>, beside the free functions Node befriends: rclcpp::init_in(argc, argv) (node.hpp) calls it, and an inline function used in a TU that never sees its definition is a link error waiting for the first caller (issue 1682's branch, found by -Wall).

◆ init() [1/2]

void rclcpp::init ( )
inline

rclcpp::init() — the zero-argument form. ADOPT.

◆ init() [2/2]

void rclcpp::init ( int  argc,
char const *const *  argv 
)
inline

rclcpp::init(argc, argv) — ADOPT-BOUNDED: --ros-args -r is honoured, every other ROS argument ABORTS the process naming it.

argv is parsed with rcl's grammar by the same code as Rust's nros::Context::new (nros_node::ros_args, reached through nros_cpp_install_argv_remaps):

  • -r / --remap [node:]from:=to inside --ros-args ... -- — HONOURED, as the FALLBACK beneath any remap the launch file projected for the same name (the generated entry's nros_cpp_declare_remap calls). That is rcl's own local-before-global order (rcl_remap_topic_name).
  • -p / --param / --params-file, __node / __name / __ns, -e / --enclave, the log flags, any unknown token — REFUSED. Runtime parameters belong to RFC-0015 section 9's channel; node identity is launch-authoritative (RFC-0046). rclcpp throws UnknownROSArgsError for what rcl leaves unparsed, so refusing is the upstream behaviour too.
  • no --ros-args → identical to rclcpp::init().

Why a refusal ABORTS rather than returns. Upstream's init returns void and a ported main does not check it, so this call site has nowhere to put a failure, and continuing is the one outcome RFC-0089 forbids: a -p that compiles and is silently dropped. The vector is validated BEFORE the session opens. rclcpp::init_in(argc, argv) honours the same arguments and RETURNS the refusal as a Result, for a caller that wants to handle it.

◆ init_in() [1/4]

Result rclcpp::init_in ( const char *  locator,
uint8_t  domain_id,
const char *  session_name 
)
inline

Initialize the nros session with an explicit session name.

session_name is the process-wide identifier used by the XRCE-DDS RMW backend to derive a unique session key. Two processes connecting to the same XRCE Agent MUST use distinct session names — otherwise the agent treats them as the same client and topic publishes don't cross-route. For zenoh / DDS backends the value is informational only.

Pick a name that's stable for the process and distinct from every other nros process you intend to share an agent with. Typical choice: the process's primary node name (e.g. "talker", "listener").

Parameters
locatorMiddleware locator, or nullptr for default.
domain_idROS domain ID (0-232); 0 = unset, rclcpp::kDomainIdExplicitZero = explicit domain 0.
session_namePer-process session identifier. Must not be nullptr.
Returns
Result indicating success or failure.

◆ init_in() [2/4]

Result rclcpp::init_in ( const char *  locator,
uint8_t  domain_id,
const char *  session_name,
const char *  node_namespace 
)
inline

Issue 1434 — [init] with the primary session's NAMESPACE.

nros_cpp_init has always taken a namespace; no rclcpp::init overload had one, so every C++ entry passed nullptr and a launch-declared namespace reached the blob and stopped there. This is the overload the generated entry's run_components call reaches, with nros_boot_config_namespace(&NROS_BOOT_CONFIG).

node_namespace is the BAKED rung of RFC-0045's precedence model A, exactly like session_name beside it: on a hosted target $NROS_NODE_NAMESPACE still wins. nullptr means the image declares none — NOT the empty namespace — and resolves to the root the same way the 3-arg overload does today. Passing "" is the same statement, because an empty C string cannot be told apart from "unset" at this edge.

Additive rather than a fourth parameter on the 3-arg overload: that one is called by user code and by every board adapter in <rclcpp/detail/main.hpp>, and a defaulted parameter would make the two declarations ambiguous.

◆ init_in() [3/4]

Result rclcpp::init_in ( const char *  locator = nullptr,
uint8_t  domain_id = 0 
)
inline

Initialize an nros session.

Opens a middleware connection. Must be called before creating nodes. Call shutdown() to clean up.

Parameters
locatorMiddleware locator (e.g., "tcp/127.0.0.1:7447"), or nullptr for default.
domain_idROS domain ID (0-232). 0 = unset (env > baked macro > default decide); rclcpp::kDomainIdExplicitZero (255) = explicitly domain 0 (issue #227).
Returns
Result indicating success or failure.

◆ init_in() [4/4]

Result rclcpp::init_in ( int  argc,
char const *const *  argv,
const char *  session_name = nullptr 
)
inline

Initialize an nros session, honouring --ros-args — the Result-returning twin of rclcpp::init(argc, argv), which has nowhere to put a refusal and aborts instead.

Reads the domain id, locator and RMW choice from the environment (ROS_DOMAIN_ID, NROS_LOCATOR, RMW_IMPLEMENTATION / NROS_RMW), as the 2-arg init_in does. No launch file is read here: a launch tree reaches an image at BUILD time — nros sync resolves it into the SystemModel and the generated entry (nano_ros_entry(... LAUNCH ...)) installs its node identities, remaps and parameters.

argc / argv are parsed as --ros-args with rcl's grammar, exactly as Rust's nros::Context::new does: -r/--remap rules are installed as the FALLBACK beneath the launch rules the generated entry declares; -p and --params-file are installed as parameter overrides when the image has a parameter store (phase-482 W5); and any other ROS argument (__node, --log-level, an unknown token, or -p with no store) makes this return ErrorCode::InvalidArgument BEFORE a session opens, naming the token. (0, nullptr) — what every RTOS board passes — is a no-op.

session_name falls back to "nros_cpp" when null (matches the 2-arg init_in overload).

◆ init_with_rmw()

Result rclcpp::init_with_rmw ( const char *  rmw,
const char *  locator = nullptr,
uint8_t  domain_id = 0,
const char *  session_name = "node" 
)
inline

Issue 1050 defect (3) — init with an explicit RMW backend name.

rmw is the BAKED rung of RFC-0045's precedence model A: a hosted $NROS_RMW still wins over it, and nullptr (or "") means "this image names no backend", which resolves only when exactly one is registered.

Use it when the image knows which backend it wants and the registry cannot be trusted to contain only that one. On a hosted target it cannot: a Rust backend compiled into libnros_cpp.a registers from its .init_array ctor, which runs BEFORE main and therefore before the generated nros_app_register_backends() — so an archive carrying a backend the image never declared registers first. That is how a PX4 module declaring BACKENDS uorb came to open zenoh.

The plain init overloads reach this automatically when the build bakes NROS_ENTRY_RMW (nano_ros_entry(... RMW <name>)); call it directly only to choose at run time.

◆ KeepAll()

constexpr QoS rclcpp::KeepAll ( )
constexpr

rclcpp::KeepAll(). Same ADOPT-BOUNDED note as KeepLast.

◆ KeepLast()

constexpr QoS rclcpp::KeepLast ( ::size_t  depth)
constexpr

rclcpp::KeepLast(depth).

ADOPT-BOUNDED: upstream returns a QoSInitialization — a history/depth pair a QoS is then built from — and this returns a whole QoS carrying the default reliability and durability. The porting spellings that matter, rclcpp::QoS(rclcpp::KeepLast(10)) and passing it straight to create_publisher, both resolve to the same profile either way. What does NOT carry over is using it as an initialiser for a profile whose other policies you meant to keep — rclcpp::SensorDataQoS(rclcpp::KeepLast(1)) has no equivalent here; write rclcpp::QoS().best_effort().keep_last(1).

◆ linked_format()

constexpr SerializationFormat rclcpp::linked_format ( )
constexpr

The format the backend this image links speaks.

Only meaningful in a single-backend image. A bridge image links two backends and has no single answer; it asks per session instead, with rclcpp::Node::serialization_format(). check-format-macro-scope refuses a bridge-linked translation unit that reaches the underlying macro.

◆ linked_format_name()

constexpr const char * rclcpp::linked_format_name ( )
constexpr

The cross-image identity string of linked_format() (RFC-0088 D2).

const char*, so the header stays usable against Zephyr's minimal libcpp. Derived from the discriminant rather than emitted beside it: cbindgen maps no Rust &str to a C constant, so a second generated macro would be a second authored spelling with nothing tying the two together.

◆ make_node()

ResultOf<::rclcpp::Node > rclcpp::make_node ( const char *  name,
const char *  ns = nullptr 
)
inline

Phase 123.B.4 — value-returning factory. Wraps create_node in the ResultOf<Node> envelope so users can write auto n = rclcpp::make_node("foo"); in the rclcpp-style.

◆ ok()

bool rclcpp::ok ( )
inline

Check if the nros session is initialized — and, like rclcpp::ok(), not asked to stop: issue 1732 folds in a guarded SIGTERM / SIGINT, so every while (rclcpp::ok()) loop returns and its rclcpp::shutdown() closes the session. The flag is only ever set where a hosted runner installed the guard (nros_cpp_termination_guard_install).

◆ on_shutdown()

Result rclcpp::on_shutdown ( ShutdownCallback  callback,
void *  context = nullptr,
OnShutdownCallbackHandle *  out = nullptr 
)
inline

Register a callback to run AFTER the global session's entities are torn down — rclcpp::on_shutdown. Issue 0790.

The entities are gone by the time it runs; use [pre_shutdown] for anything that needs the wire.

See also
pre_shutdown for the parameter and error contract.

◆ operator!=()

constexpr bool rclcpp::operator!= ( const QoS &  left,
const QoS &  right 
)
constexpr

The negation of operator==, and written as its negation so the two cannot disagree.

◆ operator==()

constexpr bool rclcpp::operator== ( const QoS &  left,
const QoS &  right 
)
constexpr

true when both profiles state the same value for every policy.

A WHOLE-PROFILE comparison, which is upstream's: two profiles that would be granted the same thing by a backend still compare unequal if they were written differently, because this compares what was REQUESTED.

◆ pre_shutdown()

Result rclcpp::pre_shutdown ( ShutdownCallback  callback,
void *  context = nullptr,
PreShutdownCallbackHandle *  out = nullptr 
)
inline

Register a callback to run BEFORE the global session's entities are torn down — issue 0790.

rclcpp hangs the shutdown hooks on Context, which nano-ros does not have (phase-379's init stage records the collapse into one support object), so they live on the executor — here, the global one rclcpp::init() opened and rclcpp::shutdown() closes.

This is the phase with no workaround: the callback runs while every entity still works, so a node can publish a final state, answer a last request, park an actuator or release a bus. rclcpp::on_shutdown below runs after teardown, when none of that is possible any more.

A CLEAN-STOP facility: a watchdog reset, a hard fault or an abort does not come through rclcpp::shutdown(), so it does not come through here either.

Parameters
callbackFunction to invoke. Must not be null.
contextOpaque pointer handed back to callback. Must stay valid until the callback runs or is removed.
outReceives the removal handle. Optional.

◆ qos_policy_kind_to_cstr()

const char * rclcpp::qos_policy_kind_to_cstr ( uint32_t  policy)
inline

rclcpp::qos_policy_kind_to_cstr — see the entry point above, which it forwards to unchanged.

◆ rclc_qos_policy_kind_to_cstr()

const char * rclcpp::rclc_qos_policy_kind_to_cstr ( uint32_t  policy)

One QoS policy's name — rclcpp::qos_policy_kind_to_cstr.

Parameters
policyONE NROS_RMW_QOS_POLICY_* bit, as declared in <nros/rmw_entity.h> and as a backend advertises through the vtable's supported_qos_policies slot.
Returns
"RELIABILITY", "DEADLINE", … — borrowed, static lifetime, never freed — or nullptr when policy is not exactly one policy bit.

What this is FOR. An NROS_CPP_RET_NOT_ALLOWED from a create_* means the backend declined a policy, and the return code alone does not say which — while rmw_vtable.h's own supported_qos_policies block told the reader those creates fail "naming a policy". The refusal is logged with this name now (nros_node's validate_qos_or_report), and this is how a C++ caller spells the same policy in its own message.

Two deliberate differences from rclcpp, both from the same constraint: upstream takes a rclcpp::QosPolicyKind enum and returns a const char* over std::string-free storage; ours takes the MASK BIT, because the bitmask is the vocabulary this tree has — one set of twelve values shared by QoSPolicyMask in Rust and NROS_RMW_QOS_POLICY_* in C, held equal by check-qos-mask-derivation. And upstream returns "Invalid" for its invalid enumerator where we return nullptr: we have no invalid enumerator, and "no policy was identified" is a real answer a caller must be able to tell apart from a policy that was.

The bytes are rclc_qos_policy_kind_to_cstr's, which are nros_rmw::QoSPolicyMask::NAMED's. This header declares the C entry point rather than including <rclc/detail/nros_generated.h> — qos.hpp is deliberately self-contained (see issue 0112 at the top of this file) — and a signature drift cannot hide: nros.hpp pulls both this header and rclc/types.h, which reaches the generated declarations, so every C++ example is a translation unit holding both spellings and the compiler compares them. The declaration is spelled EXACTLY as nros_generated.h spells it, NROS_PUBLIC included. A C-linkage function declared in two scopes is one entity, so the two must agree — and a visibility attribute that appears on only one of them is "ignored because it conflicts with previous declaration", a warning that becomes an error on this tree's -Werror lanes and whose text points at neither file's real problem.

◆ remove_on_shutdown_callback()

bool rclcpp::remove_on_shutdown_callback ( OnShutdownCallbackHandle  handle)
inline

Remove a callback registered with [on_shutdown].

See also
remove_pre_shutdown_callback

◆ remove_pre_shutdown_callback()

bool rclcpp::remove_pre_shutdown_callback ( PreShutdownCallbackHandle  handle)
inline

Remove a callback registered with [pre_shutdown]. true when handle named a live one — "it was not there" is an ordinary answer, as in rclcpp.

◆ shutdown()

bool rclcpp::shutdown ( )
inline

rclcpp::shutdown() — ADOPT-BOUNDED. Upstream's channel here is bool, so ours is too (RFC-0089's error-channel rule: a ported API keeps upstream's channel even when that is bool).

It used to discard rclcpp::shutdown()'s Result and answer true unconditionally (phase-428 W5 finding 9, one site over from the seven create_* verbs and the only one the compiler already pointed at: just check cpp carried a standing -Wunused-result). NROS_NODISCARD on Result is what pointed at it (phase-427 W8) — a fini that failed reported success, which is the exact silence the attribute exists to break.

The bound: upstream returns false when the context was never initialised; rclcpp::shutdown() answers success() for that case (it is a no-op), so we return true there. false here means the teardown itself failed.

◆ shutdown_in()

Result rclcpp::shutdown_in ( )
inline

Shut down the nros session.

Closes the middleware connection and frees all resources.

◆ spin()

void rclcpp::spin ( const Node::SharedPtr &  node)
inline

◆ spin_in() [1/2]

Result rclcpp::spin_in ( )
inline

Phase 123.B.2 — block until rclcpp::ok() returns false.

Mirror of rclcpp::spin(node). The typical pattern in user code is: install a SIGINT handler that calls rclcpp::shutdown() (which flips ok() to false), then rclcpp::spin() from main.

Returns the first non-success spin_once result, or Result::success() after a clean shutdown.

◆ spin_in() [2/2]

Result rclcpp::spin_in ( uint32_t  duration_ms,
int32_t  poll_ms = 10 
)
inline

Spin for a duration (blocking).

Repeatedly calls spin_once() until duration_ms has elapsed. Convenience wrapper around the global executor.

Parameters
duration_msTotal time to spin, in milliseconds.
poll_msIndividual spin_once timeout (default: 10ms).
Returns
Result from the last spin_once call.

◆ spin_once()

Result rclcpp::spin_once ( int32_t  timeout_ms = 10)
inline

Drive transport I/O and dispatch callbacks.

Call this periodically so subscriptions can receive data. When using manual-poll (no callbacks), this drives the network layer.

Parameters
timeout_msMaximum time to block waiting for I/O (default: 10ms).
Returns
Result indicating success or failure.

◆ spin_some()

void rclcpp::spin_some ( const Node::SharedPtr &  node)
inline

◆ spin_until_future_complete()

template<typename Future >
FutureReturnCode rclcpp::spin_until_future_complete ( const Node::SharedPtr &  node,
const Future &  future,
int32_t  timeout_ms = -1 
)
inline

rclcpp::spin_until_future_complete(node, future[, timeout]).

ADOPT-BOUNDED: the timeout is int32_t MILLISECONDS (-1 = unbounded, the default), not a std::chrono::duration, so a ported 1s argument does not compile. It spins the PROCESS executor in 10 ms spin_once slices — there is one executor per task (RFC-0002) and no executor argument — so the deadline is quantised to 10 ms. Returns upstream's FutureReturnCode.

Variable Documentation

◆ kDomainIdExplicitZero

constexpr uint8_t rclcpp::kDomainIdExplicitZero = 255
constexpr

Issue #227 — pass as domain_id to request an EXPLICIT domain 0. Plain 0 is the UNSET sentinel (defers to ROS_DOMAIN_ID env on hosted, then the baked NROS_ENTRY_DOMAIN_ID macro, then the default — the #206 model-A ladder), so a literal domain 0 is otherwise unreachable once the image bakes a nonzero domain. Valid domains cap at 232, so 255 is unambiguous. Mirrors NROS_DOMAIN_ID_EXPLICIT_ZERO in the C API (nros_generated.h); hosted env still overrides it under model A.

◆ PUBLISHER_TOPIC_NAME_MAX

constexpr size_t rclcpp::PUBLISHER_TOPIC_NAME_MAX = 256
staticconstexpr

Maximum topic name length stored inside a publisher (256). The topic name is owned C++-side, not inside the runtime handle.

Stays in rclcpp::: RFC-0089's flip moves the nine TYPES, and this is an implementation bound of one of them, not a name upstream declares.

◆ SUBSCRIPTION_TOPIC_NAME_MAX

constexpr size_t rclcpp::SUBSCRIPTION_TOPIC_NAME_MAX = 256
staticconstexpr

Maximum topic name length stored inside a subscription. Mirrors PUBLISHER_TOPIC_NAME_MAX. Phase 87.6 thin-wrapper refactor: topic name owned C++-side, not inside a runtime handle.

Stays in rclcpp::: RFC-0089's flip moves the nine TYPES, and this is an implementation bound of one of them, not a name upstream declares.