Topics
Un Topic est un canal nomme pour echanger des donnees d'un type specifique entre Publishers et Subscribers.
Vue d'ensemble
Les Topics definissent :
- Nom : Un identifiant chaine (ex. "SensorData", "RobotStatus")
- Type : La structure de donnees echangee
- QoS : Les politiques de qualite de service pour le Topic
use hdds::{Participant, QoS, TransportMode};
let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Create a topic for SensorData type
let topic = participant.topic::<SensorData>("SensorTopic")?;
Nommage des Topics
Les noms de Topics sont des chaines qui identifient les canaux de donnees :
use hdds::{Participant, TransportMode};
let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Simple names
let sensor_topic = participant.topic::<SensorData>("sensors")?;
// Hierarchical naming (convention, not enforced)
let lidar_topic = participant.topic::<PointCloud>("/robot/sensors/lidar")?;
let cmd_topic = participant.topic::<Command>("/robot/control/commands")?;
// Namespaced (common in ROS2)
let ros_topic = participant.topic::<Image>("rt/camera/image_raw")?;
Regles de nommage
- Sensible a la casse :
SensorData!=sensordata - Pas de limite de longueur (mais restez raisonnable)
- Caracteres : alphanumeriques,
/,_,- - A eviter : espaces, caracteres speciaux
Enregistrement des types
Avant de creer un Topic, le type doit etre connu :
use hdds::{Participant, DDS, TransportMode};
#[derive(Debug, Clone, DDS)]
struct SensorData {
sensor_id: u32,
value: f32,
}
let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Types using #[derive(DDS)] are auto-registered
// when you use topic::<T>()
let topic = participant.topic::<SensorData>("SensorTopic")?;
Appariement des Topics
Les Writers et Readers s'apparient quand :
- Meme nom de Topic - Correspondance exacte de chaine
- Type compatible - Le nom et la structure du type correspondent
- QoS compatibles - Les politiques QoS sont compatibles
Publisher (Domain 0) Subscriber (Domain 0)
+---------------------+ +---------------------+
| Topic: "SensorData" | MATCH | Topic: "SensorData" |
| Type: SensorData | <------> | Type: SensorData |
| QoS: Reliable | | QoS: Reliable |
+---------------------+ +---------------------+
Publisher (Domain 0) Subscriber (Domain 0)
+---------------------+ +---------------------+
| Topic: "SensorData" | NO MATCH | Topic: "OtherTopic" |
| Type: SensorData | X | Type: SensorData |
+---------------------+ +---------------------+
Creer des Topics
Creation basique
use hdds::{Participant, TransportMode};
let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Default QoS
let topic = participant.topic::<SensorData>("SensorTopic")?;
Avec QoS pour Writer/Reader
use hdds::{Participant, QoS, TransportMode};
let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
let topic = participant.topic::<SensorData>("SensorTopic")?;
// Create writer with specific QoS
let writer = topic
.writer()
.qos(QoS::reliable().keep_last(100).transient_local())
.build()?;
// Create reader with specific QoS
let reader = topic
.reader()
.qos(QoS::reliable().keep_last(100))
.build()?;
Description du Topic
let topic = participant.topic::<SensorData>("SensorTopic")?;
println!("Name: {}", topic.name()); // "SensorTopic"
println!("Type: {}", topic.type_name()); // "SensorData"
Topics avec cles
Les Topics avec des champs #[key] supportent les instances multiples :
use hdds::{Participant, DDS, TransportMode};
#[derive(Debug, Clone, DDS)]
struct RobotStatus {
#[key]
robot_id: u32, // Key field
battery: f32,
position_x: f32,
position_y: f32,
}
let participant = Participant::builder("robot_monitor")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
let topic = participant.topic::<RobotStatus>("robot/status")?;
let writer = topic.writer().qos(QoS::reliable()).build()?;
// Multiple robots on same topic - each robot_id creates a separate instance
writer.write(&RobotStatus { robot_id: 1, battery: 95.0, position_x: 0.0, position_y: 0.0 })?;
writer.write(&RobotStatus { robot_id: 2, battery: 87.0, position_x: 1.0, position_y: 2.0 })?;
// Each robot has independent history
Voir l'exemple Key Instance pour plus de details.
Multi-Topic
Creez des Topics avec le meme type mais des noms differents :
use hdds::{Participant, TransportMode};
let participant = Participant::builder("home_sensors")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Different rooms, same sensor type
let kitchen = participant.topic::<Temperature>("kitchen/temp")?;
let bedroom = participant.topic::<Temperature>("bedroom/temp")?;
let bathroom = participant.topic::<Temperature>("bathroom/temp")?;
Bonnes pratiques
- Utilisez des noms significatifs :
robot/sensors/lidaret nontopic1 - Correspondance exacte des types : Meme structure de donnees des deux cotes
- Utilisez les cles pour les instances : Quand vous suivez plusieurs entites
- Pensez aux partitions : Pour le filtrage au niveau Topic
Patrons courants
Un Topic par type de capteur
use hdds::{Participant, TransportMode};
let participant = Participant::builder("sensor_hub")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
let temperature = participant.topic::<TempReading>("temperature")?;
let humidity = participant.topic::<HumidReading>("humidity")?;
let pressure = participant.topic::<PressReading>("pressure")?;
Topic avec instances a cles
use hdds::{Participant, DDS, TransportMode};
#[derive(Debug, Clone, DDS)]
struct SensorData {
#[key]
sensor_id: u32, // Key creates separate instances
value: f32,
}
let participant = Participant::builder("multi_sensor")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Single topic, multiple sensors via @key
let sensors = participant.topic::<SensorData>("all_sensors")?;
Topics hierarchiques
use hdds::{Participant, TransportMode};
let participant = Participant::builder("navigation")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;
// Navigation subsystem
let gps = participant.topic::<GPS>("/nav/gps")?;
let imu = participant.topic::<IMU>("/nav/imu")?;
let odom = participant.topic::<Odometry>("/nav/odom")?;
Prochaines etapes
- Publishers et Subscribers - Distribution des donnees
- Exemple Key Instance - Travailler avec les instances
- Vue d'ensemble QoS - Qualite de service