use nv_core::{BBox, DetectionId, MonotonicTs, TrackId, TypedMetadata};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TrackState {
Tentative,
Confirmed,
Coasted,
Lost,
}
#[derive(Clone, Debug)]
pub struct TrackObservation {
pub ts: MonotonicTs,
pub bbox: BBox,
pub confidence: f32,
pub state: TrackState,
pub detection_id: Option<DetectionId>,
pub metadata: TypedMetadata,
}
impl TrackObservation {
#[must_use]
pub fn new(
ts: MonotonicTs,
bbox: BBox,
confidence: f32,
state: TrackState,
detection_id: Option<DetectionId>,
) -> Self {
Self {
ts,
bbox,
confidence,
state,
detection_id,
metadata: TypedMetadata::new(),
}
}
}
#[derive(Clone, Debug)]
pub struct Track {
pub id: TrackId,
pub class_id: u32,
pub state: TrackState,
pub current: TrackObservation,
pub metadata: TypedMetadata,
}
impl Track {
#[must_use]
pub fn new(id: TrackId, class_id: u32, state: TrackState, current: TrackObservation) -> Self {
Self {
id,
class_id,
state,
current,
metadata: TypedMetadata::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use nv_core::BBox;
#[test]
fn track_observation_new() {
let obs = TrackObservation::new(
MonotonicTs::from_nanos(1_000_000),
BBox::new(0.1, 0.2, 0.3, 0.4),
0.95,
TrackState::Confirmed,
Some(DetectionId::new(7)),
);
assert_eq!(obs.ts, MonotonicTs::from_nanos(1_000_000));
assert!((obs.confidence - 0.95).abs() < f32::EPSILON);
assert_eq!(obs.state, TrackState::Confirmed);
assert_eq!(obs.detection_id, Some(DetectionId::new(7)));
assert!(obs.metadata.is_empty());
}
#[test]
fn track_observation_with_metadata() {
#[derive(Clone, Debug, PartialEq)]
struct Embedding(Vec<f32>);
let mut obs = TrackObservation::new(
MonotonicTs::from_nanos(1_000_000),
BBox::new(0.1, 0.2, 0.3, 0.4),
0.95,
TrackState::Confirmed,
None,
);
obs.metadata.insert(Embedding(vec![0.1, 0.2, 0.3]));
assert_eq!(
obs.metadata.get::<Embedding>(),
Some(&Embedding(vec![0.1, 0.2, 0.3]))
);
}
#[test]
fn track_new_has_empty_metadata() {
let obs = TrackObservation::new(
MonotonicTs::from_nanos(0),
BBox::new(0.0, 0.0, 0.5, 0.5),
0.9,
TrackState::Tentative,
None,
);
let track = Track::new(TrackId::new(1), 0, TrackState::Tentative, obs);
assert_eq!(track.id, TrackId::new(1));
assert_eq!(track.class_id, 0);
assert!(track.metadata.is_empty());
}
}