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

Энергия, ветер и оборот на площадке

Три фактора, которые превращают оптимистичный план в выполнимый. ТЗ требует все три явно: «исходя из их параметров полета, объема заряда и скорости, а также учитывая скорость ветра» (R-VEH-2/3/4).

Ветер: путевая скорость

Ветер — вектор, а не число. Борт держит воздушную скорость V_a, а по земле движется с путевой V_g, которая зависит от угла между курсом и ветром.

Пусть α — угол между направлением галса и направлением, куда дует ветер; W — скорость ветра. Составляющие: W∥ = W·cos α (продольная), W⊥ = W·sin α (поперечная).

Чтобы удержаться на линии заданного пути, борт доворачивает нос на угол сноса, «съедая» часть воздушной скорости на компенсацию бокового ветра. Итог:

V_g(α) = sqrt(V_a² − W⊥²) + W∥            при |W⊥| < V_a

Если |W⊥| ≥ V_a, линию удержать невозможно — это отдельная проверка допустимости.

Что из этого следует

1. Ветер сильнее среднего замедляет, чем ускоряет. Пара галсов «туда-обратно» вдоль ветра стоит 2·L·V_a/(V_a²−W²), что всегда больше 2L/V_a. Попутный участок не компенсирует встречный.

2. Галсы поперёк ветра быстрее галсов вдоль ветра — ровно в 1/sqrt(1−(W/V_a)²) раз. Полный вывод и таблица потерь — 03-coverage-path-planning.md. Это же подтверждает руководство Planner, называя «сильный ветер вдоль линий облета полигона» причиной менять направление.

3. Ветер — жёсткий отсекатель, а не только замедлитель. У каждого борта есть wind_max:

Борт wind_max
Геоскан 201 12 м/с
Геоскан 801 10 м/с
Геоскан Gemini 10 м/с

При ветре 11 м/с из парка выбывают два борта из трёх. Это надо проверять до запуска решателя и показывать пользователю явно («при заданном ветре доступно 1 ВС из 3»), а не выдавать план, который не выполнят.

4. Посадка против ветра. Из руководства Planner:

Важно, чтобы посадка осуществлялась против ветра в области посадки. В противном случае возможна жесткая посадка, приводящая к повреждениям самолета.

То есть у площадки посадки есть направление захода, зависящее от ветра. Меняется ветер — меняется геометрия захода. Дёшево заложить, почти никто не заложит.

5. Снос при парашютировании. У 201 посадка на парашюте, и РЭ предупреждает: «примите во внимание возможный снос при спуске на парашюте». Эллипс сноса вокруг точки приземления = функция ветра и высоты раскрытия. Отличная деталь для визуализации и для проверки, что борт не сядет в бесполётную зону или на дорогу.

Модель ветра для сервиса

Минимум — однородный ветер (скорость + направление на всю область), задаётся пользователем. Этого достаточно для ТЗ и для всех расчётов выше.

Расширения, если останется время:

  • ветер по высотам (профиль): на 300 м он заметно сильнее, чем на 100 м;
  • порывы как запас прочности плана;
  • «измерение ветра на месте» по мотивам точки ожидания Planner: кнопка «уточнить ветер и пересчитать» — прямая отсылка к отраслевой практике, которую эксперт узнает.

Энергия

Две модели, обе допустимы

По времени (простая). Ресурс борта = endurance_max в минутах, расход = время полёта. Работает всегда, у 801 это единственный вариант — энергоёмкость АКБ в буклете не указана.

По ватт-часам (точная). Есть для Gemini: 144,7 Вт·ч на 40 мин → средняя мощность 217 Вт. Для 201: 40 А·ч × 18,5 В ≈ 740 Вт·ч при двигателе 220 Вт.

Точная модель позволяет учитывать, что разные фазы стоят разной мощности:

E = Σ_фазы P(фаза, V_a, ветер) · t(фаза)
Фаза Мультиротор Самолёт
Взлёт / набор высоты высокая мощность (~1,5–2× крейсера) набор на повышенной тяге
Крейсер / перелёт база база, минимум на оптимальной скорости
Съёмочный галс база база
Разворот +20–40 % (торможение/разгон) +10–20 % (крен)
Зависание (hover&capture) максимум неприменимо
Снижение / посадка низкая низкая
Полёт против ветра больше времени на ту же дистанцию → больше энергии то же

Рекомендация: начать с модели по времени, оставить интерфейс под ватт-часы. Контракт один:

def sortie_cost(uav, route, wind) -> (time_s, energy_frac)

Внутри — либо time / endurance, либо интеграл мощности. Переключается конфигом. Для критерия «суммарный налёт» из ТЗ нужны именно часы, так что временнáя модель — не костыль, а прямое попадание в постановку.

Резерв заряда — не опция

В мастере предстартовой подготовки Геоскан 201 есть «напряжение возврата» 16,5–20,75 В: по достижении порога борт самостоятельно прекращает задание и идёт на посадку. Диапазон АКБ — 15…21 В при номинале 18,5 В.

Значит, план, сажающий борт «в ноль», физически не выполнится: автопилот прервёт задание раньше, и часть галсов останется неснятой.

Практика:

доступный бюджет = endurance · (1 − reserve)
reserve = 0,20…0,25

Резерв должен быть параметром в UI со значением по умолчанию 20 %, а не константой в коде: это ровно тот вопрос, который задаст эксперт («а что у вас с резервом?»), и наличие видимой ручки отвечает на него мгновенно.

Плюс два элемента, которые резерв обязан покрывать: перелёт от последнего галса до площадки посадки и сам маршрут посадки (у Planner — три точки).

Оборот на площадке: самый недооценённый фактор

Соотношение из спецификации Gemini:

Продолжительность полёта 40 мин
Время заряда АКБ ~105 мин

2,6 : 1. Если сценарий требует от борта двух вылетов, между ними либо 105 минут простоя, либо запасная АКБ. У 801 в базовой комплектации две АКБ — то есть второй вылет доступен сразу, третий уже нет.

Что это значит для makespan: на сценарии, где парку нужно суммарно 6 вылетов при 3 бортах, наивный план даст makespan ≈ 2 × 40 = 80 мин, а реальный — 40 + 105 + 40 = 185 мин, если запасных АКБ нет. Ошибка в 2,3 раза.

Модель площадки:

launch_site:
  position: [lat, lon]
  suitable_for: [multirotor, fixed_wing]   # катапульта нужна только самолёту
  spare_batteries: {gemini: 2, geoscan_801: 2}
  turnaround_time_min: 10                  # замена АКБ + предстартовая подготовка
  charge_time_min: {gemini: 105}

В решателе это ограничение C8: между двумя вылетами одного борта на одной площадке — либо turnaround_time, если есть свободная заряженная АКБ, либо charge_time.

Дополнительно у 201 есть «время подготовки» (у 401 — 5 мин, у 701 — 30 мин), а для самолёта ещё и перезарядка катапульты. В базовой версии достаточно одного параметра turnaround_time_min на борт.

Валидация: что проверяет скрипт

Проверка Условие
Ни один вылет не превышает бюджет с резервом E_вылета ≤ endurance · (1 − reserve)
Ветер не превышает предел борта W ≤ wind_max(v) для всех задействованных
Поперечная составляющая допустима |W⊥| < V_a на каждом галсе
Оборот на площадке соблюдён интервал между вылетами борта ≥ turnaround/charge
Путевая скорость положительна V_g > 0
Время посчитано с разворотами T_план ≥ L_total / V_g строго

Последняя проверка — защита от регресса в наивную формулу: если кто-то (человек или агент) случайно уберёт учёт разворотов, тест упадёт.