ПИД-регулятор без магии
ПИД-регулятор вычисляет управляющее воздействие по ошибке e = цель − измерение. Это три слагаемых, у каждого своя роль:
- P (пропорциональное) — толкает систему к цели тем сильнее, чем больше ошибка. Слишком большой Kp даёт колебания.
- I (интегральное) — накапливает ошибку во времени и убирает постоянное отклонение (например, из-за трения или веса).
- D (дифференциальное) — реагирует на скорость изменения ошибки и гасит перерегулирование.
Код
class PID:
def __init__(self, kp, ki, kd, limit):
self.kp, self.ki, self.kd, self.limit = kp, ki, kd, limit
self.integral = 0.0
self.prev_error = None
def update(self, error, dt):
self.integral += error * dt
# защита от «накрутки» интеграла
self.integral = max(-self.limit, min(self.limit, self.integral))
deriv = 0.0 if self.prev_error is None else (error - self.prev_error) / dt
self.prev_error = error
out = self.kp * error + self.ki * self.integral + self.kd * deriv
return max(-self.limit, min(self.limit, out))
Порядок ручной настройки
- Обнулите Ki и Kd. Увеличивайте Kp, пока система не начнёт устойчиво колебаться.
- Уменьшите Kp примерно вдвое.
- Добавляйте Kd, пока перерегулирование не станет приемлемым.
- Добавьте немного Ki, чтобы убрать остаточную ошибку. Если появились медленные «раскачки» — Ki слишком велик.
Типичные проблемы
| Симптом | Причина |
|---|---|
| Дрожит около цели | Большой Kp или шумная D-составляющая — отфильтруйте производную |
| Не доезжает до цели | Нет I-составляющей, мёртвая зона привода |
| Сильно проскакивает цель | Мало Kd или накрутка интеграла |
| Ведёт себя по-разному при разной частоте цикла | Не учитывается dt |