Спутники и передатчики¶
Satellite¶
Космический аппарат в базе сети.
Поле |
Назначение |
|---|---|
|
Идентификатор вида |
|
Номер в каталоге NORAD |
|
Название |
|
|
|
|
|
Оператор ( |
|
Сеть ( |
|
Масса, килограммы |
|
|
|
|
|
Поля, которые импортёру запрещено перезаписывать |
|
Описание миссии одной строкой |
|
Развёрнутое описание миссии |
Описания и языки¶
Описание хранится по колонке на язык, а не словарём в JSON: точечная правка в
админке тривиальна, блокировка перезаписи ложится на каждый язык отдельно, а поиск
по описанию остаётся обычным LIKE.
Пустой язык — законное состояние. Китайский может быть пуст всегда. Страница показывает описание на языке читателя, а если его нет — на английском, а если нет и его — на любом заполненном. Когда не заполнено ничего, блок описания не рисуется вовсе: заголовок над прочерком хуже отсутствующего блока.
Сервиса перевода в портале нет и не будет. Перевод делается снаружи, а обмен идёт двумя командами — см. Management-команды.
Блокировка автоматической перезаписи¶
locked_fields — список имён полей, которые импортёры не трогают. Это контракт
между админкой и всеми источниками сразу, а не настройка одного скрейпера:
любой импортёр обязан прочитать список и пропустить перечисленное.
Набор полей, которые вообще можно заблокировать, задан константой
LOCKABLE_FIELDS в network/base/models.py. Форма спутника в админке рисует поверх
одной этой колонки блок чекбоксов «Не перезаписывать».
Галочка ставится вручную: автоблокировки по факту правки нет намеренно. Отсюда цена, о которой надо помнить, — администратор, вычитавший описание и забывший отметить поле, потеряет свой текст на следующем обходе источника.
Откуда берутся паспортные данные¶
Два импортёра, оба уважают locked_fields и оба соединяются с каталогом
только по номеру NORAD — подробности и расписание в Задачи Celery.
Источник |
Что даёт |
Лицензия |
|---|---|---|
nanosats.eu |
Наноспутники: масса, форм-фактор, описание одной строкой, ссылки на источники |
Не объявлена — берём текст и числа, снимки не берём |
Wikidata |
Масса, описания на трёх языках, ссылка на статью, файл на Commons |
CC0 |
Wikimedia Commons |
Сами фотографии с автором и лицензией |
По файлу, читается через API |
Ручной ввод и правка через админку доступны всегда и имеют приоритет: галочка «Не перезаписывать» замораживает поле для всех импортёров сразу.
SatellitePhoto¶
У спутника может быть несколько фотографий. Satellite.image при этом остаётся тем,
чем был: одна картинка, которую пишет импорт из SatNOGS DB и публикует API.
Поле |
Назначение |
|---|---|
|
Файл; те же ограничения, что у прочих картинок — jpg/png/gif/webp, до 2 МБ |
|
Страница-первоисточник снимка, а не наша копия |
|
Автор снимка |
|
|
|
Подпись, признак обложки, порядок |
Обложка выбирается так: отмеченная is_cover → первая по order →
Satellite.image → заглушка.
source_url, author и license заполняются обязательно и выводятся подписью под
снимком. Это не оформление: ни nanosats.eu, ни Wikimedia Commons не отдают снимок
безусловно — указание автора и лицензии есть условие, на котором его вообще можно
показывать.
Статус выставляется вручную — с единственным исключением, переходом
in orbit → re-entered (см. ниже). Поэтому для практических решений (например,
публичной выдачи TLE) портал опирается не только на него, но и на возраст
последнего набора TLE — см. Орбитальные данные (TLE).
Орбитальные параметры пересчитываются задачей calculate_all_satellite_orbital
(ежедневно в 05:00 UTC), логика — в network/base/orbital_satellite_params.py.
Сошедшие с орбиты аппараты отображаются отдельным представлением
(network/base/views/decay.py).
История орбиты¶
На вкладке «Орбита» страницы спутника под строками TLE — график средних
элементов по всем наборам TLE за 365 дней: высота большой полуоси над Землёй
(a − R⊕), наклонение, эксцентриситет, долгота восходящего узла и аргумент
перигея. По оси времени — эпоха набора из самих строк, а в выборку строки
попадают по Tle.updated. Так сделано потому, что у строк, записанных до
появления столбца epoch, он пустой. Наборы с эпохой старше года
отбрасываются: источник может заново опубликовать последние элементы
замолчавшего аппарата, и одна такая точка растянула бы ось на годы. Каждый
источник (Tle.tle_source) рисуется своей линией, легенда скрывает лишние. Если
источник молчал больше недели, линия рвётся, а не тянется через пропуск. Скачок высоты означает манёвр или
ошибочный набор, а расхождение линий показывает разницу между источниками.
Средней аномалии на графике нет: на эпоху набора это случайное число от 0 до
360°.
Данные отдаёт /orbit_history/<sat_id>/ (orbit_history в
network/base/views/satellite.py), кэш satellite-<pk>-orbit-history на
CACHE_TTL. Страница запрашивает их, только когда открыта вкладка. Набор
разбирает mean_elements в network/base/tle_utils.py, а строки, которые не
разбираются, пропускаются. История загрузок TLE хранится целиком, см. Орбитальные данные (TLE).
Строка ответа — [эпоха, a − R⊕, i, e, Ω, ω, updated, R, T, N]: времена в
миллисекундах, расхождения в километрах.
Кнопка «Возраст TLE» строит пилу по каждому источнику. В момент updated
очередного набора возраст равен updated − эпоха самого свежего набора, что
источник прислал до этого момента, и растёт до прихода следующего. updated —
время записи строки у нас, а не публикации у источника. update_tle не
записывает набор, повторённый без изменений, поэтому повтор возраст не
сбрасывает. На dev prod_sync переписывает updated временем синхронизации,
и пила там ничего не значит. Шкала логарифмическая: у Celestrak возраст
измеряется часами, а у источника, молчавшего месяц, — сотнями часов.
Расхождение прогноза¶
Второй график вкладки строится из того же ответа. Наборы одного источника
сортируются по эпохе. Предыдущий набор продолжается SGP4 до эпохи следующего и
сравнивается с состоянием следующего набора на его эпоху, оба в TEME. Разность
раскладывается по осям следующей орбиты: R — радиус, T — вдоль орбиты (плюс,
когда прогноз впереди), N — нормаль к плоскости. Расчёт —
prediction_error в network/base/tle_utils.py. Пары дальше
PREDICTION_HORIZON_DAYS (7 суток) не сравниваются, у первого набора
источника расхождения нет, и в обоих случаях там null. Источники не
смешиваются.
Это согласованность наборов между собой, а не истинная ошибка: эталон — тоже TLE с ошибкой порядка километра, а ковариации в TLE нет, так что полос σ тоже нет. Манёвр между наборами виден как выброс: у МКС подъём орбиты даёт сотни километров вдоль орбиты за сутки, а обычное расхождение у Celestrak — метры–сотни метров. Поэтому шкала логарифмическая, по ней откладывается модуль расхождения, а знак виден в подсказке вместе с горизонтом прогноза.
Автоматический перевод в «Сошёл с орбиты»¶
Задача confirm_satellite_reentries (ежедневно в 06:00 UTC, логика — в
network/base/decay_confirmation.py) переводит спутник из in orbit в
re-entered и заполняет decayed. По прогнозной дате она этого не делает
никогда: слежение часто ведут до последних сигналов, уточняя TLE уже после
того, как прогнозная дата прошла, и такой аппарат должен остаться в планировании.
Нужно одно из двух:
Space-Track опубликовал подтверждённый сход (
MSG_TYPE=Historical; предсказательные TIP-сообщения приходят сMSG_TYPE=Predictionи игнорируются). Записывается реальная дата схода.Ни один источник TLE не публиковал аппарат
DECAY_TLE_SILENCE_DAYSдней и прогнознаяdecay_dateуже прошла. Записывается эпоха последнего известного TLE — это нижняя граница. Правило работает и без учётки Space-Track.
Спутники с синтетическим номером NORAD (диапазон 70000–100000, выдаётся
generate_norad_id) по первому правилу не переводятся никогда: в каталоге
Space-Track тот же номер принадлежит другому объекту.
Каждый автоматический перевод пишется в SatelliteStatusLog (видно в админке):
старый и новый статус, сработавшее правило, время. Ручные правки туда не
попадают — они и так есть в истории объекта в админке.
Откат. Если перевод оказался ошибочным, верните статус в админке. Строка в
SatelliteStatusLog после этого навсегда запрещает автоматике переигрывать
решение человека; чтобы снова её включить, удалите эту строку.
У сошедшего аппарата остаются заполненными оба поля: decayed — подтверждённый
факт, decay_date — замороженный прогноз, каким он был, пока приходили TLE.
Вместе они дают вилку, поэтому прогноз намеренно не перезаписывается.
Будущие наблюдения переведённого спутника не удаляются. Их количество печатает
команда confirm_satellite_reentries (см. Management-команды), которая по умолчанию
работает в режиме предпросмотра.
Transmitter¶
Передатчик спутника — то, на что фактически настраивается станция.
Поле |
Назначение |
|---|---|
|
Границы диапазона передачи «вверх» |
|
Границы диапазона передачи «вниз» |
|
Режим модуляции ( |
|
|
|
|
|
Статус координации IARU |
Частоты валидируются в диапазоне от 0 Гц до 40 ГГц.
Планирование сопоставляет downlink_* передатчика с диапазонами антенн станции — см.
Наземные станции и Планирование наблюдений.
Mode¶
Справочник режимов модуляции (Mode). Загружается начальными фикстурами и пополняется
из SatNOGS DB.
Режим важен не только для приёма: от него зависит автоматическая оценка наблюдения — для аналоговых режимов (CW, FM) успешный приём кадра не означает «good», см. Оценка наблюдений.
TransmitterStats¶
Агрегированная статистика по передатчику. Пересчитывается задачей
update_transmitters_stats каждые 15 минут; кэшируемые расчёты — в
network/base/stats.py.
Telemetry¶
Telemetry описывает декодеры телеметрии, применяемые к демодулированным данным
спутника.
Подписка на данные¶
Пользователь подписывается на спутник кнопкой «Подписаться на данные» на его странице. После этого каждый новый кадр спутника приходит на сервер пользователя (например, в ЦУП) по MQTT, сразу после приёма и попытки декодирования. Подписка доступна владельцу станции, которая сейчас в сети. Пока ни одна его станция не в сети, кадры ему не приходят. Подписка при этом остаётся и снова заработает, когда станция выйдет на связь.
Параметры подключения указаны в профиле, в блоке «Подписка на данные спутников»:
Параметр |
Значение |
|---|---|
Адрес |
|
Логин |
|
Пароль |
Ключ подписки из профиля. Это не API-ключ: он открывает только потоки кадров |
Топик |
|
Каждое сообщение — один кадр, тот же JSON, что элемент GET /api/demoddata/:
demodulated_data в HEX и декодированные поля в payload_json. Если у спутника
нет декодера, payload_json — пустая строка. Транслируются кадры станций сети и
SiDS; суточный импорт из SatNOGS не транслируется. Пропущенное за время
отключения брокер хранит в постоянной сессии: подключайтесь с постоянным
client_id, clean_session=false и QoS 1. Сессия живёт 7 дней, очередь
ограничена 1000 сообщениями. Для большего разрыва есть REST:
GET /api/demoddata/?sat_id=…&start=….
import paho.mqtt.client as mqtt
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id="my-mission-control", # постоянный: по нему брокер хранит очередь
transport="websockets",
clean_session=False,
)
client.username_pw_set("subscriber-42", "<ключ подписки>")
client.ws_set_options(path="/mqtt")
client.tls_set()
client.on_connect = lambda c, *_: c.subscribe("satellites/<sat_id>/frames", qos=1)
client.on_message = lambda c, userdata, msg: print(msg.payload.decode())
client.connect("sonik.space", 443)
client.loop_forever()
Устройство на стороне портала описано в Обзор эндпоинтов, раздел «Подписка на данные спутника».
Пополнение базы¶
Источник |
Механизм |
|---|---|
SatNOGS DB |
Задача |
SatNOGS Network |
Задача |
CelesTrak |
Через TLE-конвейер, см. Орбитальные данные (TLE) |
Вручную |
Через |
Обнаружение |
|
Ручной запуск обновления из SatNOGS DB — задача manual_update_db.
Примечание
Если db.satnogs.org недоступен с хостинга, задайте SATNOGS_DB_PROXY_URL — прокси
применяется только к запросам к API SatNOGS DB и SatNOGS Network.
Синхронизация с продом¶
На тестовых стендах каталог отстаёт от sonik.space. Кнопка «Синхронизация с
sonik.space» в списке спутников админки (везде, кроме ENVIRONMENT=production) ставит
задачу sync_from_prod (network/base/prod_sync.py). В отличие от импорта SatNOGS она
перезаписывает данные: спутники, передатчики и последний TLE каждого спутника
становятся такими же, как на проде.
Источник — публичный API прода, без авторизации. Что API не отдаёт, то не меняется: описания, паспортные данные,
launch,trans_decode,paramsпередатчика.Спутник сопоставляется по
sat_id. Если такого нет — по NORAD вне синтетического диапазона, когда он у прода один: строка стенда получаетsat_idпрода.Дубли сливаются. Лишняя строка стенда с тем же NORAD отдаёт спутнику с прода наблюдения, TLE, данные и передатчики, после чего удаляется.
Спутники и передатчики, которых на проде нет, остаются. Если прод занял их синтетический NORAD, они получают новый.
Последним TLE становится TLE прода с его
tle_source. Следующийfetch_tleпересчитывает выбор по приоритетам стенда.Всё пишется одной транзакцией, поэтому недоступный прод не оставит каталог наполовину обновлённым. Прогон занимает около минуты, счётчики пишутся в лог Celery.
Операторы, сети и запуски¶
Operator— эксплуатирующая организация.Network— сеть, к которой отнесён аппарат.Launch— запуск: носитель, площадка, оператор, орбита, статус;is_trackedотделяет запуски сети от мирового календаря Launch Library 2. См. Запуски.SatelliteLaunch— аппарат в составе запуска: тип миссии, статус.
Планирование наблюдений сразу после запуска описано в Планирование наблюдений.