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

Анализ лога ArduPilot: вибрации, клиппинг, фильтры и PID

ArduCopter плохо держит высоту, уплывает в Loiter, ругается на EKF, после автотюна мелко дрожит. Очень часто корень всего — вибрации: оценка положения портится, и автопилот борется с тем, чего нет. Порядок разбора всегда один: правильный лог → вибрации и клиппинг → спектр и notch → НЧ-фильтры → PID. Перескочишь через шаг — AUTOTUNE подстроится под шум, а ты будешь крутить PID там, где надо было балансировать пропы. Ниже — пороги, которые использует bbdoctor, и цифры из реальных логов ArduCopter.

Какой лог нужен и как включить быструю запись

Нужен бортовой DataFlash-лог .bin (Mission Planner → DataFlash Logs → Download или папка APM/LOGS на SD-карте); в телеметрии .tlog слишком мало данных. Что попадёт в лог, решает битовая маска LOG_BITMASK. Для вибраций и PID важны пять битов:

БитИмяВесЗачемВ заводской маске
0ATTITUDE_FAST1ATT и RATE с частотой цикла (400 Гц) — цель регулятора скорости для разбора PIDнет
7IMU128гироскоп и акселерометр, VIBE; без него лог не разобратьесть
10RCOUT1024команды моторам; без них тоже никакесть
12PID4096составляющие P, I, D, FF в PIDR/PIDP/PIDYс 4.6
19IMU_RAW524288сырой гироскоп (сообщения GYR) с частотой датчиканет

Заводская маска до 4.5 — 176126; в 4.6 в неё добавили бит PID, стало 180222. Во всех десяти логах ArduCopter из нашего набора (от 4.1 до 4.8-dev, от fmuv2 до Pixhawk 6X, плюс два SITL) IMU записан с частотой 25 Гц, а RATE, RCOU и VIBE — 10 Гц. Для VIBE и средних нагрузок моторов этого хватает, для спектра, фильтров и отклика PID — нет.

Считать маску в уме не нужно: в Mission Planner отметь в LOG_BITMASK галочки ATTITUDE_FAST и IMU_RAW. bbdoctor, если в логе нет сырого гироскопа, сам добавляет недостающие биты к твоей текущей маске. Для 176126:

LOG_BITMASK = 700415
INS_RAW_LOG_OPT = 9

Для 180222, как во всех наших логах 4.7, выйдет 704511. INS_RAW_LOG_OPT = 9 (основной гироскоп до и после фильтров) появился в 4.5; в логах 4.3.7 его нет, и bbdoctor там предлагает только LOG_BITMASK = 700415: в этих версиях сырой гироскоп включается одним битом 19.

Лог раздувается в десятки раз, а на медленных платах и картах появляются дыры (bbdoctor пишет «Разрывы в записи»); запись сырого IMU ArduPilot описывает для плат на H7, так что на F4 вроде fmuv2 из примера ниже жди разрывов. После тестовых полётов верни прежний LOG_BITMASK и INS_RAW_LOG_OPT = 0.

Тестовый полёт на 3–5 минут: висение, плавный подъём газа заметно выше висения и обратно, несколько коротких резких наклонов стиком по каждой оси на безопасной высоте. Флипы не нужны.

bbdoctor сразу отклоняет логи не-коптеров и логи без IMU или RCOU. Так отбился реальный лог большого квадрика: бит 7 в маске стоял, а сообщений IMU в файле не было — отдавай полный .bin, а не урезанный. Лог симулятора (параметры SIM_*) идёт без проверок железа. Про настройку записи для любой прошивки — в гайде по настройке лога.

VIBE и клиппинг: два разных сигнала

VIBE.VibeX, VibeY, VibeZ — стандартное отклонение показаний акселерометра в м/с², то есть средняя сила тряски. VIBE.Clip (в старых версиях Clip0–Clip2) — счётчик моментов, когда измерение упёрлось в предел диапазона датчика. Он копится с момента включения и между полётами не обнуляется. bbdoctor оценивает так:

Почему важны оба: реальный лог ArduCopter 4.7.0 на fmuv2, 4S, семь полётов подряд, 414 с в воздухе.

Графики VIBE X, Y и Z за семь полётов ArduCopter 4.7: почти всё время ниже линии 30 м/с², а счётчик Clip ступенями растёт в каждом полёте до 424
ArduCopter 4.7.0, 4S, семь полётов в одном логе (серым — на земле, VIBE сглажен за 0,5 с). Чёрная линия — прирост Clip в полёте: 424 срабатывания, из них 176 в последнем полёте.

По VIBE аппарат проходит: 29 при пороге 30. А клиппинг — 424 раза, у bbdoctor это «критично», и по полётам видно, что это не случайность:

