use kfilter::ukf::{UKFLinear, UKFLinearNoInput};
use kfilter::{KalmanFilter, KalmanPredict, KalmanPredictInput};
use nalgebra::{Matrix2, SMatrix, SVector, Vector2};
fn main() {
println!("=== UKF Linear System Examples ===\n");
example_1d_position_tracking();
println!();
example_2d_position_velocity();
println!();
example_with_control_input();
}
fn example_1d_position_tracking() {
println!("--- Example 1: 1D Position Tracking ---");
let mut ukf: UKFLinearNoInput<f64, 1, 3> = UKFLinearNoInput::new_linear(
SMatrix::<f64, 1, 1>::identity(), SMatrix::<f64, 1, 1>::identity() * 0.01, SVector::<f64, 1>::new(0.0), SMatrix::<f64, 1, 1>::identity() * 0.5, );
println!("Initial state: position = {:.3}", ukf.state()[0]);
println!("Initial covariance: {:.3}", ukf.covariance()[(0, 0)]);
for step in 1..=5 {
ukf.predict().unwrap();
println!(
"Step {}: position = {:.3}, uncertainty = {:.3}",
step,
ukf.state()[0],
ukf.covariance()[(0, 0)]
);
}
}
fn example_2d_position_velocity() {
println!("--- Example 2: 2D Position-Velocity Tracking ---");
let dt = 0.1;
let mut ukf: UKFLinearNoInput<f64, 2, 5> = UKFLinearNoInput::new_linear(
Matrix2::new(
1.0, dt, 0.0, 1.0, ),
Matrix2::identity() * 0.01, Vector2::new(0.0, 1.0), Matrix2::identity() * 0.5, );
println!("Initial state: pos={:.3}, vel={:.3}", ukf.state()[0], ukf.state()[1]);
for step in 1..=10 {
ukf.predict().unwrap();
if step % 2 == 0 {
println!(
"Step {}: pos={:.3}, vel={:.3}",
step,
ukf.state()[0],
ukf.state()[1]
);
}
}
println!(
"Final position: {:.3} (expected ~1.0 after 10 steps with dt=0.1)",
ukf.state()[0]
);
}
fn example_with_control_input() {
println!("--- Example 3: System with Control Input ---");
let dt = 0.1;
let mut ukf: UKFLinear<f64, 2, 1, 5> = UKFLinear::new_linear_with_input(
Matrix2::new(
1.0, dt, 0.0, 1.0, ),
Matrix2::identity() * 0.01, SMatrix::<f64, 2, 1>::new(
0.5 * dt * dt, dt, ),
Vector2::new(0.0, 0.0), Matrix2::identity() * 0.1, );
println!("Controlling system to reach target position 5.0");
println!("Initial: pos={:.3}, vel={:.3}", ukf.state()[0], ukf.state()[1]);
let target_position = 5.0;
for step in 1..=20 {
let error = target_position - ukf.state()[0];
let control_acceleration = SVector::<f64, 1>::new(error * 2.0);
ukf.predict(control_acceleration).unwrap();
if step % 5 == 0 {
println!(
"Step {}: pos={:.3}, vel={:.3}, control={:.3}",
step,
ukf.state()[0],
ukf.state()[1],
control_acceleration[0]
);
}
}
println!(
"Final: pos={:.3} (target: {:.3}), vel={:.3}",
ukf.state()[0],
target_position,
ukf.state()[1]
);
}