Для понимания маштабирования и глубины расположения узлов комплексной системы пассивного мониторинга приведу карту покрытия DVB-T2 например Курской области:
Поток комплексных отсчётов IQ с reference-антенны (прямой сигнал DVB-T2). Наша задача — найти границу OFDM-кадра / символа, чтобы потом корректно делать CAF.
Как мы находим начало кадра
Используем P1-символ
В DVB-T2 каждый кадр начинается с P1 — это специально зарезервированный уникальный OFDM-символ с известной паттерной структурой. Мы делаем:
корреляцию входного потока IQ с эталоном P1,
ищем максимум корреляции,
пик корреляции → начало кадра.
Это даёт очень устойчивую синхронизацию даже при низком SNR.
2. Дополнительная проверка по циклическому префиксу
После грубой синхронизации по P1, делаем тонкую синхронизацию:
сверяем основную часть OFDM-символа с копией из CP,
ищем максимум совпадения,
уточняем временной сдвиг до точности десятков отсчётов.
3. Коррекция частоты (CFO)
Перед CAF это важно:
оцениваем остаточный частотный сдвиг по фазе CP,
компенсируем
нормализуем символы
4. Вырезаем ровно N отсчётов для каждого символа
Когда начало кадра найдено, дальше уже несложно:
N_fft отсчётов — сам OFDM-символ
CP_len отсчётов — циклический префикс
Мы адаптивно “подтягиваем” рамку по CP, чтобы дрейф не накапливался.
Корреляция с P1 — поиск начала кадра :
На вход сюда подаётся:
iq — ваш поток IQ с reference-канала
p1_ref — заранее сгенерированный эталонный P1 (есть в стандарте DVB-T2, или берётся из предварительного захвата)
Этот шаг обычно находит границу кадра с точностью ±5…10 отсчётов даже на низком SNR.
import numpy as np
from numpy.fft import fft, ifft
def correlate_with_p1(iq, p1_ref):
"""
iq - поток комплексных IQ-отсчётов
p1_ref - эталонный P1-символ (комплексный массив)
"""
# нормируем для устойчивости
p1_norm = p1_ref / np.linalg.norm(p1_ref)
iq_norm = iq / (np.abs(iq).mean() + 1e-6)# кросс-корреляция (через FFT для скорости)
corr = np.abs(np.fft.ifft(np.fft.fft(iq_norm) * np.conj(np.fft.fft(p1_norm, len(iq_norm)))))
# индекс максимума = начало кадра
frame_start = np.argmax(corr)
return frame_start, corr
Если заинтересует, могу сбросить в мессаге полный пайплайн с тонкой синхронизацией по циклическому префиксу (CP)
Да, KrakenSDR дороже HackRF, но для 5-канального стенда с RPi5 бюджет всё ещё вполне «домашний». Главная мысль была — многоканальный SDR уже не требует профессиональной РЛС, и собрать рабочий стенд реально без грантов.
Да, вы всё верно описали — без автоматической рекалибровки KrakenSDR каналы через пару часов реально начнут «танцевать вразнобой»
У нас рекалибровка включена, и она решает сразу несколько проблем: фазовые сдвиги между каналами, рассинхрон цифровой логики и рассогласование буферов после USB. Без неё CAF и треки постепенно теряли бы точность.
Кроме встроенной процедуры, мы добавляем DSP-компенсацию, чтобы минимизировать остаточные сдвиги и обеспечить стабильность DOA/CAF при длительных записях.
Если интересно, могу коротко описать, как реализована эта фазовая коррекция и интерполяция сигналов на Python — там есть несколько забавных нюансов, которые неожиданно сильно влияют на точность.
Спасибо за разбор — приятно, что кто-то реально дочитал до конца.
Да, согласен: статья не претендует на учебник по радиолокации. Цель была показать, что пассивный радар на KrakenSDR и DVB-T2 реально работает, а не расписать весь DSP пайплайн в деталях. Сейчас готовим отдельный пост с результатами: CAF-карты, CFAR-детекции, треки по Kalman filter’у и т.п. — будет куда нагляднее.
По терминам — да, мешанина сознательная. Мы держали фокус на англоязычном SDR/DSP комьюнити, где CAF, CFAR и MTI никто не переводит, в котором мы последние 20 лет вращаемся. А вот «антенный массив» оставили по-русски, чтобы не писать array . В будущем сделаем нормальную редактуру для рускоязычного клиента, чтобы не резало глаз радиотехникам.
Схемы и «тепловые карты» добавим — просто хотелось выкатить проект в живом виде, пока он дышит, а не отполированный PDF через полгода.
Если интересно, кину в комменты пару кадров CAF/MTI с реальных данных — чтобы было видно, что это не фейк и не «сгенерил ChatGPT»
Да, у нас антенная решётка на 5 элементов, где одна антенна — референсная, принимает прямой сигнал от передатчика DVB-T2, а четыре остальные — surveillance-каналы, ловят отражёнку. Так что архитектура вполне «нормальная»
Что касается синхронизации — речь не про источник, а про внутреннюю фазовую когерентность между каналами KrakenSDR. Несмотря на общий опорный генератор и GPSDO, на практике между каналами остаются небольшие фазовые и временные дрейфы. Для задач DOA и PCL это критично — особенно когда источник (DVB-T2) не когерентен с приёмником. Поэтому приходится компенсировать сдвиги уже на уровне DSP, чтобы CAF не «размазывался».
Для валидации модели пассивного радара (KrakenSDR + DVB-T2) мы собирали IQ-данные примерно в 12 км от аэродрома со спортивными одноместными самолётами — они по параметрам ближе всего к дронам самолётного типа среднего класса..
Цель была — набрать хотя бы 8–10 тыс. положительных CAF-патчей («воздушная цель») и столько же отрицательных для baseline. После настройки систему перенесли в «коридор» вероятного пролёта дронов и развернули 3 узла на расстоянии ~5 км друг от друга, на высоте 15–20 м.
За неделю через сектор пролетели четыре цели — три уверенно задетектировали и оттрекали до выхода из зоны, четвертая прошла по касательной и засеклась одним прибором. Дальность устойчивого обнаружения — порядка 12–15 км, зависит от азимута и высоты цели и естественно от высоты наших антенн.
С удовольствием.
Спасибо за вопрос по делу.
Итак, что мы имеем
Поток комплексных отсчётов IQ с reference-антенны (прямой сигнал DVB-T2).
Наша задача — найти границу OFDM-кадра / символа, чтобы потом корректно делать CAF.
Как мы находим начало кадра
Используем P1-символ
В DVB-T2 каждый кадр начинается с P1 — это специально зарезервированный уникальный OFDM-символ с известной паттерной структурой.
Мы делаем:
корреляцию входного потока IQ с эталоном P1,
ищем максимум корреляции,
пик корреляции → начало кадра.
Это даёт очень устойчивую синхронизацию даже при низком SNR.
2. Дополнительная проверка по циклическому префиксу
После грубой синхронизации по P1, делаем тонкую синхронизацию:
сверяем основную часть OFDM-символа с копией из CP,
ищем максимум совпадения,
уточняем временной сдвиг до точности десятков отсчётов.
3. Коррекция частоты (CFO)
Перед CAF это важно:
оцениваем остаточный частотный сдвиг по фазе CP,
компенсируем
нормализуем символы
4. Вырезаем ровно N отсчётов для каждого символа
Когда начало кадра найдено, дальше уже несложно:
N_fft отсчётов — сам OFDM-символ
CP_len отсчётов — циклический префикс
Мы адаптивно “подтягиваем” рамку по CP, чтобы дрейф не накапливался.
Корреляция с P1 — поиск начала кадра :
На вход сюда подаётся:
iq — ваш поток IQ с reference-канала
p1_ref — заранее сгенерированный эталонный P1 (есть в стандарте DVB-T2, или берётся из предварительного захвата)
Этот шаг обычно находит границу кадра с точностью ±5…10 отсчётов даже на низком SNR.
Если заинтересует, могу сбросить в мессаге полный пайплайн с тонкой синхронизацией по циклическому префиксу (CP)
Да, KrakenSDR дороже HackRF, но для 5-канального стенда с RPi5 бюджет всё ещё вполне «домашний». Главная мысль была — многоканальный SDR уже не требует профессиональной РЛС, и собрать рабочий стенд реально без грантов.
Да, вы всё верно описали — без автоматической рекалибровки KrakenSDR каналы через пару часов реально начнут «танцевать вразнобой»
У нас рекалибровка включена, и она решает сразу несколько проблем: фазовые сдвиги между каналами, рассинхрон цифровой логики и рассогласование буферов после USB. Без неё CAF и треки постепенно теряли бы точность.
Кроме встроенной процедуры, мы добавляем DSP-компенсацию, чтобы минимизировать остаточные сдвиги и обеспечить стабильность DOA/CAF при длительных записях.
Если интересно, могу коротко описать, как реализована эта фазовая коррекция и интерполяция сигналов на Python — там есть несколько забавных нюансов, которые неожиданно сильно влияют на точность.
Спасибо за разбор — приятно, что кто-то реально дочитал до конца.
Да, согласен: статья не претендует на учебник по радиолокации. Цель была показать, что пассивный радар на KrakenSDR и DVB-T2 реально работает, а не расписать весь DSP пайплайн в деталях. Сейчас готовим отдельный пост с результатами: CAF-карты, CFAR-детекции, треки по Kalman filter’у и т.п. — будет куда нагляднее.
По терминам — да, мешанина сознательная. Мы держали фокус на англоязычном SDR/DSP комьюнити, где CAF, CFAR и MTI никто не переводит, в котором мы последние 20 лет вращаемся. А вот «антенный массив» оставили по-русски, чтобы не писать array . В будущем сделаем нормальную редактуру для рускоязычного клиента, чтобы не резало глаз радиотехникам.
Схемы и «тепловые карты» добавим — просто хотелось выкатить проект в живом виде, пока он дышит, а не отполированный PDF через полгода.
Если интересно, кину в комменты пару кадров CAF/MTI с реальных данных — чтобы было видно, что это не фейк и не «сгенерил ChatGPT»
Да, у нас антенная решётка на 5 элементов, где одна антенна — референсная, принимает прямой сигнал от передатчика DVB-T2, а четыре остальные — surveillance-каналы, ловят отражёнку. Так что архитектура вполне «нормальная»
Что касается синхронизации — речь не про источник, а про внутреннюю фазовую когерентность между каналами KrakenSDR. Несмотря на общий опорный генератор и GPSDO, на практике между каналами остаются небольшие фазовые и временные дрейфы. Для задач DOA и PCL это критично — особенно когда источник (DVB-T2) не когерентен с приёмником. Поэтому приходится компенсировать сдвиги уже на уровне DSP, чтобы CAF не «размазывался».
Да, результаты есть 🙂
Для валидации модели пассивного радара (KrakenSDR + DVB-T2) мы собирали IQ-данные примерно в 12 км от аэродрома со спортивными одноместными самолётами — они по параметрам ближе всего к дронам самолётного типа среднего класса..
Цель была — набрать хотя бы 8–10 тыс. положительных CAF-патчей («воздушная цель») и столько же отрицательных для baseline. После настройки систему перенесли в «коридор» вероятного пролёта дронов и развернули 3 узла на расстоянии ~5 км друг от друга, на высоте 15–20 м.
За неделю через сектор пролетели четыре цели — три уверенно задетектировали и оттрекали до выхода из зоны, четвертая прошла по касательной и засеклась одним прибором.
Дальность устойчивого обнаружения — порядка 12–15 км, зависит от азимута и высоты цели и естественно от высоты наших антенн.