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

Namespaces

namespace  detail
 

Classes

class  ActionClient
 
class  ActionServer
 
class  Client
 
class  Executor
 
class  Expected
 
struct  FixedSequence
 
struct  FixedString
 
struct  format_of
 
class  Future
 
class  GuardCondition
 
struct  LeSpan
 
class  Node
 
class  NodeBuilder
 
class  OnShutdownCallbackHandle
 
class  PollingActionClient
 
class  PollingActionServer
 
class  PollingSubscription
 
class  PreShutdownCallbackHandle
 
class  Publisher
 
class  QoS
 
class  Result
 
class  Service
 
class  ShutdownCallbackHandle
 
struct  Span
 
class  Stream
 
struct  StringView
 
class  Subscription
 
class  Timer
 

Typedefs

using ShutdownCallback = void(*)(void *context)
 

Enumerations

enum class  CancelResponse : int32_t { Reject = 0 , Accept = 1 }
 
enum class  CancelReturnCode : int8_t { Ok = 0 , Rejected = 1 , UnknownGoal = 2 , GoalTerminated = 3 }
 
enum  DurabilityPolicy { Volatile = 0 , TransientLocal = 1 }
 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  GoalResponse : int32_t { Reject = 0 , AcceptAndExecute = 1 , AcceptAndDefer = 2 }
 Goal acceptance response returned from the user's goal callback. More...
 
enum class  GoalStatus : int8_t {
  Unknown = 0 , Accepted = 1 , Executing = 2 , Canceling = 3 ,
  Succeeded = 4 , Canceled = 5 , Aborted = 6
}
 
enum  HistoryPolicy { KeepLast = 0 , KeepAll = 1 }
 History policy. Matches DDS HISTORY_QOS_POLICY. More...
 
enum  LivelinessPolicy { LivelinessNone = 0 , LivelinessAutomatic = 1 , LivelinessManualByTopic = 2 , LivelinessManualByNode = 3 }
 
enum  ReliabilityPolicy { Reliable = 0 , BestEffort = 1 }
 Reliability policy. Matches DDS RELIABILITY_QOS_POLICY. More...
 
enum class  SerializationFormat : uint8_t { Cdr = 1 , Uorb = 2 }
 

Functions

Result create_node (Node &out, const char *name, const char *ns=nullptr)
 
Result create_node_on (Node &out, void *executor_handle, const char *name, const char *ns=nullptr)
 
void * global_handle ()
 
Result init (const char *locator, uint8_t domain_id, const char *session_name)
 
Result init (const char *locator=nullptr, uint8_t domain_id=0)
 
Result init_with_launch (const char *path, int argc=0, char **argv=nullptr, const char *session_name=nullptr)
 
