Перейти к содержанию

Рецепт 14 — AA-INDI на нелинейной F-16

AA-INDI (Active-Adaptive Incremental Nonlinear Dynamic Inversion) сочетает классический INDI-закон с VFF-RLS идентификацией матрицы эффективности управления G и лёгким сенсорным фильтром-суррогатом. Самый сильный fault-tolerance baseline в библиотеке: переменный фактор забывания сжимается под большими невязками, поэтому идентификатор догоняет ополовиненный руль за несколько сотен мс.

Документация. AA-INDI · Полный ноутбук. example_aaindi_nonlinear_f16.ipynb · Связано. Рецепт 09 — Отказоустойчивость.

Когда использовать AA-INDI

  • Отказоустойчивость к приводам — главное требование (повреждённые поверхности, обледенение, заклинивание).
  • Нужен регулятор с инверсией динамики (INDI) без записи полной нелинейной модели — достаточно warm-start G.
  • Вы предпочитаете не-НС онлайн-регулятор, который легко аудировать.
Свойство AA-INDI vs iADP
Закон управления Псевдо-инверсия , классический INDI
Триггер адаптации Переменный фактор забывания λ (сжимается при отказе)
Внешний контур PI по ошибке слежения (опционально)
Число гиперпараметров ~10 ручек

Шаг 1 — Минимальная конфигурация

import numpy as np
from tensoraerospace.agent.aa_indi import AAINDIAgent, AAINDIConfig

cfg = AAINDIConfig(
    dt=0.01,
    # эталонная модель — формирует команду до INDI-инверсии
    ref_wn=2.5,
    ref_zeta=0.9,
    # ограничения привода (жёсткая страховка)
    u_magnitude_limit=15.0,
    u_rate_limit=60.0,
    # VFF-RLS: фактор забывания сжимается при больших невязках
    vff_forgetting_min=0.97,
    vff_forgetting_max=0.9999,
    vff_eps_sensitivity=0.1,
    vff_cov_init=1.0,
    # сенсорный фильтр (низкочастотный дифференциатор + оценщик смещения)
    sensor_cutoff_hz=15.0,
    bias_forgetting=0.995,
    enable_bias_correction=False,
    # warm-start G; знак и порядок важны
    G_init=np.array([[-0.5]]),
    # опциональный внешний PI по ошибке слежения
    ref_error_kp=0.6,
    ref_error_ki=0.0,
    seed=0,
)

Ручки ref_error_kp / ref_error_ki добавляют внешний PI-контур, закрывающий установившуюся ошибку — полезно для rate-команд с ненулевой установившейся.

Шаг 2 — Цикл

Идентичен остальным онлайн-адаптивным агентам:

agent = AAINDIAgent(n_state=1, n_control=1, config=cfg)
env.reset()

for k in range(n_steps):
    obs = env.get_state()
    u = agent.predict(obs[controlled_channels], ref[:, k], k)
    obs, *_ = env.step(u)
    agent.learn(obs[controlled_channels], ref[:, k], k)

predict() применяет reference-фильтр + INDI-инверсию + внешний PI. learn() делает VFF-RLS шаг по (Δu, Δẏ) и шаг оценщика смещения.

Шаг 3 — Ожидаемое поведение при 50 % отказе руля

Классическое AA-INDI-демо: слежение за угловой скоростью тангажа с потерей 50 % эффективности руля в t = 10 с.

AA-INDI с отказом руля

Характерные признаки:

  • ω_z продолжает отслеживать команду через отказ; небольшой всплеск, затем возврат на команду.
  • λ (фактор забывания) сжимается к vff_forgetting_min сразу после отказа — видно на диагностической трассе в полном ноутбуке.
  • G̃ переидентифицируется к ополовиненному значению за несколько сотен мс.

Источник: example_aaindi_nonlinear_f16.ipynb. Рецепт 09 гоняет AA-INDI в лоб против iADP на том же профиле.

Шаг 4 — Save / load / публикация в HuggingFace

run_dir = agent.save('./checkpoints')
restored = AAINDIAgent.from_pretrained(run_dir)
agent.publish_to_hub('me/my-aaindi', folder_path=run_dir, access_token='hf_…')

Mid-episode сохранения восстанавливаются бит-в-бит — см. Рецепт 08.

Подводные камни

  • Неверный знак G_init. INDI инвертирует G, поэтому смена знака гонит привод не туда — объект расходится. Проверьте, что PE-возбуждение даёт ожидаемый знак.
  • Устойчивая ошибка на rate-командах. Поднимите ref_error_kp (0.3 → 0.8 — типовой диапазон); добавьте немного ref_error_ki для интегрального действия.
  • Коррекция смещения дестабилизирует на шумных средах. enable_bias_correction=True по умолчанию выключен для F-16-сима; включайте только если у сенсора измеримое DC-смещение.

Куда дальше