Architecture de HDDS
HDDS suit une architecture en couches conçue pour la performance, la modularité et la conformité aux standards.
Vue d'ensemble des couches
+---------------------------------------------------------+
| Couche Application |
| (Votre application Rust/C/C++/Python) |
+---------------------------------------------------------+
| Couche DCPS |
| DomainParticipant | Publisher | Subscriber | Topic | QoS|
+---------------------------------------------------------+
| Couche RTPS |
| Discovery (SPDP/SEDP) | Writers | Readers | History |
+---------------------------------------------------------+
| Couche Transport |
| UDP Multicast | UDP Unicast | Shared Memory |
+---------------------------------------------------------+
Couche DCPS (Data-Centric Publish-Subscribe)
La couche DCPS fournit l'API DDS avec laquelle les applications interagissent :
| Entité | Role |
|---|---|
| DomainParticipant | Point d'entrée, possède toutes les autres entités |
| Publisher | Regroupe les DataWriters, applique des QoS communes |
| Subscriber | Regroupe les DataReaders, applique des QoS communes |
| Topic | Canal de données nommé avec un type |
| DataWriter | Écrit des échantillons sur un Topic |
| DataReader | Lit des échantillons depuis un Topic |
Hiérarchie des entités
DomainParticipant
+-- Publisher
| +-- DataWriter<SensorData>
| +-- DataWriter<Command>
+-- Subscriber
| +-- DataReader<SensorData>
| +-- DataReader<Status>
+-- Topic
+-- "SensorTopic"
+-- "CommandTopic"
Couche RTPS (Real-Time Publish-Subscribe)
La couche RTPS implémente le protocole filaire pour l'interopérabilité :
RTPS Writers et Readers
+------------------+ Protocole RTPS +------------------+
| RTPS Writer | ----------------------> | RTPS Reader |
| | | |
| +------------+ | DATA, HEARTBEAT | +------------+ |
| | History | | ---------------------> | | History | |
| | Cache | | | | Cache | |
| +------------+ | ACKNACK, GAP | +------------+ |
| | <--------------------- | |
+------------------+ +------------------+
History Cache
Chaque Writer et Reader maintient un History Cache :
- Writer History : Stocke les échantillons jusqu'à l'acquittement
- Reader History : Stocke les échantillons reçus jusqu'à leur consommation
use hdds::QoS;
// History depth controlled by QoS
let qos = QoS::reliable().keep_last(100);
Architecture de la découverte
La découverte utilise deux protocoles s'exécutant sur des endpoints intégrés :
+---------------------------------------------------------+
| DomainParticipant |
+----------------------------+----------------------------+
| SPDP (Participants) | SEDP (Endpoints) |
| | |
| BuiltinParticipant | BuiltinPublications |
| Writer/Reader | Writer/Reader |
| | |
| Multicast: 239.255.x.x | BuiltinSubscriptions |
| Port: 7400 + offset | Writer/Reader |
+----------------------------+----------------------------+
Flux de découverte
1. Annonce SPDP (multicast)
Participant A --> 239.255.0.1:7400 --> Participant B
2. Échange SEDP (unicast)
A.Publications ------> B (infos endpoints)
A <------ B.Publications (infos endpoints)
3. Appariement
A.Writer apparié avec B.Reader (QoS compatibles)
4. Flux de données utilisateur
A.Writer --> DATA --> B.Reader
Couche Transport
HDDS supporte plusieurs transports :
| Transport | Cas d'usage | Latence |
|---|---|---|
| UDP Multicast | Discovery, multi-Subscriber | Moyenne |
| UDP Unicast | Point à point, WAN | Moyenne |
| Shared Memory | Même hôte, haute performance | Faible (~1 us) |
Sélection du transport
let config = ParticipantConfig::default()
.transport(Transport::UdpMulticast) // Default
.transport(Transport::SharedMemory); // Add SHM
Modèle de threading
HDDS utilise un runtime async avec des threads dédiés :
+---------------------------------------------------------+
| Threads utilisateur |
| (write(), take(), create_reader(), etc.) |
+---------------------------------------------------------+
| Runtime HDDS |
| +-------------+ +-------------+ +------------------+ |
| | Discovery | | Pool I/O | | Timer/Scheduler | |
| | Thread | | (tokio) | | | |
| +-------------+ +-------------+ +------------------+ |
+---------------------------------------------------------+
- Threads utilisateur : Les appels applicatifs sont non-bloquants autant que possible
- Thread Discovery : Gère le protocole SPDP/SEDP
- Pool I/O : Opérations réseau async (basées sur tokio)
- Thread Timer : Heartbeats, deadlines, liveliness
Architecture mémoire
Chemin zéro-copy
Pour les scenarios haute performance, HDDS supporte le zéro-copy :
// Standard path (copy)
writer.write(&sample)?;
// Zéro-copy path (loan buffer)
let mut loan = writer.loan_sample()?;
*loan = sample;
loan.write()?; // No copy to internal buffer
Gestion des buffers
+-----------------+ +-----------------+ +-----------------+
| Buffer utilisa-| | History Cache | | Buffer réseau |
| teur | -> | (par Writer) | -> | (par envoi) |
+-----------------+ +-----------------+ +-----------------+
Les limites de ressources empechent une croissance mémoire non bornee :
use hdds::QoS;
let qos = QoS::reliable()
.max_samples(10000)
.max_instances(100)
.max_samples_per_instance(100);
Flux de données
Chemin d'ecriture
1. L'application appelle writer.write(&sample)
2. L'échantillon est sérialisé (CDR2/XCDR2)
3. Ajouté au History Cache du Writer
4. Encapsule dans un sous-message RTPS DATA
5. Envoyé via le transport (UDP/SHM)
6. Acquitté (si reliable)
7. Retiré de l'historique (si acquitté)
Chemin de lecture
1. Le réseau reçoit un paquet RTPS
2. Analyse des sous-messages (DATA, HEARTBEAT, etc.)
3. Désérialisation de l'échantillon
4. Ajout au History Cache du Reader
5. Envoi d'ACKNACK (si reliable)
6. L'application appelle reader.take()
7. L'échantillon est retiré de l'historique
Structure des modules
hdds/
+-- dcps/ # API DDS (Participant, Publisher, etc.)
+-- rtps/ # Implémentation du protocole RTPS
| +-- writer.rs # Machine à états RTPS Writer
| +-- reader.rs # Machine à états RTPS Reader
| +-- discovery/ # SPDP et SEDP
| +-- messages/ # Types de messages RTPS
+-- transport/ # Transports réseau
| +-- udp.rs
| +-- shm.rs
+-- serialization/ # Codecs CDR/XCDR2
+-- qos/ # Implémentations des politiques QoS
Caractéristiques de performance
| Operation | Latence typique |
|---|---|
| write() vers le réseau | 5-50 us |
| Réseau vers take() | 10-100 us |
| Aller-retour Shared Memory | 1-5 us |
| Discovery (démarrage à froid) | 100-500 ms |
Prochaines étapes
- DomainParticipant - Détails du point d'entrée
- Topics - Canaux de données
- Discovery - Comment les endpoints se trouvent