Планирование наблюдений

Планирование — это подбор временных окон, в которые конкретная станция видит конкретный спутник, и создание из них наблюдений. В портале три сценария: ручной, автоматический и отдельный для новых запусков.

Расчёт пролётов

Геометрия пролёта считается через skyfield. Общие примитивы вынесены в network/base/skyfield_pass_utils.py: наблюдатель на WGS-84, EarthSatellite из TLE, разностный вектор и find_events() для событий восход/кульминация/заход, плюс угол места и азимут.

Примечание

EarthSatellite разбирает TLE через sgp4 (пин sgp4==2.24), который штатно понимает Alpha-5-кодированные номера каталога NORAD — в отличие от ephem, на котором этот код был раньше.

Основной расчёт живёт в network/base/scheduling.py:

Функция

Назначение

predict_available_observation_windows()

Главная точка входа: доступные окна для станции и передатчика

generate_overhead_observation_window()

Окно для пролетающего спутника

generate_geo_observation_window()

Окно для геостационарного спутника

create_station_window(), create_station_windows()

Формирование окон станции

recalculate_window_parameters()

Пересчёт параметров окна

split_long_window()

Разбиение длинного окна на части

resolve_overlaps()

Разрешение пересечений с уже запланированным

over_min_duration()

Отсев слишком коротких окон

get_available_stations()

Станции, которым доступен данный передатчик

create_new_observation()

Создание наблюдения из окна

Ограничения задаются настройками (см. Конфигурация): OBSERVATION_DATE_MIN_START — насколько близко к «сейчас» разрешено планировать станции, которая не на связи по MQTT; станция на связи заявляет свой порог в секундах (reported_status.scheduling.lead_seconds, Station.scheduling_lead()), и начало внутри порога create_new_observation() сдвигает вперёд, а не отклоняет — пользователь видит сообщение о сдвиге. OBSERVATION_DURATION_MIN — минимальная длительность, OBSERVATION_SPLIT_DURATION и OBSERVATION_SPLIT_BREAK_DURATION — порог и пауза разбиения, OBSERVATION_DATE_MAX_RANGE — горизонт планирования.

Ручное планирование

Через веб-интерфейс (network/base/views/scheduling.py): пользователь выбирает спутник, передатчик и станцию, портал показывает доступные окна, пользователь подтверждает.

Право планировать проверяется в network/base/perms.py. Для спутников-нарушителей действует поле станции violator_scheduling («Никто» / «Только операторы» / «Все») и квоты OBSERVATIONS_PER_VIOLATOR_SATELLITE за период OBSERVATIONS_PER_VIOLATOR_SATELLITE_PERIOD.

Автопланирование

network/base/auto_scheduling.py строит наблюдения без участия человека:

Функция

Назначение

predict_candidate_windows()

Окна-кандидаты по параметрам расписания

schedule_windows_by_priority()

Отбор и постановка окон с учётом приоритета

schedule_windows_by_yield()

Деление времени станции между пролётами по ожидаемой отдаче

satellite_yield_factors()

Вес спутника по кадрам, принятым станцией за 14 суток

constrain_pass_to_az_window()

Обрезка пролёта по азимутальному окну

check_az()

Попадание азимута в разрешённый сектор

unpack_schedule_params()

Разбор JSON-параметров расписания с учётом горизонта станции

window_validation()

Финальная валидация окна

Параметры берутся из StationSchedule, StationScheduleSec и NetworkSchedule (см. Наземные станции) — список спутников и JSON с ограничениями.

Запускается задачей auto_schedule_network каждые 12 часов с горизонтом 36 часов. Внутри есть отдельные задачи по источникам расписания: auto_schedule_station_primary, auto_schedule_station_second, auto_schedule_station_network.

У дополнительного расписания есть порядок планирования — ключ mode в его параметрах:

mode

Как делится время станции

random (по умолчанию)

Пролёты берутся по раннему окончанию; проигравший слот пролёт обрезается до свободного остатка

elevation

То же, но по полосам кульминации 90–70, 70–50, 50–30 и ниже: верхняя полоса занимает слоты первой

yield

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

yield_history

Как yield, но вес умножается на отдачу спутника на этой станции: кадров на секунду наблюдения за 14 суток к среднему по станции, в пределах 0,5–2. Наблюдения с более чем 100 кадрами (сбросы) не считаются, спутник без истории получает 1

Первые два режима решают, какому пролёту достанется слот, и отдают его целиком, вместе с участками у горизонта. Два последних решают, какому спутнику достанется каждый отрезок времени: выше 20° отдача почти не растёт, ниже 10° её почти нет, поэтому хвост высокого пролёта стоит меньше, чем кульминация соседнего низкого. Наблюдений при этом больше, и они короче. Таблица ELEVATION_YIELD измерена на одной станции диапазона UHF с квадрифилярной антенной; для другой антенны её нужно перемерить.

Планирование запусков

Для только что запущенных аппаратов расчёт особый: точный TLE ещё не опубликован, а объекты идут плотной группой. Этим занимается network/base/launch_scheduler.py.

Модели: Launch (запуск с типом ракеты, типом разгонного блока и космодромом) и SatelliteLaunch (аппарат в составе запуска, с типом миссии и статусом).

Функция

Назначение

launch_scheduler()

Основной проход планирования по запуску

update_station_windows()

Обновление окон станций

get_available_transmitter()

Подбор передатчика

create_new_launch_observations()

Создание наблюдений

Класс SatelliteStats считает статистику уже запланированных наблюдений по аппарату, чтобы распределять их равномерно.

Отдельный набор настроек: LAUNCH_MIN_ELEVATION (5°), LAUNCH_GOOD_ELEVATION (25°), LAUNCH_MIN_HORIZON (0°), LAUNCH_MIN_PERIOD (48), LAUNCH_SPLIT_DURATION (480 с), LAUNCH_BREAK_DURATION (20 с), LAUNCH_WAITING_FOR_SATELLITE.

Слот — 8 минут, то есть наблюдение занимает пролёт почти целиком: на пролёт группы над станцией приходится одно наблюдение одного аппарата, а пролёты короче слота пропускаются. Короткий слот даёт больше строк (120 с — впятеро), но режет пролёт на куски, и заметная часть наблюдений достаётся краям у горизонта, где ничего не принять. Число наблюдений ограничено временем станций, а не числом аппаратов: в замере на элементах Transporter-18 и 13 станциях за 48 часов выходит около 150 наблюдений, будь аппаратов 12 или 70.

Планировщик запускается сам, один раз, когда Launch Library 2 ставит отслеживаемому запуску «Успешный пуск», с этими настройками и от имени NETWORK_SCHEDULER_USERNAME; тогда же аппараты запуска переходят из future в in orbit. Дальнейшие запуски — кнопкой на вкладке «Планирование». Слоты, занятые другими наблюдениями станции, планировщик пропускает.

Связанные задачи: launch_scheduler_task, fetch_satellite_from_tle_source_for_all_launches (ежедневно в 04:00 UTC) — заводит объекты запуска по международному обозначению и проставляет аппаратам настоящие номера, fetch_launch_supgp (каждые 2 часа) — даёт аппаратам TLE до старта, check_unknown_satellites — обнаружение неизвестных объектов (раз в сутки, и каждые 15 минут в режиме проверки запусков).

Пересчёт по новым TLE

Задача update_future_observations_with_new_tle_sets (каждые 30 минут) пересчитывает окна уже запланированных будущих наблюдений, когда для спутника появился более свежий набор TLE. Без этого окно, рассчитанное по устаревшим элементам, уезжает от фактического пролёта.