use tracktor::filters::phd::GmPhdFilter;
use tracktor::prelude::*;
use tracktor::utils::{ExtractionConfig, PruningConfig, extract_targets, prune_and_merge};
fn main() {
println!("Measurement-Driven Birth Model Example");
println!("======================================\n");
let transition = ConstantVelocity2D::new(
1.0, 0.98, );
let observation = PositionSensor2D::new(
10.0, 0.9, );
let clutter = UniformClutter2D::new(
3.0, (0.0, 200.0), (0.0, 200.0), );
let expander = ConstantVelocity2DExpander::new(
100.0, 100.0, 0.02, );
let mut birth = MeasurementDrivenBirthModel::new(expander);
let filter = GmPhdFilter::new(transition, observation, clutter.clone(), birth.clone());
let mut state = filter.initial_state();
println!(
"Initial state: {} components, {:.2} expected targets\n",
state.mixture.len(),
state.expected_target_count()
);
let measurements_per_step = [
vec![[32.0, 28.0], [180.0, 90.0], [45.0, 160.0]],
vec![[37.0, 33.0], [10.0, 10.0]],
vec![[42.0, 38.0], [148.0, 152.0]],
vec![[47.0, 43.0], [141.0, 143.0]],
vec![[52.0, 48.0], [134.0, 134.0], [102.0, 48.0]],
vec![[57.0, 53.0], [127.0, 125.0], [100.0, 56.0]],
vec![[62.0, 58.0], [120.0, 116.0], [98.0, 64.0], [175.0, 175.0]],
vec![[67.0, 63.0], [113.0, 107.0], [96.0, 72.0]],
];
let dt = 1.0;
let pruning_config = PruningConfig::new(1e-4, 4.0, 100);
let extraction_config = ExtractionConfig::weight_threshold(0.5);
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 step {}: {} measurements", t, measurements.len());
birth.set_measurements(measurements.clone());
let predicted = state.predict(&filter.transition, &birth, dt);
println!(
" After predict: {} components, {:.2} expected targets (birth added {} components)",
predicted.mixture.len(),
predicted.expected_target_count(),
birth.num_adaptive_measurements()
);
let updated = predicted.update(&measurements, &filter.observation, &clutter);
println!(
" After update: {} components, {:.2} expected targets",
updated.mixture.len(),
updated.expected_target_count()
);
let pruned = prune_and_merge(&updated.mixture, &pruning_config);
state = tracktor::filters::phd::PhdFilterState::from_mixture(pruned);
println!(
" After prune: {} components, {:.2} expected targets",
state.mixture.len(),
state.expected_target_count()
);
let targets = extract_targets(&state.mixture, &extraction_config);
println!(" Extracted {} targets:", targets.len());
for (i, target) in targets.iter().enumerate() {
println!(
" Target {}: pos=({:.1}, {:.1}), vel=({:.1}, {:.1}), weight={:.2}",
i,
target.state.index(0),
target.state.index(1),
target.state.index(2),
target.state.index(3),
target.confidence
);
}
println!();
}
}