bbdoctor
Диагностика дрона по логу: Betaflight, INAV, ArduPilot, PX4
RUENESPTUA

Анализ лога PX4 (.ulg): вибрации, фильтры, регулятор скорости

Flight Review рисует хорошие графики, но на главные вопросы не отвечает: какой пик опасен, механика это или регулятор, какой фильтр крутить, хватает ли данных в логе. Все примеры ниже взяты из реальных логов PX4 1.12–1.17, на которых проверялся bbdoctor, все цифры в них измерены.

Как получить полезный лог

Файл .ulg лежит в папке log/ на SD-карте, или его можно скачать в QGroundControl → Analyze Tools → Log Download. В нашей выборке из 18 логов PX4 у 11 стоит SDLOG_PROFILE = 1, то есть профиль по умолчанию. В таком логе гироскоп есть только в sensor_combined с частотой 200 Гц: PX4 усредняет его по окнам IMU_INTEG_RATE (200 Гц в 17 из 18 наших логов). А vehicle_rates_setpoint в логах 1.12 бывал всего 5–50 Гц. По такому логу не видно ни вибраций выше 100 Гц, ни отклика контура скорости.

Бит SDLOG_PROFILEЗначениеЧто даёт
0 Default+1Обычный набор топиков
4 High rate+16Цель регулятора, угловая скорость и команды моторам на высокой частоте
8 Raw FIFO high-rate IMU (Gyro)+256Сырой гироскоп sensor_gyro_fifo на частоте датчика
9 Raw FIFO high-rate IMU (Accel)+512То же для акселерометра, лог ещё больше

Прибавляй биты к текущему значению, а не заменяй его: 1 превращается в 273, а 25 (Default + System identification + High rate) — в 281. Пример: в логе PX4 1.15.4 на ARK FMU v6X с SDLOG_PROFILE = 1023 (биты 0–9) sensor_gyro_fifo идёт пачками по 10 отсчётов 800 раз в секунду (8 кГц), а угловая скорость после фильтров и actuator_motors — на 800 Гц. Это 25 МБ на 43 секунды, и логгер всё равно пропустил 0,13 с (4 разрыва).

sd_bench -r 100
param set SDLOG_PROFILE 273
reboot

SDLOG_PROFILE применяется только после перезагрузки. Документация PX4 оценивает поток лога по умолчанию примерно в 50 КБ/с, с High rate и Raw FIFO он больше в разы. Губит логи не средняя скорость карты, а провалы записи на сотни миллисекунд. Проверь карту sd_bench в MAVLink Console, объём — до 32 ГБ (предел NuttX). В логе 1.16.2 на обычном профиле 1 логгер потерял 5,4 с: при таком скромном потоке это почти наверняка карта.

Обороты моторов. Для поиска конкретного мотора нужен esc_status с оборотами: bidirectional DShot, телеметрия DShot (DSHOT_TEL_CFG) или DroneCAN-регуляторы. В 1.16–1.17 bidirectional DShot включается DSHOT_BIDIR_EN = 1 с правильным MOT_POLE_COUNT; в текущей документации PX4 отдельного параметра уже нет: для группы выходов выбирается протокол BDShot, а полюса задаются DSHOT_MOT_POL1…12. В логе 1.17 esc_status писался на 167 Гц, в логе 1.12 — на 4 Гц.

Тестовый полёт: 20–30 секунд висения, плавные изменения газа и 10–20 коротких резких отклонений стика по каждой оси. Stabilized подходит: PX4 пишет цель регулятора в любом режиме. Флипы не нужны. Для Betaflight то же самое описано в гайде настройка blackbox.

Вибрации: на что смотреть

Осторожно с accel_vibration_metric и gyro_vibration_metric: судя по нашим логам, их масштаб зависит от версии. В логе 1.12.3 с сырым шумом гироскопа 68,5 °/с метрика акселерометра — 0,06 (медиана за полёт), а на 1.15.4 при шуме вдесятеро меньше (6,4 °/с) — 1,6. На 1.17 она 11,7. Сравнивать эти числа можно только в пределах одной версии и одного аппарата.

bbdoctor считает сырой шум гироскопа как среднеквадратичное значение выше 80 Гц по roll и pitch: до 4 °/с — механика чистая, 4–10 — шумно, больше 10 — плохо. Резонанс — пик выше 60 Гц, стоящий над локальным фоном больше чем на 6 дБ хотя бы в 60% диапазонов газа. Его частота однозначна, если гироскоп записан на полной частоте датчика (sensor_gyro_fifo) или хотя бы на 2 кГц при пике ниже половины частоты Найквиста; иначе bbdoctor перечисляет кандидатов. Как найти конкретный мотор — в гайде вибрация и плохой мотор.

