Модуль «воздух у старта» (air-start)

Ветка feature/air-start, копия ~/deltaplan-air-start (от main 938d1ea). Журнал — docs/archive/plan/air-start-progress.md. Фон: docs/plan/air_model.md, docs/contracts/air-model.md, docs/archive/plan/air-model-progress.md (AM-11/AM-12 — не здесь).

Цель

Жалоба пилота на 1.0.0: при 6 м/с на старте «сдувает», нос гуляет, крыло само отрывается и падает. Две находки других модулей — обе в поле воздуха GPU (AirRuntime/AirCase):

  1. Ветер меню задан не у старта (WPC-2, feature/wing-physics-check 576550e): AirRuntime.conditions_of отдаёт ветер меню как u10 «на 10 м у старта», а AirCase.prepare (air_case.gd:236–238, u_a = u10·max_profile) ставит его притоком на краю области 38,4 км. Над стартом на 10 м при 6 м/с — 6,2…12,6 м/с (медиана 1,40 × меню), на 100 м — 1,6–2,5 × меню; аналитика у старта на 10 м = меню (1,01–1,05).
  2. Турбулентность и разворот ветра у земли (CF-1, control-fix/cf1): на 1,5 м над стартом в 1.0.0 σw 0,4–1,05 м/с, направление ±90–180°, |ΔU| до 4 м/с за 0,5 с; в 551e79b σw 0,02, ±30°. Регрессия между 551e79b и 041d8ed (AM-04/AM-09/А1.2/Б2), 0d1ecf2 ни при чём. Бисект ведёт CF-1, результат передадут сюда.

Решения пользователя (не обсуждаются)

  • 01.10 — проблема 1: подстроить поле под старт: после первого расчёта поля умножить u10 притока на U_меню / U_поле(10 м над стартом) и посчитать второй раз (≈ +5 с к загрузке — приемлемо); класс устойчивости и z_sat — по ветру меню; калибровку решателя (Askervein, Б1/AM-09) не трогать.
  • 01.10 (поправка главной сессии) — сплющивание профиля аналитики над гребнем по Taylor & Lee 1984 пользователь не выбирал: аналитику (wind_model.gd, atmosphere.gd), Б1/AM-09 и test_ridge_starts не трогать. Если после исправления поля расхождение аналитики и поля у старта останется заметным — шлюз с числами.
  • Проблема 2 — исправить у причины; турбулентность у земли — физичная (масштабы и σ по теории приземного слоя для данного ветра и устойчивости, без разворотов на 180° за доли секунды при 6 м/с).

Границы и чего не трогаем

  • Только модель воздуха: AirRuntime, AirCase, AirPlace, AirWindowCase, AirClipmap, поле/болтанка (wind_field.gd, field_turbulence.gd, gust_spectrum.gd, ветка поля в atmosphere.gd) и их тесты.
  • Не трогаем: scripts/flight/* (ground_run.gd, input_controller.gd — feature/control-fix), configs/wings/ (feature/wing-physics-check), раскладку клавиш (feature/ui-controls), аналитический профиль WindModel и склоновый подъём аналитики, решатель (air_picard.glsl, Params, калибровка), AM-11/AM-12.

Контракты

Стыки — в docs/contracts/air-model.md (единый источник, контрактный тест tests/contracts/test_air_contracts.gd):

  • C2 v6 — inflow_k в AirPlace.domain_case / AirWindowCase.window_case / window_at; α, класс, z_sat по ветру меню; AirCase.u10 = k·меню (приток), u10_menu, inflow_k в случае и meta().
  • C7 v3 — AirClipmap.setup/set_conditions(…, inflow_k).
  • C9 v3 — AirRuntime: загрузка в два прохода, inflow_k, last_info.inflow_k/passes/u_start10_first/u_start10; в полёте — k последней загрузки.
  • Проблема 2 (AS-2) — стык C4 (turb_at, болтанка поля, lee.*/turbulence.field_*) — версия по итогу бисекта, до исполнителя AS-2. Контрактный тест v6/v3/v3 записан до исполнителя и падает до AS-1 (test_c2_inflow_scale, C7/C9-проверки).

