QoS Silent No-Match
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.requestedevent naming the exact offending policy (via aqos_policy_id_namehelper) instead of silently dropping the match. The unit testincompatible_qos_match_emits_loud_warningpins this behaviour. - Static pre-flight validation. The
qos_checkCLI 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
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 (viaqos_policy_id_name-Helper), statt den Match still zu droppen. Der Unit-Testincompatible_qos_match_emits_loud_warningpinnt 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