Skip to main content

ControlAllocator

Struct ControlAllocator 

Source
pub struct ControlAllocator<const NU: usize, const NV: usize, const NC: usize>{ /* 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 actuators
  • NV: number of pseudo-controls
  • NC: must equal NU + 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>
where Const<NC>: DimName + DimMin<Const<NU>, Output = Const<NU>>, Const<NU>: DimName, Const<NV>: DimName, DefaultAllocator: Allocator<Const<NC>, Const<NU>> + Allocator<Const<NC>, Const<NC>> + Allocator<Const<NU>, Const<NU>> + Allocator<Const<NC>> + Allocator<Const<NU>> + Allocator<Const<NV>>,

Source

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.

Source

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.

Source

pub fn solution(&self) -> &OVector<f32, Const<NU>>

The current actuator solution (also the warm-start for the next solve).

Source

pub fn gamma(&self) -> f32

The regularisation scalar γ chosen at construction time.

Source

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.

Source

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.