Реальные случаи из логов

PX4 1.15.4: резонанс 469 Гц и статический notch

Тот самый лог 1.15.4 с ARK FMU v6X (6S, сырой гироскоп на 8 кГц). bbdoctor нашёл пик 469 Гц только по pitch, на 6 дБ над фоном при любом газе. Сырой шум: roll 6,4, pitch 1,6, yaw 2,1 °/с, после фильтров остаётся 0,11 °/с. Выше 250 Гц причину обычно ищут в мягких проставках стека и крепеже, а не в лучах.

Слева спектр pitch до и после фильтров PX4 1.15.4 с горбом на 469 Гц; справа сырой спектр pitch на двух уровнях газа, горб на 469 Гц не сдвигается
PX4 1.15.4, 6S, сырой гироскоп из sensor_gyro_fifo на 8 кГц. Слева pitch до фильтров (серый) и после (синий); отфильтрованная скорость пишется на 800 Гц, поэтому синяя линия обрывается на 400 Гц. Справа сырой pitch при газе около 34% (A) и 37% (B): горбы моторов на 280–400 Гц сдвигаются, горб у 469 Гц стоит на месте.

Как временная мера подойдёт статический notch на эту частоту:

param set IMU_GYRO_NF0_FRQ 469
param set IMU_GYRO_NF0_BW 100

Ширину обычно берут около 30% от частоты, но больше 100 Гц ставить нельзя: это максимум IMU_GYRO_NF0_BW (и IMU_GYRO_NF_BW в 1.12). Две тонкости. Первая: в этом логе включён бортовой FFT, но с настройками по умолчанию он ищет пики только в окне IMU_GYRO_FFT_MIN–IMU_GYRO_FFT_MAX (30–150 Гц), и все записанные им пики лежат в 31–146 Гц. Динамический notch по FFT этот резонанс не поймал бы. Окно можно расширить, но для пика, который стоит на месте, статический notch проще и предсказуемее. Вторая: при IMU_GYRO_CUTOFF = 40 ФНЧ второго порядка уже ослабляет 469 Гц примерно на 43 дБ, так что notch окупится, когда захочешь поднять срез и убрать часть задержки в 5,6 мс. bbdoctor так и пишет: запас по фильтрам есть, но ослаблять их рано, сначала механика.

PX4 1.17: самовозбуждение 42 Гц по pitch

Квадрокоптер 4S на FMU v6C, сырого гироскопа в логе нет, зато есть esc_status. На 63 секундах спокойного полёта в ошибке (гироскоп − цель) по pitch стоит узкий пик 41,7 Гц: на 28 дБ над фоном, 11,5 °/с. Это ниже частоты моторов (61–87 Гц). Roll при тех же P 0.18, I 0.15, D 0.003 чистый. Когерентность гироскопа с командами моторам на этой частоте — 1,0, фаза +13°: контур раскачивает P.

Спектр ошибки гироскоп минус цель для PX4 1.17: узкий пик 42 Гц по pitch, по roll на этой частоте пика нет, полоса частот моторов 61–87 Гц выше пика
PX4 1.17.0, 4S, спектр ошибки (гироскоп − цель) на спокойных участках, 63 с. Pitch (синий) с узким пиком 42 Гц, roll (серый) при тех же коэффициентах — на той же частоте на 31 дБ ниже. Оранжевая полоса — частота вращения моторов (5–95 перцентиль, 61–87 Гц).
param set MC_PITCHRATE_P 0.162

Минус 10% к P. Слетай ещё раз: пик уменьшился — это был контур; вырос — верни P; не изменился — верни P и ищи механику. Обрати внимание на фильтры: IMU_GYRO_CUTOFF = 40 Гц на частоте 42 Гц сам по себе даёт около 90° запаздывания, а IMU_DGYRO_CUTOFF = 20 ослабляет D на 42 Гц в несколько раз и добавляет своё запаздывание, так что D гасит качание слабо. Поднять срез гироскопа было бы полезно, но без сырого гироскопа шум потом не проверить: сначала P, фильтры — по отдельному логу с профилем 281.

PX4 1.12.3: 68,5 °/с шума в логе 222 Гц

Старый полётник FMU v3, 4S, профиль 1. Сырой шум гироскопа выше 80 Гц: roll 68,5, pitch 27,8, yaw 14,5 °/с. А ведь лог видит только полосу 80–111 Гц! Плюс пик, стоящий на месте при любом газе, — но из-за записи 222 Гц настоящая частота может быть 94, 129 или 316 Гц. Так что никакого notch вслепую: сначала пропы, моторы и крепёж, потом короткий лог с Raw FIFO для точной частоты.

