Дифференциальная часть D: демпфирование и шум

Производная смотрит на скорость ошибки и гасит колебания — но боится шума.

Дифференциальная составляющая (D) реагирует на скорость изменения ошибки: u_D = Kd·de/dt. Она предвидит будущее и демпфирует колебания, но усиливает шум датчика.

Идея производной: предвидеть, а не догонять

P смотрит на текущую ошибку, I — на накопленную (прошлое). А D смотрит в будущее: она оценивает, как быстро меняется ошибка, и реагирует на тенденцию. Если ошибка стремительно сокращается, D понимает, что мы вот-вот достигнем цели, и заранее ослабляет воздействие, чтобы не перелететь. Это как опытный водитель, который отпускает газ перед поворотом, а не в повороте. D-составляющая добавляет системе демпфирования — гасит колебания и уменьшает перерегулирование.

u_D(t) = Kd * de/dt = Kd * (e(t) - e(t-dt)) / dt

Как работает под капотом: D гасит колебания

Возьмём колебательный объект (масса-пружина) и сравним PI и PID. Производная должна заметно снизить раскачку.

def run(Kp, Ki, Kd):
    m, b, kc, dt = 1.0, 0.3, 4.0, 0.05
    setpoint, x, v = 1.0, 0.0, 0.0
    integral, prev_err = 0.0, setpoint - 0.0
    peak = 0.0
    for _ in range(400):
        err = setpoint - x
        integral += err*dt
        deriv = (err - prev_err)/dt
        prev_err = err
        F = Kp*err + Ki*integral + Kd*deriv
        a = (F - b*v - kc*x)/m
        v += a*dt; x += v*dt
        peak = max(peak, x)
    return peak

pi_peak  = run(6.0, 2.0, 0.0)    # без D
pid_peak = run(6.0, 2.0, 3.0)    # с D
print(f"PI  (Kd=0): пик = {pi_peak:.3f}  -> перерегулирование {(pi_peak-1)*100:.0f}%")
print(f"PID (Kd=3): пик = {pid_peak:.3f}  -> перерегулирование {(pid_peak-1)*100:.0f}%")

Вывод:

PI  (Kd=0): пик = 1.325  -> перерегулирование 33%
PID (Kd=3): пик = 0.995  -> перерегулирование -1%

Производная срезала перерегулирование с 33% почти до нуля — система стала заметно спокойнее. D как бы «придерживает» выход, когда тот разгоняется к цели слишком быстро. Именно поэтому D незаменима в системах, где важна плавность: позиционирование, стабилизация дрона, точная механика.

Тёмная сторона: чувствительность к шуму

У D есть серьёзный недостаток. Производная — это разность соседних измерений, делённая на маленький dt. Если в измерении есть шум (а он есть всегда), то даже крошечные случайные скачки превращаются в огромные значения производной: дрожание на 0.01 при dt=0.01 даёт скачок производной на единицу. В результате D-составляющая начинает «нервно дёргать» привод в ответ на шум, что изнашивает механику и ухудшает управление. Покажем это.

import random
random.seed(1)
Kd, dt = 2.0, 0.01
prev = 0.0
clean_d, noisy_d = [], []
true_err = 1.0    # ошибка почти не меняется
for _ in range(6):
    measured = true_err + random.uniform(-0.02, 0.02)   # лёгкий шум
    d = Kd * (measured - prev)/dt
    noisy_d.append(round(d, 1))
    prev = measured
print("D-выход на ПОЧТИ постоянной ошибке (должен быть ~0):")
print(noisy_d)
print("шум 0.02 при dt=0.01 раздувается производной в десятки раз")

Вывод:

D-выход на ПОЧТИ постоянной ошибке (должен быть ~0):
[197.1, 5.7, -0.7, -4.1, 1.9, -0.4]
шум 0.02 при dt=0.01 раздувается производной в десятки раз

Хотя ошибка почти постоянна (D должна быть около нуля), шум вызывает дикие всплески производной. Лечится это фильтрацией сигнала перед дифференцированием или применением D не к ошибке, а к выходу — об этих приёмах поговорим в разделе про доработки. Главное правило: D — мощное демпфирование, но требует чистого сигнала.

D-составляющая как предсказание

Можно взглянуть на производную иначе — как на простейший предсказатель будущего. Линейная экстраполяция говорит: «где ошибка окажется через время Td, если тренд сохранится» — это как раз e + Td·de/dt. То есть D-регулятор реагирует не на текущую ошибку, а на её прогноз на горизонт Td = Kd/Kp секунд вперёд. Этот взгляд объясняет и силу, и слабость D: он полезен, когда тренд предсказуем (плавная динамика), и вреден, когда «тренд» — это шум, ведь экстраполяция шума бессмысленна. Современные регуляторы развивают эту идею до предиктивного управления (MPC), которое прогнозирует поведение на много шагов вперёд по полной модели объекта — но это уже отдельная большая тема.

Частые ошибки

  • Большой Kd на шумном датчике. Производная усиливает шум — привод начинает дёргаться, износ растёт.
  • Дифференцировать ошибку при скачке уставки. Резкое изменение setpoint даёт мгновенный гигантский всплеск D («derivative kick»); часто D берут от выхода, а не от ошибки.
  • Считать, что D ускоряет систему. D не ускоряет, а демпфирует — позволяет поднять Kp без раскачки, что уже косвенно ускоряет.

Итоги

  • D-составляющая реагирует на скорость ошибки, демпфирует колебания и снижает перерегулирование.
  • Она чувствительна к шуму: производная раздувает случайные скачки измерения.
  • Лечение — фильтрация сигнала и применение D к выходу вместо ошибки.
Проверьте себя
1. На что реагирует дифференциальная составляющая?
AНа накопленную ошибку
BНа скорость изменения ошибки (de/dt)
CНа текущую ошибку
DНа уставку
2. Какой главный недостаток D-составляющей?
AОставляет статическую ошибку
BСильная чувствительность к шуму датчика
CЗамедляет систему
DТребует много памяти
3. Что даёт D-составляющая в переходном процессе?
AУстраняет статическую ошибку
BДемпфирует колебания и снижает перерегулирование
CУскоряет нарастание напрямую
DКопит воздействие