10#ifndef NROS_CPP_NODE_HPP
11#define NROS_CPP_NODE_HPP
16#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
18#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
26#include "nros_cpp_ffi.h"
29#include "nros/nros_cpp_config_generated.h"
34#include "nros/options.hpp"
48#include "nros/clock.hpp"
52#include "nros/callback_group.hpp"
54#ifdef NROS_RMW_CYCLONEDDS
55extern "C" int32_t nros_rmw_cyclonedds_register(
void);
57#if defined(NROS_RMW_XRCE) || defined(NROS_RMW_XRCE_CFFI)
58extern "C" int32_t nros_rmw_xrce_register(
void);
60#ifdef NROS_RMW_ZENOH_CFFI
61extern "C" int32_t nros_rmw_zenoh_register(
void);
64extern "C" int32_t nros_rmw_uorb_register(
void);
70static_assert(NROS_CPP_RET_NOT_FOUND == -4 && NROS_CPP_RET_ALREADY_EXISTS == -5 &&
71 NROS_CPP_RET_FULL == -6 && NROS_CPP_RET_NOT_INIT == -7 &&
72 NROS_CPP_RET_TRY_AGAIN == -14 && NROS_CPP_RET_REENTRANT == -15 &&
73 NROS_CPP_RET_UNSUPPORTED == -16,
74 "nros_cpp_ret_t diverged from the shared numbering (issue #229)");
82template <
typename M>
class Publisher;
83template <
typename M>
class Subscription;
84template <
typename S>
class Service;
85template <
typename S>
class Client;
86template <
typename A>
class ActionServer;
87template <
typename A>
class ActionClient;
122inline Result init(
const char* locator =
nullptr, uint8_t domain_id = 0);
143inline Result init(
const char* locator, uint8_t domain_id,
const char* session_name);
162inline Result init_with_rmw(
const char* rmw,
const char* locator =
nullptr, uint8_t domain_id = 0,
163 const char* session_name =
"node");
184 const char* session_name =
nullptr);
193 const char* session_name =
nullptr);
215 : handle_(), initialized_(false), executor_handle_(nullptr), clock_(NROS_CLOCK_ROS_TIME) {}
224 if (!out.executor_handle_) {
228 nros_cpp_ret_t ret = nros_cpp_node_create(out.executor_handle_, name, ns, &out.handle_);
231 out.initialized_ =
true;
238 if (!initialized_)
return "";
239 return nros_cpp_node_get_name(&handle_);
244 if (!initialized_)
return "";
245 return nros_cpp_node_get_namespace(&handle_);
266 if (!initialized_)
return nullptr;
267 return nros_cpp_node_get_serialization_format(&handle_);
277 if (!initialized_)
return nullptr;
278 return nros_cpp_node_get_logger(&handle_);
302 Time
now()
const {
return clock_.now(); }
322 const nros_cpp_node_t*
ffi_handle()
const {
return initialized_ ? &handle_ :
nullptr; }
336 ::nros_cpp_node_set_qos_overrides(&handle_, overrides, len);
354 template <
typename M>
370 template <
typename M>
372 const PublisherOptions& options);
380 template <
typename M>
396 template <
typename M>
398 const SubscriptionOptions& options);
419 typename M,
typename F,
420 typename =
typename std::enable_if<std::is_convertible<F, void (*)(
const M&)>::value>::type>
423 const SubscriptionOptions& options = {});
432 template <
typename M,
typename F,
433 typename =
typename std::enable_if<
434 std::is_convertible<F, void (*)(
const M&,
const uint8_t*, size_t)>::value>::type>
437 const SubscriptionOptions& options = {});
439#if defined(NANO_ROS_SAFETY_E2E)
454 template <
typename M,
typename F,
455 typename =
typename std::enable_if<std::is_convertible<
456 F, void (*)(
const M&,
const nros_cpp_integrity_status_t&)>::value>::type>
457 Result create_subscription_with_safety(Subscription<M>& out,
const char* topic, F callback,
459 const SubscriptionOptions& options = {});
468 template <
typename S>
484 template <
typename S,
typename F,
485 typename =
typename std::enable_if<std::is_convertible<
486 F, void (*)(
const typename S::Request&,
typename S::Response&)>::value>::type>
487 Result
create_service(Service<S>& out,
const char* service_name, F callback,
488 const QoS& qos =
QoS::services(),
const ServiceOptions& options = {});
496 template <
typename S>
497 Result
create_client(Client<S>& out,
const char* service_name,
510 template <
typename S,
typename F,
511 typename =
typename std::enable_if<
512 std::is_convertible<F, void (*)(
const typename S::Response&)>::value>::type>
513 Result
create_client(Client<S>& out,
const char* service_name, F callback,
514 const QoS& qos =
QoS::services(),
const ClientOptions& options = {});
526 template <
typename A>
529 const ActionServerOptions& options = {});
537 template <
typename A>
544 template <
typename A>
548 template <
typename A>
556 template <
typename M>
584 nros_cpp_timer_callback_t callback,
void* context =
nullptr) {
586 size_t handle_id = 0;
588 executor_handle_,
static_cast<uint8_t
>(clock.get_clock_type()), period_ms, callback,
589 context, &handle_id);
591 out.executor_ = executor_handle_;
592 out.handle_id_ = handle_id;
593 out.initialized_ =
true;
609 void* context =
nullptr) {
611 size_t handle_id = 0;
613 nros_cpp_timer_create(executor_handle_, period_ms, callback, context, &handle_id);
615 out.executor_ = executor_handle_;
616 out.handle_id_ = handle_id;
617 out.initialized_ =
true;
631 void* context =
nullptr) {
633 size_t handle_id = 0;
634 nros_cpp_ret_t ret = nros_cpp_timer_create_oneshot(executor_handle_, delay_ms, callback,
635 context, &handle_id);
637 out.executor_ = executor_handle_;
638 out.handle_id_ = handle_id;
639 out.initialized_ =
true;
668 nros_cpp_timer_callback_t callback,
void* context =
nullptr) {
670 size_t handle_id = 0;
672 executor_handle_, &handle_, period_ms, callback, context, group.get_name(), &handle_id);
674 out.executor_ = executor_handle_;
675 out.handle_id_ = handle_id;
676 out.initialized_ =
true;
696 typename M,
typename F,
697 typename =
typename std::enable_if<std::is_convertible<F, void (*)(
const M&)>::value>::type>
699 const char* topic, F callback,
701 const SubscriptionOptions& options = {});
714 template <
typename M>
717 return create_publisher<M>(out, topic, qos);
728 void* context =
nullptr) {
731 nros_cpp_guard_condition_create(executor_handle_, callback, context, out.storage_);
733 out.initialized_ =
true;
741 nros_cpp_node_destroy(&handle_);
742 initialized_ =
false;
748 : handle_(other.handle_), initialized_(other.initialized_),
749 executor_handle_(other.executor_handle_), clock_(other.clock_) {
750 other.initialized_ =
false;
751 other.executor_handle_ =
nullptr;
755 if (
this != &other) {
757 nros_cpp_node_destroy(&handle_);
759 handle_ = other.handle_;
760 initialized_ = other.initialized_;
761 executor_handle_ = other.executor_handle_;
762 clock_ = other.clock_;
763 other.initialized_ =
false;
764 other.executor_handle_ =
nullptr;
773 nros_cpp_node_t handle_;
775 void* executor_handle_;
784 friend Result init(
const char* locator, uint8_t domain_id);
785 friend Result init(
const char* locator, uint8_t domain_id,
const char* session_name);
787 const char* session_name);
795 friend Result spin(uint32_t duration_ms, int32_t poll_ms);
807 template <
int = 0>
struct GlobalStorageHolder {
808 alignas(8)
static uint8_t storage[NROS_CPP_EXECUTOR_STORAGE_SIZE];
809 static bool initialized;
811 static uint8_t* global_storage() {
return GlobalStorageHolder<>::storage; }
812 static bool& global_initialized() {
return GlobalStorageHolder<>::initialized; }
819alignas(8) uint8_t Node::GlobalStorageHolder<N>::storage[NROS_CPP_EXECUTOR_STORAGE_SIZE] = {};
820template <
int N>
bool Node::GlobalStorageHolder<N>::initialized =
false;
832 return init(locator, domain_id,
"node");
835inline Result init(
const char* locator, uint8_t domain_id,
const char* session_name) {
839 if (session_name ==
nullptr) {
842#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
862#ifdef NROS_ENTRY_LOCATOR
863 if (locator ==
nullptr) {
864 locator = NROS_ENTRY_LOCATOR;
867#ifdef NROS_ENTRY_DOMAIN_ID
871 if (domain_id == 0) {
872 domain_id =
static_cast<uint8_t
>(NROS_ENTRY_DOMAIN_ID);
903 const char* rmw = NROS_ENTRY_RMW;
905 const char* rmw =
nullptr;
908 nros_cpp_init_rmw(rmw, locator, domain_id, session_name,
nullptr, Node::global_storage());
910 Node::global_initialized() =
true;
916 const char* session_name) {
919 if (session_name ==
nullptr) {
922#ifdef NROS_ENTRY_LOCATOR
923 if (locator ==
nullptr) {
924 locator = NROS_ENTRY_LOCATOR;
927#ifdef NROS_ENTRY_DOMAIN_ID
928 if (domain_id == 0) {
929 domain_id =
static_cast<uint8_t
>(NROS_ENTRY_DOMAIN_ID);
936 nros_cpp_init_rmw(rmw, locator, domain_id, session_name,
nullptr, Node::global_storage());
938 Node::global_initialized() =
true;
944 if (!Node::global_initialized()) {
948 Node::global_initialized() =
false;
969 const char* name = (session_name !=
nullptr) ? session_name :
"nros_cpp";
970 return init(
nullptr, 0, name);
977 if (path ==
nullptr) {
980#if defined(NROS_CPP_STD) || (__STDC_HOSTED__ + 0)
983 if (FILE* f = std::fopen(path,
"rb")) {
992 const char* name = (session_name !=
nullptr) ? session_name :
"nros_cpp";
993 return init(
nullptr, 0, name);
998 return Node::global_initialized();
1009 if (!Node::global_initialized()) {
1012 out.executor_handle_ = Node::global_storage();
1028 const char* ns =
nullptr) {
1029 if (executor_handle ==
nullptr) {
1032 out.executor_handle_ = executor_handle;
1050 out.executor_handle_ = storage_;
1074 : executor_handle_(executor_handle), name_(name),
1075 options_(nros_cpp_node_get_default_options()) {}
1082 copy_bounded(name, options_.rmw_name, &options_.rmw_name_len, NROS_CPP_RMW_NAME_LEN);
1089 copy_bounded(loc, options_.locator, &options_.locator_len, NROS_CPP_LOCATOR_LEN);
1096 options_.domain_id_override = id;
1103 copy_bounded(ns, options_.namespace_, &options_.namespace_len, NROS_CPP_NAMESPACE_LEN);
1110 options_.sched_context_id = sc_id;
1117 out.executor_handle_ = executor_handle_;
1119 nros_cpp_node_create_ex(executor_handle_, name_, &options_, &out.handle_);
1121 out.initialized_ =
true;
1127 static void copy_bounded(
const char* src, uint8_t* dst,
size_t* dst_len,
size_t cap) {
1129 if (src !=
nullptr) {
1130 while (src[n] !=
'\0' && n < cap) {
1131 dst[n] =
static_cast<uint8_t
>(src[n]);
1136 for (
size_t i = n; i < cap; ++i) {
1142 void* executor_handle_;
1144 nros_cpp_node_options_t options_;
NodeBuilder node_builder(const char *name)
Definition node.hpp:1147
void * handle()
Definition executor.hpp:401
Result create_node(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:1048
Definition result.hpp:198
ErrorCode error() const
Definition result.hpp:221
bool ok() const
Definition result.hpp:214
Definition guard_condition.hpp:45
NodeBuilder & domain_id(uint32_t id)
Definition node.hpp:1095
NodeBuilder & sched(uint8_t sc_id)
Definition node.hpp:1109
NodeBuilder(void *executor_handle, const char *name)
Definition node.hpp:1073
NodeBuilder & rmw(const char *name)
Definition node.hpp:1081
NodeBuilder & locator(const char *loc)
Definition node.hpp:1088
NodeBuilder & namespace_(const char *ns)
Definition node.hpp:1102
Result build(Node &out) const
Materialize the Node.
Definition node.hpp:1115
friend Result init(const char *locator, uint8_t domain_id)
Definition node.hpp:824
Time now() const
Definition node.hpp:302
Result create_subscription_in(const CallbackGroup &group, Subscription< M > &out, const char *topic, F callback, const QoS &qos=QoS::default_profile(), const SubscriptionOptions &options={})
Definition subscription.hpp:706
Result create_polling_action_server(PollingActionServer< A > &out, const char *action_name)
Result create_timer(Timer &out, const Clock &clock, uint64_t period_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:583
Result create_client(Client< S > &out, const char *service_name, const QoS &qos=QoS::services())
Definition client.hpp:345
friend class ComponentNode
Definition node.hpp:783
Result create_action_server(ActionServer< A > &out, const char *action_name, const QoS &qos=QoS::services(), const ActionServerOptions &options={})
Definition action_server.hpp:466
friend class NodeBuilder
Definition node.hpp:782
const void * get_logger() const
Definition node.hpp:276
friend bool ok()
Check if the nros session is initialized.
Definition node.hpp:997
const nros_cpp_node_t * ffi_handle() const
Definition node.hpp:322
const char * get_namespace() const
Get the node namespace.
Definition node.hpp:243
CallbackGroup create_callback_group(const char *name)
Definition node.hpp:654
Result create_publisher_in(const CallbackGroup &, Publisher< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
Definition node.hpp:715
friend Result spin()
Definition nros.hpp:157
Result create_subscription(Subscription< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
Definition subscription.hpp:608
Result create_action_client(ActionClient< A > &out, const char *action_name, const QoS &qos=QoS::services())
Definition action_client.hpp:482
void * executor_handle() const
Definition node.hpp:346
friend Result create_node(Node &out, const char *name, const char *ns)
Definition node.hpp:1008
Clock * get_clock()
Definition node.hpp:291
friend class Executor
Definition node.hpp:781
Node(Node &&other)
Definition node.hpp:747
Result create_service(Service< S > &out, const char *service_name, const QoS &qos=QoS::services())
Definition service.hpp:246
const Clock * get_clock() const
Const overload of get_clock().
Definition node.hpp:293
~Node()
Destructor — releases node resources.
Definition node.hpp:739
Result create_publisher(Publisher< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
Definition publisher.hpp:274
static Result create(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:223
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:743
const char * serialization_format() const
Definition node.hpp:265
Node()
Default constructor — creates an uninitialized node.
Definition node.hpp:214
Result create_wall_timer(Timer &out, uint64_t period_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:608
bool is_valid() const
Check if the node is initialized and valid.
Definition node.hpp:305
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:63
friend Result spin_once(int32_t timeout_ms)
Definition nros.hpp:75
Result create_timer_oneshot(Timer &out, uint64_t delay_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:630
Result create_timer_in(const CallbackGroup &group, Timer &out, uint64_t period_ms, nros_cpp_timer_callback_t callback, void *context=nullptr)
Definition node.hpp:667
Result create_guard_condition(GuardCondition &out, nros_cpp_guard_callback_t callback, void *context=nullptr)
Definition node.hpp:727
void set_qos_overrides(const nros_cpp_qos_override_t *overrides, size_t len)
Definition node.hpp:334
friend Result shutdown()
Definition node.hpp:943
Result create_polling_subscription(PollingSubscription< M > &out, const char *topic, const QoS &qos=QoS::default_profile())
friend Result create_node_on(Node &out, void *executor_handle, const char *name, const char *ns)
Definition node.hpp:1027
const char * get_name() const
Get the node name.
Definition node.hpp:237
friend Result init_with_rmw(const char *rmw, const char *locator, uint8_t domain_id, const char *session_name)
Definition node.hpp:915
Node & operator=(Node &&other)
Definition node.hpp:754
Definition publisher.hpp:48
static constexpr QoS default_profile()
Default profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:328
static constexpr QoS services()
Services profile: RELIABLE + VOLATILE + KEEP_LAST(10).
Definition qos.hpp:334
static constexpr Result success()
Named constructors.
Definition result.hpp:112
bool ok() const
Returns true if the operation succeeded.
Definition result.hpp:100
Definition subscription.hpp:100
nros::Executor — drives transport I/O and dispatches callbacks.
int nros_cpp_ret_t
Definition future.hpp:21
nros::GuardCondition — cross-thread wake source.
Result init_with_rmw(const char *rmw, const char *locator=nullptr, uint8_t domain_id=0, const char *session_name="node")
Definition node.hpp:915
Result init_with_launch(const char *path, int argc=0, char **argv=nullptr, const char *session_name=nullptr)
Definition node.hpp:973
Expected< Node > make_node(const char *name, const char *ns=nullptr)
Definition node.hpp:1039
Result shutdown()
Definition node.hpp:943
bool ok()
Check if the nros session is initialized.
Definition node.hpp:997
constexpr uint8_t kDomainIdExplicitZero
Definition node.hpp:110
Result init_with_launch_auto(int argc=0, char **argv=nullptr, const char *session_name=nullptr)
Definition node.hpp:959
Result init(const char *locator=nullptr, uint8_t domain_id=0)
Definition node.hpp:824
Result create_node(Node &out, const char *name, const char *ns=nullptr)
Definition node.hpp:1008
Result create_node_on(Node &out, void *executor_handle, const char *name, const char *ns=nullptr)
Definition node.hpp:1027
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.