Внутренняя логика PID (PID-Internals) | Betaflight
Статья объясняет, какие переменные участвуют во внутреннем контуре управления и как вычисляются компоненты P/I/D в классическом контроллере «PID controller 0 / MultiWii».
Цель: дать описание, которое удобно «трассировать» до формул и псевдокода. Поэтому имена переменных (gyroADC, rcCommand, axisPID…) сохранены, а коэффициенты и множители в формулах приведены без «упрощений».
Содержание
- Введение и модель сигналов
- IO variables (переменные ввода/вывода)
- PID controller 0 / MultiWii (дефолтная логика)
- Mode dependent mix (смешивание по режимам)
- Gyro stabilization (стабилизация по гироскопу)
- Интерпретация как сумма PI и PD
- Чек‑лист самопроверки (для техперсонала)
- Примечания и важные моменты (HTML/CSS/JS)
Введение и модель сигналов
Что считается «входом» и «выходом» PID
Входы (сигналы):
- rcCommand[axis] — команда пилота по оси (roll/pitch/yaw).
- gyroADC[axis] — сигнал гироскопа (угловая скорость, в «сырых» единицах).
- inclination[axis] — оценка наклона (угол) из акселерометра в 0.1° (обычно для roll/pitch).
Выход:
- axisPID[axis] — управляющее воздействие на микшер моторов, которое суммируется с газом.
Как читать формулы и ограничения
В формулах используются типовые операции: constrain(...) — ограничение значения по модулю (clamp), integrate(...) — накопление ошибки (интеграл) с ограничением состояния интегратора (anti-windup), diff() и mean() — дискретная производная и усреднение.
↑ К оглавлениюIO variables (переменные ввода/вывода)
gyroADC: перевод в deg/s
Две ключевые оценки перевода gyroADC в градусы в секунду:
$$\frac{\text{gyroADC}}{8192} \cdot 2000 = \text{deg/s}$$
$$\frac{\text{gyroADC}}{4} \sim \text{deg/s}$$
Техническая интерпретация: второе выражение — практичная «быстрая» аппроксимация, которая часто встречается в высокочастотном коде управления (где важна скорость вычислений). Важно именно то, что дальнейшие формулы используют масштаб gyroADC/4.
rcCommand: диапазон и масштабирование
rcCommand номинально лежит в диапазоне $$\langle -500 \dots 500 \rangle,$$ но затем масштабируется коэффициентом rcRate/100, из‑за чего может достигать $$\pm 1250.$$
inclination и max_angle_inclination
inclination измеряется в 0.1 градуса и описывает отклонение по roll/pitch от горизонта. Параметр max_angle_inclination задаёт лимит целевого наклона (также в 0.1°), значение по умолчанию — 50° (то есть 500).
axisPID и связь с микшером
axisPID — выход PID на микшер; он добавляется к газу $$\text{throttle} \in \langle 1000 \dots 2000 \rangle.$$ Диапазон выхода ограничен $$\langle \text{minthrottle}, \text{maxthrottle} \rangle,$$ типичные значения по умолчанию — $$\langle 1150 \dots 1850 \rangle.$$
| Переменная | Смысл | Единицы/масштаб | Зачем это важно в настройке |
|---|---|---|---|
| gyroADC | Измеренная угловая скорость | /4 ≈ deg/s | Определяет, что именно демпфирует D-term и часть P в стабилизации |
| rcCommand | Команда пилота | ≈ [-500;500], до ±1250 | Формирует целевую скорость/наклон, влияет на setpoint и насыщения |
| inclination | Наклон от горизонта | 0.1° | Важен для ANGLE/HORIZON (уровень выравнивания) |
| axisPID | Выход в микшер моторов | внутренние единицы микшера | Ограничения min/max throttle влияют на клиппинг и управляемость на газу |
PID controller 0, «MultiWii» (логика по умолчанию)
Контроллер разбит на две части: Leveling term (по углу, на базе inclination) и Gyro term (по угловой скорости, на базе gyroADC).
Leveling term (уровень выравнивания)
Псевдокод и формулы (с сохранением коэффициентов):
$$error = \operatorname{constrain}\!\left(2\cdot rcCommand[axis], \pm\,max\_angle\_inclination\right) - inclination[axis]$$
$$P_{acc} = \operatorname{constrain}\!\left(\frac{P8[PIDLEVEL]}{100}\cdot error,\ \pm\,5\cdot D8[PIDLEVEL]\right)$$
$$I_{acc} = \operatorname{intergrate}(error,\ \pm 10000)\cdot \frac{I8[PIDLEVEL]}{4096}$$
Примечание по трассировке: в строке интегратора слово intergrate оставлено намеренно — так оно встречается в исходном материале. В реальном коде это обычно integrate.
Как это понимать инженеру:
- 2*rcCommand формирует «целевой наклон» от стика, далее ограниченный max_angle_inclination.
- Разность с inclination даёт ошибку по углу: «сколько ещё нужно наклониться/вернуться».
- constrain(... ± 5 * D8[PIDLEVEL]) ограничивает величину Pacc (защита от чрезмерных команд).
- Интеграл Iacc ограничен по модулю (±10000), чтобы не накапливать «бесконечную» ошибку.
Gyro term (по угловой скорости)
Псевдокод и формулы (с сохранением коэффициентов):
$$P_{gyro} = rcCommand[axis]$$
$$error = \frac{rcCommand[axis]\cdot 10\cdot 8}{pidProfile \to P8[axis]} - \frac{gyroADC[axis]}{4}$$
$$I_{gyro} = \frac{\operatorname{integrate}(error,\ \pm 16000)}{10\cdot 8}\cdot \frac{I8[axis]}{100}$$
Практический смысл:
- gyroADC[axis]/4 используется как оценка фактической угловой скорости в deg/s (приближённо).
- Левая часть в формуле error — преобразование rcCommand к сопоставимому масштабу, чтобы вычитание с gyroADC/4 было осмысленным.
- Ограничение интегратора на ±16000 — анти‑windup: защита от «разгона» I-term в ситуациях, когда достичь цели невозможно (например, при насыщении моторов или резких манёврах).
Сброс I-term: условия
Интегральная часть сбрасывается, если выполняется одно из условий:
- скорость вращения по оси > +-64deg/s
- ось — YAW и rcCommand > +-100
Зачем это делают: чтобы I-term не «копил» ошибку во время активного разворота/высокой скорости вращения, а затем не создавал длительный паразитный «хвост» коррекции после прекращения команды.
Mode dependent mix (смешивание по режимам)
Заметка: yaw всегда берётся из gyro
Для оси yaw в смешивании указано правило: yaw is always from gyro. Это означает, что для yaw не используется «выравнивание по горизонту» (через inclination), а берётся контур по угловой скорости.
HORIZON — смешивание пропорционально max deflection
В режиме HORIZON доли Leveling и Gyro зависят от максимального отклонения стиков roll/pitch:
$$deflection = \frac{\max\left(|rcCommand[PITCH]|,\ |rcCommand[ROLL]|\right)}{500},\quad \text{limit } 0.0 \dots 1.0$$
$$P = P_{acc}\cdot(1-deflection) + P_{gyro}\cdot deflection$$
$$I = I_{acc}\cdot(1-deflection) + I_{gyro}\cdot deflection$$
Инженерная трактовка: при малых отклонениях стика (deflection≈0) приоритет — удержание горизонта (Leveling), при больших (deflection≈1) — поведение «как в rate/acro» (Gyro).
GYRO
$$P = P_{gyro}$$
$$I = I_{gyro}$$
ANGLE
$$P = P_{acc}$$
$$I = I_{acc}$$
Gyro stabilization (стабилизация по гироскопу)
Отдельно описана часть стабилизации, которая формирует дополнительную коррекцию по текущей угловой скорости и её изменению. Ниже — ровно те же формулы и эквивалентность, но оформленные как текст + LaTeX.
Коррекция P через dynP8
$$P \mathrel{-}= \frac{gyroADC[axis]}{4}\cdot \frac{dynP8}{10\cdot 8}$$
D-term через mean(diff(...), over 3 samples)
$$D = -\operatorname{mean}\!\Big(\operatorname{diff}\!\left(\frac{gyroADC[axis]}{4}\right),\ \text{over 3 samples}\Big)\cdot \frac{3\cdot dynD8}{32}$$
Как это обычно читают на практике: diff() — дискретная производная сигнала угловой скорости, а усреднение по 3 отсчётам снижает влияние шума. Множитель dynD8 задаёт усиление D-части.
Эквивалентная форма («3 loops old»)
$$D = -\left(\frac{gyroADC[axis]}{4} - \left(\frac{gyroADC[axis]}{4}\right)_{\text{3 loops old}}\right)\cdot \frac{dynD8}{32}$$
Интерпретация как сумма PI и PD
PI + PD с нулевой уставкой по gyroADC
Эту схему удобно рассматривать как сумму двух регуляторов:
- PI‑регулятор, который обрабатывает rcCommand и режимы HORIZON/ANGLE; при этом Igyro — это выход интеграла, основанный на gyroADC.
- PD‑регулятор с параметрами dynP8/dynD8 и нулевой уставкой, действующий на gyroADC.
Практическая польза такого взгляда
Для диагностики и настройки:
- Если проблема связана с «следованием команде» (setpoint tracking), обычно анализируют ветку, где участвуют rcCommand и соответствующий error.
- Если проблема похожа на «колебания/дрожание/перерегулирование», часто смотрят на демпфирование (D) и на стабилизирующую коррекцию по gyroADC.
- Сброс I-term при высокой скорости вращения — типовой механизм, который объясняет, почему «после флипа» модель может быстро “вернуться в себя” без затяжных хвостов интеграла.
Чек‑лист самопроверки (для техперсонала)
Единицы измерения и масштабы
| ✓ | Проверка | Критерий «ОК» |
|---|---|---|
| Понимаю, почему в формулах используется gyroADC/4 | Могу связать это с оценкой deg/s и с тем, что D-term дифференцирует именно эту величину | |
| Понимаю диапазоны rcCommand и влияние rcRate/100 | Могу объяснить, почему максимум может быть около ±1250 | |
| Понимаю, что inclination — в 0.1° | Могу перевести 500 → 50° и обратно |
Трассировка «вход → P/I/D → axisPID → микшер»
| ✓ | Проверка | Критерий «ОК» |
|---|---|---|
| Могу показать, где именно формируется error для Leveling term | Использую формулу с constrain(2*rcCommand...) и inclination | |
| Могу показать, где формируется error для Gyro term | Использую формулу с rcCommand*10*8/pidProfile->P8 - gyroADC/4 | |
| Понимаю, как HORIZON смешивает Pacc/Pgyro и Iacc/Igyro | Использую deflection в диапазоне 0..1 и формулы линейной интерполяции | |
| Понимаю D-term и его эквивалентную форму «3 loops old» | Могу объяснить, что это разность текущего и значения 3 цикла назад + масштабирование |
