Standardizing SYSTEM_DEFAULT QoS resolution across RMW implementations

When a node uses SystemDefaultsQoS() (or leaves any policy to *_SYSTEM_DEFAULT), the intent is clear: delegate QoS
resolution to the underlying middleware. In theory, this is the right hook for system-wide QoS configuration without touching
node code.

In practice, the behavior is inconsistent across RMW implementations:

  • FastDDS: supports full XML-based QoS override via FASTDDS_DEFAULT_PROFILES_FILE + RMW_FASTRTPS_USE_QOS_FROM_XML=1.
    Works as expected for SYSTEM_DEFAULT policies.
  • CycloneDDS: CYCLONEDDS_URI controls participant-level settings (network, threads), not endpoint QoS (reliability,
    durability, depth). No equivalent mechanism exists.
  • Zenoh (rmw_zenoh): end-to-end reliability for RELIABLE + VOLATILE + KEEP_LAST is not yet fully implemented
    (ros2/rmw_zenoh#457), and there is no external configuration mechanism for
    endpoint QoS defaults.

The consequence is that a node written with SystemDefaultsQoS() — which is arguably the correct way to write portable,
externally-configurable nodes — behaves differently depending on which RMW is in use, and is only truly configurable on one of
them.

Root cause

All predefined QoS profiles (SensorDataQoS, ParametersQoS, ServicesQoS, etc.) are defined as static const in
rmw/qos_profiles.h — hardcoded values with no indirection layer:

Profile Reliability Durability Depth
QoS(n) / default RELIABLE VOLATILE 10
SensorDataQoS() BEST_EFFORT VOLATILE 5
ParametersQoS() RELIABLE VOLATILE 1000
ServicesQoS() RELIABLE VOLATILE 10
RosoutQoS() RELIABLE TRANSIENT_LOCAL 1000
SystemDefaultsQoS() SYSTEM_DEFAULT SYSTEM_DEFAULT SYSTEM_DEFAULT

A node calling SensorDataQoS() gets BEST_EFFORT with depth 5, unconditionally. The only escape hatch is
SystemDefaultsQoS(), but its resolution is RMW-specific and undocumented as a standard contract.

Proposal

Define a minimal standardized mechanism at the rcl or rmw interface level for resolving SYSTEM_DEFAULT QoS policies. This
could be:

  • A well-defined env var (e.g. RCL_DEFAULT_QOS_PROFILE) pointing to a vendor-neutral config file (YAML or similar), parsed by
    rcl before handing off to the RMW.
  • Or alternatively, a formal contract in the RMW interface spec requiring each implementation to document how it resolves
    SYSTEM_DEFAULT policies and what configuration mechanism it exposes.

This would make SystemDefaultsQoS() actually useful as a portability and deployment tool — especially relevant as more RMW
implementations (Zenoh, Eclipse Cyclone, proprietary) diverge from the DDS XML model.

Interested in hearing whether others have hit this in practice, and whether there is appetite for a REP or a design doc to
formalize this.

4 Likes