PX4 1.12.3: мотор 2 и вторая гармоника

Аппарат 6S, больше 15 минут в воздухе, моторы по esc_status крутятся на 2500–3170 об/мин (42–53 Гц). Порядковый анализ (гироскоп демодулируется фазой вращения каждого мотора) показал у M2 составляющую 2× в 5,3 °/с при почти нуле у остальных: обычно это повреждённая лопасть или разный шаг лопастей. Оговорка: обороты записаны всего 4 раза в секунду, а 2× (около 83 Гц) близко к краю окна 100 Гц. Это подсказка, а не приговор. В стандартном Quad X мотор 2 — задний левый, но у этого аппарата нестандартный SYS_AUTOSTART, так что сверься с миксером, прежде чем снимать проп.

Фильтры PX4

ПараметрВерсииЧто делаетКогда трогать
IMU_GYRO_CUTOFFвсеФНЧ гироскопа (по умолчанию 40 Гц, так в 10 из 18 наших логов)Поднимать ради меньшей задержки, если после фильтров чисто и моторы холодные
IMU_DGYRO_CUTOFFвсеФНЧ для D: D считается по производной угловой скорости. По умолчанию 20 Гц (в 1.12 — 30)Ниже — меньше шума на моторах, но D хуже гасит быстрые качания
IMU_GYRO_NF0_FRQ, IMU_GYRO_NF0_BW, IMU_GYRO_NF1_*1.13+Статические notchТолько на однозначную частоту резонанса
IMU_GYRO_NF_FREQ, IMU_GYRO_NF_BW1.12Статический notchТо же
IMU_GYRO_DNF_EN (бит 0 — обороты ESC, бит 1 — FFT), IMU_GYRO_DNF_HMC, IMU_GYRO_DNF_BW1.13+ (в 1.12 — IMU_GYRO_DYN_NF)Динамический notch по оборотам или по бортовому FFTЕсть телеметрия оборотов — бит 0
IMU_GYRO_FFT_EN, IMU_GYRO_FFT_MIN, IMU_GYRO_FFT_MAX1.12+Бортовой FFT, ищет пики в окне 30–150 Гц по умолчанию (в 1.12 — 32–192)Сам по себе ничего не фильтрует

PX4 фильтрует каждый отсчёт FIFO на полной частоте датчика и только потом прореживает до IMU_GYRO_RATEMAX (по умолчанию 400 Гц, в 16 из 18 наших логов 800). Поэтому notch на 469 Гц работает и при регуляторе на 800 Гц.

Задержка. Задержку ФНЧ гироскопа bbdoctor считает по настройке: для фильтра второго порядка это √2/(2π·fc). Сдвиг во времени между записанными топиками для этого не годится: у PX4 он бывает нулевым при срезе 30–60 Гц.

IMU_GYRO_CUTOFF, Гц2530406080
Задержка, мс9,07,55,63,752,8

Как поднимать срез. Шагами по 10 Гц (40 → 50 → 60). После каждого — полёт на 20–30 секунд, посадка, пальцем по моторам и регуляторам: документация PX4 предупреждает, что их можно перегреть до повреждения. Остановись там, где шум в Actuator Controls FFT заметно растёт, и откатись на шаг. При сыром шуме выше 4 °/с фильтры не трогай: сначала механика. Почему шум греет моторы, разобрано в гайде шум и фильтры.

param set IMU_GYRO_CUTOFF 50

Регулятор скорости: P, I, D, FF и K

Регулятор скорости PX4 считает так: K·(P·ошибка + I·интеграл − D·угловое ускорение) + FF·цель. D считается по измеренному ускорению, а не по ошибке, и резкий стик его не дёргает. Параметры: MC_ROLLRATE_P/I/D/FF/K, то же для PITCHRATE и YAWRATE, пределы интегратора MC_RR_INT_LIM, MC_PR_INT_LIM, MC_YR_INT_LIM.

Множитель K. K = 1 — параллельная форма, P = 1 — стандартная, где K задаёт общее усиление. В логе 1.13.1 на CubeOrange стоит P 1, I 2, D 0.029 и K 0.08 по roll и pitch: реальные коэффициенты 0.08, 0.16 и 0.0023, и сравнивать его «P = 1» с чьим-то 0.15 бессмысленно. FF на K не умножается.

param show MC_ROLLRATE*
param show MC_PITCHRATE*

