use tracktor::filters::lmb::{
LabeledBirthModel, LmbmFilter, extract_best_hypothesis, extract_lmbm_estimates,
};
use tracktor::prelude::*;
struct LmbmBirthModel;
impl LabeledBirthModel<f64, 4> for LmbmBirthModel {
fn birth_tracks(&self, label_gen: &mut LabelGenerator) -> Vec<BernoulliTrack<f64, 4>> {
let cov = StateCovariance::from_matrix(nalgebra::matrix![
150.0, 0.0, 0.0, 0.0;
0.0, 150.0, 0.0, 0.0;
0.0, 0.0, 30.0, 0.0;
0.0, 0.0, 0.0, 30.0
]);
vec![BernoulliTrack::new(
label_gen.next_label(),
0.01,
GaussianState::new(1.0, StateVector::from_array([50.0, 50.0, 0.0, 0.0]), cov),
)]
}
fn expected_birth_count(&self) -> f64 {
0.01
}
}
fn main() {
println!("LMBM Filter: Multi-Hypothesis Tracking");
println!("======================================\n");
let transition = ConstantVelocity2D::new(1.5, 0.98);
let observation = PositionSensor2D::new(6.0, 0.88);
let clutter = UniformClutter2D::new(4.0, (0.0, 150.0), (0.0, 150.0));
let birth = LmbmBirthModel;
let filter: LmbmFilter<f64, _, _, _, _, 4, 2> =
LmbmFilter::new(transition, observation, clutter, birth, 5, 20);
let mut state = filter.initial_state();
println!("Initial: {} hypotheses\n", state.num_hypotheses());
let measurements_per_step = [
vec![[30.0, 30.0], [35.0, 32.0], [100.0, 80.0]], vec![[32.0, 32.0], [37.0, 34.0]], vec![[34.0, 33.0], [40.0, 37.0], [20.0, 100.0]], vec![[35.0, 35.0], [43.0, 39.0]], vec![[37.0, 36.0], [47.0, 42.0]], ];
let dt = 1.0;
for (t, meas_data) in measurements_per_step.iter().enumerate() {
let measurements: Vec<Measurement<f64, 2>> = meas_data
.iter()
.map(|m| Measurement::from_array(*m))
.collect();
println!("Time {}: {} measurements", t, measurements.len());
let (updated, stats) = filter.step(state, &measurements, dt);
state = updated;
println!(
" Hypotheses: {}, Singular: {}",
state.num_hypotheses(),
stats.singular_covariance_count
);
if let Some(best) = extract_best_hypothesis(&state) {
println!(
" Best hypothesis: {} tracks, log_w={:.2}",
best.num_tracks(),
best.log_weight
);
for track in &best.tracks {
println!(
" {:?}: ({:.1}, {:.1}), r={:.3}",
track.label,
track.state.mean.index(0),
track.state.mean.index(1),
track.existence
);
}
}
let marginals = extract_lmbm_estimates(&state, 0.3);
if !marginals.is_empty() {
println!(" Marginal estimates (r > 0.3):");
for (label, mean, existence) in &marginals {
println!(
" {:?}: ({:.1}, {:.1}), r={:.3}",
label,
mean.index(0),
mean.index(1),
existence
);
}
}
println!();
}
}