# Декодер Geoscan `satellites/geoscan_gfsk_decoder.grc`, режим `GFSK_GEOSCAN`. Добавлен форком — в апстриме SatNOGS его нет. Декодирует телеметрию аппаратов «Геоскан» с GFSK-модуляцией. Разбор кадров выполняют блоки **gr-satellites**, а не gr-satnogs, — этим флоуграф принципиально отличается от остальных в репозитории. :::{warning} Требует установленного [gr-satellites](https://github.com/daniestevez/gr-satellites). Зависимость не объявлена ни в `CMakeLists.txt`, ни в `debian/control`: без неё падает сборка всего проекта. См. [](../install.md). ::: ## Параметры Общий набор (см. [](../dispatcher.md)) плюс: | Параметр | По умолчанию | Смысл | |---|---|---| | `baudrate` | 9600 | скорость передачи; диспетчер подставляет из `--baud` | | `rx_freq` | 435 МГц | центральная частота приёма | Внутренние переменные: ```python audio_samp_rate = 48000 decimation = max(4, satnogs.find_decimation(baudrate, 2, audio_samp_rate)) ``` `frame_size` (74 байта) — **параметр**, как и в `satellites/fsk_phasma_decoder.grc`, поэтому переопределяется из командной строки: `--frame-size=…`. Диспетчер его для режима `GFSK_GEOSCAN` не передаёт, так что по умолчанию действует 74. Нижняя граница `max(4, …)` появилась в форке (коммит «Fix decimation for USP»): на некоторых бодрейтах `satnogs.find_decimation` возвращает слишком малое значение, и последующая целочисленная децимация `decimation // 2` обращается в ноль. Частота после доплеровской компенсации — `baudrate × decimation`. ## Тракт декодирования Кадры собираются напрямую из потока после доплер-компенсации, минуя всю локальную обработку: ``` soapy_source → satnogs_doppler_compensation → doppler_corrected → satellites_fsk_demodulator (iq=1, samp_rate = baudrate·decimation, subaudio=0) → satellites_geoscan_deframer (frame_size=74, threshold=6) → zeromq_pub_msg_sink → :zmq_base_port ``` `threshold=6` — допустимое число несовпавших бит в синхрослове. Больше значение — больше найденных кадров и больше ложных срабатываний. `satellites_fsk_demodulator` содержит собственные АРУ, фильтрацию и восстановление тактовой частоты, поэтому ни `clock_recovery_mm`, ни `binary_slicer`, ни `satnogs_frame_decoder` здесь не нужны. ## Тракт аудио Аудио-ветка **не участвует** в декодировании — это независимый когерентный контур, нужный только чтобы записать слышимую дорожку: ``` doppler_corrected ─┬─▶ blocks_delay (512) ──▶ blocks_multiply ──▶ low_pass_filter │ ▲ (0.625·baudrate, │ │ децимация decimation/2) │ blocks_vco_c │ (−baudrate·decimation) │ ▲ └─▶ low_pass_filter ──▶ quadrature_demod ──▶ moving_average (1024) (baudrate·1.75) (1.0) (масштаб 1/1024) ↓ analog_quadrature_demod_cf (0.9) ↓ pfb_arb_resampler → dc_blocker → ZMQ :zmq_base_port+2 ``` Коэффициент передискретизации подобран так, чтобы на выходе получилось ровно 48 кГц: `audio_samp_rate / ((baudrate × decimation) / (decimation // 2))`. Остальные ответвления — водопад, IQ на `zmq_base_port + 1`, UDP-поток — стандартные, см. [](generic.md#общий-скелет). ## Формат кадра Дефреймер gr-satellites метаданных не публикует, поэтому JSON-файл кадра содержит только полезную нагрузку: ```json { "pdu": "…base64…" } ``` Это ожидаемое поведение, а не ошибка. Апстримовый подписчик на таком сообщении падал; форк добавил подстановку пустых метаданных. Подробнее — [](../outputs.md). ## Отладка Записать IQ и разобрать офлайн штатными средствами gr-satellites: ```sh flowgraph_dispatcher --mode GFSK_GEOSCAN --baud 9600 --enable-iq-dump=1 \ --iq-file-path=/tmp/.satnogs/data/iq … gr_satellites Geoscan-Edelveis --iq --samp_rate \ --wavfile /tmp/.satnogs/data/iq_cs16_*.raw ``` Частоту дискретизации придётся указать вручную: в имени файла её нет. Если кадров нет, а сигнал на водопаде виден, попробуйте поднять `threshold` в `.grc` — но помните, что `.grc` собирается заново, а сгенерированный `.py` коммитить нельзя. ## Близнец `satellites/usp_fsk_decoder.grc` устроен точно так же и отличается двумя числами — см. [](usp.md).