use piddiy::PidController;
#[derive(Clone, Copy)]
struct ControlData {
temperature: f64,
integral_limit: f64,
integral_reset: bool,
}
fn control_system_compute(
pid: &mut PidController<f64, ControlData>,
data: ControlData,
) -> (f64, f64, f64) {
if data.integral_reset {
pid.reset_integral(); }
let error = pid.calculate_error(data.temperature); let integral = pid
.calculate_integral(error)
.clamp(-data.integral_limit, data.integral_limit); let derivative = pid.calculate_derivative(error);
(error, integral, derivative)
}
fn main() {
let set_point = -2.0; let mut pid = PidController::<f64, ControlData>::new();
pid.compute_fn(control_system_compute)
.set_point(set_point)
.kp(0.5) .ki(0.1) .kd(0.05);
let mut control_data = ControlData {
temperature: 30.0, integral_limit: 10.0, integral_reset: false, };
println!("Target Temperature: {:.2}°C", set_point);
println!("Initial Temperature: {:.2}°C", control_data.temperature);
for i in 0..10 {
let (error, integral, derivative) = (pid.error, pid.integral, pid.derivative);
control_data.integral_reset = control_data.integral_limit - 1.0 <= integral.abs();
println!("Cycle {}: Temp = {:.2}°C, Error = {:.2}, Integral = {:.2}, Derivative = {:.2}, Windup = {}",
i, control_data.temperature, error, integral, derivative, control_data.integral_reset);
let control_output = pid.compute(control_data);
control_data.temperature += control_output; }
}