Skip to content

TuneWizard: этап 2 — спектр до фильтров и гармонический notch - #1

Merged
deathnemo merged 30 commits into
mainfrom
tune-wizard-stage2
Oct 24, 2026
Merged

deathnemo merged 30 commits into
mainfrom
tune-wizard-stage2

Conversation

@deathnemo

Copy link
Copy Markdown
Owner

Что сделано

  • Шаг 1 «Спектр до фильтров»: настройки спектра как в FilterReview, средний спектр, спектрограмма, таблица пиков с происхождением (порядковый спектр; запасной метод — медиана частоты моторов), вердикт, кнопка «Открыть в FilterReview».
  • Шаг 2 «Гармонический notch»: варианты настроек — как в логе, автоподбор (PR FilterReview: add auto fit for the first notch ArduPilot/WebTools#363), автоподбор с гармониками из лога, настройки лога с ослаблением из автоподбора, второй статический notch с шириной по пику. Для каждого варианта считаются шум после фильтров и задержка на 10 и 30 Гц. Рекомендуется вариант не хуже лога: каждый пик хуже не более чем на 3 дБ, задержка на 30 Гц больше не более чем на 0.5 мс. На шаге есть форма параметров с описаниями ArduPilot, бодэ, спектрограмма, сохранение и загрузка .param, кнопка «Принять».
  • core/: математика FilterReview перенесена минимальным диффом (gyro, filters, tracking, spectrum); новые модули autofit, metrics, candidates, params. Реестр графиков plots.js. Тема одна — тёмная «Графит».
  • Исправлены 8 дефектов исходного FilterReview (список — в design-документе, раздел 2). Главный: частота дискретизации batch-лога теперь берётся по всем пакетам, а не по первому; на тестовом логе оси частот сдвигались в 1.000334 раза.

Результат на тестовом логе

ArduCopter 4.6.3, версия фильтра 2. Рекомендован вариант «Как в логе + второй notch на 153 Гц»: INS_HNTC2_FREQ 153, INS_HNTC2_BW 22, INS_HNTC2_ATT 30, INS_HNTC2_MODE 0. Пик 153 Гц ниже на 23.8 дБ, полоса 20–400 Гц тише на 0.26 дБ, задержка на 30 Гц больше на 0.15 мс.

Проверки

  • npm run lint — 0 ошибок
  • npm test — 242 из 242
  • npm run test:tunewizard (Chrome) — шаги 0–2 пройдены
  • npm run test:tunewizard-compare — полное совпадение с FilterReview, в который подставлены те же исправления (отклонение 0)

Документы: docs/plans/2026-10-24-tune-wizard-stage2-design.md, docs/plans/2026-10-24-tune-wizard-stage2.md.

🤖 Generated with Claude Code

deathnemo and others added 30 commits October 24, 2026 06:35
… notch

Перенос математики FilterReview в ядро «минимальным диффом», реестр
графиков plots.js, полный набор органов управления спектром, автоподбор
первого notch по PR ArduPilot#363, регрессия против FilterReview в Chrome,
исправление дефектов upstream отдельной задачей.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
register_plot/render_plot/restyle_plots применяют токены темы ко всем
графикам: фоны, шрифт, оси, ползунок, легенда, colorbar; цвета линий —
хуком on_theme. График полёта переведён на реестр.

Шрифт осей, легенды и colorbar задаётся без цвета: Plotly наследует его
из layout.font, который обновляется при смене темы. Иначе цвет первой
темы оставался бы в подписях осей навсегда, а свой цвет оси нельзя было
бы отличить от цвета темы. Подпись colorbar при смене темы сохраняет
текст.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…и colorbar сливаются, тесты темы

Скрытый график помечается dirty и дорисовывается при показе шага
(show_plots); шрифты легенды/colorbar дополняются темой, а не
заменяются; строковые заголовки; контракт реестра в комментариях;
Node-тесты смены темы со стабами document/Plotly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Загрузчики batch/raw, run_batch_fft, подготовка Z1/Z2 и сетки бодэ,
флаги pre/post и первичный гироскоп перенесены построчно; DOM и alert
заменены аргументами и предупреждениями. Известные дефекты upstream
сохранены и помечены для задачи 8. Тесты ядра грузят скрипты как страница.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Plotly пересчитывает размер и у скрытых графиков (ширина 100 px), поэтому
show_plots вызывает Plots.resize для графиков без изменений и рендерит
только dirty. Защита от отсутствующей секции; план этапа 2 уточнён.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…акета) в задачу 8

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… о смене параметра

