167 lines
15 KiB
Markdown
167 lines
15 KiB
Markdown
# CLOCK-001: независимые такты перед RF-001
|
||
|
||
17 сентября 2026 года. Статус **PARTIAL**: программный приёмник прошёл основную
|
||
сетку до ±50 ppm, но потерял длинные пакеты при ±100 ppm. Последняя точка
|
||
служит только стресс-тестом. Частоты реальных генераторов Auron HackRF Plus
|
||
не измерялись. SDR не открывался, `RF TX = 0`. Данные каждого запуска
|
||
сохранены в `data/processed/clock001/results.json`.
|
||
|
||
## Модель и вход приёмника
|
||
|
||
TX строит QPSK/FEC 2/3/RRC при номинальных 8 Мвыб/с и 500 ксимв/с. Для
|
||
приёмника с независимой частотой `Fs_RX = Fs_TX · (1 + ε)`, где
|
||
`ε = ppm · 10⁻⁶`, программа берёт комплексную TX-волну в моменты
|
||
`n / (1 + ε)` по её исходной сетке. Дробные отсчёты получаются линейной
|
||
интерполяцией. Поэтому ошибка момента **накапливается по времени**, а не
|
||
подменяется одним постоянным сдвигом. Интерполяция не описывает аналоговый
|
||
тракт АЦП, шум генераторов или аппаратное квантование.
|
||
|
||
CFO добавляется отдельно как поворот с частотой в герцах физического времени
|
||
RX; начальная фаза и AWGN задаются отдельными параметрами. Даже при нулевом
|
||
внешнем CFO цифровая несущая 125 кГц из-за изменения частоты выборки даёт
|
||
остаток `(125000 + CFO) / (1 + ε) − 125000` Гц относительно номинального
|
||
цифрового смесителя. Отчёт хранит и заданный CFO, и этот ожидаемый остаток;
|
||
один не выдаётся за другой. Частотный тест проверяет оба эффекта раздельно.
|
||
|
||
Программа `tools/clock001.py` строит по три пакета каждого размера с паузой
|
||
5 мс и seed `20260917`. Нагрузка 256 байт совпадает с RF-001; для 512 и
|
||
1012 байт та же SHA-последовательность продлена. **1012 байт** заполняют
|
||
допустимый PHY-пакет 1024 байта с 12 байтами заголовка и CRC. Во всех
|
||
39 точках ppm-сетки приёмник получает только полученный IQ и номинальный
|
||
радиорежим. TX-границы, исходные пакеты, заданный ppm/CFO и число пакетов
|
||
используются только после декодирования для оценки.
|
||
|
||
```powershell
|
||
python -B -X utf8 tools/clock001.py `
|
||
--numba-packages C:\Users\user\Desktop\projects\SDR_Rover\.lab053_cpu_runtime\packages
|
||
```
|
||
|
||
Параметр с локальным путём к Numba нужен на этом ПК; в обычном окружении с
|
||
зависимостями проекта он не требуется. Команда отказывается перезаписывать
|
||
готовый отчёт.
|
||
|
||
## Строгие результаты
|
||
|
||
В таблице каждая ячейка означает число **точных пакетов из трёх** после
|
||
PHY/FEC/CRC. CFO, фаза и AWGN в этой сетке равны нулю/отсутствуют.
|
||
|
||
| Payload | 0 | ±1 ppm | ±5 ppm | ±10 ppm | ±20 ppm | ±50 ppm | ±100 ppm, стресс |
|
||
|---|---:|---:|---:|---:|---:|---:|---:|
|
||
| 256 байт | 3/3 | 3/3 в обе стороны | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 |
|
||
| 512 байт | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 |
|
||
| 1012 байт | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 | **0/3** |
|
||
|
||
Основная сетка 0, ±1, ±5, ±10, ±20 и ±50 ppm: **99/99**. Наибольшая
|
||
симметричная проверенная точка со 100% точных пакетов для всех размеров:
|
||
**±50 ppm**. Для 256 и 512 байт стресс ±100 ppm тоже дал 3/3 в обе стороны.
|
||
Одиночный пакет 1012 байт при −100 и +100 ppm дал 0/1; в обоих случаях
|
||
найден один корреляционный кандидат, но CRC-пакета нет. Значит, новый поиск
|
||
преамбулы перед следующим пакетом не устраняет эту потерю внутри текущего
|
||
длинного пакета. При ±100 ppm модель накапливает по нему ±0,7572 символа.
|
||
Контроль с отдельной кубической интерполяцией повторил для одиночного
|
||
1012-байтного пакета 1/1 при ±50 и 0/1 при ±100 ppm. Вывод не зависит
|
||
только от выбора линейного интерполятора в основном опыте.
|
||
|
||
Текущий приёмник оценивает начало **каждого** пакета заново, затем выбирает
|
||
его символы с постоянным шагом 16 отсчётов. Для 1012 байт при −50 ppm
|
||
медианная ошибка в начале/расчётная ошибка в конце составили
|
||
−0,0325 / +0,3461 символа; при +50 ppm +0,0322 / −0,3464. Разность по
|
||
модели равна ±0,3786 символа. Начальную ошибку считаем по началу принятого
|
||
CRC-пакета и известной **после приёма** TX-шкале. Конечная ошибка
|
||
экстраполирована из заданного ppm при фиксированном шаге приёмника; это не
|
||
независимое измерение последнего символа. Для потерянного пакета эти оценки
|
||
равны `null`, а введённый моделью дрейф указан отдельно.
|
||
|
||
В JSON `correlation_candidates` считает кандидатов поиска. Поле
|
||
`detected_packets` равно числу CRC-valid пакетов: нынешний API не выдаёт
|
||
отдельное число пакетов, распознанных до CRC. Поля точности и потерь
|
||
считаются отдельно по TX-ведомости после приёма.
|
||
|
||
Отдельно проверены шесть сочетаний для **256 байт**, каждое с тремя пакетами:
|
||
|
||
| ppm | CFO | Фаза | Eb/N0 | Точные пакеты |
|
||
|---:|---:|---:|---:|---:|
|
||
| +5 | +20 Гц | +15° | 9 и 12 дБ | 3/3 при каждом уровне |
|
||
| +10 | +100 Гц | +90° | 9 и 12 дБ | 3/3 при каждом уровне |
|
||
| +20 | +100 Гц | −45° | 9 и 12 дБ | 3/3 при каждом уровне |
|
||
|
||
Итого **18/18**. Шум задан прежней программной AWGN-моделью VIDEO-005;
|
||
это не оценка реального RF-канала.
|
||
|
||
## Компенсация и скорость
|
||
|
||
Для основной сетки повторной оценки момента по преамбуле каждого пакета
|
||
хватило. **Непрерывное слежение в рабочий приёмник не добавлялось.** Для
|
||
расширения диапазона до ±100 ppm на пакете 1012 байт потребовалась бы
|
||
коррекция внутри пакета, например отдельное исследование детектора ошибки
|
||
момента [Gardner для BPSK/QPSK](https://doi.org/10.1109/TCOM.1986.1096561)
|
||
с интерполяцией и петлёй. [Документация GNU Radio](https://www.gnuradio.org/doc/doxygen/classgr_1_1digital_1_1symbol__sync__cc.html)
|
||
показывает такой класс синхронизатора и его параметры. Перед включением
|
||
понадобятся строгие CRC-тесты на всей сетке, проверка без истинного ppm и
|
||
новый замер скорости. Старый BPSK-детектор сюда не переносился.
|
||
|
||
На каноническом потоке VIDEO-005 из 32 длинных пакетов с добавленными
|
||
+20 ppm, +20 Гц CFO, фазой +15° и Eb/N0 9 дБ получено **32/32** при каждом
|
||
из трёх прогретых запусков. Времена приёмника: 0,272 / 0,262 / 0,262 с;
|
||
длительность IQ 0,485764 с; медианный **RADIO RECEIVER REALTIME FACTOR =
|
||
0,540**. Построение канала и ресемплирование в это время не входят. Для
|
||
сравнения, сохранённый ориентир VIDEO-005 равен 0,578 на другом входе;
|
||
разница не доказывает ускорения. Первый запуск ppm-сетки включал JIT и не
|
||
использован для оценки скорости. Порог 0,67 на этом ПК выполнен.
|
||
|
||
## Code quality audit
|
||
|
||
Рабочий `receive_iq_stream()` и его защитные проверки не менялись. Новый
|
||
пересчёт временной шкалы, сравнение с эталоном и запись JSON остаются вне
|
||
пути приёма. Отдельный `cProfile` того же 32-пакетного IQ занял 0,293 с;
|
||
его время включает накладные расходы профилировщика и не подставляется в
|
||
фактор 0,540. Основные этапы:
|
||
|
||
| Этап | Время, мс | Доля профиля | Вызовы | Основные массивы и копии |
|
||
|---|---:|---:|---:|---|
|
||
| Цифровое смещение несущей | 16,4 | 5,6% | 1 | Осциллятор и baseband |
|
||
| Согласованный RRC | 62,1 | 21,2% | 1 | Выход и внутренние FFT-буферы |
|
||
| Поиск преамбул | 47,6 | 16,2% | 1 | Две корреляции и массивы энергии |
|
||
| Восстановление момента | 9,9 | 3,4% | 32 | Индексы и символы каждого кандидата |
|
||
| Оценка CFO и фазы | 12,2 | 4,2% | 32 | Исправленные символы |
|
||
| PHY-заголовок | 0,8 | 0,3% | 32 | Короткие массивы заголовка |
|
||
| Слежение за фазой тела | 78,4 | 26,8% | 32 | Копия символов пакета и блоки решений |
|
||
| Строгий PHY/FEC/CRC | 54,8 | 18,7% | 32 | Мягкие биты и рабочие массивы декодера |
|
||
|
||
Число аллокаций NumPy не измерялось; в таблице перечислены видимые по коду
|
||
массивы. Resampling создаёт один выходной complex64 IQ и временные массивы
|
||
до миллиона отсчётов за блок; в измеренное время приёмника он не входит. Проверки
|
||
размеров и конечности IQ оставлены как защита входа; диапазон ppm и длина
|
||
пакета проверяются при создании опыта. Проверка эталона находится после
|
||
приёмника. Ruff не нашёл неиспользуемых импортов, временных compatibility
|
||
wrappers и лабораторных ветвей в новом коде нет. Канонический генератор
|
||
32-пакетного VIDEO-005 входа также строит сигнал с нарушениями канала,
|
||
который CLOCK-001 не использует; это один офлайн-вызов, не приёмный hot path.
|
||
Удалять или переписывать его здесь нет оснований. Поведение VIDEO-005
|
||
проверено его неизменённым шлюзом: 178 тестов прошли.
|
||
|
||
| Предмет | Место | Почему проверен | Решение |
|
||
|---|---|---|---|
|
||
| Дополнительный IQ от канонического генератора | `tools/clock001.py`, `run()` | Создаётся, но не участвует в CLOCK-входе | **KEEP**: однократная офлайн-цена за неизменный эталон VIDEO-005 |
|
||
| Длинная оркестрация опыта | `tools/clock001.py`, `run()` | Собирает сетку, сочетания и замер | **KEEP**: не исполняется в рабочем приёмнике; шаги явно разделены |
|
||
| Проверка конечности всего TX IQ | `tools/clock001.py`, `sample_independent_clock()` | Один проход по большому массиву | **KEEP**: защита от повреждённого входа до интерполяции |
|
||
|
||
В CLOCK-001 нет внешнего erasure FEC и видеотранспорта: это опыт с PHY-пакетами,
|
||
поэтому их время нельзя включать в фактор радиоприёмника.
|
||
|
||
## Следующий аппаратный план
|
||
|
||
План RF-001 разделён на **RF-001A** с проводной общей опорой 10 МГц как
|
||
лабораторным baseline и **RF-001B** с независимыми тактами. В B провод
|
||
CLKOUT → CLKIN отключён. Остальные параметры и TX-волна должны совпасть;
|
||
оба режима сохраняют исходный RX IQ и полные наблюдения счётчиков. В B
|
||
нужны последовательности оценок CFO и моментов пакетов, чтобы после
|
||
приёма оценить их изменение во времени и фактическую разницу частот
|
||
дискретизации. Моделируемые ppm не считаются характеристикой плат.
|
||
|
||
**Готовность A и B: да, только к подготовке контролируемого опыта.**
|
||
Фактические частоты, соединения, gain и RF-условия ещё не проверены. Для
|
||
каждого аппаратного сеанса потребуется отдельный preflight и прямое
|
||
разрешение. CLOCK-001 не открывала SDR, не меняла аппаратную конфигурацию
|
||
и не выполняла RF TX/RX. Коммита и push для этого этапа нет.
|