// Параметры ПИД-регулятора
typedef struct {
float Kp; // Пропорциональный коэффициент
float Ki; // Интегральный коэффициент
float Kd; // Дифференциальный коэффициент
float Ts; // Время дискретизации
float deadzone; // Мертвая зона
float error_limit; // Ограничение ошибки
float integral; // Интегральная составляющая
float prev_error; // Предыдущее значение ошибки
} PIDController;
// Инициализация ПИД-регулятора
void PID_Init(PIDController *pid, float Kp, float Ki, float Kd, float Ts, float deadzone, float error_limit) {
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->Ts = Ts;
pid->deadzone = deadzone;
pid->error_limit = error_limit;
pid->integral = 0.0f;
pid->prev_error = 0.0f;
}
// Вычисление выходного сигнала ПИД-регулятора
float PID_Compute(PIDController *pid, float setpoint, float measured_value) {
float error = setpoint - measured_value;
// Ограничение ошибки
if (error > pid->error_limit) {
error = pid->error_limit;
} else if (error < -pid->error_limit) {
error = -pid->error_limit;
}
// Мертвая зона
if (error > -pid->deadzone && error < pid->deadzone) {
error = 0.0f;
}
// Пропорциональная составляющая
float P = pid->Kp * error;
// Интегральная составляющая
pid->integral += error * pid->Ts;
// Ограничение интегральной составляющей
if (pid->integral > 1.0f) {
pid->integral = 1.0f;
} else if (pid->integral < 0.0f) {
pid->integral = 0.0f;
}
float I = pid->Ki * pid->integral;
// Дифференциальная составляющая
float D = pid->Kd * (error - pid->prev_error) / pid->Ts;
pid->prev_error = error;
// Суммарный выходной сигнал
float output = P + I + D;
// Ограничение выходного сигнала
if (output > 1.0f) {
output = 1.0f;
// Отключение накопления интегральной составляющей при ограничении
pid->integral -= error * pid->Ts;
} else if (output < 0.0f) {
output = 0.0f;
// Отключение накопления интегральной составляющей при ограничении
pid->integral -= error * pid->Ts;
}
return output;
}
int main() {
// Пример использования ПИД-регулятора
PIDController pid;
PID_Init(&pid, 1.0f, 0.1f, 0.01f, 0.01f, 0.05f, 1.0f);
float setpoint = 1.0f;
float measured_value = 0.0f;
for (int i = 0; i < 100; i++) {
float output = PID_Compute(&pid, setpoint, measured_value);
measured_value += output * 0.01f; // Пример изменения измеренного значения
printf("Output: %f, Measured: %f\n", output, measured_value);
}
return 0;
}