QoS Silent No-Match

← Back to overview

The pain

DDS matches a publisher and subscriber only if their QoS is compatible (reliability, durability, history, deadline, liveliness…). When it is not compatible, the spec behaviour is to silently not match — no data, and often no error the application ever sees (36 reports). The result is the most demoralizing ROS 2 debugging session there is: everything looks connected, ros2 topic list shows the topic, and not a single message arrives.

  • A sensor driver publishes BEST_EFFORT; your node subscribes RELIABLE → no match, no message, no log.
  • transient_local (latched) on one side only → silent no-match.
  • The community position is that QoS compatibility is “too strict” and fails in a way that is invisible to non-experts.

Most recent example

ros2#1562 — “QoS compatibility is too strict, should be more user-friendly and flexible” (2024-05-10). A maintainer-level request acknowledging that the current QoS-compatibility model produces silent failures that are hostile to users, and asking for friendlier, more visible behaviour.

Reference list (most recent)

Date Source Problem
2024-05-10 ros2#1562 QoS compatibility too strict; silent, user-hostile
2024-01-31 Stereolabs forum ZED wrapper QoS mismatch → no data, user stuck
2024-01-12 rviz#1122 RViz: “requesting incompatible QoS” on /scan
2023-09-13 rmw_cyclonedds#473 Lifespan silently not working with transient_local
2023-08-29 rclcpp#2291 Intra-process type adaptation fails silently on type mismatch

How ZeroDDS solves it

Make the failure loud, and catch it before launch.

  • Loud no-match events. When an endpoint is discovered but the QoS is incompatible, ZeroDDS emits a qos.incompatible.offered / qos.incompatible.requested event naming the exact offending policy (via a qos_policy_id_name helper) instead of silently dropping the match. The unit test incompatible_qos_match_emits_loud_warning pins this behaviour.
  • Static pre-flight validation. The qos_check CLI computes publisher/subscriber compatibility before you launch and exits non-zero on a mismatch, with the specific incompatible policy reported — so a CI job or a launch wrapper catches “RELIABLE vs BEST_EFFORT” the moment it is introduced, not after a field debugging session.
  • Right defaults so the common case just matches. RuntimeConfig::ros_defaults() offers the representations and caps ROS writers actually use, so the most common silent-mismatch cause (representation/encoding) does not arise out of the box.

Why it no longer has to be a pain

The pain is not that QoS has rules — it is that breaking them is invisible. ZeroDDS keeps the spec-correct matching semantics (so interop is preserved) but converts the silent no-match into a named, surfaced event and a pre-launch check. The bug stops being “no data, no clue” and becomes “line 12: RELIABLE requested, BEST_EFFORT offered.”

Reproduce it yourself

# Static QoS compatibility check (exit code + named offending policy):
cargo run -p zerodds-qos --example qos_check -- <writer-qos> <reader-qos>

The loud-warning path is covered by incompatible_qos_match_emits_loud_warning in the DCPS test suite.

→ Back to overview · Next: Large data

QoS stilles No-Match

← Zurück zur Übersicht

Der Schmerz

DDS matcht einen Publisher und Subscriber nur, wenn ihre QoS kompatibel ist (Reliability, Durability, History, Deadline, Liveliness…). Wenn sie nicht kompatibel ist, ist das Spec-Verhalten, still nicht zu matchen — keine Daten, und oft kein Fehler, den die Anwendung je sieht (36 Reports). Das Ergebnis ist die demoralisierendste ROS-2-Debugging-Session, die es gibt: alles sieht verbunden aus, ros2 topic list zeigt das Topic, und keine einzige Nachricht kommt an.

  • Ein Sensor-Treiber publiziert BEST_EFFORT; dein Node subscribt RELIABLE → kein Match, keine Nachricht, kein Log.
  • transient_local (latched) nur auf einer Seite → stilles No-Match.
  • Die Community-Position ist, dass QoS-Kompatibilität „zu strikt” ist und auf eine Weise scheitert, die für Nicht-Experten unsichtbar ist.

Jüngstes Beispiel

ros2#1562 — „QoS compatibility is too strict, should be more user-friendly and flexible” (2024-05-10). Eine Anfrage auf Maintainer-Ebene, die anerkennt, dass das aktuelle QoS-Kompatibilitätsmodell stille Fehler produziert, die nutzerfeindlich sind, und um freundlicheres, sichtbareres Verhalten bittet.

Referenzliste (jüngste zuerst)

Datum Quelle Problem
2024-05-10 ros2#1562 QoS-Kompatibilität zu strikt; still, nutzerfeindlich
2024-01-31 Stereolabs-Forum ZED-Wrapper-QoS-Mismatch → keine Daten, Nutzer steckt fest
2024-01-12 rviz#1122 RViz: „requesting incompatible QoS” auf /scan
2023-09-13 rmw_cyclonedds#473 Lifespan funktioniert still nicht mit transient_local
2023-08-29 rclcpp#2291 Intra-Process-Type-Adaptation scheitert still bei Type-Mismatch

Wie ZeroDDS es löst

Mach den Fehler laut, und fang ihn vor dem Launch ab.

  • Laute No-Match-Events. Wenn ein Endpoint entdeckt wird, die QoS aber inkompatibel ist, emittiert ZeroDDS ein qos.incompatible.offered- / qos.incompatible.requested-Event, das die genaue verletzende Policy nennt (via qos_policy_id_name-Helper), statt den Match still zu droppen. Der Unit-Test incompatible_qos_match_emits_loud_warning pinnt dieses Verhalten.
  • Statische Pre-Flight-Validierung. Das qos_check-CLI berechnet die Publisher/Subscriber-Kompatibilität vor dem Launch und exitet non-zero bei einem Mismatch, mit der konkreten inkompatiblen Policy gemeldet — sodass ein CI-Job oder ein Launch-Wrapper „RELIABLE vs BEST_EFFORT” in dem Moment fängt, in dem es eingeführt wird, nicht nach einer Feld-Debugging-Session.
  • Richtige Defaults, sodass der Normalfall einfach matcht. RuntimeConfig::ros_defaults() bietet die Representations und Caps, die ROS-Writer tatsächlich nutzen, sodass die häufigste stille-Mismatch-Ursache (Representation/Encoding) out of the box nicht entsteht.

Warum es kein Schmerz mehr sein muss

Der Schmerz ist nicht, dass QoS Regeln hat — es ist, dass sie zu brechen unsichtbar ist. ZeroDDS behält die spec-korrekte Matching-Semantik (sodass Interop erhalten bleibt), wandelt das stille No-Match aber in ein benanntes, sichtbares Event und einen Pre-Launch-Check um. Der Bug ist nicht mehr „keine Daten, keine Ahnung”, sondern „Zeile 12: RELIABLE requested, BEST_EFFORT offered.”

Selbst reproduzieren

# Statischer QoS-Kompatibilitäts-Check (Exit-Code + benannte verletzende Policy):
cargo run -p zerodds-qos --example qos_check -- <writer-qos> <reader-qos>

Der Laute-Warnung-Pfad ist durch incompatible_qos_match_emits_loud_warning in der DCPS-Test-Suite abgedeckt.

→ Zurück zur Übersicht · Weiter: Large-Data