Порядок ручной настройки по документации PX4: P и D по roll и pitch подбираются по очереди, потом I. На yaw D обычно 0. На время настройки документация велит выключить MC_AIRMODE.

Автотюн. С 1.13 есть встроенный автотюн мультикоптера: MC_AT_EN = 1, затем в QGroundControl (Vehicle Setup → PID Tuning) включи Autotune и нажми кнопку в полёте в режиме со стабилизацией высоты: Altitude, Hold или Position. Любое движение стиков прерывает процесс, так что держи безопасную высоту. MC_AT_APPLY = 1 (по умолчанию) применяет коэффициенты после дизарма. Если после автотюна появились быстрые качания (чаще раза в секунду), документация советует снижать MC_ROLLRATE_K и MC_PITCHRATE_K шагами по 0.02.

TPA, как в Betaflight, в PX4 нет. Ни в одном из наших логов 1.12–1.17 параметров MC_TPA_* нет. Изменение усиления с газом выравнивает модель тяги THR_MDL_FAC (0 — тяга линейна по сигналу, 1 — квадратична); у большинства наших аппаратов 0, у трёх 0.3, у одного 0.1. По документации типичны 0.3–0.5: начни с 0.3 и меняй по 0.1. Качания на малом газе — значение велико, на большом — мало. После изменения перепроверь регулятор скорости.

param set MC_AT_EN 1
param set THR_MDL_FAC 0.3

Отклик bbdoctor оценивает по vehicle_rates_setpoint даже в Stabilized, если гироскоп и цель записаны хотя бы на 200 Гц и пригодных участков с резким стиком не меньше 10 и не меньше четверти от всех (если кривая выходит неустойчивой — 30). В логе 1.16.2 roll доходил лишь до 84% цели, и bbdoctor предложил +10% к P и I: MC_ROLLRATE_P 0.102 → 0.112, MC_ROLLRATE_I 0.1301 → 0.143. Как читать переходную характеристику, разобрано в гайде PID по blackbox.

Самовозбуждение или резонанс рамы

Узкий пик лечат двумя противоположными способами, и путать их дорого: если против самовозбуждения контура опустить фильтры, запаздывание вырастет и качание усилится.

ПризнакКонтур раскачивается самМеханический резонанс
ЧастотаОбычно 10–80 Гц, ниже частоты моторовЛюбая, часто выше 100 Гц, не зависит от газа
ОсиОдна ось или roll+pitch без yawЧасто все оси, включая yaw
МоторыКачаются в такт с гироскопом (высокая когерентность)Связь с командами моторам слабая
P −10%Пик уменьшаетсяНе меняется
Что делатьСнизить P (или D, если раскачивает D)Крепёж, стек, лучи; notch как временная мера

bbdoctor ищет такие пики на спокойных участках (цель меньше 60 °/с, газ ровный) от 10 Гц до 80 Гц или до 0,8 от частоты моторов. Пик должен быть узким, на 10 дБ выше локального фона и не меньше 1 °/с; он отбрасывается, если совпадает с гармониками моторов, стоит на всех осях вместе с yaw или на известном резонансе рамы. Взаимный спектр гироскопа и команды момента показывает, качаются ли моторы в такт (когерентность от 0,5), а фаза — кто раскачивает: P, D или запаздывание фильтров.

Failsafe и батарея

Сам failsafe bbdoctor видит по флагу в vehicle_status, а причина — в сообщениях лога (Flight Review → Messages). В логе 1.13.1 на CubeOrange один эпизод выглядел так: «Failsafe enabled: no offboard», затем «Position-Ctrl activation failed» и «Failsafe: blind descend». Пропал offboard, на этот случай стоял COM_OBL_RC_ACT = 0 (Position), но позиционный режим не включился. «Blind descend» PX4 пишет, когда у регулятора позиции нет даже оценки вертикальной скорости: аппарат снижается с тягой чуть ниже висения. Лечится это связью с компаньон-компьютером, оценкой высоты в EKF2 и действием, которое работает с твоими датчиками (без позиции — Altitude или Land), а не антеннами пульта. Таймаут — COM_OF_LOSS_T; в 1.13 есть ещё COM_OBL_ACT на случай без пульта, с 1.14 остался только COM_OBL_RC_ACT.

