Aller au contenu principal

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 :

  1. Meme nom de Topic - Correspondance exacte de chaine
  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 |
+---------------------+ +---------------------+

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

  1. Utilisez des noms significatifs : robot/sensors/lidar et non topic1
  2. Correspondance exacte des types : Meme structure de donnees des deux cotes
  3. Utilisez les cles pour les instances : Quand vous suivez plusieurs entites
  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 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