use crate::protocol::dds::discovery::qos::{
DeadlineQosPolicy, DurabilityKind, DurabilityQosPolicy, HistoryKind, HistoryQosPolicy,
LivelinessKind, LivelinessQosPolicy, ReliabilityKind, ReliabilityQosPolicy,
};
use crate::protocol::dds::types::time::Duration;
const DURATION_INFINITE: Duration = Duration {
seconds: 0x7FFF_FFFF,
fraction: 0xFFFF_FFFF,
};
const FRACTION_100MS: u32 = 0x1999_9999;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QosProfile {
pub reliability: ReliabilityQosPolicy,
pub history: HistoryQosPolicy,
pub durability: DurabilityQosPolicy,
pub deadline: DeadlineQosPolicy,
pub liveliness: LivelinessQosPolicy,
}
impl QosProfile {
pub const fn ros2_default() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityKind::Reliable,
max_blocking_time: Duration {
seconds: 0,
fraction: FRACTION_100MS,
},
},
history: HistoryQosPolicy {
kind: HistoryKind::KeepLast,
depth: 10,
},
durability: DurabilityQosPolicy {
kind: DurabilityKind::Volatile,
},
deadline: DeadlineQosPolicy {
period: DURATION_INFINITE,
},
liveliness: LivelinessQosPolicy {
kind: LivelinessKind::Automatic,
lease_duration: DURATION_INFINITE,
},
}
}
pub const fn ros2_sensor_data() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityKind::BestEffort,
max_blocking_time: Duration {
seconds: 0,
fraction: 0,
},
},
history: HistoryQosPolicy {
kind: HistoryKind::KeepLast,
depth: 5,
},
durability: DurabilityQosPolicy {
kind: DurabilityKind::Volatile,
},
deadline: DeadlineQosPolicy {
period: DURATION_INFINITE,
},
liveliness: LivelinessQosPolicy {
kind: LivelinessKind::Automatic,
lease_duration: DURATION_INFINITE,
},
}
}
pub const fn ros2_services_default() -> Self {
Self::ros2_default()
}
pub const fn ros2_parameters() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityKind::Reliable,
max_blocking_time: Duration {
seconds: 0,
fraction: FRACTION_100MS,
},
},
history: HistoryQosPolicy {
kind: HistoryKind::KeepLast,
depth: 1000,
},
durability: DurabilityQosPolicy {
kind: DurabilityKind::Volatile,
},
deadline: DeadlineQosPolicy {
period: DURATION_INFINITE,
},
liveliness: LivelinessQosPolicy {
kind: LivelinessKind::Automatic,
lease_duration: DURATION_INFINITE,
},
}
}
pub const fn ros2_parameter_events() -> Self {
Self::ros2_parameters()
}
pub const fn ros2_rosout() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityKind::Reliable,
max_blocking_time: Duration {
seconds: 0,
fraction: FRACTION_100MS,
},
},
history: HistoryQosPolicy {
kind: HistoryKind::KeepLast,
depth: 1000,
},
durability: DurabilityQosPolicy {
kind: DurabilityKind::TransientLocal,
},
deadline: DeadlineQosPolicy {
period: DURATION_INFINITE,
},
liveliness: LivelinessQosPolicy {
kind: LivelinessKind::Automatic,
lease_duration: DURATION_INFINITE,
},
}
}
pub const fn ros2_clock() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityKind::BestEffort,
max_blocking_time: Duration {
seconds: 0,
fraction: 0,
},
},
history: HistoryQosPolicy {
kind: HistoryKind::KeepLast,
depth: 1,
},
durability: DurabilityQosPolicy {
kind: DurabilityKind::Volatile,
},
deadline: DeadlineQosPolicy {
period: DURATION_INFINITE,
},
liveliness: LivelinessQosPolicy {
kind: LivelinessKind::Automatic,
lease_duration: DURATION_INFINITE,
},
}
}
}
impl Default for QosProfile {
fn default() -> Self {
Self::ros2_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::dds::discovery::qos_match::match_endpoint_qos;
#[test]
fn ros2_default_profile_fields() {
let p = QosProfile::ros2_default();
assert_eq!(p.reliability.kind, ReliabilityKind::Reliable);
assert_eq!(p.history.kind, HistoryKind::KeepLast);
assert_eq!(p.history.depth, 10);
assert_eq!(p.durability.kind, DurabilityKind::Volatile);
}
#[test]
fn ros2_sensor_data_profile_fields() {
let p = QosProfile::ros2_sensor_data();
assert_eq!(p.reliability.kind, ReliabilityKind::BestEffort);
assert_eq!(p.history.kind, HistoryKind::KeepLast);
assert_eq!(p.history.depth, 5);
}
#[test]
fn ros2_rosout_uses_transient_local() {
let p = QosProfile::ros2_rosout();
assert_eq!(p.durability.kind, DurabilityKind::TransientLocal);
assert_eq!(p.history.depth, 1000);
}
#[test]
fn ros2_default_self_compatible() {
let p = QosProfile::ros2_default();
assert!(match_endpoint_qos(&p, &p).is_ok());
}
}