В логе 1.17 посреди полёта появилось «Battery 1: over voltage. Land now!», хотя в среднем было 3,6–3,7 В на банку. В текущем коде PX4 эта проверка срабатывает, когда одиночный замер напряжения без фильтрации выше BAT1_N_CELLS × BAT1_V_CHARGED × 1,05: здесь 4 × 4,05 × 1,05 = 17,0 В. Записанные 5 раз в секунду замеры порог не переходят (максимум 16,27 В), зато соседние отличаются на 2–3,5 В: 16,13 → 12,6 → 14,96 В. Разброс тока 6–19 А даже при 22 мОм на банку (оценка bbdoctor, см. ниже) даёт не больше 1,2 В, значит, шумит само измерение напряжения, и сработал незаписанный выброс. Проверь провода и землю от модуля питания до полётника и калибровку BAT1_V_DIV. BAT1_V_CHARGED 4,05 вместо 4,2 (в текущих версиях это значение по умолчанию) только опускает порог.

ПараметрЗначения
NAV_RCL_ACTПотеря пульта: 1 — Hold, 2 — Return, 3 — Land
COM_RC_LOSS_TЧерез сколько секунд пульт считается потерянным: 0.5 в 11 наших логах, но встречалось и 10, и 35 с
BAT_LOW_THR, BAT_CRIT_THR, BAT_EMERGEN_THRПороги остатка: 0.15, 0.07, 0.05 по умолчанию
COM_LOW_BAT_ACT0 — только предупреждение, 2 — Land, 3 — Return на критическом уровне и Land на аварийном

В 12 из 18 наших логов стоит COM_LOW_BAT_ACT = 0 — только предупреждение. Для большого аппарата с GPS разумнее так:

param set COM_LOW_BAT_ACT 3
param set NAV_RCL_ACT 2

Return работает только при рабочей оценке позиции. Без GPS выбирай посадку: COM_LOW_BAT_ACT 2 и NAV_RCL_ACT 3.

Изношенную батарею видно по внутреннему сопротивлению. bbdoctor оценивает его по наклону напряжения от тока на участках с резкой сменой тока: до 12 мОм на банку — норма, 12–25 — предупреждение, больше — плохо. В том же логе 1.17 вышло около 22 мОм против 2–10 у остальных аппаратов, но при таком шумном напряжении цифра ненадёжна: сначала почини измерение, а банку перемерь зарядкой. Полёт начался не с полной батареи (3,94 В на банку), устойчивый минимум (медиана за 0,5 с) — 3,41 В на банку при пиковом токе всего 18 А.

Частые ловушки в логах PX4

Как проверить автоматически

bbdoctor бесплатно разбирает .ulg-логи PX4 онлайн: шум до и после фильтров, резонансы, самовозбуждение контура, отклик регулятора скорости, нагрузку и обороты моторов, батарею, failsafe и разрывы записи. Если лог слишком медленный, он называет нужный SDLOG_PROFILE. Пороги подобраны на FPV-квадрах Betaflight, поэтому большой аппарат сравнивай с его же прошлыми логами. Посмотри пример отчёта или гайды логи ArduPilot и blackbox INAV.

Частые вопросы

Как включить в PX4 запись для анализа вибраций?

В SDLOG_PROFILE прибавь к текущему значению бит 4 High rate (+16) и бит 8 Raw FIFO high-rate IMU Gyro (+256): из 1 получится 273, и перезагрузи полётник. Тогда сырой гироскоп пишется в sensor_gyro_fifo на частоте датчика. Лог вырастет в разы, поэтому включай профиль на тестовые полёты и проверь карту командой sd_bench.

Какие фильтры настраивать в PX4?

IMU_GYRO_CUTOFF (ФНЧ гироскопа), IMU_DGYRO_CUTOFF (ФНЧ D-составляющей), статические notch IMU_GYRO_NF0_FRQ/BW (в 1.12 — IMU_GYRO_NF_FREQ/BW) и динамический notch IMU_GYRO_DNF_EN (в 1.12 — IMU_GYRO_DYN_NF). Но сначала механика: фильтром лечат то, что осталось после пропов, моторов и крепежа. После каждого повышения частоты — полёт на 20–30 секунд и проверка температуры моторов.

Чем bbdoctor отличается от Flight Review?

Flight Review строит графики, выводы делаешь сам. bbdoctor считает шум до и после фильтров, ищет резонансы и самовозбуждение контура, сравнивает моторы и батарею и выдаёт команды param set. Удобно использовать оба: графики во Flight Review, диагноз и команды в bbdoctor.

Почему в логе 200 Гц не видно вибрации моторов?

При записи 200 Гц видны частоты только до 100 Гц, а вибрации пропов и моторов обычно выше. По умолчанию PX4 пишет sensor_combined, а там гироскоп усреднён по окнам IMU_INTEG_RATE (200 Гц). Всё, что выше, либо срезано, либо заворачивается на ложную частоту. Нужен профиль с Raw FIFO.

Обновлено:

Другие гайды