advanced_pid/
config.rs

1//! The `config` module provides structures for configuring a PID controller.
2//!
3//! [`Gain`] is a structure that holds the proportional, integral, and derivative gains for a PID controller.
4//! [`Config`] is a structure that holds a [`Gain`] and also provides optional limits for the controller output.
5//!
6//! # Examples
7//!
8//! ```rust
9//! use advanced_pid::config::{Config, Gain};
10//!
11//! let gain = Gain { kp: 1.0, ki: 0.1, kd: 0.1 };
12//! let config = Config::from(gain);
13//!
14//! let config_with_limits = Config::new(1.0, 0.1, 0.1).with_limits(-1.0, 1.0);
15//! ```
16use super::FloatType;
17
18/// `Gain` holds the proportional, integral, and derivative gains for a PID controller.
19///
20/// See also: [`Config`]
21#[derive(Debug, Clone, Default)]
22pub struct Gain {
23    pub kp: FloatType,
24    pub ki: FloatType,
25    pub kd: FloatType,
26}
27
28/// `Config` holds a [`Gain`] and also provides optional limits for the controller output.
29#[derive(Debug, Clone)]
30pub struct Config {
31    pub gain: Gain,
32    pub min: FloatType,
33    pub max: FloatType,
34}
35
36impl Default for Config {
37    fn default() -> Self {
38        Self {
39            gain: Default::default(),
40            min: FloatType::NEG_INFINITY,
41            max: FloatType::INFINITY,
42        }
43    }
44}
45
46impl Config {
47    /// Creates a new `Config` with the specified gains.
48    pub fn new(kp: FloatType, ki: FloatType, kd: FloatType) -> Self {
49        Self {
50            gain: Gain { kp, ki, kd },
51            ..Default::default()
52        }
53    }
54
55    /// Returns a new `Config` with the specified limits.
56    pub fn with_limits(self, min: FloatType, max: FloatType) -> Self {
57        Self { min, max, ..self }
58    }
59}
60
61impl From<Gain> for Config {
62    /// Converts a `Gain` into a `Config`.
63    fn from(gain: Gain) -> Self {
64        Self {
65            gain,
66            ..Default::default()
67        }
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_gain_default() {
77        let gain = Gain::default();
78        assert_eq!(gain.kp, 0.0);
79        assert_eq!(gain.ki, 0.0);
80        assert_eq!(gain.kd, 0.0);
81    }
82
83    #[test]
84    fn test_config_new() {
85        let config = Config::new(1.0, 0.5, 0.1);
86        assert_eq!(config.gain.kp, 1.0);
87        assert_eq!(config.gain.ki, 0.5);
88        assert_eq!(config.gain.kd, 0.1);
89        assert_eq!(config.min, FloatType::NEG_INFINITY);
90        assert_eq!(config.max, FloatType::INFINITY);
91    }
92
93    #[test]
94    fn test_config_with_limits() {
95        let config = Config::new(1.0, 0.5, 0.1).with_limits(-2.0, 2.0);
96        assert_eq!(config.gain.kp, 1.0);
97        assert_eq!(config.gain.ki, 0.5);
98        assert_eq!(config.gain.kd, 0.1);
99        assert_eq!(config.min, -2.0);
100        assert_eq!(config.max, 2.0);
101    }
102
103    #[test]
104    fn test_config_from_gain() {
105        let gain = Gain {
106            kp: 1.0,
107            ki: 0.5,
108            kd: 0.1,
109        };
110        let config = Config::from(gain);
111        assert_eq!(config.gain.kp, 1.0);
112        assert_eq!(config.gain.ki, 0.5);
113        assert_eq!(config.gain.kd, 0.1);
114        assert_eq!(config.min, FloatType::NEG_INFINITY);
115        assert_eq!(config.max, FloatType::INFINITY);
116    }
117
118    #[test]
119    fn test_config_default() {
120        let config = Config::default();
121        assert_eq!(config.gain.kp, 0.0);
122        assert_eq!(config.gain.ki, 0.0);
123        assert_eq!(config.gain.kd, 0.0);
124        assert_eq!(config.min, FloatType::NEG_INFINITY);
125        assert_eq!(config.max, FloatType::INFINITY);
126    }
127}