Struct PidCtrl

Source
pub struct PidCtrl<T: FloatCore + Default> {
    pub kp: KPTerm<T>,
    pub ki: KITerm<T>,
    pub kd: KDTerm<T>,
    pub limits: Limits<T>,
    pub setpoint: T,
}

Fields§

§kp: KPTerm<T>§ki: KITerm<T>§kd: KDTerm<T>§limits: Limits<T>§setpoint: T

Implementations§

Source§

impl<T: FloatCore + Default> PidCtrl<T>

Source

pub fn new() -> Self

Source

pub fn new_with_pid(p: T, i: T, d: T) -> Self

Examples found in repository?
examples/case.rs (line 4)
3fn main() {
4    let mut pid = pid::PidCtrl::new_with_pid(0.5, 0.1, 0.1);
5    let mut measurement = 0.0;
6    let mut width:usize;
7    pid.init(7.5, measurement);
8
9    for _i in 1..21 {
10        measurement += pid.step(pid::PidIn::new(measurement, 1.0)).out;
11        width = (measurement * 10.0) as usize;
12
13        println!("{measurement:>0$.2}", width);
14    }
15}
More examples
Hide additional examples
examples/usage.rs (line 5)
4fn main() {
5    let mut pid = pid_ctrl::PidCtrl::new_with_pid(3.0, 2.0, 1.0);
6
7    let setpoint = 5.0;
8    let prev_measurement = 0.0;
9    // calling init optional. Setpoint and prev_measurement set to 0.0 by default.
10    // Recommended to avoid derivative kick on startup
11    pid.init(setpoint, prev_measurement);
12
13    let measurement = 0.0;
14    let time_delta = 1.0;
15    assert_eq!(
16        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
17        pid_ctrl::PidOut::new(15.0, 10.0, 0.0, 25.0)
18    );
19
20    // changing pid constants
21    pid.kp.set_scale(4.0);
22    assert_eq!(
23        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
24        pid_ctrl::PidOut::new(20.0, 20.0, 0.0, 40.0)
25    );
26
27    // setting symmetrical limits around zero
28    pid.kp.limits.set_limit(10.0);
29    assert_eq!(
30        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
31        pid_ctrl::PidOut::new(10.0, 30.0, 0.0, 40.0)
32    );
33
34    let time_delta = 0.5;
35    assert_eq!(
36        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
37        pid_ctrl::PidOut::new(10.0, 35.0, 0.0, 45.0)
38    );
39
40    // setting upper limits returns error if new value conflicts with lower limit
41    pid.ki.limits.try_set_upper(28.0).unwrap();  
42    assert_eq!(
43        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
44        pid_ctrl::PidOut::new(10.0, 28.0, 0.0, 38.0)
45    );
46
47    // time_delta gets clamped to Float::epsilon() - Float::infinity()
48    let measurement = 1.0;
49    let time_delta = -7.0;
50    pid.kd.set_scale(num_traits::float::FloatCore::epsilon());
51    assert_eq!(pid.step(
52        pid_ctrl::PidIn::new(measurement, time_delta)), 
53        pid_ctrl::PidOut::new(10.0, 28.0, -1.0, 37.0)
54    );
55
56    // configure setpoint directly
57    pid.setpoint = 1.0;
58    assert_eq!(pid.step(
59        pid_ctrl::PidIn::new(measurement, time_delta)), 
60        pid_ctrl::PidOut::new(0.0, 28.0, 0.0, 28.0)
61    );
62}
Source

pub fn init(&mut self, setpoint: T, prev_measurement: T) -> &mut Self

Examples found in repository?
examples/case.rs (line 7)
3fn main() {
4    let mut pid = pid::PidCtrl::new_with_pid(0.5, 0.1, 0.1);
5    let mut measurement = 0.0;
6    let mut width:usize;
7    pid.init(7.5, measurement);
8
9    for _i in 1..21 {
10        measurement += pid.step(pid::PidIn::new(measurement, 1.0)).out;
11        width = (measurement * 10.0) as usize;
12
13        println!("{measurement:>0$.2}", width);
14    }
15}
More examples
Hide additional examples
examples/usage.rs (line 11)
4fn main() {
5    let mut pid = pid_ctrl::PidCtrl::new_with_pid(3.0, 2.0, 1.0);
6
7    let setpoint = 5.0;
8    let prev_measurement = 0.0;
9    // calling init optional. Setpoint and prev_measurement set to 0.0 by default.
10    // Recommended to avoid derivative kick on startup
11    pid.init(setpoint, prev_measurement);
12
13    let measurement = 0.0;
14    let time_delta = 1.0;
15    assert_eq!(
16        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
17        pid_ctrl::PidOut::new(15.0, 10.0, 0.0, 25.0)
18    );
19
20    // changing pid constants
21    pid.kp.set_scale(4.0);
22    assert_eq!(
23        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
24        pid_ctrl::PidOut::new(20.0, 20.0, 0.0, 40.0)
25    );
26
27    // setting symmetrical limits around zero
28    pid.kp.limits.set_limit(10.0);
29    assert_eq!(
30        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
31        pid_ctrl::PidOut::new(10.0, 30.0, 0.0, 40.0)
32    );
33
34    let time_delta = 0.5;
35    assert_eq!(
36        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
37        pid_ctrl::PidOut::new(10.0, 35.0, 0.0, 45.0)
38    );
39
40    // setting upper limits returns error if new value conflicts with lower limit
41    pid.ki.limits.try_set_upper(28.0).unwrap();  
42    assert_eq!(
43        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
44        pid_ctrl::PidOut::new(10.0, 28.0, 0.0, 38.0)
45    );
46
47    // time_delta gets clamped to Float::epsilon() - Float::infinity()
48    let measurement = 1.0;
49    let time_delta = -7.0;
50    pid.kd.set_scale(num_traits::float::FloatCore::epsilon());
51    assert_eq!(pid.step(
52        pid_ctrl::PidIn::new(measurement, time_delta)), 
53        pid_ctrl::PidOut::new(10.0, 28.0, -1.0, 37.0)
54    );
55
56    // configure setpoint directly
57    pid.setpoint = 1.0;
58    assert_eq!(pid.step(
59        pid_ctrl::PidIn::new(measurement, time_delta)), 
60        pid_ctrl::PidOut::new(0.0, 28.0, 0.0, 28.0)
61    );
62}
Source

