Aller au contenu principal

Topics

Un Topic est un canal nommé pour échanger des données d'un type spécifique entre Publishers et Subscribers.

Vue d'ensemble

Les Topics définissent :

  • Nom : Un identifiant chaîne (ex. "SensorData", "RobotStatus")
  • Type : La structure de données échangée
  • QoS : Les politiques de qualité de service pour le Topic
use hdds::{Participant, QoS, TransportMode};

let participant = Participant::builder("app")
.domain_id(0)
.with_transport(TransportMode::UdpMulticast)
.build()?;

// Create à topic for SensorData type
let topic = participant.topic::<SensorData>("SensorTopic")?;

Nommage des Topics

Les noms de Topics sont des chaînes qui identifient les canaux de données :

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 à la casse : SensorData != sensordata
  • Pas de limite de longueur (mais restez raisonnable)
  • Caractères : alphanumériques, /, _, -
  • A éviter : espaces, caractères spéciaux

Enregistrement des types

Avant de créer 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 :

  1. Même nom de Topic - Correspondance exacte de chaîne
  2. Type compatible - Le nom et la structure du type correspondent
  3. 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 |
+---------------------+ +---------------------+

Créer des Topics

Création 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 à 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 détails.

Multi-Topic

Créez des Topics avec le même 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

  1. Utilisez des noms significatifs : robot/sensors/lidar et non topic1
  2. Correspondance exacte des types : Même structure de données des deux côtés
  3. Utilisez les cles pour les instances : Quand vous suivez plusieurs entités
  4. 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 à 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 étapes