pub struct ControlAllocator<const NU: usize, const NV: usize, const NC: usize>where
Const<NC>: DimName,
Const<NU>: DimName,
Const<NV>: DimName,
DefaultAllocator: Allocator<Const<NC>, Const<NU>> + Allocator<Const<NU>> + Allocator<Const<NV>>,{ /* private fields */ }Expand description
Stateful WLS control allocator: owns the static problem data and the warm-start solver state across solves.
Build once via ControlAllocator::new when the effectiveness matrix or
weights change, then call solve on every control tick.
The previous solution is automatically reused as the warm-start for the
next solve.
Const generics:
NU: number of actuatorsNV: number of pseudo-controlsNC: must equalNU + NV(compile-time checked)
§Example
use wls_alloc::wls::ControlAllocator;
use wls_alloc::ExitCode;
use nalgebra::{SMatrix, SVector, Vector4, Vector3};
// 3 pseudo-controls × 4 motors (e.g. roll/pitch/yaw mixer)
#[rustfmt::skip]
let g = SMatrix::<f32, 3, 4>::new(
-0.5, 0.5, 1.0, // motor 1
0.5, 0.5, -1.0, // motor 2
-0.5, -0.5, -1.0, // motor 3
0.5, -0.5, 1.0, // motor 4
);
let wv = Vector3::new(1.0_f32, 1.0_f32, 0.5_f32);
let wu = Vector4::from_element(1.0_f32);
let mut alloc = ControlAllocator::<4, 3, 7>::new(&g, &wv, wu, 2e-9, 4e5);
let v = Vector3::new(0.1_f32, -0.2_f32, 0.05_f32);
let ud = Vector4::from_element(0.5_f32);
let umin = Vector4::from_element(0.0_f32);
let umax = Vector4::from_element(1.0_f32);
let stats = alloc.solve(&v, &ud, &umin, &umax, 100);
assert_eq!(stats.exit_code, ExitCode::Success);
let u = alloc.solution();Implementations§
Source§impl<const NU: usize, const NV: usize, const NC: usize> ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> ControlAllocator<NU, NV, NC>
Sourcepub fn new(
g: &OMatrix<f32, Const<NV>, Const<NU>>,
wv: &OVector<f32, Const<NV>>,
wu: OVector<f32, Const<NU>>,
theta: f32,
cond_bound: f32,
) -> Self
pub fn new( g: &OMatrix<f32, Const<NV>, Const<NU>>, wv: &OVector<f32, Const<NV>>, wu: OVector<f32, Const<NU>>, theta: f32, cond_bound: f32, ) -> Self
Build the allocator: factor the augmented matrix A, compute the
regularisation scalar γ, and normalise the actuator weights.
wu is consumed so the in-place normalisation is fully internal — the
caller’s data is never mutated through aliasing. The warm-start is
initialised to zero; use set_warmstart to
seed a non-zero initial guess before the first solve.
Sourcepub fn solve(
&mut self,
v: &OVector<f32, Const<NV>>,
ud: &OVector<f32, Const<NU>>,
umin: &OVector<f32, Const<NU>>,
umax: &OVector<f32, Const<NU>>,
imax: usize,
) -> SolverStats
pub fn solve( &mut self, v: &OVector<f32, Const<NV>>, ud: &OVector<f32, Const<NU>>, umin: &OVector<f32, Const<NU>>, umax: &OVector<f32, Const<NU>>, imax: usize, ) -> SolverStats
Run one constrained least-squares solve.
Builds the right-hand side b from v and ud using the stored
weights and γ, then runs the active-set solver continuing from the
current warm-start. The solution is left in the allocator and can be
read via solution.
Sourcepub fn solution(&self) -> &OVector<f32, Const<NU>>
pub fn solution(&self) -> &OVector<f32, Const<NU>>
The current actuator solution (also the warm-start for the next solve).
Sourcepub fn set_warmstart(&mut self, us: &OVector<f32, Const<NU>>)
pub fn set_warmstart(&mut self, us: &OVector<f32, Const<NU>>)
Seed the warm-start with an explicit initial guess and clear the
active set. Call before solve when starting a new
trajectory; otherwise the previous solution is reused automatically.
Sourcepub fn reset_warmstart(&mut self)
pub fn reset_warmstart(&mut self)
Zero the warm-start solution and clear the active set.
Auto Trait Implementations§
impl<const NU: usize, const NV: usize, const NC: usize> !Freeze for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !RefUnwindSafe for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !Send for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !Sync for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !Unpin for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !UnsafeUnpin for ControlAllocator<NU, NV, NC>
impl<const NU: usize, const NV: usize, const NC: usize> !UnwindSafe for ControlAllocator<NU, NV, NC>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.