Result init_with_launch_auto (int argc=0, char **argv=nullptr, 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 SerializationFormat linked_format ()
 
constexpr const char * linked_format_name ()
 
Expected< Nodemake_node (const char *name, const char *ns=nullptr)
 
bool ok ()
 Check if the nros session is initialized.
 
Result on_shutdown (ShutdownCallback callback, void *context=nullptr, OnShutdownCallbackHandle *out=nullptr)
 
Result pre_shutdown (ShutdownCallback callback, void *context=nullptr, PreShutdownCallbackHandle *out=nullptr)
 
bool remove_on_shutdown_callback (OnShutdownCallbackHandle handle)
 
bool remove_pre_shutdown_callback (PreShutdownCallbackHandle handle)
 
Result shutdown ()
 
Result spin ()
 
Result spin (uint32_t duration_ms, int32_t poll_ms=10)
 
Result spin_once (int32_t timeout_ms=10)
 

Variables

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

Typedef Documentation

◆ ShutdownCallback

using nros::ShutdownCallback = typedef void (*)(void* context)

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.

Enumeration Type Documentation

◆ CancelResponse

enum class nros::CancelResponse : int32_t
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 values (Reject and Ok are both 0), so never cast between them. C names them apart too (nros_cancel_response_t vs nros_cancel_return_code_t), and Rust now does (nros_core::CancelResponse vs nros_core::CancelReturnCode).

Enumerator
Reject 
Accept 

◆ CancelReturnCode

enum class nros::CancelReturnCode : int8_t
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 

◆ DurabilityPolicy

Durability policy. Matches DDS DURABILITY_QOS_POLICY.

Enumerator
Volatile 
TransientLocal 

◆ ErrorCode

enum class nros::ErrorCode : int32_t
strong

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 

nros::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.

◆ GoalResponse

enum class nros::GoalResponse : int32_t
strong

Goal acceptance response returned from the user's goal callback.

Enumerator
Reject 
AcceptAndExecute 
AcceptAndDefer 

◆ GoalStatus

enum class nros::GoalStatus : int8_t
strong

Mirror of action_msgs/msg/GoalStatus — lifecycle state reported by for_each_active_goal.

Enumerator
Unknown 
Accepted 
Executing 
Canceling 
Succeeded 
Canceled 
Aborted 

◆ HistoryPolicy

History policy. Matches DDS HISTORY_QOS_POLICY.

Enumerator
KeepLast 
KeepAll 

◆ LivelinessPolicy

Liveliness policy kind. Matches DDS LIVELINESS_QOS_POLICY.

The enumerators keep their Liveliness prefix because these are UNSCOPED enums at namespace scope: a bare Automatic / None in nros:: would be far worse names than the redundancy costs. nros::LivelinessPolicy:: LivelinessAutomatic also works, so a qualified rclcpp-shaped spelling compiles. LivelinessManualByNode is ours-only — rmw deprecated it, so rclcpp's LivelinessPolicy does not list it.

Enumerator
LivelinessNone 
LivelinessAutomatic 
LivelinessManualByTopic 
LivelinessManualByNode 

◆ ReliabilityPolicy

Reliability policy. Matches DDS RELIABILITY_QOS_POLICY.

Enumerator
Reliable 
BestEffort 

◆ SerializationFormat

enum class nros::SerializationFormat : uint8_t
strong

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

◆ create_node()

Result nros::create_node ( 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 nros::init().

Parameters
outReceives the initialized node.
nameNode name.
nsNode namespace, or nullptr for "/".

◆ create_node_on()

Result nros::create_node_on ( 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, or nullptr for "/".

◆ global_handle()

void * nros::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(nros::global_handle(), ...).

Returns
Executor handle, or nullptr if not initialized.

◆ init() [1/2]

Result nros::init ( 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, nros::kDomainIdExplicitZero = explicit domain 0.
session_namePer-process session identifier. Must not be nullptr.
Returns
Result indicating success or failure.

◆ init() [2/2]

Result nros::init ( 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); nros::kDomainIdExplicitZero (255) = explicitly domain 0 (issue #227).
Returns
Result indicating success or failure.

◆ init_with_launch()

Result nros::init_with_launch ( const char *  path,
int  argc = 0,
char **  argv = nullptr,
const char *  session_name = nullptr 
)
inline

Phase 212.L.5 Pattern 2 — explicit-path variant of [init_with_launch_auto].

Verifies path exists (so misspelled paths fail fast) but does NOT yet parse the XML — the env overlay is the active source today. See the auto variant's notes for the follow-up plan.

◆ init_with_launch_auto()

Result nros::init_with_launch_auto ( int  argc = 0,
char **  argv = nullptr,
const char *  session_name = nullptr 
)
inline

Phase 212.L.5 Pattern 2 — launch-aware init.

Resolves runtime knobs (domain id, locator, RMW choice) in this order:

  1. $NROS_RUNTIME_OVERLAY (JSON sidecar emitted by nros launch --emit-runtime-overlay). NOT yet consumed — placeholder for the follow-up wave.
  2. Launch XML at <CARGO_MANIFEST_DIR>/launch/*.xml. NOT yet parsed — the runtime trusts the launcher to project params/remaps into the child env before exec().
  3. Env vars: ROS_DOMAIN_ID, NROS_LOCATOR, RMW_IMPLEMENTATION / NROS_RMW. This is the active overlay channel today.

argc / argv are reserved for the structured --ros-args parse that lands with the runtime-overlay wave. They are accepted and ignored for forward-compat.

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

◆ init_with_rmw()

Result nros::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.

◆ linked_format()

constexpr SerializationFormat nros::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 nros::Node::serialization_format(). check-format-macro-scope refuses a bridge-linked translation unit that reaches the underlying macro.

◆ linked_format_name()

constexpr const char * nros::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()

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

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

◆ ok()

bool nros::ok ( )
inline

Check if the nros session is initialized.

◆ on_shutdown()

Result nros::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.

◆ pre_shutdown()

Result nros::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 nros::init() opened and nros::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. nros::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 nros::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.

◆ remove_on_shutdown_callback()

bool nros::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 nros::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()

Result nros::shutdown ( )
inline

Shut down the nros session.

Closes the middleware connection and frees all resources.

◆ spin() [1/2]

Result nros::spin ( )
inline

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

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

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

◆ spin() [2/2]

Result nros::spin ( 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 nros::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.

Variable Documentation

◆ kDomainIdExplicitZero

constexpr uint8_t nros::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 nros::PUBLISHER_TOPIC_NAME_MAX = 256
staticconstexpr

Maximum topic name length stored inside nros::Publisher<M> (256). The topic name is owned C++-side, not inside the runtime handle.

◆ SUBSCRIPTION_TOPIC_NAME_MAX

constexpr size_t nros::SUBSCRIPTION_TOPIC_NAME_MAX = 256
staticconstexpr

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