use piddiy::PidController;
#[derive(Clone, Copy)]
struct ControlData {
altitude: f64, altitude_previous: f64, gyro: f64, gyro_previous: f64, integral_decay: f64, alpha: f64, dt: f64, }
fn control_system_compute(
pid: &mut PidController<f64, ControlData>,
data: ControlData,
) -> (f64, f64, f64) {
let altitude_change = (data.altitude - data.altitude_previous) / data.dt;
let error = pid.set_point - data.altitude + 0.1 * altitude_change;
let integral = pid.integral * data.integral_decay + error * data.dt;
let angular_acceleration = (data.gyro - data.gyro_previous) / data.dt;
let derivative = data.alpha * error / data.dt + (1.0 - data.alpha) * angular_acceleration;
(error, integral, derivative)
}
fn main() {
let set_point = 100.0;
let mut pid = PidController::<f64, ControlData>::new();
pid.compute_fn(control_system_compute)
.set_point(set_point)
.kp(0.3) .ki(0.05) .kd(0.65);
let mut control_data = ControlData {
altitude: 65.0, altitude_previous: 50.0, gyro: 15.0, gyro_previous: 15.0, integral_decay: 0.85, alpha: 0.7, dt: 0.1, };
println!("Target Altitude: {:.2}m", set_point);
println!("Initial Altitude: {:.2}m", control_data.altitude);
let mut control_output;
for i in 0..10 {
control_output = pid.compute(control_data);
control_data.altitude += control_output * 0.1; control_data.gyro = control_output * 0.05;
control_data.altitude_previous = control_data.altitude;
control_data.gyro_previous = control_data.gyro;
println!(
"Cycle {:2}: Altitude = {:.2}m, Gyro = {:.2}deg/s, Error = {:.2}, Integral = {:.2}, Derivative = {:.2}",
i, control_data.altitude, control_data.gyro, pid.error, pid.integral, pid.derivative
);
}
}