Введение
Пропорционально‑интегрально‑дифференциальный (ПИД) регулятор — один из самых распространённых алгоритмов управления в технике. Он применяется везде, где нужно поддерживать заданное значение (уставку, setpoint) физической величины:
- температура в печи;
- скорость двигателя;
- положение сервопривода;
- давление в трубопроводе;
- уровень жидкости в резервуаре.
В статье разберём:
- принцип работы ПИД‑регулятора;
- математическую модель и параметры настройки;
- методы настройки (Зиглера‑Николса, ручной подбор);
- реализацию на языке C для микроконтроллеров;
- типичные проблемы и способы их решения.
1. Принцип работы ПИД‑регулятора
1.1. Базовая схема управления
Система управления с обратной связью включает:
- Уставку (setpoint, SP) — желаемое значение величины.
- Датчик — измеряет текущее значение (process variable, PV).
- Регулятор — вычисляет управляющее воздействие (output, OP).
- Исполнительный механизм — изменяет процесс (нагреватель, клапан, двигатель).
- Объект управления — сама физическая система.
Ошибка регулирования:
e(t)=SP−PV(t)
1.2. Три составляющие ПИД
Регулятор формирует выход OP как сумму трёх компонентов:
- Пропорциональная часть (P):OPP=Kp⋅e(t)
- Чем больше ошибка, тем сильнее реакция.
- Недостаток: статическая ошибка (если OP не может полностью скомпенсировать возмущение).
- Интегральная часть (I):OPI=Ki⋅∫0te(τ)dτ
- Накапливает ошибку со временем, устраняет статическую ошибку.
- Опасность: интегральное насыщение (windup).
- Дифференциальная часть (D):OPD=Kd⋅dtde(t)
- Реагирует на скорость изменения ошибки, демпфирует колебания.
- Усиливает шум датчиков (требуется фильтрация).
Итоговый выход:
OP(t)=Kp⋅e(t)+Ki⋅∫0te(τ)dτ+Kd⋅dtde(t)
2. Параметры настройки ПИД
2.1. Физический смысл коэффициентов
- Kp (пропорциональный коэффициент):
- определяет «жёсткость» регулирования;
- при слишком большом Kp — колебания и неустойчивость;
- при слишком малом — медленная реакция.
- Ki (интегральный коэффициент):
- устраняет статическую ошибку;
- при большом Ki — перерегулирование и «раскачка»;
- единица измерения: 1/время (например, 1/с).
- Kd (дифференциальный коэффициент):
- демпфирует систему, снижает перерегулирование;
- при большом Kd — усиление шума;
- требует фильтрации производной.
2.2. Формы записи
- Параллельная форма (приведена выше).
- Последовательная форма (с постоянной времени интегрирования Ti и дифференцирования Td):OP(t)=Kp(e(t)+Ti1∫0te(τ)dτ+Tddtde(t)) где Ki=Kp/Ti, Kd=Kp⋅Td.
3. Методы настройки ПИД
3.1. Метод Зиглера‑Николса (частотный)
Шаг 1. Установим Ki=0, Kd=0.
Шаг 2. Постепенно увеличиваем Kp, пока система не войдёт в устойчивые колебания.
Шаг 3. Зафиксируем:
- Kpкр — критическое значение Kp;
- Tкол — период колебаний.
Расчёт коэффициентов:
| Параметр | P | PI | PID |
|---|---|---|---|
| Kp | 0.5⋅Kpкр | 0.45⋅Kpкр | 0.6⋅Kpкр |
| Ki | — | 0.83⋅TколKp | Tкол2⋅Kp |
| Kd | — | — | 8Kp⋅Tкол |
Плюсы: простота, не требует модели объекта.
Минусы: грубая настройка, часто даёт избыточное перерегулирование.
3.2. Ручной подбор (по шагам)
- Настройка Kp:
- установите Ki=0, Kd=0;
- увеличивайте Kp, пока не появятся колебания;
- уменьшите Kp на 30–50 %.
- Настройка Ki:
- медленно увеличивайте Ki, пока статическая ошибка не исчезнет;
- следите за перерегулированием.
- Настройка Kd:
- добавляйте Kd, чтобы снизить колебания;
- если появляется шум — уменьшите Kd или добавьте фильтр.
3.3. Автонастройка
Современные контроллеры поддерживают:
- релейную автонастройку (аналогично Зиглеру‑Николсу);
- адаптивные алгоритмы (нечёткая логика, нейросетевые регуляторы).
4. Реализация ПИД на C
4.1. Дискретизация
В цифровых системах:
- время квантуется шагом Δt (период опроса датчика);
- интеграл заменяется суммой;
- производная — разностной схемой.
Дискретная форма:
OP[n]=Kp⋅e[n]+Ki⋅Δt⋅i=0∑ne[i]+Kd⋅Δte[n]−e[n−1]=OPP+OPI+OPD
4.2. Код (базовая версия)
#include <stdint.h>
typedef struct {
float Kp; // Пропорциональный коэффициент
float Ki; // Интегральный коэффициент
float Kd; // Дифференциальный коэффициент
float dt; // Шаг времени (секунды)
float setpoint; // Уставка
float output; // Текущий выход
float integrator; // Сумма для интегральной части
float error_prev; // Предыдущая ошибка
} pid_t;
// Инициализация регулятора
void pid_init(pid_t *pid, float Kp, float Ki, float Kd, float dt) {
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->dt = dt;
pid->integrator = 0.0f;
pid->error_prev = 0.0f;
}
// Вычисление выхода ПИД
float pid_update(pid_t *pid, float process_variable) {
float error = pid->setpoint - process_variable;
// Пропорциональная часть
float P = pid->Kp * error;
// Интегральная часть
pid->integrator += pid->Ki * error * pid->dt;
// Ограничение интегратора (защита от windup)
if (pid->integrator > 100.0f) pid->integrator = 100.0f;
if (pid->integrator <