ПолётВремя в воздухеVIBE p95 X / Y / ZПрирост Clip
169 с16 / 19 / 2422
269 с16 / 20 / 2534
379 с20 / 23 / 2647
473 с20 / 22 / 30106
531 с22 / 22 / 2835
615 с16 / 20 / 244
779 с22 / 20 / 32176

Октокоптер на CubeOrangePlus (4.5.7): счётчик за лог вырос на 64, но в полёте только на 19, и bbdoctor выдал предупреждение по 19. Здоровый Tarot X4 на 4.5.5 (рисунок ниже): X 3, Y 3, Z 7 м/с², Clip = 0.

Что видноВероятная причинаЧто делать
Все оси высокие, растут с газомдисбаланс пропов или колоколовбалансировка, замена пропов, проверка вала и подшипников
Z заметно выше X и Yгибкие лучи, крепление моторов, слишком жёсткая или мягкая развязка полётникапротянуть моторы и лучи, проверить проставки полётника
Одна ось вдвое выше другойчто-то болтается в этом направлении: мачта GPS, шасси, подвесзакрепить, проверить люфт рукой
VIBE в норме, Clip растёт в каждом полётеудары: аккумулятор, провода, задевающий пропстяжки, демпфирующая подложка под АКБ, провода подальше от полётника

Пока VIBE и клиппинг не в норме, не трогай фильтры и PID. Как найти конкретный плохой мотор — в гайде про вибрации моторов. Сообщение «Vibration compensation ON» значит, что сработал вибрационный failsafe (FS_VIBE_ENABLE, включён по умолчанию) и удержание высоты уже перешло на более устойчивую к тряске оценку.

Спектр гироскопа и гармонический notch

С сырым гироскопом (сообщения GYR) bbdoctor строит спектр до и после фильтров и ищет пики, которые не двигаются с газом, — резонансы рамы. Он советует протянуть раму, а как временную меру — второй notch INS_HNTC2_* на фиксированной частоте, только если частота однозначна; если пик может быть зеркальным отражением, он перечисляет возможные частоты и просит короткий лог с сырым гироскопом. Для резонанса 140 Гц:

INS_HNTC2_ENABLE = 1
INS_HNTC2_MODE = 0
INS_HNTC2_FREQ = 140
INS_HNTC2_BW = 70
INS_HNTC2_ATT = 40

Второй источник спектра — батч-семплер (INS_LOG_BAT_MASK, INS_LOG_BAT_OPT, бит IMU_RAW при этом выключен): пакеты по 1024 отсчёта (ISBH/ISBD), лог почти не растёт. bbdoctor их пока не читает — смотри в веб-инструменте Filter Review от ArduPilot или в FFT Mission Planner. Вот что они показали на Tarot X4.

Слева низкие ровные графики VIBE Tarot X4 около 3–7 м/с²; справа спектр гироскопа до и после фильтров с пиками 34, 67, 134 и 202 Гц, окном поиска FFT 25–62 Гц и notch на 35 и 70 Гц
Tarot X4, ArduCopter 4.5.5, 6S. A: VIBE 3/3/7 м/с², Clip = 0. B: спектр гироскопа примерно по 50 пакетам батч-семплера (2025 Гц), серым — до фильтров, синим — после. Оранжевым — окно поиска FFT, пунктир — FTN1.PkAvg, что сообщал FFT, точечные линии — где на самом деле стоял notch.

Notch здесь в режиме FFT (INS_HNTCH_MODE = 4). Самая сильная линия — 67 Гц, за ней 134 и 202. 34 Гц похоже на частоту вращения (около 2000 об/мин), а 67 — её вторая гармоника, у двухлопастного пропа это частота прохода лопастей. Но окно поиска FFT заканчивается на 62 Гц, и весь полёт FFT сообщал 25 Гц — ровно FFT_MINHZ (выученная FFT_FREQ_HOVER тоже 25,0). Моторную линию он так и не нашёл.

В режиме FFT notch не опускается ниже INS_HNTCH_FREQ, здесь 35 Гц, — там он и стоял, а INS_HNTCH_HMNCS = 3 добавил второй notch на 70 Гц. По счастливой случайности это как раз линии 34 и 67 Гц: по сравнению с одним НЧ-фильтром 20 Гц спектр после фильтров ниже примерно на 10 дБ на 34 Гц и на 17 дБ на 67 Гц, а на 134 и 202 Гц добавки нет. Notch работает, но как фиксированный.

И здесь важная мысль: не всё, что можно поправить, нужно править сразу. После фильтров линии 67, 134 и 202 Гц ниже на 35–43 дБ, VIBE 3/3/7, клиппинга нет. Но поставишь аккумулятор тяжелее или другие пропы — линии сместятся, а FFT за ними не пойдёт. Перед следующим AUTOTUNE я бы перевёл notch на газ:

