Skip to main content

wls_alloc/
lib.rs

1//! Weighted least-squares (WLS) constrained control allocator.
2//!
3//! Solves `min ‖Au − b‖²` subject to `umin ≤ u ≤ umax` using an active-set
4//! method with incremental QR updates. Designed for real-time motor mixing on
5//! flight controllers: `no_std`, fully stack-allocated, const-generic over
6//! problem dimensions.
7//!
8//! # Regularised (standard WLS)
9//!
10//! ```no_run
11//! use wls_alloc::{setup_a, setup_b, solve, ExitCode, VecN, MatA};
12//!
13//! // Effectiveness matrix G (6 pseudo-controls × 4 motors)
14//! let g: MatA<6, 4> = MatA::zeros(); // replace with real data
15//! let wv: VecN<6> = VecN::from_column_slice(&[10.0, 10.0, 10.0, 1.0, 0.5, 0.5]);
16//! let mut wu: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
17//!
18//! // Build LS problem
19//! let (a, gamma) = setup_a::<4, 6, 10>(&g, &wv, &mut wu, 2e-9, 4e5);
20//! let v: VecN<6> = VecN::zeros();
21//! let ud: VecN<4> = VecN::from_column_slice(&[0.5; 4]);
22//! let b = setup_b::<4, 6, 10>(&v, &ud, &wv, &wu, gamma);
23//!
24//! // Solve
25//! let umin: VecN<4> = VecN::from_column_slice(&[0.0; 4]);
26//! let umax: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
27//! let mut us: VecN<4> = VecN::from_column_slice(&[0.5; 4]);
28//! let mut ws = [0i8; 4];
29//! let stats = solve::<4, 6, 10>(&a, &b, &umin, &umax, &mut us, &mut ws, 100);
30//! assert_eq!(stats.exit_code, ExitCode::Success);
31//! ```
32//!
33//! # Unregularised (constrained least-squares)
34//!
35//! When the regularisation term `γ ‖Wu (u − u_pref)‖²` is not needed, use
36//! [`setup_a_unreg`] / [`setup_b_unreg`] with [`solve_cls`]. The coefficient
37//! matrix is `NV × NU` instead of `(NV + NU) × NU`, yielding a smaller QR
38//! factorisation.
39//!
40//! ```no_run
41//! use wls_alloc::{setup_a_unreg, setup_b_unreg, solve_cls, ExitCode, VecN, MatA};
42//!
43//! // Square system: 4 pseudo-controls × 4 motors
44//! let g: MatA<4, 4> = MatA::zeros(); // replace with real data
45//! let wv: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
46//!
47//! let a = setup_a_unreg::<4, 4>(&g, &wv);
48//! let v: VecN<4> = VecN::zeros();
49//! let b = setup_b_unreg(&v, &wv);
50//!
51//! let umin: VecN<4> = VecN::from_column_slice(&[0.0; 4]);
52//! let umax: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
53//! let mut us: VecN<4> = VecN::from_column_slice(&[0.5; 4]);
54//! let mut ws = [0i8; 4];
55//! let stats = solve_cls::<4, 4>(&a, &b, &umin, &umax, &mut us, &mut ws, 100);
56//! assert_eq!(stats.exit_code, ExitCode::Success);
57//! ```
58
59#![no_std]
60#![warn(missing_docs)]
61
62/// Low-level linear algebra: Householder QR, back-substitution, constraint checking.
63pub mod linalg;
64/// Problem setup: convert WLS control-allocation parameters into LS form.
65pub mod setup;
66/// Active-set constrained least-squares solver.
67pub mod solver;
68/// Core types, constants, and nalgebra type aliases.
69pub mod types;
70
71pub use setup::{setup_a, setup_a_unreg, setup_b, setup_b_unreg};
72pub use solver::{solve, solve_cls};
73pub use types::{ExitCode, MatA, SolverStats, VecN};