Выходные данные

Флоуграф сам пишет на диск только водопад. Всё остальное он публикует в ZMQ-сокеты на localhost, а на диск это кладут отдельные процессы-подписчики, которые поднимает диспетчер.

Каналы ZMQ

Порт

Что публикует флоуграф

Тип данных

Подписчик

Результат

base (16887)

zeromq_pub_msg_sink после декодера кадров

PMT-сообщение

zmq_frame_decoder_sub

по одному JSON-файлу на кадр

base + 1 (16888)

zeromq_pub_sink после доплер-компенсации

short, vlen 2

zmq_iq_sub

один .raw за наблюдение

base + 2 (16889)

zeromq_pub_sink после демодулятора

float

zmq_audio_sub

один OGG за наблюдение

base задаётся аргументом --zmq-base-port диспетчера и по умолчанию равен 16887. Диспетчер передаёт его во флоуграф как --zmq-base-port, и все три адреса выводятся из одного параметра zmq_base_port в .grc:

address: '"tcp://127.0.0.1:" + str(zmq_base_port + 2)'

Число живёт в одном месте на каждой стороне, поэтому две станции на одной машине разводятся одним аргументом.

Подписчики опрашивают сокет с интервалом 500 мс, поэтому после сигнала на завершение выходят примерно за полсекунды.

Кадры телеметрии

Порт base, подписчик zmq_frame_decoder_sub, запускается только для режимов с флагом «кадры» (см. Справочник режимов).

Имя файла: <--decoded-data-file-path>_<UTC> — префикс, подчёркивание и метка времени ГГГГ-ММ-ДДTчч-мм-сс.ssssssZ. Расширения нет. Микросекунды в метке делают имя уникальным даже при плотном потоке кадров.

Содержимое: JSON с отступом 4 и отсортированными ключами.

{
    "decoder_corrected_bits": 0,
    "decoder_crc_valid": true,
    "decoder_name": "satnogs_frame_decoder",
    "decoder_version": "1.0",
    "pdu": "QUJDREVGRw==",
    "sample_cnt": 4096,
    "sample_start": 122880,
    "time": "2026-08-22T14:31:07.482915Z"
}

Ключ

Тип

Смысл

pdu

строка

полезная нагрузка кадра в base64. Единственное гарантированное поле

decoder_name

строка

блок-декодер, породивший кадр

decoder_version

строка

версия декодера

decoder_crc_valid

bool

контрольная сумма сошлась

decoder_corrected_bits

int

сколько бит исправила коррекция ошибок

sample_start

int

номер первого отсчёта кадра от начала наблюдения

sample_cnt

int

длина кадра в отсчётах

time

строка

метка времени приёма, ISO 8601

Примечание

Набор ключей, кроме pdu, целиком задаёт публикующий блок. Декодеры gr-satellites (Geoscan, USP) метаданных не отдают вовсе, поэтому их файлы содержат ровно {"pdu": "…"}. Апстрим в этом случае падал; форк добавил подстановку пустых метаданных, так что кадр всё равно сохраняется.

Аудио

Порт base + 2, подписчик zmq_audio_sub. Запускается всегда, независимо от режима.

--file-path здесь — полный путь к результату, а не префикс: метка времени не добавляется. Если файл уже существует, он удаляется перед записью.

Формат зафиксирован в коде подписчика: OGG Vorbis, 48000 Гц, моно, входные отсчёты float32. Флоуграф обязан привести звук именно к 48 кГц — рассогласование частот не обнаруживается, аудио просто окажется ускоренным или замедленным.

Если за наблюдение не пришло ни одного отсчёта, подписчик пишет предупреждение в stderr: пустой OGG больше не выглядит как успешная запись. Так проявляет себя PHASMA, у которого аудиоветки нет вовсе.

Что попадает в аудио, зависит от режима: для FM — демодулированный НЧ-сигнал, для BPSK — сигнал, перенесённый на 12 кГц и взятый по действительной части, для Geoscan и USP — выход отдельного когерентного контура, работающего параллельно декодеру.

IQ

Порт base + 1, подписчик zmq_iq_sub. Запускается только при --enable-iq-dump=1.

Имя файла: <--iq-file-path>_cs16_<UTC>.raw, метка времени берётся один раз при старте.

Формат: чередующиеся комплексные знаковые 16-битные целые (I, Q, I, Q, …), порядок байтов машинный. Отсчёты получены умножением комплексного потока на 16384.

Данные сняты после доплеровской компенсации. Частота дискретизации в файле никак не отражена, а зависит она от режима:

  • FM и SSTV (оба идут через fm.grc) — 48000 Гц;

  • APT и SSTV_PD120 — 4*4160*4 = 66560 Гц. audio_samp_rate = 48000 в этих графах относится только к последнему ресемплеру аудио, не к IQ;

  • все режимы с бодрейтом — baudrate × decimation, где децимация вычисляется флоуграфом (см. Соглашения в .grc).

Открыть в GNU Radio: blocks_file_source типа shortblocks_interleaved_short_to_complex, множитель 1/16384.

Водопад

Пишет сам флоуграф блоком satnogs_waterfall_sink в файл --waterfall-file-path. Параметры зашиты во всех флоуграфах одинаково: БПФ на 1024 точки, 10 строк в секунду.

Частота дискретизации на входе водопада та же, что у IQ, — то есть полоса и разрешение водопада зависят от режима. Для FM это 48 кГц, для FSK 9600 — 57.6 кГц (find_decimation(9600, 2, 48000) = 6, не 4), для BPSK 9600 — 76.8 кГц (sps = 4), для APT/SSTV — 66.56 кГц, для PHASMA — 200 кГц. Геометрия (частота, число каналов, число БПФ на строку) записана в заголовок .dat; клиент отдаёт её порталу в client_metadata.signal вместе с уровнем шума, нормированным на ширину бина (noise_dbhz).

Живой поток по UDP

Независимо от файлов флоуграф всегда шлёт доплер-скорректированный поток в network_udp_sink на --udp-dump-host:--udp-dump-port. Формат — комплексные 16-битные целые, размер полезной нагрузки пакета 1472 байта. Частота дискретизации та же, что у IQ-дампа.

Предназначен для анализа в реальном времени во время наблюдения; на диск ничего не пишется.