Робототехніка · Теорія керування
📅 Липень 2026 ⏱ ≈ 12 хв читання 🎯 Середній · Останнє оновлення: 9 липня 2026 р.

ПД-регулятор (PID) для стабілізації руху

Чи це двоколісний робот-балансир, чи гексапод, що вирівнює своє тіло, чи дрон, що утримує висоту, — більшість задач стабілізації в робототехніці зводяться до одного й того самого: якнайшвидше звести сигнал похибки до нуля, без перерегулювання чи коливань. PID-регулятор — пропорційний, інтегральний, диференціальний — це робочий кінь такого рішення, який налаштовують по-своєму для сотні різних механізмів.

Коротко: Стаття пояснює формулу PID у неперервному та дискретному вигляді, чому «закручування» (windup) інтегральної складової при насиченні виконавчого механізму вимагає anti-windup обмеження, як derivative kick усувають, диференціюючи виміряне значення замість похибки, налаштування за методом Зіглера-Ніколса, каскадні (вкладені) контури керування та приклад балансування оберненого маятника на JavaScript.

Формула PID

Маючи бажану уставку r(t) та виміряне значення y(t), похибка дорівнює e(t) = r(t) − y(t). Закон керування PID у неперервному часі:

u(t) = Kp·e(t) + Ki·∫₀ᵗ e(τ)dτ + Kd·de(t)/dt

u(t) — керуючий вихід: момент двигуна, команда тяги, кут сервоприводу — те, що надсилається на виконавчий механізм. Kp, Ki, Kd — три коефіцієнти налаштування, що визначають, наскільки агресивно реагує регулятор.

Дискретна реалізація

Реальні контролери працюють із фіксованою частотою дискретизації (наприклад, 100–1000 Гц для робота-балансира), тож інтеграл стає накопичувальною сумою, а похідна — скінченною різницею:

integral += e · dt
derivative = (e − e_prev) / dt
u = Kp·e + Ki·integral + Kd·derivative
e_prev = e
class PID {
  constructor(kp, ki, kd) {
    this.kp = kp; this.ki = ki; this.kd = kd;
    this.integral = 0;
    this.prevError = 0;
  }

  update(setpoint, measured, dt) {
    const error = setpoint - measured;
    this.integral += error * dt;
    const derivative = (error - this.prevError) / dt;
    this.prevError = error;
    return this.kp * error + this.ki * this.integral + this.kd * derivative;
  }
}

Роль кожної складової у стабільності

Інтуїція коефіцієнта демпфування: збільшення Kd — наче додавання амортизатора; збільшення Kp — наче жорсткіша пружина. Стабільному, чутливому стабілізатору потрібен правильний баланс обох — надто жорстко без демпфування коливається вічно, надто багато демпфування без жорсткості ніколи швидко не повертається до уставки.

Накопичення інтегральної складової (windup) та anti-windup

Якщо виконавчий механізм насичується (наприклад, двигун вже на 100% потужності, а похибка залишається), інтегральна складова продовжує накопичуватися — «закручується» (windup) — далеко за межі потрібного. Коли похибка нарешті змінює знак, регулятор продовжує давати повну потужність у неправильному напрямку, доки закручений інтеграл не розкрутиться, спричиняючи велике перерегулювання.

Anti-windup із обмеженням: припинити інтегрувати, щойно вихід насичується
якщо (|u| >= u_max ТА знак(похибки) == знак(u)) → заморозити накопичення інтеграла
update(setpoint, measured, dt) {
  const error = setpoint - measured;
  const pTerm = this.kp * error;
  const dTerm = this.kd * (error - this.prevError) / dt;
  this.prevError = error;

  // орієнтовний вихід без додавання нового інтеграла
  let u = pTerm + this.ki * this.integral + dTerm;
  const saturated = Math.abs(u) >= this.uMax;
  const sameSign = Math.sign(u) === Math.sign(error);

  // інтегруємо лише коли ЩЕ НЕ насичені в тому самому напрямку
  if (!(saturated && sameSign)) this.integral += error * dt;

  u = pTerm + this.ki * this.integral + dTerm;
  return Math.max(-this.uMax, Math.min(this.uMax, u));
}

