1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! Weighted least-squares (WLS) constrained control allocator.
//!
//! Solves `min ‖Au − b‖²` subject to `umin ≤ u ≤ umax` using an active-set
//! method with incremental QR updates. Designed for real-time motor mixing on
//! flight controllers: `no_std`, fully stack-allocated, const-generic over
//! problem dimensions.
//!
//! # Encapsulated API (recommended)
//!
//! [`wls::ControlAllocator`] owns the static problem (effectiveness matrix,
//! weights, `γ`) and the warm-start solver state. Build once, then call
//! [`solve`](wls::ControlAllocator::solve) on every control tick.
//!
//! ```no_run
//! use wls_alloc::wls::ControlAllocator;
//! use wls_alloc::{ExitCode, VecN, MatA};
//!
//! // Effectiveness matrix G (6 pseudo-controls × 4 motors)
//! let g: MatA<6, 4> = MatA::zeros(); // replace with real data
//! let wv: VecN<6> = VecN::from_column_slice(&[10.0, 10.0, 10.0, 1.0, 0.5, 0.5]);
//! let wu: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
//!
//! let mut alloc = ControlAllocator::<4, 6, 10>::new(&g, &wv, wu, 2e-9, 4e5);
//!
//! // Per-tick solve
//! let v: VecN<6> = VecN::zeros();
//! let ud: VecN<4> = VecN::from_column_slice(&[0.5; 4]);
//! let umin: VecN<4> = VecN::from_column_slice(&[0.0; 4]);
//! let umax: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
//!
//! let stats = alloc.solve(&v, &ud, &umin, &umax, 100);
//! assert_eq!(stats.exit_code, ExitCode::Success);
//! let u = alloc.solution();
//! ```
//!
//! # Raw building blocks
//!
//! The [`raw`] module exposes the underlying free functions
//! (`setup_a` / `setup_b` / `solve` / `solve_cls`) for advanced use: custom
//! `A` matrices, the unregularised CLS variant, or composing pieces of the
//! pipeline differently.
//!
//! ```no_run
//! use wls_alloc::raw::{setup_a_unreg, setup_b_unreg, solve_cls};
//! use wls_alloc::{ExitCode, VecN, MatA};
//!
//! let g: MatA<4, 4> = MatA::zeros();
//! let wv: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
//!
//! let a = setup_a_unreg::<4, 4>(&g, &wv);
//! let v: VecN<4> = VecN::zeros();
//! let b = setup_b_unreg(&v, &wv);
//!
//! let umin: VecN<4> = VecN::from_column_slice(&[0.0; 4]);
//! let umax: VecN<4> = VecN::from_column_slice(&[1.0; 4]);
//! let mut us: VecN<4> = VecN::from_column_slice(&[0.5; 4]);
//! let mut ws = [0i8; 4];
//! let stats = solve_cls::<4, 4>(&a, &b, &umin, &umax, &mut us, &mut ws, 100);
//! assert_eq!(stats.exit_code, ExitCode::Success);
//! ```
/// Low-level linear algebra: Householder QR, back-substitution, constraint checking.
/// Problem setup: convert WLS control-allocation parameters into LS form.
/// Active-set constrained least-squares solver.
/// Core types, constants, and nalgebra type aliases.
/// High-level encapsulated WLS control allocator.
pub use ;
/// Low-level free-function building blocks. Use [`wls::ControlAllocator`] for
/// typical flight-controller workloads; reach for `raw` when you need a custom
/// `A`, the unregularised CLS solver, or non-standard pipeline composition.
pub use ;
pub use ;