Покрыты raw-загрузчик с разрывом, post-only batch, выбор batch/raw при
обоих источниках, первичный гироскоп без данных и второй путь ошибки.
Смена INS_LOG_BAT_OPT/INS_RAW_LOG_OPT в полёте даёт предупреждение (upstream
брал первое значение). decode_devid — глобал страницы. Дефект 6 — в дизайне.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Восемь классов трекинга и фильтры (biquad, notch, multi-notch, harmonic
notch), передаточная функция, оценка «после», бодэ и статистика линий
notch перенесены построчно; версия фильтра, параметры и диапазон
передаются через env/аргументы, alert заменён предупреждениями.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ate, предупреждение у выключенного notch)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…есты опций notch

bode_mean возвращает null без бодэ/H (как пропуск в upstream); load_filters
собирает предупреждения трекинга; тесты на triple/quintuple/бит 32, многопиковую
статистику линий, оценку вне notch и агрегацию предупреждений.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ие упоминания env)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…а, линии notch

Перенос из FilterReview: среднее по окнам интервала с поправкой окна,
сворачивание алиасинга к частоте контура, матрица спектрограммы с
разрывами, линии гармоник notch и логированных notch; шкалы с русскими
подписями.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…рекинга

alias строится от того же FFT; контракт тепловой карты (transpose);
PSD-расхождение спектрограммы названо точно; alias_obj без окон → null;
тесты: многопиковые линии с клампом и логированные notch, пустота на
100 Гц без сворачивания, положение маркеров разрыва.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
find_peaks: локальные максимумы не меньше 6 дБ над медианой шума в окне
±15 Гц (без ±2 Гц вокруг пика), выше 5 Гц, по убыванию превышения;
attribute_peaks: «моторы, гармоника N» в пределах ±10 % от N·f_мотора
(N ≤ 8), иначе «рама»; motor_fundamental: медиана среднего ESC в
диапазоне, иначе медиана цели газа (при INS_HNTCH_REF > 0), иначе null.
Тесты в tests/tunewizard-steps.test.cjs (7).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…я против FilterReview

steps/step1.js: панель «Настройки спектра» (тип лога, окон на пакет, версия
фильтра — по «Пересчитать»; шкала амплитуды, Гц/RPM, лог-ось, алиасинг —
сразу), средний спектр Spectrum1 (3 гироскопа × до/после/оценка × X/Y/Z,
видимость по умолчанию как в FilterReview, цвета через on_theme),
спектрограмма Spectrogram1 (Viridis, линии логированных notch), таблица
пиков и вердикт по core/metrics.js, «Открыть в FilterReview» (hook_load).
Фильтры — из параметров лога с умолчаниями формы FilterReview; гармоники
логированных notch из параметров (FR 2586); окно batch пишется в поле шага 0.

wizard.js: state.spectrum/gyro/tracking/logged/filters/env/log_buffer/file,
доступность шагов по проверкам gyro_log и pid_log, хук on_show_step,
step1_init/step1_reset.

tests/tunewizard-compare.cjs (npm run test:tunewizard-compare): тот же лог
в FilterReview и в мастере — средний спектр сенсора 0 и спектрограмма
совпадают поэлементно (допуск 1e-6). tests/tunewizard-browser.cjs: шаг 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
)

Порядковый спектр относительно частоты ESC или газа, проверка кратности
пиков, выбор гармоник и ослабления по превышению над шумом, правила PR
без изменений; без DOM: результат и ошибки возвращаются, значения
INS_HNTCH_* собирает auto_fit_values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…очнение моторной частоты

find_axis_peaks: пики ищутся на X/Y/Z отдельно и сливаются ближе
max(2 Гц, 2 бина), у пика — список осей; окрестность пика без шума —
не уже главного лепестка окна Ханна (2 бина); окно шума ±50 Гц (шире
горбов гармоник, [наше]). Атрибуция: |freq/f − N| ≤ 0.1 порядка, N ≤ 8;
refine_fundamental уточняет медиану ESC/газа по пику первой гармоники.
Атрибуция по медиане — запасной способ до порядкового спектра PR ArduPilot#363
(задача 7). Тесты: слияние осей, два близких пика, −Infinity, ESC с нулевыми
оборотами, FREQ = 0, уточнение основной (12 в tunewizard-steps.test.cjs).
Дизайн, раздел 5 — новое правило атрибуции.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…дикт, линии notch, тесты

