Skip to main content

flight_solver/
lib.rs

1//! Real-time solvers for flight controllers.
2//!
3//! `flight-solver` provides `no_std`, fully stack-allocated solvers designed
4//! for real-time system identification and control allocation on embedded
5//! targets. All dimensions are const-generic for
6//! zero-overhead monomorphization.
7//!
8//! # Solvers
9//!
10//! | Module | Algorithm | Use case |
11//! |--------|-----------|----------|
12//! | [`rls`] | Recursive Least Squares | Online parameter estimation |
13//! | [`cls`] | Constrained Least Squares | Box-constrained allocation |
14//! | [`wls`] | Encapsulated WLS allocator | High-level control allocation API |
15//!
16//! # Example: RLS online parameter estimation
17//!
18//! ```no_run
19//! use flight_solver::rls::{RlsParallel, CovarianceGuards};
20//!
21//! let mut rls = RlsParallel::<4, 3>::new(1e2, 0.995, CovarianceGuards::default());
22//!
23//! let a = nalgebra::SVector::<f32, 4>::new(0.1, -0.2, 0.3, 0.05);
24//! let y = nalgebra::SVector::<f32, 3>::new(0.5, -0.3, 0.1);
25//! rls.update(&a, &y);
26//!
27//! let estimate = rls.params(); // 4×3 parameter matrix
28//! ```
29//!
30//! # Example: WLS constrained allocation (encapsulated API — recommended)
31//!
32//! [`wls::ControlAllocator`] owns the static problem (effectiveness matrix,
33//! weights, `γ`) and the warm-start solver state. Build once, then call
34//! [`solve`](wls::ControlAllocator::solve) on every control tick.
35//!
36//! ```no_run
37//! use flight_solver::wls::ControlAllocator;
38//! use flight_solver::cls::{ExitCode, Mat, VecN};
39//!
40//! let g: Mat<6, 4> = Mat::zeros();  // effectiveness matrix
41//! let wv = VecN::<6>::from_column_slice(&[10.0, 10.0, 10.0, 1.0, 0.5, 0.5]);
42//! let wu = VecN::<4>::from_column_slice(&[1.0; 4]);
43//!
44//! let mut alloc = ControlAllocator::<4, 6, 10>::new(&g, &wv, wu, 2e-9, 4e5);
45//!
46//! let v = VecN::<6>::zeros();
47//! let ud = VecN::<4>::from_column_slice(&[0.5; 4]);
48//! let umin = VecN::<4>::from_column_slice(&[0.0; 4]);
49//! let umax = VecN::<4>::from_column_slice(&[1.0; 4]);
50//!
51//! let stats = alloc.solve(&v, &ud, &umin, &umax, 100);
52//! assert_eq!(stats.exit_code, ExitCode::Success);
53//! let u = alloc.solution();
54//! ```
55//!
56//! # Example: WLS constrained allocation (raw building blocks)
57//!
58//! For advanced use — custom `A` matrices or non-standard pipeline composition —
59//! the [`cls::setup::wls`] and [`cls`] modules expose the free functions
60//! directly.
61//!
62//! ```no_run
63//! use flight_solver::cls::{solve, ExitCode, Mat, VecN};
64//! use flight_solver::cls::setup::wls::{setup_a, setup_b};
65//!
66//! let g: Mat<6, 4> = Mat::zeros();
67//! let wv = VecN::<6>::from_column_slice(&[10.0, 10.0, 10.0, 1.0, 0.5, 0.5]);
68//! let mut wu = VecN::<4>::from_column_slice(&[1.0; 4]);
69//!
70//! let (a, gamma) = setup_a::<4, 6, 10>(&g, &wv, &mut wu, 2e-9, 4e5);
71//! let v = VecN::<6>::zeros();
72//! let ud = VecN::<4>::from_column_slice(&[0.5; 4]);
73//! let b = setup_b::<4, 6, 10>(&v, &ud, &wv, &wu, gamma);
74//!
75//! let umin = VecN::<4>::from_column_slice(&[0.0; 4]);
76//! let umax = VecN::<4>::from_column_slice(&[1.0; 4]);
77//! let mut us = VecN::<4>::from_column_slice(&[0.5; 4]);
78//! let mut ws = [0i8; 4];
79//! let stats = solve::<4, 6, 10>(&a, &b, &umin, &umax, &mut us, &mut ws, 100);
80//! assert_eq!(stats.exit_code, ExitCode::Success);
81//! ```
82//!
83//! # Example: Unregularised LS allocation
84//!
85//! ```no_run
86//! use flight_solver::cls::{solve_cls, ExitCode, Mat, VecN};
87//! use flight_solver::cls::setup::ls;
88//!
89//! let g: Mat<4, 4> = Mat::zeros();  // square system
90//! let wv = VecN::<4>::from_column_slice(&[1.0; 4]);
91//!
92//! let a = ls::setup_a::<4, 4>(&g, &wv);
93//! let v = VecN::<4>::zeros();
94//! let b = ls::setup_b(&v, &wv);
95//!
96//! let umin = VecN::<4>::from_column_slice(&[0.0; 4]);
97//! let umax = VecN::<4>::from_column_slice(&[1.0; 4]);
98//! let mut us = VecN::<4>::from_column_slice(&[0.5; 4]);
99//! let mut ws = [0i8; 4];
100//! let stats = solve_cls::<4, 4>(&a, &b, &umin, &umax, &mut us, &mut ws, 100);
101//! assert_eq!(stats.exit_code, ExitCode::Success);
102//! ```
103
104#![no_std]
105#![warn(missing_docs)]
106
107pub mod cls;
108pub mod givens;
109pub mod rls;
110pub mod wls;