nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
node.hpp
Go to the documentation of this file.
1// nros-cpp: Node class
2// Freestanding C++ — no exceptions, no STL required
3
10#ifndef NROS_CPP_NODE_HPP
11#define NROS_CPP_NODE_HPP
12
13#include <cstdint>
14#include <cstddef>
15#include <type_traits> // Phase 189.M3.3.e — SFINAE on the callback-style create_service
16#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
17#include <cstdlib> // getenv — Phase 123.B.3 env-aware init
18#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
19#include <cstdio> // fopen — Phase 212.L.5 init_with_launch path-exists check
20#endif
21#endif
22
23// Phase 118.D: ffi.h MUST come before qos.hpp so qos.hpp's
24// `#ifndef NROS_CPP_FFI_H` guard sees the canonical types and skips
25// its local redefinitions.
26#include "nros_cpp_ffi.h"
27
28#include "nros/result.hpp"
29#include "nros/nros_cpp_config_generated.h"
30#include "nros/qos.hpp"
31// Phase 189.M3.1 — rclcpp-style named-options structs
32// (`SubscriptionOptions` / `PublisherOptions`) used by the 4-arg
33// `create_subscription` / `create_publisher` overloads below.
34#include "nros/options.hpp"
35// Phase 84.G8: heavy entity headers (publisher / subscription / service /
36// client / action_server / action_client) are no longer pulled in here.
37// Each entity header provides the out-of-line definition of its
38// corresponding `Node::create_X<T>()` template and includes `node.hpp`
39// itself. Consumers that #include `nros/nros.hpp` (the umbrella) still
40// get every entity + every create method via that path; consumers that
41// only want lightweight Node access can include this header directly
42// and pay for only the light entities (timer, guard_condition,
43// executor) below.
44#include "nros/timer.hpp"
46#include "nros/executor.hpp"
47
48#ifdef NROS_RMW_CYCLONEDDS
49extern "C" int32_t nros_rmw_cyclonedds_register(void);
50#endif
51#if defined(NROS_RMW_XRCE) || defined(NROS_RMW_XRCE_CFFI)
52extern "C" int32_t nros_rmw_xrce_register(void);
53#endif
54#ifdef NROS_RMW_ZENOH_CFFI
55extern "C" int32_t nros_rmw_zenoh_register(void);
56#endif
57#ifdef NROS_RMW_UORB
58extern "C" int32_t nros_rmw_uorb_register(void);
59#endif
60
61namespace nros {
62
63// Phase 84.G8: forward declarations of the heavy entity class
64// templates. Full definitions live in the corresponding `*.hpp`,
65// which also provide the out-of-line `Node::create_X<>` template
66// bodies — consumers only pay for the entities they #include.
67template <typename M> class Publisher;
68template <typename M> class Subscription;
69template <typename S> class Service;
70template <typename S> class Client;
71template <typename A> class ActionServer;
72template <typename A> class ActionClient;
73// Phase 122.3.d.b — L1 polling-mode action wrappers.
74template <typename A> class PollingActionServer;
75template <typename A> class PollingActionClient;
76// Phase 242.1 (RFC-0044) — rclcpp-faithful IS-A-node base. It wraps an owned
77// `Node` and creates that node against an executor-bound handle in its ctor, so
78// it needs friend access to set `executor_handle_` + call `Node::create`
79// (the same private-create pattern `Executor` / `NodeBuilder` already use).
80class ComponentNode;
81
90inline Result init(const char* locator = nullptr, uint8_t domain_id = 0);
91
110inline Result init(const char* locator, uint8_t domain_id, const char* session_name);
111
130inline Result init_with_launch_auto(int argc = 0, char** argv = nullptr,
131 const char* session_name = nullptr);
132
139inline Result init_with_launch(const char* path, int argc = 0, char** argv = nullptr,
140 const char* session_name = nullptr);
141
145inline Result shutdown();
146
158class Node {
159 public:
161 Node() : handle_(), initialized_(false), executor_handle_(nullptr) {}
162
169 static Result create(Node& out, const char* name, const char* ns = nullptr) {
170 if (!out.executor_handle_) {
172 }
173
174 nros_cpp_ret_t ret = nros_cpp_node_create(out.executor_handle_, name, ns, &out.handle_);
175
176 if (ret == 0) {
177 out.initialized_ = true;
178 }
179 return Result(ret);
180 }
181
183 const char* get_name() const {
184 if (!initialized_) return "";
185 return nros_cpp_node_get_name(&handle_);
186 }
187
189 const char* get_namespace() const {
190 if (!initialized_) return "";
191 return nros_cpp_node_get_namespace(&handle_);
192 }
193
200 const void* get_logger() const {
201 if (!initialized_) return nullptr;
202 return nros_cpp_node_get_logger(&handle_);
203 }
204
206 bool is_valid() const { return initialized_; }
207
223 const nros_cpp_node_t* ffi_handle() const { return initialized_ ? &handle_ : nullptr; }
224
236 if (initialized_) {
237 ::nros_cpp_node_set_qos_overrides(&handle_, overrides, len);
238 }
239 }
240
247 void* executor_handle() const { return initialized_ ? executor_handle_ : nullptr; }
248
255 template <typename M>
257 const QoS& qos = QoS::default_profile());
258
271 template <typename M>
272 Result create_publisher(Publisher<M>& out, const char* topic, const QoS& qos,
274
281 template <typename M>
283 const QoS& qos = QoS::default_profile());
284
297 template <typename M>
300
319 template <
320 typename M, typename F,
321 typename = typename std::enable_if<std::is_convertible<F, void (*)(const M&)>::value>::type>
323 const QoS& qos = QoS::default_profile(),
324 const SubscriptionOptions& options = {});
325
333 template <typename M, typename F,
334 typename = typename std::enable_if<
335 std::is_convertible<F, void (*)(const M&, const uint8_t*, size_t)>::value>::type>
336 Result create_subscription_with_info(Subscription<M>& out, const char* topic, F callback,
337 const QoS& qos = QoS::default_profile(),
338 const SubscriptionOptions& options = {});
339
346 template <typename S>
347 Result create_service(Service<S>& out, const char* service_name,
348 const QoS& qos = QoS::services());
349
362 template <typename S, typename F,
363 typename = typename std::enable_if<std::is_convertible<
364 F, void (*)(const typename S::Request&, typename S::Response&)>::value>::type>
365 Result create_service(Service<S>& out, const char* service_name, F callback,
366 const QoS& qos = QoS::services(), const ServiceOptions& options = {});
367
374 template <typename S>
375 Result create_client(Client<S>& out, const char* service_name,
376 const QoS& qos = QoS::services());
377
388 template <typename S, typename F,
389 typename = typename std::enable_if<
390 std::is_convertible<F, void (*)(const typename S::Response&)>::value>::type>
391 Result create_client(Client<S>& out, const char* service_name, F callback,
392 const QoS& qos = QoS::services(), const ClientOptions& options = {});
393
404 template <typename A>
405 Result create_action_server(ActionServer<A>& out, const char* action_name,
406 const QoS& qos = QoS::services(),
407 const ActionServerOptions& options = {});
408
415 template <typename A>
416 Result create_action_client(ActionClient<A>& out, const char* action_name,
417 const QoS& qos = QoS::services());
418
422 template <typename A>
424
426 template <typename A>
428
438 void* context = nullptr) {
439 if (!initialized_) return Result(ErrorCode::NotInitialized);
440 size_t handle_id = 0;
442 nros_cpp_timer_create(executor_handle_, period_ms, callback, context, &handle_id);
443 if (ret == 0) {
444 out.executor_ = executor_handle_;
445 out.handle_id_ = handle_id;
446 out.initialized_ = true;
447 }
448 return Result(ret);
449 }
450
460 void* context = nullptr) {
461 if (!initialized_) return Result(ErrorCode::NotInitialized);
462 size_t handle_id = 0;
464 context, &handle_id);
465 if (ret == 0) {
466 out.executor_ = executor_handle_;
467 out.handle_id_ = handle_id;
468 out.initialized_ = true;
469 }
470 return Result(ret);
471 }
472
481 void* context = nullptr) {
482 if (!initialized_) return Result(ErrorCode::NotInitialized);
484 nros_cpp_guard_condition_create(executor_handle_, callback, context, out.storage_);
485 if (ret == 0) {
486 out.initialized_ = true;
487 }
488 return Result(ret);
489 }
490
493 if (initialized_) {
494 nros_cpp_node_destroy(&handle_);
495 initialized_ = false;
496 }
497 }
498
499 // Move semantics (non-copyable)
501 : handle_(other.handle_), initialized_(other.initialized_),
502 executor_handle_(other.executor_handle_) {
503 other.initialized_ = false;
504 other.executor_handle_ = nullptr;
505 }
506
508 if (this != &other) {
509 if (initialized_) {
510 nros_cpp_node_destroy(&handle_);
511 }
512 handle_ = other.handle_;
513 initialized_ = other.initialized_;
514 executor_handle_ = other.executor_handle_;
515 other.initialized_ = false;
516 other.executor_handle_ = nullptr;
517 }
518 return *this;
519 }
520
521 private:
522 Node(const Node&) = delete;
523 Node& operator=(const Node&) = delete;
524
525 nros_cpp_node_t handle_;
526 bool initialized_;
527 void* executor_handle_; // Set by nros::init() via friendship
528
529 friend class Executor;
530 friend class NodeBuilder;
531 friend class ComponentNode; // Phase 242.1 — ctor-creates the owned node
532 friend Result init(const char* locator, uint8_t domain_id);
533 friend Result init(const char* locator, uint8_t domain_id, const char* session_name);
534 friend Result shutdown();
535 friend bool ok();
536 friend Result create_node(Node& out, const char* name, const char* ns);
538 friend Result spin();
540 friend void* global_handle();
541
542 // Global executor inline storage for init/shutdown free functions.
543 //
544 // Use a template-static-member trick instead of a function-local static.
545 // Function-local statics need __cxa_guard_acquire/release on first-call
546 // initialisation; on NuttX the resulting guard logic returns NULL for
547 // the storage pointer (observed empirically with LTO on armv7a-nuttx-eabihf,
548 // even with constant-initialisation `= {}`). A template static member is
549 // emitted into .bss like a file-scope variable and gets COMDAT-folded by
550 // the linker, sidestepping the guarded-init path entirely.
551 template <int = 0> struct GlobalStorageHolder {
552 alignas(8) static uint8_t storage[NROS_CPP_EXECUTOR_STORAGE_SIZE];
553 static bool initialized;
554 };
555 static uint8_t* global_storage() { return GlobalStorageHolder<>::storage; }
556 static bool& global_initialized() { return GlobalStorageHolder<>::initialized; }
557};
558
559// Out-of-class definitions for Node::GlobalStorageHolder<> — the template
560// machinery means these get emitted as COMDAT symbols, so multiple TUs
561// including this header all collapse to a single .bss allocation.
562template <int N>
563alignas(8) uint8_t Node::GlobalStorageHolder<N>::storage[NROS_CPP_EXECUTOR_STORAGE_SIZE] = {};
564template <int N> bool Node::GlobalStorageHolder<N>::initialized = false;
565
566// -- Free function implementations --
567
568inline Result init(const char* locator, uint8_t domain_id) {
569#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
570 // Phase 123.B.3 — on hosted builds, fall through to env vars
571 // ($NROS_LOCATOR / $ROS_DOMAIN_ID) so the no-arg `nros::init()`
572 // call works without `getenv()` boilerplate in user code.
573 // Explicit non-null `locator` / non-zero `domain_id` still win.
574 if (locator == nullptr) {
575 const char* env_loc = ::std::getenv("NROS_LOCATOR");
576 if (env_loc != nullptr && env_loc[0] != '\0') {
577 locator = env_loc;
578 } else {
579 locator = "tcp/127.0.0.1:7447";
580 }
581 }
582 if (domain_id == 0) {
583 const char* env_dom = ::std::getenv("ROS_DOMAIN_ID");
584 if (env_dom != nullptr && env_dom[0] != '\0') {
585 // Parse decimal digits inline — no <cstdlib> dep.
586 unsigned acc = 0;
587 for (const char* p = env_dom; *p; ++p) {
588 if (*p < '0' || *p > '9') {
589 acc = 0;
590 break;
591 }
592 acc = acc * 10 + static_cast<unsigned>(*p - '0');
593 if (acc > 232) {
594 acc = 0;
595 break;
596 }
597 }
598 domain_id = static_cast<uint8_t>(acc);
599 }
600 }
601#endif
602 return init(locator, domain_id, "nros_cpp");
603}
604
605inline Result init(const char* locator, uint8_t domain_id, const char* session_name) {
606 // NROS_CPP_RET_INVALID_ARGUMENT = -3 (defined in nros_cpp_ffi.h
607 // which isn't included from this header — duplicate the value
608 // inline; generated header is the source of truth).
609 if (session_name == nullptr) {
610 return Result(-3);
611 }
612#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
613 // Issue #39 — apply the same `$NROS_LOCATOR` / `$ROS_DOMAIN_ID` env
614 // fallback as the 2-arg `init()` when `locator` is null / `domain_id` is
615 // 0. This makes `init_with_launch_auto()` (which delegates here with a
616 // null locator) honor the env overlay instead of passing a null locator
617 // to the backend → TransportError / degraded session.
618 if (locator == nullptr) {
619 const char* env_loc = ::std::getenv("NROS_LOCATOR");
620 if (env_loc != nullptr && env_loc[0] != '\0') {
621 locator = env_loc;
622 } else {
623 locator = "tcp/127.0.0.1:7447";
624 }
625 }
626 if (domain_id == 0) {
627 const char* env_dom = ::std::getenv("ROS_DOMAIN_ID");
628 if (env_dom != nullptr && env_dom[0] != '\0') {
629 unsigned acc = 0;
630 for (const char* p = env_dom; *p; ++p) {
631 if (*p < '0' || *p > '9') {
632 acc = 0;
633 break;
634 }
635 acc = acc * 10 + static_cast<unsigned>(*p - '0');
636 if (acc > 232) {
637 acc = 0;
638 break;
639 }
640 }
641 domain_id = static_cast<uint8_t>(acc);
642 }
643 }
644#endif
645 // Phase 128.C.1 — RMW-blind init. Every backend (cyclonedds,
646 // xrce, dds, zenoh, uorb, …) contributes its registration entry
647 // to the `RMW_INIT_ENTRIES` linker section via the
648 // `NROS_RMW_REGISTER_BACKEND` macro (C/C++) or
649 // `#[linkme::distributed_slice]` (Rust). The cffi runtime's
650 // section walker fires inside `nros_cpp_init` and dispatches to
651 // whichever backends were linked into this binary. No
652 // `#ifdef NROS_RMW_*` chain here, no CMake-driven fan-out — the
653 // user's `target_link_libraries(... NanoRos::Rmw::<name>)` is
654 // the only selector.
656 nros_cpp_init(locator, domain_id, session_name, nullptr, Node::global_storage());
657 if (ret == 0) {
658 Node::global_initialized() = true;
659 }
660 return Result(ret);
661}
662
663inline Result shutdown() {
664 if (!Node::global_initialized()) {
665 return Result::success();
666 }
667 nros_cpp_ret_t ret = nros_cpp_fini(Node::global_storage());
668 Node::global_initialized() = false;
669 return Result(ret);
670}
671
672// -- Phase 212.L.5 launch-aware init --
673//
674// Both `init_with_launch_auto` and `init_with_launch(path)` delegate to
675// the existing 3-arg `init` after resolving the launch overlay (today:
676// env vars only — see header docs for the follow-up plan). The session
677// name falls back to `"nros_cpp"` so existing callsites keep working.
678
679inline Result init_with_launch_auto(int argc, char** argv, const char* session_name) {
680 (void)argc;
681 (void)argv;
682 // TODO (Phase 212.L.5 follow-up):
683 // 1. If $NROS_RUNTIME_OVERLAY is set, read the JSON sidecar and
684 // fold its params/remaps/env into the init call.
685 // 2. Else walk <CARGO_MANIFEST_DIR>/launch/* and parse the XML
686 // in-process.
687 // For now the env overlay (NROS_LOCATOR / ROS_DOMAIN_ID consumed by
688 // the 2-arg `init`) is the only channel.
689 const char* name = (session_name != nullptr) ? session_name : "nros_cpp";
690 return init(nullptr, 0, name);
691}
692
693inline Result init_with_launch(const char* path, int argc, char** argv, const char* session_name) {
694 (void)argc;
695 (void)argv;
696 // NROS_CPP_RET_INVALID_ARGUMENT = -3 (mirrors the 3-arg init guard).
697 if (path == nullptr) {
698 return Result(-3);
699 }
700#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
701 // Verify the file exists so misspelled paths fail fast at init time
702 // instead of surfacing as a silently-empty overlay later.
703 if (FILE* f = std::fopen(path, "rb")) {
704 std::fclose(f);
705 } else {
707 }
708#endif
709 // TODO (Phase 212.L.5 follow-up): parse `path` as launch XML and
710 // fold params/remaps/env into the init call. Today the env overlay
711 // is the only channel.
712 const char* name = (session_name != nullptr) ? session_name : "nros_cpp";
713 return init(nullptr, 0, name);
714}
715
717inline bool ok() {
718 return Node::global_initialized();
719}
720
728inline Result create_node(Node& out, const char* name, const char* ns = nullptr) {
729 if (!Node::global_initialized()) {
731 }
732 out.executor_handle_ = Node::global_storage();
733 return Node::create(out, name, ns);
734}
735
739inline Expected<Node> make_node(const char* name, const char* ns = nullptr) {
740 Node n;
742 if (!r.ok()) return Expected<Node>::error(r);
743 return Expected<Node>::ok(::std::move(n));
744}
745
746// -- Executor::create_node implementation (requires full Node definition) --
747
748inline Result Executor::create_node(Node& out, const char* name, const char* ns) {
749 if (!initialized_) return Result(ErrorCode::NotInitialized);
750 out.executor_handle_ = storage_;
751 return Node::create(out, name, ns);
752}
753
754// -- Phase 104.C.9 — NodeBuilder ----------------------------------------
755//
756// Mirrors Rust's `Executor::node_builder(name).rmw(...).locator(...).
757// domain_id(...).namespace(...).sched(...).build()` chain. The C++
758// wrapper is value-typed and stack-allocated; it accumulates options
759// into an inline `nros_cpp_node_options_t` and ships it to
760// `nros_cpp_node_create_ex` on `.build()`.
761//
762// Usage:
763// ```cpp
764// nros::Node node;
765// NROS_TRY(executor.node_builder("egress")
766// .rmw("cyclonedds")
767// .domain_id(0)
768// .build(node));
769// ```
770
772 public:
773 NodeBuilder(void* executor_handle, const char* name)
774 : executor_handle_(executor_handle), name_(name),
776
781 NodeBuilder& rmw(const char* name) {
782 copy_bounded(name, options_.rmw_name, &options_.rmw_name_len, NROS_CPP_RMW_NAME_LEN);
783 return *this;
784 }
785
788 NodeBuilder& locator(const char* loc) {
789 copy_bounded(loc, options_.locator, &options_.locator_len, NROS_CPP_LOCATOR_LEN);
790 return *this;
791 }
792
796 options_.domain_id_override = id;
797 return *this;
798 }
799
802 NodeBuilder& namespace_(const char* ns) {
803 copy_bounded(ns, options_.namespace_, &options_.namespace_len, NROS_CPP_NAMESPACE_LEN);
804 return *this;
805 }
806
810 options_.sched_context_id = sc_id;
811 return *this;
812 }
813
816 if (!executor_handle_) return Result(ErrorCode::NotInitialized);
817 out.executor_handle_ = executor_handle_;
819 nros_cpp_node_create_ex(executor_handle_, name_, &options_, &out.handle_);
820 if (ret == 0) {
821 out.initialized_ = true;
822 }
823 return Result(ret);
824 }
825
826 private:
827 static void copy_bounded(const char* src, uint8_t* dst, size_t* dst_len, size_t cap) {
828 size_t n = 0;
829 if (src != nullptr) {
830 while (src[n] != '\0' && n < cap) {
831 dst[n] = static_cast<uint8_t>(src[n]);
832 ++n;
833 }
834 }
835 // Zero out the tail so stale bytes don't leak across reuses.
836 for (size_t i = n; i < cap; ++i) {
837 dst[i] = 0;
838 }
839 *dst_len = n;
840 }
841
842 void* executor_handle_;
843 const char* name_;
844 nros_cpp_node_options_t options_;
845};
846
848 return NodeBuilder(initialized_ ? handle() : nullptr, name);
849}
850
851} // namespace nros
852
853#endif // NROS_CPP_NODE_HPP
NodeBuilder node_builder(const char *name)
Definition node.hpp:847
void * handle()
Definition executor.hpp:166
Result create_node(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:748
ErrorCode error() const
Definition result.hpp:183
bool ok() const
Definition result.hpp:176
Definition future.hpp:40
Definition guard_condition.hpp:45
Definition node.hpp:771
NodeBuilder & domain_id(uint32_t id)
Definition node.hpp:795
NodeBuilder & sched(uint8_t sc_id)
Definition node.hpp:809
NodeBuilder(void *executor_handle, const char *name)
Definition node.hpp:773
NodeBuilder & rmw(const char *name)
Definition node.hpp:781
NodeBuilder & locator(const char *loc)
Definition node.hpp:788
NodeBuilder & namespace_(const char *ns)
Definition node.hpp:802
Result build(Node &out) const
Materialize the Node.
Definition node.hpp:815
Definition node.hpp:158
friend Result init(const char *locator, uint8_t domain_id)
Definition node.hpp:568
Result create_polling_action_server(PollingActionServer< A > &out, const char *action_name)
Result create_client(Client< S > &out, const char *service_name, const QoS &qos=QoS::services())
Definition client.hpp:240
friend class ComponentNode
Definition node.hpp:531
Result create_action_server(ActionServer< A > &out, const char *action_name, const QoS &qos=QoS::services(), const ActionServerOptions &options={})
Definition action_server.hpp:350
friend class NodeBuilder
Definition node.hpp:530
const void * get_logger() const
Definition node.hpp:200
friend bool ok()
Check if the nros session is initialized.
Definition node.hpp:717
const nros_cpp_node_t * ffi_handle() const
Definition node.hpp:223
const char * get_namespace() const
Get the node namespace.
Definition node.hpp:189
friend Result spin()
Definition nros.hpp:77
Result create_subscription(Subscription< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
Definition subscription.hpp:460
Result create_action_client(ActionClient< A > &out, const char *action_name, const QoS &qos=QoS::services())
Definition action_client.hpp:399
void * executor_handle() const
Definition node.hpp:247
friend Result create_node(Node &out, const char *name, const char *ns)
Definition node.hpp:728
Result create_timer(Timer &out, uint64_t period_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:437
friend class Executor
Definition node.hpp:529
Node(Node &&other)
Definition node.hpp:500
Result create_service(Service< S > &out, const char *service_name, const QoS &qos=QoS::services())
Definition service.hpp:214
~Node()
Destructor — releases node resources.
Definition node.hpp:492
Result create_publisher(Publisher< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
Definition publisher.hpp:272
static Result create(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:169
Result create_subscription_with_info(Subscription< M > &out, const char *topic, F callback, const QoS &qos=QoS::default_profile(), const SubscriptionOptions &options={})
Definition subscription.hpp:567
Node()
Default constructor — creates an uninitialized node.
Definition node.hpp:161
bool is_valid() const
Check if the node is initialized and valid.
Definition node.hpp:206
Result create_polling_action_client(PollingActionClient< A > &out, const char *action_name)
Phase 122.3.d.b — Create an L1 polling-mode action client.
friend void * global_handle()
Definition nros.hpp:50
friend Result spin_once(int32_t timeout_ms)
Definition nros.hpp:62
Result create_timer_oneshot(Timer &out, uint64_t delay_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:459
Result create_guard_condition(GuardCondition &out, nros_cpp_guard_callback_t callback, void *context=nullptr)
Definition node.hpp:480
void set_qos_overrides(const nros_cpp_qos_override_t *overrides, size_t len)
Definition node.hpp:235
friend Result shutdown()
Definition node.hpp:663
const char * get_name() const
Get the node name.
Definition node.hpp:183
Node & operator=(Node &&other)
Definition node.hpp:507
Definition node.hpp:75
Definition node.hpp:74
Definition qos.hpp:67
static constexpr QoS default_profile()
Default profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:160
static constexpr QoS services()
Services profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:166
Definition result.hpp:52
static constexpr Result success()
Named constructors.
Definition result.hpp:74
Definition timer.hpp:42
nros::Executor — drives transport I/O and dispatches callbacks.
int nros_cpp_ret_t
Definition future.hpp:20
nros::GuardCondition — cross-thread wake source.
Definition nros.hpp:42
Result init_with_launch(const char *path, int argc=0, char **argv=nullptr, const char *session_name=nullptr)
Definition node.hpp:693
Expected< Node > make_node(const char *name, const char *ns=nullptr)
Definition node.hpp:739
Result shutdown()
Definition node.hpp:663
bool ok()
Check if the nros session is initialized.
Definition node.hpp:717
Result init_with_launch_auto(int argc=0, char **argv=nullptr, const char *session_name=nullptr)
Definition node.hpp:679
Result init(const char *locator=nullptr, uint8_t domain_id=0)
Definition node.hpp:568
Result create_node(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:728
nros::QoS — full DDS-shaped QoS settings (Phase 108.B.7).
nros::Result, nros::ErrorCode, and the NROS_TRY macro.
nros::Timer — periodic callback driven by the executor.