Предупреждения собираются заново из загрузки, FFT и фильтров (не теряются
при повторном показе и пересчёте одной версии фильтра); версия фильтра без
VER.FV — 1, неподдерживаемая — 4 с предупреждением, как в FilterReview;
вердикт шага 1 — ok (warn только при предупреждениях); таблица пиков со
столбцом «Оси»; линии логированных notch — в легенде, толщина 1, выбор
сохраняется между перерисовками; подсказка допустимых чисел окон на пакет;
поле окна FFT шага 0 выключается при загрузке, если окно не действует;
step1_ready() для шага 2; postMessage на location.origin; state.log_buffer
убран; поле выбора файла очищается — тот же лог загружается повторно.

compare: версия фильтра как в FilterReview, вторая конфигурация PSD +
свёрнутый алиасинг, проверка, что сравнение не пустое. browser: «свернуть»,
RPM, лог-ось, FFT не пересчитывается при смене шкал, повторная загрузка.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Автоподбор PR ArduPilot#363 на логе пользователя хуже текущих настроек (убирает
третью гармонику: +14/+21 дБ на 153/235 Гц, +5 дБ по полосе 20–400 Гц).
Шаг 2 оценивает несколько вариантов и рекомендует лучший, не хуже
летавшего; атрибуция пиков — по порядковому спектру. Задача 7 разбита
на 7a (ядро) и 7b (интерфейс); дефект 8 (NaN в линиях notch) — в 7a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…у спектру

core/candidates.js: варианты (лог, автоподбор, их сочетания, второй notch),
оценка шума после фильтров на главных пиках и в полосе 20–400 Гц, задержка
на 10/30 Гц, выбор лучшего не хуже лога. Атрибуция пиков по порядковому
спектру PR ArduPilot#363 с медианой как запасным методом. Исправлен дефект upstream 8:
NaN в трекинге убирал среднюю линию notch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ch по пику, строгий отбор

Окно атрибуции по порядку расширено допуском (ровное висение больше не
даёт «раму» на моторных гармониках); BW второго notch — удвоенная
ширина пика по −3 дБ в пределах 10 Гц…0.5·F (решение пользователя);
отбор вариантов отказывает при NaN и недостающих пиках и учитывает пики
оценки «после» для лога; диспетчер attribute_peaks_auto; band_f2_dB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…еполными

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…по порядковому спектру

core/params.js (без DOM): param_file_text — текст .param через
get_param_download_text (Libraries/Param_Helpers.js, подключён на странице),
parse_param_file — разбор форматов Mission Planner и MAVProxy с комментариями;
тесты в tests/tunewizard-params.test.cjs.

Шаг 1: пики и их происхождение — step1_peaks() через attribute_peaks_auto
(порядковый спектр ESC, без него — медиана ESC/газа), столбец «Метод», в
подписи — метод и p5/p50/p95 частоты ESC; step1_prepare() — расчёт без
перерисовки для шага 2. Заголовок таблицы пиков и подсказка окон на пакет —
в разметке index.html.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ики, .param

steps/step2.js: при первом показе — автоподбор PR ArduPilot#363, варианты notch_candidates
(+ второй notch), оценка evaluate_candidate и выбор rank_candidates; таблица
вариантов с уровнями на пиках шага 1 и пиках «после», полосами 20–400 Гц
(и с весом f²) и задержкой 10/30 Гц с разницей к логу, пометкой
«рекомендуется» и причинами отказа; вердикт «менять не нужно» / рекомендация /
неполная оценка; таблица гармоник порядкового спектра ESC.
Форма INS_GYRO_FILTER, SCHED_LOOP_RATE, INS_HNTCH_*, INS_HNTC2_* по метаданным
FilterReview (load_param_inputs): «в логе: …», .changed, выключение полей по
ENABLE, ESCMSK с версии фильтра 4, маска HMNCS 8/32 бит. «Применить вариант»,
«Подобрать заново» (варианты помечаются устаревшими при смене интервала),
«Пересчитать фильтры» (строка «Текущий»), «Сохранить/Загрузить .param»,
«Принять» → state.steps[2] и шаг 3. Графики через реестр: спектр с линиями
notch (shapes из notch_line_stats), бодэ амплитуда/фаза со свёрткой, спектрограмма
с линиями notch формы. Передаточная функция значений формы считается отдельно
(filter_transfer), FFT.H шага 1 не меняется.