INS_HNTCH_ENABLE = 1
INS_HNTCH_MODE = 1
INS_HNTCH_REF = 0.2
INS_HNTCH_FREQ = 67
INS_HNTCH_BW = 33
INS_HNTCH_HMNCS = 7

REF — газ висения (MOT_THST_HOVER = 0,20), FREQ — частота линии на висении, BW — половина частоты, HMNCS = 7 — гармоники 1–3: 67, 134 и 201 Гц. При заводском INS_HNTCH_FM_RAT = 1 notch не опускается ниже FREQ. Notch на 34 Гц я убираю сознательно: в гироскопе эта линия едва выше шума, а notch так низко, рядом с частотами, на которых работает регулятор большого коптера, съедает фазу. Хочешь оставить — FREQ 34, BW 17, HMNCS 43 (гармоники 1, 2, 4 и 6: 34, 67, 134, 202 Гц). Или оставь FFT и расширь окно FFT_MINHZ/FFT_MAXHZ, чтобы 67 Гц попала внутрь.

Как выбрать INS_HNTCH_MODE (0 — фиксированный, 1 — по газу, 2 — датчик RPM, 3 — ESC-телеметрия, 4 — FFT): есть телеметрия оборотов — режим 3. Нет телеметрии, но есть F7/H7 — FFT, только проверь по логу, что FTN1.PkAvg двигается с газом, а не стоит на FFT_MINHZ. Слабый полётник — по газу. В режимах ESC, RPM и FFT FREQ — нижняя граница, а REF = 1; REF = 0 намертво ставит notch на FREQ.

НЧ-фильтры: INS_GYRO_FILTER и ATC_RAT_*_FLTD

INS_GYRO_FILTER — НЧ-фильтр гироскопа, по умолчанию 20 Гц (столько и в логе 4.7, и у Tarot; в логе 4.3.7 — 40). ATC_RAT_RLL_FLTD и ATC_RAT_PIT_FLTD — фильтр D-составляющей (20 в логе 4.7, 10 у Tarot), FLTT — фильтр цели, FLTE — фильтр ошибки (по yaw обычно 2–2,5 Гц). Стартовые значения под размер пропов считает мастер Initial Tune Parameters в Mission Planner: чем меньше пропы, тем выше частота фильтра.

Ловушка для анализа: лог 25 Гц показывает движение только до 12,5 Гц, всё быстрее заворачивается в ложную низкую частоту. Поэтому bbdoctor на таком логе фильтры и PID не проверяет и прямо об этом пишет. Подробнее — в гайде про фильтры.

PID: что видно из лога и когда нужен AUTOTUNE

Регулятор скорости — ATC_RAT_RLL_P, _I, _D, _FF, то же для PIT и YAW. bbdoctor сравнивает цель RATE.RDes (и PDes, YDes) с гироскопом: перелёт, отставание, качание после резкого движения. RDes — цель уже после сглаживания входа: ATC_INPUT_TC делает её мягче, но не меняет того, насколько точно гироскоп за ней идёт, так что это оценка самого контура скорости. Нужна запись от 200 Гц. Иначе bbdoctor не гадает, а пишет «PID по этому логу не оценить: гироскоп записан с частотой 25 Гц» и даёт команды из первого раздела.

Для ArduCopter обычно надёжнее встроенный AUTOTUNE, но только после вибраций и notch, иначе он подстроится под шум:

  1. VIBE ниже 30, Clip не растёт, notch настроен.
  2. AUTOTUNE на переключатель; оси — в AUTOTUNE_AXES (1 — roll, 2 — pitch, 4 — yaw; 7 — все три), агрессивность — AUTOTUNE_AGGR (в обоих логах выше 0,075).
  3. AltHold, Loiter или PosHold в спокойную погоду; на ось уходит несколько минут — нужен запас батареи.
  4. Чтобы сохранить результат, сажай и дизарми, не выключая переключатель.

Что ещё bbdoctor советует по ArduPilot, когда лог быстрый:

Две вещи bbdoctor не проверяет. Компенсация напряжения: в логе 4.7 MOT_BAT_VOLT_MAX = 0, и MOTB.BatVolt весь полёт равен 1,00 — компенсация выключена, к концу пакета контур слабеет. Для 4S:

MOT_BAT_VOLT_MAX = 16.8
MOT_BAT_VOLT_MIN = 13.2

Это 4,2 и 3,3 В на банку; ставь до AUTOTUNE — она меняет эффективное усиление. И PIDR.Dmod: если он часто падает ниже 1, ограничитель ATC_RAT_*_SMAX гасит раскачку — усиления на грани. В логе 4.7 Dmod весь полёт ровно 1,00 (пишется 10 раз в секунду, так что очень короткие провалы могли проскочить).

Моторы при записи 10 Гц: нагрузки видно, шум — нет