pub fn step(&mut self, input: PidIn<T>) -> PidOut<T>

Examples found in repository?
examples/case.rs (line 10)
3fn main() {
4    let mut pid = pid::PidCtrl::new_with_pid(0.5, 0.1, 0.1);
5    let mut measurement = 0.0;
6    let mut width:usize;
7    pid.init(7.5, measurement);
8
9    for _i in 1..21 {
10        measurement += pid.step(pid::PidIn::new(measurement, 1.0)).out;
11        width = (measurement * 10.0) as usize;
12
13        println!("{measurement:>0$.2}", width);
14    }
15}
More examples
Hide additional examples
examples/usage.rs (line 16)
4fn main() {
5    let mut pid = pid_ctrl::PidCtrl::new_with_pid(3.0, 2.0, 1.0);
6
7    let setpoint = 5.0;
8    let prev_measurement = 0.0;
9    // calling init optional. Setpoint and prev_measurement set to 0.0 by default.
10    // Recommended to avoid derivative kick on startup
11    pid.init(setpoint, prev_measurement);
12
13    let measurement = 0.0;
14    let time_delta = 1.0;
15    assert_eq!(
16        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
17        pid_ctrl::PidOut::new(15.0, 10.0, 0.0, 25.0)
18    );
19
20    // changing pid constants
21    pid.kp.set_scale(4.0);
22    assert_eq!(
23        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
24        pid_ctrl::PidOut::new(20.0, 20.0, 0.0, 40.0)
25    );
26
27    // setting symmetrical limits around zero
28    pid.kp.limits.set_limit(10.0);
29    assert_eq!(
30        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
31        pid_ctrl::PidOut::new(10.0, 30.0, 0.0, 40.0)
32    );
33
34    let time_delta = 0.5;
35    assert_eq!(
36        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
37        pid_ctrl::PidOut::new(10.0, 35.0, 0.0, 45.0)
38    );
39
40    // setting upper limits returns error if new value conflicts with lower limit
41    pid.ki.limits.try_set_upper(28.0).unwrap();  
42    assert_eq!(
43        pid.step(pid_ctrl::PidIn::new(measurement, time_delta)), 
44        pid_ctrl::PidOut::new(10.0, 28.0, 0.0, 38.0)
45    );
46
47    // time_delta gets clamped to Float::epsilon() - Float::infinity()
48    let measurement = 1.0;
49    let time_delta = -7.0;
50    pid.kd.set_scale(num_traits::float::FloatCore::epsilon());
51    assert_eq!(pid.step(
52        pid_ctrl::PidIn::new(measurement, time_delta)), 
53        pid_ctrl::PidOut::new(10.0, 28.0, -1.0, 37.0)
54    );
55
56    // configure setpoint directly
57    pid.setpoint = 1.0;
58    assert_eq!(pid.step(
59        pid_ctrl::PidIn::new(measurement, time_delta)), 
60        pid_ctrl::PidOut::new(0.0, 28.0, 0.0, 28.0)
61    );
62}

Trait Implementations§

Source§

impl<T: Clone + FloatCore + Default> Clone for PidCtrl<T>

Source§

fn clone(&self) -> PidCtrl<T>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + FloatCore + Default> Debug for PidCtrl<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default + FloatCore + Default> Default for PidCtrl<T>

Source§

fn default() -> PidCtrl<T>

Returns the “default value” for a type. Read more
Source§

impl<T: Hash + FloatCore + Default> Hash for PidCtrl<T>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T: PartialEq + FloatCore + Default> PartialEq for PidCtrl<T>

Source§

fn eq(&self, other: &PidCtrl<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: PartialOrd + FloatCore + Default> PartialOrd for PidCtrl<T>

Source§

fn partial_cmp(&self, other: &PidCtrl<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T: Copy + FloatCore + Default> Copy for PidCtrl<T>

Source§

impl<T: FloatCore + Default> StructuralPartialEq for PidCtrl<T>

Auto Trait Implementations§

§

impl<T> Freeze for PidCtrl<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for PidCtrl<T>
where T: RefUnwindSafe,

§

impl<T> Send for PidCtrl<T>
where T: Send,

§

impl<T> Sync for PidCtrl<T>
where T: Sync,

§

impl<T> Unpin for PidCtrl<T>
where T: Unpin,

§

impl<T> UnwindSafe for PidCtrl<T>
where T: UnwindSafe,

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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, 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.