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