RCOU в стандартном логе пишется с частотой 10 Гц, и bbdoctor так и пишет: «Команды моторам записаны с частотой 10 Гц — видны средние нагрузки, но не шум на моторах». Что из такого лога можно достать:

Не путай порядок моторов: в ArduCopter Quad X M1 — передний правый, M2 — задний левый, M3 — передний левый, M4 — задний правый. В Betaflight нумерация другая.

Вибрацию конкретного мотора по 10 Гц не найти, нужны обороты: bidirectional DShot (SERVO_BLH_BDMASK, DShot в MOT_PWM_TYPE, правильное SERVO_BLH_POLES) или ESC с телеметрией по проводу. У Tarot полюса выставлены (28), но моторы на обычном PWM, поэтому оборотов в логе нет. С оборотами bbdoctor сравнит моторы, а notch можно перевести в режим 3.

Failsafe и батарея

Если разбираешь падение, первым делом проверь, что failsafe вообще был настроен: bbdoctor при подозрении на потерю связи или батарею напоминает про эти параметры. В логе 4.7 (4S):

FS_THR_ENABLE = 1
FS_THR_VALUE = 950
BATT_LOW_VOLT = 14.4
BATT_CRT_VOLT = 14.0
BATT_FS_LOW_ACT = 2
BATT_FS_CRT_ACT = 1

По батарее bbdoctor считает старт, минимум под нагрузкой и внутреннее сопротивление. В логе 4.7: старт 4,11 В на банку, минимум под нагрузкой 3,76 (держалось 0,5 с), в конце 3,91, пиковый ток 13 А, около 1010 мА·ч и около 10 мОм на банку (оценка: напряжение и ток меряются раздельно).

Имена параметров меняются между версиями

ЧтоСтарое имяНовое имя
Макс. ускорение по roll/pitch/yawATC_ACCEL_R_MAX и т. д., в cdeg/s²ATC_ACC_R_MAX и т. д., в deg/s² (4.7)
Максимальный угол наклонаANGLE_MAX, в сантиградусахATC_ANGLE_MAX, в градусах (4.7)
Скорость вращения в ACROACRO_RP_P, коэффициент: ×45 = °/с (до 4.1)ACRO_RP_RATE, в °/с (4.2+)

ANGLE_MAX = 3000 в логе 4.5.5 и ATC_ANGLE_MAX = 30 в логе 4.7 — один и тот же наклон 30°. При обновлении прошивка пересчитывает значения сама; ловушка — переносить числа руками из старого лога или с форума. Впишешь 48000 из ATC_ACCEL_R_MAX у Tarot в ATC_ACC_R_MAX вместо 480 — попросишь ускорение в сто раз больше.

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

Загрузи .bin в bbdoctor — это бесплатно. Он делает проверки из этого гайда (запись, VIBE, клиппинг, нагрузки моторов, батарея, а на быстром логе — спектр и PID), говорит, каких данных не хватает, и выдаёт параметры в формате ИМЯ = значение. Батч-семплер, FFT, компенсацию напряжения и Dmod смотри сам. Пороги подбирались на FPV-квадриках, поэтому на больших аппаратах сравнивай с прошлыми логами того же аппарата. Посмотри пример отчёта, а для PX4 есть гайд про ULog.

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

Какие значения VIBE нормальные в ArduPilot?

По документации ArduPilot ниже 30 м/с² — норма, 30–60 — возможны проблемы с удержанием, выше 60 — почти всегда плохо держит высоту и позицию. Но смотри и на Clip: в идеале счётчик клиппинга не растёт вообще, а ровный рост через весь полёт — серьёзная проблема, даже если VIBE в норме.

Как включить запись сырого гироскопа в ArduPilot?

На 4.5 и новее: INS_RAW_LOG_OPT = 9 (основной гироскоп до и после фильтров) и бит 19 IMU_RAW в LOG_BITMASK; на 4.3–4.4 только бит 19. Для разбора PID добавь бит 0 ATTITUDE_FAST. С заводской маской 176126 (до 4.5) получится 700415, с 180222 (4.6 и новее) — 704511. Лог сильно растёт — включай на тестовые полёты.

Можно ли анализировать .tlog вместо .bin?

Нет. Телеметрия .tlog пишется с низкой частотой и без нужных полей. Нужен бортовой DataFlash-лог .bin с SD-карты или скачанный через Mission Planner (DataFlash Logs → Download).

Почему bbdoctor пишет, что PID по логу не оценить?

Потому что гироскоп в логе записан реже 200 Гц. В стандартном логе ArduCopter IMU пишется с частотой 25 Гц, а RATE — 10 Гц: этого хватает для вибраций и нагрузок, но не для отклика регулятора. Включи биты 0 и 19 в LOG_BITMASK на тестовый полёт или настрой PID через AUTOTUNE.

Обновлено:

Другие гайды