Задачи

AS-1 — поле под старт (проблема 1) — dp-engineer

Скоуп: C2 v6, C7 v3, C9 v3 в коде (air_place.gd, air_case.gd, air_window_case.gd, air_clipmap.gd, air_runtime.gd, при необходимости wind_profile.gd — только способ вызова, не формулы); замер U над стартом по поданному набору уровней (горизонталь среднего поля без болтанки на 10 м над землёй старта); второй проход; строка журнала; GPU-регрессионный тест; замер до/после инструментом WPC-2 (wind_audit из 576550e — копия в tools/research/air_start/). Приёмка:

  • контрактные тесты --filter=test_air_contracts — все зелёные;
  • GPU-тест: U поля на 10 м над стартом = меню ±10 % на всех 10 стартах (6 м/с; плюс 3 и 10 м/с — замером инструмента);
  • таблица до/после (поле, 3/6/10 м/с, все старты): U над стартом 1,5/10/50/100/200 м, отношение к меню, направление на 10 м относительно меню, k, U₁ первого прохода; рядом аналитика (не меняется);
  • время загрузки до/после (wall_s, ≈ +5 с — приемлемо);
  • прежние GPU-тесты поля (tools/gpu_tests.sh --filter=air_) и headless atmosphere, contracts — без новых падений;
  • калибровка не тронута: inflow_k = 1 даёт побитно прежний случай (тесты Askervein/эталонов зелёные). Оценка: 0,5–1 день.

AS-2 — турбулентность и разворот ветра у земли (проблема 2) — dp-engineer (после бисекта CF-1 и AS-1)

Скоуп: по результату бисекта (коммит, файл:строка) — причина болтанки/разворота на 1,5 м над стартом; исправление у причины в модели воздуха; GPU-регрессионный тест на стартах. Приёмка (числа — по литературе, окончательно в задании AS-2 по итогам бисекта):

  • на 1,5 м над стартом при 6 м/с (10 м) в нейтрали: σw ≈ 1,25 u*, σu ≈ 2,4 u*, σv ≈ 1,9 u* (Panofsky & Dutton 1984; Kaimal & Finnigan 1994), u* — по профилю поля у старта; при z0 = 0,1 м u* ≈ 0,52 м/с → σw ≈ 0,65 м/с; разброс направления σθ ≈ σv/U ≈ 15–20° (за 60 с — без разворотов > 90°); |ΔU| за 0,5 с — в пределах масштаба порывов (Lu ≈ z…десятки м): цифры с обоснованием;
  • без ложной «зоны отрыва»/обратного потока на наветренном старте (разворот ≥ 90° на 1,5 м — только если поле само даёт средний обратный поток);
  • до/после на стартах (σw, σθ, max|ΔU|/0,5 с) — тот же зонд, что CF-1 (tools/research/cf1_start/ в control-fix/cf1). Оценка: 0,5–1,5 дня (зависит от бисекта).

Шлюзы (условия остановки)

  • После двух проходов отклонение U над стартом > 10 % хоть на одном старте (нелинейность решателя) — варианты (третий проход / подбор k по двум точкам / допуск) с ценой по времени загрузки.
  • После AS-1 расхождение поля и аналитики у старта выше 10 м заметное (> ~25 % на 50–100 м) — числа на шлюз (Taylor & Lee не делаем без решения).
  • Бисект CF-1 указывает на правку, которая была сознательной физикой (например, болтанка AM-08 по u*), а «регрессия» — её завышение на старте из-за проблемы 1 — шлюз с числами после AS-1.

Риски

  • k зависит от часа (устойчивость) и направления: в полёте k не уточняется — граница модели (в журнал).
  • В штиль (u10 ≈ 0) — без масштаба (один проход).
  • Нелинейность: k₁ после одного уточнения может дать остаток в несколько процентов.