|
nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
|
#include <subscription.hpp>
Public Types | |
| using | ConstSharedPtr = ::rclcpp::SubscriptionHandle< M > |
| using | SharedPtr = ::rclcpp::SubscriptionHandle< M > |
| using | TypedSubscriptionFn = void(*)(const M &msg) |
| using | TypedSubscriptionFnWithCtx = void(*)(const M &msg, void *ctx) |
| using | TypedSubscriptionInfoFn = void(*)(const M &msg, const uint8_t *attachment, size_t attachment_len) |
| using | UniquePtr = ::rclcpp::SubscriptionHandle< M > |
rclcpp::Subscription<M>::UniquePtr — see SharedPtr. | |
Public Member Functions | |
| ::rclcpp::QoS | get_actual_qos () const |
| Result | get_publisher_count (::rclcpp::Executor &executor, size_t *out_count) const |
| const char * | get_topic_name () const |
| Get the topic name. | |
| bool | has_sched_handle () const |
| bool | is_valid () const |
| Check if the subscription is initialized and valid. | |
| Subscription & | operator= (Subscription &&other) |
| size_t | sched_handle_id () const |
| Subscription () | |
| Subscription (Subscription &&other) | |
| ~Subscription () | |
Friends | |
| class | ::rclcpp::Node |
Typed DISPATCH subscription for a ROS 2 topic — phase-456 W2b.
Mirrors upstream's rclcpp::Subscription<M>: the entity is owned by the runtime and the executor calls your handler. The message type M must provide TYPE_NAME, TYPE_HASH, and deserialization support (generated by codegen).
Usage:
TO TAKE INSTEAD OF BEING CALLED, use rclcpp::PollSubscription<M> (rclcpp/polling_subscription.hpp), which owns its subscriber and carries take, take_serialized, take_validated, take_sequence and try_borrow. That API lived on THIS class until phase-456 W2b, for both owners at once: on the dispatch path storage_ was 656 value-initialized zero bytes the arena never filled, and take() handed them to the runtime as an RmwSubscriber rather than refusing. One class, two owners, and half the methods answerable only under one of them.
The name went to the dispatch half because that is what upstream's Subscription<M> is — an entity the node owns and the executor drives — and because Subscription<M>::SharedPtr is what ported source declares. Note that rclcpp::Subscription does carry take() upstream (called after a WaitSet reports the entity ready); ours is on PollSubscription<M> because we have no wait set and the caller-owned subscriber is the thing that can answer it. That trade is ledgered at cpp:Subscription::take.
| using rclcpp::Subscription< M >::ConstSharedPtr = ::rclcpp::SubscriptionHandle<M> |
rclcpp::Subscription<M>::ConstSharedPtr — see SharedPtr. The same handle: there is no mutable/const distinction to draw over a registration that exposes no operation on the entity.
| using rclcpp::Subscription< M >::SharedPtr = ::rclcpp::SubscriptionHandle<M> |
rclcpp::Subscription<M>::SharedPtr — phase-456 W2.
rclcpp::Subscription<M>::SharedPtr member_; is close to universal in ported source, so this alias must exist on every target — which std::shared_ptr does not.
IT IS NOT A POINTER TO A Subscription<M>, and that is the point. create_subscription with a callback registers into the executor arena, which owns the subscriber, the rx buffer, the callback and its capture; there is no C++ object to point at. What this names is rclcpp::SubscriptionHandle<M> — two words, copyable, and carrying only the operations a dispatch subscription can actually perform.
W2 recorded a cost here: the alias and the class had become different things, because the class still carried a taking API that a handle's referent could not perform. phase-456 W2b repaid it — the taking API is rclcpp::PollSubscription<M>'s now, so the handle's element_type IS Subscription<M> again and names a type whose every operation belongs to a registration. The two are still not the same C++ type, and never will be: one is a value the caller holds, the other an index into the arena.
Phase 189.M3.x — typed message-handler signatures for the callback-style subscription (rclcpp dispatch model). The executor invokes the handler during spin_once() on each new sample.
| using rclcpp::Subscription< M >::TypedSubscriptionInfoFn = void (*)(const M& msg, const uint8_t* attachment, size_t attachment_len) |
| using rclcpp::Subscription< M >::UniquePtr = ::rclcpp::SubscriptionHandle<M> |
rclcpp::Subscription<M>::UniquePtr — see SharedPtr.
|
inline |
Destructor — there is nothing to release.
The executor arena owns the subscriber, the rx buffer, the callback and (phase-456 W1) its capture, and frees them when the executor drops. No unregister FFI exists, so this cannot remove the registration and does not pretend to: it clears this object's own bookkeeping. Until phase-456 W2b the same destructor also freed a POLL subscriber, behind an if (initialized_ && !callback_mode_); that half moved to rclcpp::PollSubscription<M>, where the condition is unconditional.
|
inline |
|
inline |
Default constructor — creates an unregistered subscription. Use one of Node's callback-taking create_subscription overloads.
|
inline |
The QoS profile this subscription is ACTUALLY running — rclcpp::Subscription::get_actual_qos, no arguments, as upstream's is.
The phase-467 RMW gap-closure design study's Row 13, closing the gap phase-456 W2b RECORDED rather than guessed at. The split gave the two subscription roads two types; rclcpp::PollSubscription<M> owns its subscriber and kept this, and the DISPATCH half — the one a ported rclcpp node holds, and therefore the one where a missing accessor is a compile error on ported source — lost it, because the FFI needs (storage, executor, handle_id) and this class held only the handle. The fix is the executor pointer beside it, NOT an argument: adding one would close the gate and open a divergence on a method that exists to adopt the no-argument spelling.
Per policy, and a policy the backend cannot report is an ABSENCE — ReliabilityPolicy::Unknown, DurabilityPolicy::Unknown, … — never the request echoed back. See rclcpp::PollSubscription::get_actual_qos and rclcpp::Publisher::get_actual_qos, which answer the same question on their own roads.
A default-constructed or unregistered subscription answers the all-absent profile, as the sibling accessors do.
|
inline |
How many publishers are on this subscription's topic, RIGHT NOW — rclcpp's Subscription::get_publisher_count. phase-444.
The subscription half of Publisher::get_subscription_count, which states the weakening (topic-wide, not matched-to-this-entity), why the executor and the out-parameter are there, and why an error is not 0.
phase-456 W2b split this class in two and this method answers on BOTH halves, unchanged: it reads topic_name_, which each half keeps, and takes the executor as an argument rather than holding one. A topic-wide count does not depend on which owner holds the subscriber.
Get the topic name.
|
inline |
Phase 189.M3.1 — internal: executor HandleId usable with nros_cpp_bind_handle_to_sched_context, or SIZE_MAX before the registration has happened.
phase-456 W2b — this used to be a question worth asking, because the class also held POLL subscriptions, which register no arena entry and so left the field at SIZE_MAX forever. Every object of this type is an arena registration now, so a successfully created one always has a handle; has_sched_handle() is false only on a default-constructed object. Node is a friend and sets this on create.
|
inline |
Check if the subscription is initialized and valid.
|
inline |
|
inline |
|
friend |