Derivative kick і фільтрація

Коли уставка змінюється миттєво (ступінчаста команда), наївна похідна de/dt миттєво «стрибає», бо стрибає сама похибка — це називають derivative kick. Стандартне рішення — брати похідну від виміряного значення, а не від похибки (стрибок уставки не з'являється у виміряному сигналі):

derivative = −(y − y_prev) / dt // похідна від виміряного значення, з протилежним знаком

Оскільки диференціальна складова також посилює високочастотний шум датчиків, реальні контролери пропускають її через фільтр низьких частот (часто достатньо простого експоненційного ковзного середнього) перед використанням.

Налаштування: Зіглер-Ніколс та ручне налаштування

Класичний метод Зіглера-Ніколса: встановіть Ki = Kd = 0, підвищуйте Kp, доки система не почне коливатися зі сталою, незгасаючою амплітудою — це граничний коефіцієнт Ku та період коливань Tu. Далі застосовують:

РегуляторKpKiKd
Лише P0.50·Ku
PI0.45·Ku1.2·Kp / Tu
PID (класичний)0.60·Ku2·Kp / TuKp·Tu / 8

Зіглер-Ніколс дає агресивну відправну точку, часто занадто коливальну для делікатних робототехнічних задач. На практиці більшість інженерів вручну доналаштовують звідти: підвищують Kp, доки реакція швидка, але злегка коливальна, додають Kd, доки коливання не згасне, і додають невеликий Ki, лише якщо залишається усталена похибка.

Не викликайте навмисно сталі коливання на реальному обладнанні поблизу механічних обмежень — для будь-чого з реальним моментом (рука робота, дрон) спочатку змоделюйте процес налаштування або використайте безпечніший метод, як-от relay feedback / налаштування за ступінчастою реакцією.

Каскадне керування

Багато систем стабілізації в робототехніці використовують вкладені PID-контури замість одного плоского регулятора. Робот-балансир зазвичай каскадує: зовнішній контур керує кутом нахилу (уставка = вертикальне положення), вихід якого стає уставкою для внутрішнього, швидшого контуру, що керує швидкістю коліс, вихід якого стає струмом двигуна. Внутрішній контур працює з вищою частотою й відхиляє збурення (тертя двигуна, нерівна підлога), перш ніж вони взагалі досягнуть повільнішого, стратегічнішого зовнішнього контуру.

Зовнішній контур (кут, ~50 Гц): ω_ціль = PID_кут(0 − θ)
Внутрішній контур (швидкість, ~500 Гц): момент = PID_швидкість(ω_ціль − ω_виміряна)

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

Обернений маятник на візку (класичний тестовий приклад «самобалансуючого робота») використовує PID на куті нахилу для обчислення команди прискорення візка:

const pid = new PID(60, 2, 8);   // Kp, Ki, Kd налаштовані для цього маятника

function controlLoop(dt) {
  const theta = pendulum.getTiltAngle();     // радіани від вертикалі
  const accelCmd = pid.update(0, theta, dt); // уставка = 0 (вертикально)
  cart.applyAcceleration(accelCmd);
  pendulum.step(dt);
}

Оскільки маятник має реальну інерцію, саме диференціальна складова насправді не дає йому перегойдатися через вертикаль — чисте P-керування оберненим маятником коливається зі зростаючою амплітудою, доки він не впаде; додавання D дає демпфування, потрібне для стабільної рівноваги.

🦾 Дослідіть кінематику роботизованої руки

Побачте концепції керування зі зворотним зв'язком поруч із прямою та зворотною кінематикою.

Відкрити симуляцію →