How to Use Ros2 for Real-Time Robot Data Processing
Table of Contents
Echtzeit-Datenverarbeitung mit ROS2
Das Robot Operating System 2 (ROS2) ist zum Standard-Framework für den Aufbau von Robotersystemen mit deterministischer Latenz geworden, die eine deterministische Kommunikation mit geringer Latenz erfordern. Echtzeit-Datenverarbeitung ist für Anwendungen wie autonomes Fahren, industrielle Manipulation und Drohnen unerlässlich, wo das Fehlen eines Termins Systemausfälle verursachen kann. ROS2 adressiert diese Herausforderungen durch seine modulare Publisher-Abonnenten-Architektur, die durch die DDS-Middleware (Data Distribution Service) unterstützt wird. Im Gegensatz zu ROS1 wurde ROS2 von Grund auf so konzipiert, dass es Echtzeit-Einschränkungen unterstützt, konfigurierbare Quality-of-Service-Richtlinien (QoS) bietet, mehrere Ausführungsmodelle und Kompatibilität mit Echtzeit-Betriebssystemen. Dieser Leitfaden erklärt, wie ROS2 für die Echtzeit-Roboterdatenverarbeitung genutzt werden kann, von architektonischen Grundlagen bis hin zu fortschrittlichen Optimierungstechniken.
Kernarchitektur: Nodes, Themen, Services und Aktionen
Das Kommunikationsparadigma von ROS2 basiert auf vier Schlüsselabstraktionen:
- Knotenpunkte In Echtzeitsystemen läuft jeder Knoten typischerweise in seinem eigenen Prozess, wodurch eine Speicherisolierung erreicht wird und der Systementwickler CPU-Affinitäten und Planungsrichtlinien pro Knoten zuweisen kann.
- Themen Datenproduzenten veröffentlichen zu einem benannten Thema und Verbraucher abonnieren Nachrichten. Die DDS-Middleware übernimmt die Erkennung, Serialisierung und den Transport, so dass Knoten zur Laufzeit ohne Rekonfiguration hinzugefügt oder entfernt werden können.
- Dienstleistungen synchrone Anfrage-Antwort-Kommunikation bereitstellen: Dienste sind zwar nicht in Echtzeit, aber für Konfigurationsänderungen oder Parameteraktualisierungen nützlich, die keine harten Fristen erfordern.
- Aktionen erweitern Dienste für langfristige Ziele mit periodischem Feedback, geeignet für Aufgaben wie Navigationswegpunkt, der dem Zwischenstatus folgt.
Für Echtzeitanwendungen ist das themenbasierte Publish-Subscribe-Modell die häufigste Wahl, da es die entkoppelte Kommunikation unterstützt und für eine deterministische Bereitstellung über DDS-Servicequalitätseinstellungen abgestimmt werden kann.
ROS2 für die Echtzeit-Datenverarbeitung einrichten
Installation und DDS Selection
Beginnen Sie mit der Installation einer aktuellen ROS2-Distribution wie Humble Hawksbill, Eisen-Irwini, oder Rolling Ridley auf einem Betriebssystem, das Echtzeitplanung unterstützt – Linux mit einem Echtzeit-Kernel-Patch, QNX oder VxWorks. Die Standard-DS-Implementierung (Fast DDS) funktioniert für viele Systeme gut, aber für strenge Echtzeitanforderungen sollten Alternativen in Betracht gezogen werden:
- Zyklon DDS – Bekannt für geringe Latenz und hohe Skalierbarkeit; in der Produktion autonome Fahrzeugsysteme verwendet.
- RTI Connext Pro Ein kommerzielles DDS mit erweiterter Echtzeitplanung, Sicherheitsfunktionen und einem gemeinsamen Speicher ohne Kopie.
- Schnelle DDS - Die Standardoption; die neuesten Versionen enthalten einen gemeinsamen Speichertransport mit niedrigem Jitter.
Nach der Installation konfigurieren Sie die DDS-Domäne und die QoS-Standards entsprechend den Timing-Anforderungen Ihrer Anwendung. Legen Sie die Umgebungsvariable so fest, dass Ihr System von anderen ROS2-Netzwerken isoliert wird. Passen Sie die DDS-Konfigurationsdatei (z. B. für Fast DDS oder für Cyclone DDS) an, um den gemeinsamen Speichertransport zu aktivieren und Thread-Prioritäten festzulegen.
Echtzeit-Kernel und Prozessplanung
Um ein deterministisches Timing zu erreichen, muss der Regelkreis Ihres Roboters mit erhöhter Priorität ausgeführt werden.
- Installieren Sie einen Echtzeit-Kernel – für Ubuntu verwenden Sie ; alternativ wenden Sie den PREEMPT RT-Patch auf Ihren Kernel an.
- Bearbeiten Sie , damit Ihr Benutzer Echtzeit-Prioritäten festlegen kann, z. B. .
- Weisen Sie Ihren ROS2-Knoten Echtzeit-Planungsrichtlinien mit oder Systemaufruf zu. Normalerweise funktioniert mit einer Priorität von 80-95 gut für Regelkreise.
Verwenden Sie für die erweiterte Isolation den Kernel-Boot-Parameter , um CPU-Kerne für Echtzeit-Aufgaben zu reservieren, und verbinden Sie dann die Threads jedes Knotens mit oder an dedizierte Kerne.
Entwicklung von Echtzeit-Datenknoten
Node Design Prinzipien
Das Schreiben von Echtzeit-Knoten in ROS2 erfordert eine sorgfältige Aufmerksamkeit auf die Ressourcennutzung in Callbacks:
- Dynamische Speicherzuweisung vermeiden Inside Callbacks. Verwenden Sie vorab zugewiesene Puffer und vermeiden Sie , oder STL-Containeroperationen wie , die eine Heap-Fragmentierung verursachen können.
- Halten Sie Callbacks kurz und deterministischKomplexe Verarbeitung sollte auf einen separaten Thread oder Executor übertragen werden, wobei Rückrufe auf das Parsen von Daten und das Veröffentlichen zu neuen Themen beschränkt sind.
- Verwenden Sie den entsprechenden Executor. Die ordnet Speicher für alle Timer und Abonnements vor und bietet eine vorhersagbare Rückrufplanung. Für Multithreaded-Knoten wenden Sie mit einer festen Anzahl von Threads an. Vermeiden Sie den Standard für zeitkritische Knoten, da dies keine deterministische Ordnung garantiert.
Erwägen Sie außerdem, das ROS2 zu verwenden Echtzeit-unterstützter Executor (verfügbar in Iron und höher), die Thread-Prioritäten respektiert und Prioritätsinversion während der Callback-Ausführung vermeidet.
Umsetzung von Qualität der Dienstleistungen
ROS2 QoS-Richtlinien sind das wichtigste Instrument zur Durchsetzung von Echtzeitverhalten.
- Zuverlässigkeit: Setzen Sie auf für die garantierte Lieferung von kritischen Befehlen; verwenden Sie für Sensordaten, bei denen gelegentliche Tropfen tolerierbar sind, aber eine minimale Latenz unerlässlich ist.
- Dauerhaltbarkeit: für transiente Sensordaten; für persistente Zustandsinformationen wie Kartendaten.
- Frist: Erzwingt, dass eine Nachricht innerhalb einer bestimmten Dauer empfangen wird. Wenn der Publisher die Frist nicht einhält, warnt die Middleware die Abonnenten. Dies ist für Regelkreise, die Daten mit einer festen Rate (z. B. alle 10 ms) benötigen, von entscheidender Bedeutung.
- LatenzhaushaltDDS-Implementierungen optimieren den Transport entsprechend - zum Beispiel durch die Verwendung von Shared Memory anstelle von Netzwerk, wenn das Budget sehr knapp ist.
- Lebensdauer: Verwirft automatisch Daten, die älter als ein Schwellenwert sind, und verhindert, dass veraltete Informationen verarbeitet werden.
- Geschichte: Setzen Sie auf mit Tiefe 1 oder 2, um die Speichernutzung zu minimieren und die Nachschlagezeit zu reduzieren.
Beispiel C++ Snippet für einen Publisher mit Echtzeit-QoS:
Unstimmige QoS-Einstellungen zwischen Publisher und Abonnent können Verbindungsfehler verursachen; immer mit testen, um die Kompatibilität zu überprüfen.
Testen und Optimieren
Messung von Latenz und Durchsatz
ROS2 bietet mehrere Tools zur Bewertung der Echtzeit-Leistung:
- Mit dem Flag protokolliert die FLT:26 Nachrichtenzeitstempel für die Offline-Analyse von Jitter.
- (aus dem Paket ) misst die Round-Trip-Verzögerung zwischen zwei Knoten.
- Benutzerdefinierte Latenzmessung mit gestempelten Nachrichten: Veröffentlichen Sie eine Nachricht mit einem synthetischen Zeitstempel und berechnen Sie die Verzögerung auf der Abonnentenseite.
- prüft auf häufige Probleme wie QoS-Mismatches und Netzwerküberlastung.
Profilknoten CPU-Nutzung mit oder , um Engpässe zu identifizieren. Achten Sie besonders auf die Rückrufausführungszeit; wenn Rückrufe einige Mikrosekunden überschreiten, laden Sie die Verarbeitung in einen separaten Thread ab oder reduzieren Sie die Nachrichtenrate. Verwenden Sie innerhalb von Rückrufen, um die Ausführungszeit zu messen, aber achten Sie darauf, keine dynamische Zuweisung über das Uhrenobjekt einzuführen.
Optimierung des Nachrichtentransports
Große Datenströme – Punktwolken, Bilder, hochtourige IMU-Daten – profitieren von Transportoptimierungen:
- Zero-Copy Shared Memory: Aktivieren Sie dies, wenn Sie ein DDS verwenden, das SHMEM unterstützt (Fast DDS mit , Cyclone DDS mit freigegebenem Speicher oder RTI Connext Pro mit freigegebenem Speichertransport).
- Serialisierungs-Overhead reduzierenVerwenden Sie flache Nachrichtenstrukturen anstelle tief verschachtelter Typen. vermeiden Sie Felder in Hochfrequenznachrichten; verwenden Sie stattdessen Arrays mit fester Länge oder Integer-Kennungen.
- DDS History Tiefe anpassenMit Tiefe 1 behält die Middleware nur das neueste Sample, wodurch Speicher und Nachschlagezeit minimiert werden.
- Verwenden Sie die Intra-Prozess-Kommunikation (IPC) Funktion, wenn Knoten im selben Prozess ausgeführt werden. Aktivieren Sie und setzen Sie in Ihrem Knoten. Dies umgeht DDS vollständig für die Kommunikation mit dem gleichen Prozess und bietet die geringstmögliche Latenz.
Fortgeschrittene Echtzeit-Techniken
Echtzeit-Executor und Timer Scheduling
Die ist ideal für die deterministische Callback-Ausführung, da sie allen erforderlichen Speicher vorab zuweist und dynamische Planungsentscheidungen vermeidet.
Bei Multi-Rate-Systemen sollten für jede Rate-Gruppe separate Executoren verwendet werden, die jeweils an einen anderen Kern gekoppelt sind, wodurch verhindert wird, dass ein Rückruf mit niedriger Rate einen Hochrate-Prozess blockiert.
Integration mit Real-Time Linux (PREEMPT RT)
Bei Verwendung des PREEMPT RT-Kernel-Patches ist sicherzustellen, dass ROS2-Knoten Systemaufrufe in Echtzeit-Threads nicht blockieren.
- Dynamische Speicherzuweisung: Verwenden Sie vorab zugewiesene Pools in Callbacks.
- Datei I/ODie Anmeldung zur Festplatte sollte in einem separaten Nicht-Echtzeit-Thread erfolgen.
- Printf-style DebuggingVerwenden Sie nur in der Entwicklung; diese Aufrufe können Mutexe blockieren.
- Prioritätsinversion: Verwenden Sie prioritäre Vererbungs-Mutexe (), um gemeinsam genutzte Ressourcen zu schützen. Die DDS-Implementierungen von ROS2 behandeln dies normalerweise korrekt, aber benutzerdefinierte Mutexe müssen explizit konfiguriert werden.
Testen Sie Ihr System unter Last im schlimmsten Fall mit Tools wie , um die maximale Latenz zu messen und sicherzustellen, dass es unter Ihren Fristen bleibt.
Umgang mit Multi-Rate und Mixed Criticality
Robotersysteme haben Sensoren, die oft mit unterschiedlichen Geschwindigkeiten arbeiten – eine Kamera mit 30 Hz, LiDAR mit 10 Hz, IMU mit 1 kHz. Verwenden Sie separate Executoren für jede Ratengruppe, die jeweils an einen dedizierten CPU-Kern gekoppelt sind. Weisen Sie Aufgaben mit engeren Fristen höhere Prioritäten zu (z. B. IMU-Verarbeitung mit Priorität 95, Steuerung mit 90, LiDAR mit 80, nicht-kritische Protokollierung mit 50). rclcpp lifecycle Framework zum Verwalten von Knotenzustandsübergängen (unkonfiguriert → inaktiv → aktiv) und um sicherzustellen, dass Echtzeitkomponenten nur dann aktiv sind, wenn das System bereit ist.
Praktischer Anwendungsfall: Echtzeit-LiDAR-Datenverarbeitung
Betrachten wir einen autonomen mobilen Roboter, der einen Velodyne LiDAR-Scan (300.000 Punkte pro Sekunde) verarbeiten und eine gefilterte Punktwolke mit einer maximalen Latenz von 10 ms ausgeben muss.
- Fahrerknoten: Lesen Sie Rohdaten aus dem LiDAR über eine Ethernet-Buchse und veröffentlichen Sie Rohpakete () mit der nativen Rate des Sensors (10 Hz).
- Echtzeit-Filterknoten: Abonniert rohe Pakete, wendet einen Passthrough-Filter an (Entfernen von Punkten über 2 Meter Höhe) und veröffentlicht gefilterte Punkte (.
- Lokalisierungsknoten: Verwendet die gefilterte Cloud für den Scan-Matching bei 10 Hz.
Um die 10 ms Frist einzuhalten:
- Setzen Sie die QoS-Frist auf 10 ms sowohl für Roh- als auch für gefilterte Themen.
- Verbinden Sie Treiber und Filterknoten mit dedizierten CPU-Kernen mit SCHED FIFO-Priorität 95.
- Verwenden Sie den Transport von Shared Memory, um die Serialisierung von 2 MB Punktwolkendaten zu vermeiden.
- Verwenden Sie innerhalb des Filter-Callbacks vorab zugewiesene Puffer mit fester Größe, z. B. weisen Sie während der Node-Initialisierung ein mit zu und verwenden Sie es dann in jedem Callback mit wieder (was keine Kapazität neu zuordnet).
- Vermeiden Sie dynamische Strukturen: Verwenden Sie nicht ; verfolgen Sie stattdessen die Anzahl der gültigen Punkte mit einem Zähler und fügen Sie diese über die Array-Indizierung ein.
Nach der Bereitstellung Latenz mit einem benutzerdefinierten Knoten überwachen, der jede gefilterte Cloud mit einem Zeitstempel vergleicht und mit dem ursprünglichen Paket-Zeitstempel vergleicht. Verwenden Sie , um die Roundtrip-Zeiten zu überprüfen, und , um unnötige Präemptionen zu erkennen.
Schlussfolgerung
ROS2 bietet ein robustes Ökosystem für die Echtzeit-Roboterdatenverarbeitung, das verteilte Rechenflexibilität mit dem Determinismus kombiniert, der von modernen autonomen Systemen gefordert wird. Der Erfolg hängt von der Auswahl der richtigen DDS-Implementierung, der korrekten Konfiguration von QoS-Richtlinien und dem Entwurf von Knoten mit Echtzeitbeschränkungen von Anfang an ab. Durch die Verwendung von Echtzeit-Kerneln, Priority Scheduling und Zero-Copy-Transport können Entwickler Systeme erstellen, die hochrate Sensordaten mit vorhersehbaren Latenzen verarbeiten. Mit der Weiterentwicklung von ROS2 werden die Unterstützung zeitsensibler Netzwerke (Time-Sensible Networking, TSN) und eine engere Integration mit Hardware-Beschleunigern wie FPGAs und GPUs seine Fähigkeiten für die missionskritische Robotik weiter erweitern.
Für weitere Informationen lesen Sie die offizielle ROS2-Echtzeitdokumentation ()Echtzeit-Programmierung Tutorial), die DDS Performance Benchmarks von eProsima (Schnelle DDS), und das PREEMPT RT-Projekt (Echtzeit Linux Wiki. Die ROS2 Echtzeit-Hintergrund Ein Artikel bietet einen tieferen Einblick in die Designphilosophie hinter der Echtzeit-Unterstützung des Frameworks. Für praktische Experimente enthält das ROS2-Demos-Repository Echtzeit-Beispiele mit ausführbarem Code.