Тесты: браузерный прогон шага 2; сверка с FilterReview — бодэ (обе шкалы фазы)
и оценка «после» с параметрами лога.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
По обновлённым правилам проектов пользователя: токены одной тёмной
палитры на :root с color-scheme:dark, без светлой темы, переключателя,
prefers-color-scheme и data-theme; печать остаётся на белом фоне.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oat32, маски, тесты

- Вердикт: неудача автоподбора — приставкой к обычному тексту, если есть
  другие варианты (второй notch); «Принято» показывается первым, принятое
  сравнивается с логом (rank_candidates), «Принято, но хуже лога» — warn;
  «Принять» под оверлеем с перехватом ошибок; в рекомендации — самое
  большое изменение на пике и «Он выбран — нажмите «Применить вариант»».
- Форма: значения как float32 (0.7 из .param = 0.699999988 из лога),
  числа показываются через param_to_string; пустое поле маски — значение
  лога; .changed только у числовых полей и списков; «в логе нет (взято …)».
- .param: 8-битная HMNCS со старшим битом — со знаком, как FilterReview;
  подсказка про INS_HNTC2_ENABLE = 1 на аппарате.
- Таблица: заголовок «Шум после фильтров на пиках, дБ», «пик «после» лога»,
  маски словами, столбец f² без цвета, причины отказа без повторов и с
  «не оценён», строка «Текущий» вне рекомендации; «взята» — только у
  автоподбора по ESC.
- Переключатели графиков — только при готовом расчёте; applied_id убран;
  пороги во вступлении — из candidate_rules; допуск окна атрибуции в
  подписи шага 1; план: задержка на 10/30 Гц из filters_lag_ms.
- Браузерный тест: шаг 1 не меняется шагом 2 (FFT.H и оценка «после»),
  шаг 2 сразу с шага 0, ветка «автоподбор не удался + второй notch»,
  принятие варианта хуже лога.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…овых масок

core/params.js: is_bitmask_param, hmncs_bits (правило update_hidden_params),
mask_unsigned / mask_signed (как parameter_get_value и запись .param в
FilterReview). values_from_log: 8-битная HMNCS из лога без знака (−128 →
128), иначе load_filters включал гармоники 8–16, а неизменённое поле
считалось изменённым. Шаг 2: битовые маски не округляются до float32.
Тесты: преобразования масок (unit) и int8-маска в values_from_log (браузер).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1. run_batch_fft: проверка длины пакета до размера окна, частота по пакету (FR 284, 289)
2. load_from_raw_log: конец среза для всех экземпляров (FR 2295–2297)
3. load_from_batch: неполная последовательность не обрывает загрузку (FR 2109, 2130)
4. ThrottleTarget без RATE/CTUN: «нет данных газа» вместо «неподдерживаемый режим» (tracking/Throttle.js:14)
5. load_from_batch: последний пакет у конца лога не теряется (FR 2118–2122)
6. FFTTarget.interpolate: пропуск отсутствующих экземпляров FTN2 (tracking/FFT.js)
7. HarmonicNotchFilter: выключенный notch без предупреждений (FR 174–186)
(8 — NaN в линиях notch — исправлен в задаче 7a.)
Тест сравнения с FilterReview проверяет ожидаемые расхождения точно.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Структура ядра и шагов 1–2, как шаг 2 выбирает настройки notch,
отличия от FilterReview (исправленные дефекты), все проверки, включая
сравнение с FilterReview с теми же исправлениями.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…га на границе пакета

Сетка бодэ при ρ < 1 короче — сравнивается общее начало. Сдвиг времени и
«без изменений» — только для batch-логов, у raw — отчёт. Средние частоты
мастера сверяются с FilterReview с исправлениями (дефекты 1 и 5 вместе не
роняют отчёт). Оси времени — абсолютный допуск 1e-9 с. Другой интервал
эталона печатается и задаётся обоим. Правила проверены без браузера
(tunewizard-compare-rules.test.cjs).

load_from_batch: заголовок без сообщений ISBD посреди лога пропускается,
а не обрывает разбор (часть дефекта 3, FR 2087–2095); эталон в тесте
сравнения исправлен так же.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant