nros C++ API
Lightweight ROS 2 client for embedded real-time systems (C++ headers)
Loading...
Searching...
No Matches
qos.hpp
Go to the documentation of this file.
1// nros-cpp: QoS (Quality of Service) profiles
2// Freestanding C++ — no STL required
3
10#ifndef NROS_CPP_QOS_HPP
11#define NROS_CPP_QOS_HPP
12
13#include <stdint.h>
14
15// Phase 379 W5 — the deadline / lifespan / lease accessors take and return
16// `nros::Duration`, so this header names it. `nros.hpp` includes `qos.hpp`
17// before `duration.hpp`, so the dependency is spelled HERE rather than left to
18// the umbrella's ordering: a header that names a type must be able to be
19// included first.
20#include "nros/duration.hpp"
21
22// FFI struct definition — mirrors `nros_cpp_qos_t` in
23// nros_cpp_ffi.h. Phase 118.D: guarded by `NROS_CPP_FFI_H`. If
24// `nros_cpp_ffi.h` was included earlier (it sets that guard), the
25// canonical types are already in scope; otherwise emit local
26// definitions so this header stays self-contained for callers that
27// don't pull the cbindgen header directly.
28//
29// The FIELD names below are ABI. `deadline_ms` / `lifespan_ms` /
30// `liveliness_lease_ms` are `uint32_t` milliseconds and are mirrored again in
31// `nros/component.h` (issue 0160, gated by `check-ffi-struct-mirrors`). The
32// `_ms` suffix on a `QoS` METHOD was renamed in phase-379 W5; the suffix on a
33// STRUCT FIELD was not, and must not be — the C ABI carries milliseconds.
34#ifndef NROS_CPP_FFI_H
35extern "C" {
66}
67#endif // NROS_CPP_FFI_H
68
69namespace nros {
70
71// -- Policy enums (phase 379 W5) ------------------------------------------
72//
73// At NAMESPACE scope and public, under rclcpp's names, because that is where a
74// ported node looks for them (`rclcpp::ReliabilityPolicy`, `qos.hpp:34-58`).
75// Three of these were PRIVATE members of `QoS` until phase-379 W5, which is why
76// the getters had to hand back `int` — a public getter cannot name a private
77// type. Ledger: `cpp:ReliabilityPolicy` and its three siblings.
78//
79// Two deliberate differences from rclcpp survive the rename, both ledgered:
80// * no `SystemDefault` — it means "defer to the middleware" and there is
81// none to defer to; the backend is linked at build time (RFC-0036).
82// * no `Unknown` — it is a discovery artefact for a policy read off a remote
83// endpoint, and we do no dynamic discovery.
84//
85// These are UNSCOPED enums, not rclcpp's `enum class`. Both spellings work as a
86// result: `nros::Reliable` (ours, historical) and `nros::ReliabilityPolicy::
87// Reliable` (rclcpp's). Switching to `enum class` would break the first and is
88// its own decision, which no ledger row makes — see the qos.json rows.
89
95
101
107
122
123class QoS;
124
125namespace detail {
126
142constexpr uint32_t qos_window_ms(const Duration& d) {
143 return d.nanoseconds() <= 0
144 ? 0u
145 : (d.nanoseconds() > static_cast<int64_t>(UINT32_MAX) * 1000000
146 ? UINT32_MAX
147 : static_cast<uint32_t>((d.nanoseconds() + 999999) / 1000000));
148}
149
152constexpr Duration qos_window_duration(uint32_t ms) {
153 return Duration::from_nanoseconds(static_cast<int64_t>(ms) * 1000000);
154}
155
156} // namespace detail
157
173class QoS {
174 public:
176 using Liveliness [[deprecated("QoS::Liveliness is deprecated; use nros::LivelinessPolicy")]] =
178
179 // The four liveliness enumerators were reachable as `QoS::Liveliness*`
180 // while the enum was a member. They still are, deprecated, so no source
181 // that named one stops compiling. The enumerator SPELLING did not change —
182 // only its scope — so `nros::LivelinessAutomatic` is the live name.
183 [[deprecated("QoS::LivelinessNone is deprecated; use "
184 "nros::LivelinessNone")]] static constexpr LivelinessPolicy LivelinessNone =
186 [[deprecated(
187 "QoS::LivelinessAutomatic is deprecated; use "
188 "nros::LivelinessAutomatic")]] static constexpr LivelinessPolicy LivelinessAutomatic =
190 [[deprecated("QoS::LivelinessManualByTopic is deprecated; use "
191 "nros::LivelinessManualByTopic")]] static constexpr LivelinessPolicy
193 [[deprecated(
194 "QoS::LivelinessManualByNode is deprecated; use "
195 "nros::LivelinessManualByNode")]] static constexpr LivelinessPolicy LivelinessManualByNode =
197
200 constexpr QoS()
201 : reliability_(Reliable), durability_(Volatile), history_(KeepLast),
202 liveliness_(::nros::LivelinessAutomatic), depth_(10), deadline_ms_(0), lifespan_ms_(0),
203 liveliness_lease_ms_(0), avoid_ros_namespace_conventions_(0), tx_express_(0) {}
204
208 explicit constexpr QoS(int depth) : QoS() { depth_ = depth; }
209
210 // -- Chainable setters (match rclcpp fluent API) --
211
213 constexpr QoS& reliable() {
214 reliability_ = Reliable;
215 return *this;
216 }
217
219 constexpr QoS& best_effort() {
220 reliability_ = BestEffort;
221 return *this;
222 }
223
225 constexpr QoS& transient_local() {
226 durability_ = TransientLocal;
227 return *this;
228 }
229
232 durability_ = Volatile;
233 return *this;
234 }
235
238 constexpr QoS& keep_last(int depth) {
239 history_ = KeepLast;
240 depth_ = depth;
241 return *this;
242 }
243
245 constexpr QoS& keep_all() {
246 history_ = KeepAll;
247 return *this;
248 }
249
257 constexpr QoS& deadline(const Duration& d) {
258 deadline_ms_ = detail::qos_window_ms(d);
259 return *this;
260 }
261
264 constexpr QoS& lifespan(const Duration& d) {
265 lifespan_ms_ = detail::qos_window_ms(d);
266 return *this;
267 }
268
271 constexpr QoS& liveliness(LivelinessPolicy kind) {
272 liveliness_ = kind;
273 return *this;
274 }
275
278 constexpr QoS& liveliness_lease_duration(const Duration& d) {
279 liveliness_lease_ms_ = detail::qos_window_ms(d);
280 return *this;
281 }
282
286 avoid_ros_namespace_conventions_ = on ? 1 : 0;
287 return *this;
288 }
289
294 constexpr QoS& tx_express(bool on) {
295 tx_express_ = on ? 1 : 0;
296 return *this;
297 }
298
299 // -- Deprecated millisecond setters (phase 379 W5) --
300
302 [[deprecated("QoS::deadline_ms(uint32_t) is deprecated; use "
303 "QoS::deadline(nros::Duration)")]] constexpr QoS&
304 deadline_ms(uint32_t ms) {
305 deadline_ms_ = ms;
306 return *this;
307 }
308
310 [[deprecated("QoS::lifespan_ms(uint32_t) is deprecated; use "
311 "QoS::lifespan(nros::Duration)")]] constexpr QoS&
312 lifespan_ms(uint32_t ms) {
313 lifespan_ms_ = ms;
314 return *this;
315 }
316
318 [[deprecated("QoS::liveliness_lease_ms(uint32_t) is deprecated; use "
319 "QoS::liveliness_lease_duration(nros::Duration)")]] constexpr QoS&
320 liveliness_lease_ms(uint32_t ms) {
321 liveliness_lease_ms_ = ms;
322 return *this;
323 }
324
325 // -- Predefined profiles (match rclcpp named constructors) --
326
328 static constexpr QoS default_profile() { return QoS(); }
329
331 static constexpr QoS sensor_data() { return QoS().best_effort().keep_last(5); }
332
334 static constexpr QoS services() { return QoS().reliable(); }
335
336 // -- Accessors --
337
339 constexpr ReliabilityPolicy reliability() const { return reliability_; }
341 constexpr DurabilityPolicy durability() const { return durability_; }
343 constexpr HistoryPolicy history() const { return history_; }
345 constexpr LivelinessPolicy liveliness() const { return liveliness_; }
347 constexpr int depth() const { return depth_; }
349 constexpr Duration deadline() const { return detail::qos_window_duration(deadline_ms_); }
351 constexpr Duration lifespan() const { return detail::qos_window_duration(lifespan_ms_); }
353 constexpr Duration liveliness_lease_duration() const {
354 return detail::qos_window_duration(liveliness_lease_ms_);
355 }
357 constexpr bool avoid_ros_namespace_conventions() const {
358 return avoid_ros_namespace_conventions_ != 0;
359 }
361 constexpr bool tx_express() const { return tx_express_ != 0; }
362
363 // -- Deprecated accessors (phase 379 W5) --
364 //
365 // The `_raw()` four existed only because their enums were private; the
366 // `_ms()` three only because C++ had no `Duration`. Both reasons are gone.
367
369 [[deprecated("QoS::reliability_raw() is deprecated; use QoS::reliability()")]] constexpr int
371 return static_cast<int>(reliability_);
372 }
374 [[deprecated("QoS::durability_raw() is deprecated; use QoS::durability()")]] constexpr int
376 return static_cast<int>(durability_);
377 }
379 [[deprecated("QoS::history_raw() is deprecated; use QoS::history()")]] constexpr int
380 history_raw() const {
381 return static_cast<int>(history_);
382 }
384 [[deprecated("QoS::liveliness_raw() is deprecated; use QoS::liveliness()")]] constexpr int
386 return static_cast<int>(liveliness_);
387 }
389 [[deprecated("QoS::deadline_ms() is deprecated; use QoS::deadline()")]] constexpr uint32_t
390 deadline_ms() const {
391 return deadline_ms_;
392 }
394 [[deprecated("QoS::lifespan_ms() is deprecated; use QoS::lifespan()")]] constexpr uint32_t
395 lifespan_ms() const {
396 return lifespan_ms_;
397 }
399 [[deprecated("QoS::liveliness_lease_ms() is deprecated; use "
400 "QoS::liveliness_lease_duration()")]] constexpr uint32_t
402 return liveliness_lease_ms_;
403 }
404
405 private:
406 // The private members keep their `_ms_` spelling: they hold exactly what
407 // the C ABI carries (`uint32_t` milliseconds), and renaming them would say
408 // the storage changed when only the accessors did.
409 ReliabilityPolicy reliability_;
410 DurabilityPolicy durability_;
411 HistoryPolicy history_;
412 LivelinessPolicy liveliness_;
413 int depth_;
414 uint32_t deadline_ms_;
415 uint32_t lifespan_ms_;
416 uint32_t liveliness_lease_ms_;
417 uint8_t avoid_ros_namespace_conventions_;
418 uint8_t tx_express_;
419};
420
421namespace detail {
422
436constexpr nros_cpp_qos_t qos_to_ffi(const QoS& qos) {
437 nros_cpp_qos_t f{};
438 f.reliability = static_cast<nros_cpp_qos_reliability_t>(qos.reliability());
439 f.durability = static_cast<nros_cpp_qos_durability_t>(qos.durability());
440 f.history = static_cast<nros_cpp_qos_history_t>(qos.history());
441 f.liveliness_kind = static_cast<nros_cpp_qos_liveliness_t>(qos.liveliness());
442 f.depth = qos.depth();
443 // The FFI FIELDS are milliseconds and keep their `_ms` names; only the
444 // accessors changed. `qos_window_ms` is the exact inverse of the
445 // `Duration` the getter built, so this round-trip loses nothing.
446 f.deadline_ms = qos_window_ms(qos.deadline());
447 f.lifespan_ms = qos_window_ms(qos.lifespan());
448 f.liveliness_lease_ms = qos_window_ms(qos.liveliness_lease_duration());
449 f.avoid_ros_namespace_conventions = qos.avoid_ros_namespace_conventions() ? 1 : 0;
450 f.tx_express = qos.tx_express() ? 1 : 0;
451 return f;
452}
453
454} // namespace detail
455
456} // namespace nros
457
458#endif // NROS_CPP_QOS_HPP
Definition qos.hpp:173
constexpr int depth() const
Configured queue depth (only meaningful for KEEP_LAST).
Definition qos.hpp:347
constexpr QoS & best_effort()
Set reliability to BEST_EFFORT (fire-and-forget; default for sensors).
Definition qos.hpp:219
constexpr HistoryPolicy history() const
The history policy.
Definition qos.hpp:343
constexpr int history_raw() const
Definition qos.hpp:380
constexpr bool avoid_ros_namespace_conventions() const
Whether to skip the /rt/ ROS topic-name prefix.
Definition qos.hpp:357
constexpr Duration lifespan() const
The lifespan window. Duration() (zero) = infinite.
Definition qos.hpp:351
constexpr uint32_t lifespan_ms() const
Definition qos.hpp:395
constexpr QoS & deadline_ms(uint32_t ms)
Definition qos.hpp:304
constexpr QoS & liveliness_lease_duration(const Duration &d)
Definition qos.hpp:278
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
constexpr ReliabilityPolicy reliability() const
The reliability policy.
Definition qos.hpp:339
constexpr QoS & avoid_ros_namespace_conventions(bool on)
Definition qos.hpp:285
constexpr Duration deadline() const
The deadline window. Duration() (zero) = infinite.
Definition qos.hpp:349
constexpr QoS & reliable()
Set reliability to RELIABLE (acked transport, retransmits on loss).
Definition qos.hpp:213
constexpr DurabilityPolicy durability() const
The durability policy.
Definition qos.hpp:341
static constexpr QoS sensor_data()
Sensor-data profile: BEST_EFFORT + VOLATILE + KEEP_LAST(5).
Definition qos.hpp:331
constexpr Duration liveliness_lease_duration() const
The liveliness lease window. Duration() (zero) = infinite.
Definition qos.hpp:353
constexpr QoS & tx_express(bool on)
Definition qos.hpp:294
static constexpr LivelinessPolicy LivelinessAutomatic
Definition qos.hpp:188
constexpr uint32_t deadline_ms() const
Definition qos.hpp:390
constexpr QoS()
Definition qos.hpp:200
constexpr LivelinessPolicy liveliness() const
The liveliness policy kind.
Definition qos.hpp:345
constexpr QoS & lifespan_ms(uint32_t ms)
Definition qos.hpp:312
constexpr int liveliness_raw() const
Definition qos.hpp:385
constexpr int reliability_raw() const
Definition qos.hpp:370
constexpr QoS & keep_last(int depth)
Definition qos.hpp:238
constexpr QoS & durability_volatile()
Set durability to VOLATILE — late joiners get nothing (default).
Definition qos.hpp:231
constexpr QoS & liveliness(LivelinessPolicy kind)
Definition qos.hpp:271
constexpr uint32_t liveliness_lease_ms() const
Definition qos.hpp:401
constexpr int durability_raw() const
Definition qos.hpp:375
constexpr QoS & keep_all()
Use KEEP_ALL history (bounded by transport).
Definition qos.hpp:245
static constexpr LivelinessPolicy LivelinessManualByNode
Definition qos.hpp:195
constexpr bool tx_express() const
Whether this publisher's samples bypass transport tx batching.
Definition qos.hpp:361
static constexpr LivelinessPolicy LivelinessNone
Definition qos.hpp:184
constexpr QoS & deadline(const Duration &d)
Definition qos.hpp:257
static constexpr LivelinessPolicy LivelinessManualByTopic
Definition qos.hpp:192
constexpr QoS & transient_local()
Set durability to TRANSIENT_LOCAL — late joiners get the last value.
Definition qos.hpp:225
constexpr QoS & liveliness_lease_ms(uint32_t ms)
Definition qos.hpp:320
constexpr QoS(int depth)
Definition qos.hpp:208
constexpr QoS & lifespan(const Duration &d)
Definition qos.hpp:264
constexpr uint32_t qos_window_ms(const Duration &d)
Definition qos.hpp:142
constexpr Duration qos_window_duration(uint32_t ms)
Definition qos.hpp:152
Definition nros.hpp:55
LivelinessPolicy
Definition qos.hpp:116
@ LivelinessManualByNode
Definition qos.hpp:120
@ LivelinessNone
Definition qos.hpp:117
@ LivelinessAutomatic
Definition qos.hpp:118
@ LivelinessManualByTopic
Definition qos.hpp:119
HistoryPolicy
History policy. Matches DDS HISTORY_QOS_POLICY.
Definition qos.hpp:103
@ KeepLast
Definition qos.hpp:104
@ KeepAll
Definition qos.hpp:105
ReliabilityPolicy
Reliability policy. Matches DDS RELIABILITY_QOS_POLICY.
Definition qos.hpp:91
@ BestEffort
Definition qos.hpp:93
@ Reliable
Definition qos.hpp:92
DurabilityPolicy
Durability policy. Matches DDS DURABILITY_QOS_POLICY.
Definition qos.hpp:97
@ TransientLocal
Definition qos.hpp:99
@ Volatile
Definition qos.hpp:98
nros_cpp_qos_history_t
Definition qos.hpp:44
@ NROS_CPP_QOS_KEEP_LAST
Definition qos.hpp:45
@ NROS_CPP_QOS_KEEP_ALL
Definition qos.hpp:46
nros_cpp_qos_liveliness_t
Definition qos.hpp:48
@ NROS_CPP_QOS_LIVELINESS_MANUAL_BY_NODE
Definition qos.hpp:52
@ NROS_CPP_QOS_LIVELINESS_AUTOMATIC
Definition qos.hpp:50
@ NROS_CPP_QOS_LIVELINESS_MANUAL_BY_TOPIC
Definition qos.hpp:51
@ NROS_CPP_QOS_LIVELINESS_NONE
Definition qos.hpp:49
nros_cpp_qos_durability_t
Definition qos.hpp:40
@ NROS_CPP_QOS_VOLATILE
Definition qos.hpp:41
@ NROS_CPP_QOS_TRANSIENT_LOCAL
Definition qos.hpp:42
nros_cpp_qos_reliability_t
Definition qos.hpp:36
@ NROS_CPP_QOS_RELIABLE
Definition qos.hpp:37
@ NROS_CPP_QOS_BEST_EFFORT
Definition qos.hpp:38
Definition qos.hpp:54
enum nros_cpp_qos_durability_t durability
Definition qos.hpp:56
uint32_t liveliness_lease_ms
Definition qos.hpp:62
uint32_t lifespan_ms
Definition qos.hpp:61
enum nros_cpp_qos_history_t history
Definition qos.hpp:57
uint8_t tx_express
Definition qos.hpp:64
enum nros_cpp_qos_liveliness_t liveliness_kind
Definition qos.hpp:58
enum nros_cpp_qos_reliability_t reliability
Definition qos.hpp:55
uint8_t avoid_ros_namespace_conventions
Definition qos.hpp:63
uint32_t deadline_ms
Definition qos.hpp:60
int depth
Definition qos.hpp:59